summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/screenshot.c2
-rw-r--r--video/mp_image.c3
-rw-r--r--video/out/gl_video.c6
-rw-r--r--video/out/gl_video.h1
-rw-r--r--video/out/vo.c43
-rw-r--r--video/out/vo.h5
-rw-r--r--video/out/vo_direct3d.c27
-rw-r--r--video/out/vo_opengl.c7
-rw-r--r--video/out/vo_opengl_cb.c9
-rw-r--r--video/out/vo_sdl.c14
-rw-r--r--video/out/vo_vaapi.c11
-rw-r--r--video/out/vo_vdpau.c10
-rw-r--r--video/out/vo_wayland.c11
-rw-r--r--video/out/vo_x11.c13
-rw-r--r--video/out/vo_xv.c12
15 files changed, 39 insertions, 135 deletions
diff --git a/player/screenshot.c b/player/screenshot.c
index 2a1aaf6746..702e2dd766 100644
--- a/player/screenshot.c
+++ b/player/screenshot.c
@@ -337,7 +337,7 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode)
vo_wait_frame(mpctx->video_out); // important for each-frame mode
if (mode != MODE_FULL_WINDOW)
- vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &image);
+ image = vo_get_current_frame(mpctx->video_out);
if (!image) {
vo_control(mpctx->video_out, VOCTRL_SCREENSHOT_WIN, &image);
mode = MODE_FULL_WINDOW;
diff --git a/video/mp_image.c b/video/mp_image.c
index cf17429d89..269db4b2b0 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -252,6 +252,9 @@ void mp_image_steal_data(struct mp_image *dst, struct mp_image *src)
// while img is left untouched.
struct mp_image *mp_image_new_ref(struct mp_image *img)
{
+ if (!img)
+ return NULL;
+
if (!img->refcount)
return mp_image_new_copy(img);
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 2eeb86f353..bc1e04b0e6 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -2188,12 +2188,6 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi)
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
-struct mp_image *gl_video_download_image(struct gl_video *p)
-{
- struct video_image *vimg = &p->image;
- return vimg->mpi ? mp_image_new_ref(vimg->mpi) : NULL;
-}
-
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
{
struct gl_video *p = ctx;
diff --git a/video/out/gl_video.h b/video/out/gl_video.h
index f62a292785..195ab40902 100644
--- a/video/out/gl_video.h
+++ b/video/out/gl_video.h
@@ -72,7 +72,6 @@ void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b);
void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d);
void gl_video_upload_image(struct gl_video *p, struct mp_image *img);
void gl_video_render_frame(struct gl_video *p, int fbo, struct frame_timing *t);
-struct mp_image *gl_video_download_image(struct gl_video *p);
void gl_video_resize(struct gl_video *p, struct mp_rect *window,
struct mp_rect *src, struct mp_rect *dst,
struct mp_osd_res *osd, bool vflip);
diff --git a/video/out/vo.c b/video/out/vo.c
index 36bd2a9c2e..11690afb67 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -135,7 +135,8 @@ struct vo_internal {
int64_t drop_count;
bool dropped_frame; // the previous frame was dropped
- struct mp_image *dropped_image; // used to possibly redraw the dropped frame
+
+ struct mp_image *current_frame; // last frame queued to the VO
int64_t wakeup_pts; // time at which to pull frame from decoder
@@ -333,6 +334,8 @@ static void run_reconfig(void *p)
int flags = *(int *)pp[2];
int *ret = pp[3];
+ struct vo_internal *in = vo->in;
+
vo->dwidth = params->d_w;
vo->dheight = params->d_h;
@@ -347,7 +350,11 @@ static void run_reconfig(void *p)
talloc_free(vo->params);
vo->params = NULL;
}
- forget_frames(vo); // implicitly synchronized
+
+ pthread_mutex_lock(&in->lock);
+ mp_image_unrefp(&in->current_frame);
+ forget_frames(vo);
+ pthread_mutex_unlock(&in->lock);
update_display_fps(vo);
}
@@ -388,7 +395,7 @@ static void forget_frames(struct vo *vo)
in->hasframe_rendered = false;
in->drop_count = 0;
mp_image_unrefp(&in->frame_queued);
- mp_image_unrefp(&in->dropped_image);
+ // don't unref current_frame; we always want to be able to redraw it
}
#ifndef __MINGW32__
@@ -555,7 +562,8 @@ static bool render_frame(struct vo *vo)
if (in->vsync_timed && !in->hasframe)
goto nothing_done;
- mp_image_unrefp(&in->dropped_image);
+ if (img)
+ mp_image_setrefp(&in->current_frame, img);
in->rendering = true;
in->frame_queued = NULL;
@@ -598,7 +606,7 @@ static bool render_frame(struct vo *vo)
}
if (in->dropped_frame) {
- in->dropped_image = img;
+ talloc_free(img);
} else {
in->hasframe_rendered = true;
pthread_mutex_unlock(&in->lock);
@@ -679,20 +687,21 @@ static void do_redraw(struct vo *vo)
pthread_mutex_lock(&in->lock);
in->request_redraw = false;
in->want_redraw = false;
- bool skip = !in->paused && in->dropped_frame;
- struct mp_image *img = in->dropped_image;
- if (!skip) {
- in->dropped_image = NULL;
+ bool force_full_redraw = in->dropped_frame;
+ struct mp_image *img = NULL;
+ if (vo->config_ok)
+ img = mp_image_new_ref(in->current_frame);
+ if (img)
in->dropped_frame = false;
- }
pthread_mutex_unlock(&in->lock);
- if (!vo->config_ok || skip)
+ if (!img)
return;
- if (img) {
+ if (force_full_redraw) {
vo->driver->draw_image(vo, img);
} else {
+ talloc_free(img);
if (vo->driver->control(vo, VOCTRL_REDRAW_FRAME, NULL) < 1)
return;
}
@@ -749,6 +758,7 @@ static void *vo_thread(void *ptr)
wait_vo(vo, wait_until);
}
forget_frames(vo); // implicitly synchronized
+ mp_image_unrefp(&in->current_frame);
vo->driver->uninit(vo);
return NULL;
}
@@ -920,6 +930,15 @@ int vo_query_and_reset_events(struct vo *vo, int events)
return r;
}
+struct mp_image *vo_get_current_frame(struct vo *vo)
+{
+ struct vo_internal *in = vo->in;
+ pthread_mutex_lock(&in->lock);
+ struct mp_image *r = mp_image_new_ref(vo->in->current_frame);
+ pthread_mutex_unlock(&in->lock);
+ return r;
+}
+
/**
* \brief lookup an integer in a table, table must have 0 as the last key
* \param key key to search for
diff --git a/video/out/vo.h b/video/out/vo.h
index 9ae489e2cd..e5eccd3f86 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -97,9 +97,7 @@ enum mp_voctrl {
// imgfmt/w/h/d_w/d_h can be omitted for convenience.
VOCTRL_GET_COLORSPACE, // struct mp_image_params*
- // Retrieve original image.
- VOCTRL_SCREENSHOT, // struct mp_image**
- // Retrieve window contents.
+ // Retrieve window contents. (Normal screenshots use vo_get_current_frame().)
VOCTRL_SCREENSHOT_WIN, // struct mp_image**
VOCTRL_SET_COMMAND_LINE, // char**
@@ -319,6 +317,7 @@ void vo_increment_drop_count(struct vo *vo, int64_t n);
void vo_query_formats(struct vo *vo, uint8_t *list);
void vo_event(struct vo *vo, int event);
int vo_query_and_reset_events(struct vo *vo, int events);
+struct mp_image *vo_get_current_frame(struct vo *vo);
void vo_set_flip_queue_params(struct vo *vo, int64_t offset_us, bool vsync_timed);
int64_t vo_get_vsync_interval(struct vo *vo);
diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c
index 5b4fb7856a..88eb619b8a 100644
--- a/video/out/vo_direct3d.c
+++ b/video/out/vo_direct3d.c
@@ -225,7 +225,6 @@ static void d3d_clear_video_textures(d3d_priv *priv);
static bool resize_d3d(d3d_priv *priv);
static void uninit(struct vo *vo);
static void flip_page(struct vo *vo);
-static mp_image_t *get_screenshot(d3d_priv *priv);
static mp_image_t *get_window_screenshot(d3d_priv *priv);
static void draw_osd(struct vo *vo);
static bool change_d3d_backbuffer(d3d_priv *priv);
@@ -1260,9 +1259,6 @@ 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 mp_image **)data = get_screenshot(priv);
- return VO_TRUE;
case VOCTRL_SCREENSHOT_WIN:
*(struct mp_image **)data = get_window_screenshot(priv);
return VO_TRUE;
@@ -1445,29 +1441,6 @@ done:
talloc_free(mpi);
}
-static mp_image_t *get_screenshot(d3d_priv *priv)
-{
- if (!priv->d3d_device)
- return NULL;
-
- if (!priv->have_image)
- return NULL;
-
- if (!priv->vo->params)
- return NULL;
-
- struct mp_image buffer;
- if (!get_video_buffer(priv, &buffer))
- return NULL;
-
- struct mp_image *image = mp_image_new_copy(&buffer);
- if (image)
- mp_image_set_attributes(image, priv->vo->params);
-
- d3d_unlock_video_objects(priv);
- return image;
-}
-
static mp_image_t *get_window_screenshot(d3d_priv *priv)
{
D3DDISPLAYMODE mode;
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 618ed90aff..0cd8d49343 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -349,15 +349,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
mpgl_unlock(p->glctx);
return VO_TRUE;
case VOCTRL_SCREENSHOT_WIN:
- case VOCTRL_SCREENSHOT:
- {
mpgl_lock(p->glctx);
- *(struct mp_image **)data = request == VOCTRL_SCREENSHOT
- ? gl_video_download_image(p->renderer)
- : glGetWindowScreenshot(p->gl);
+ *(struct mp_image **)data = glGetWindowScreenshot(p->gl);
mpgl_unlock(p->glctx);
return true;
- }
case VOCTRL_GET_HWDEC_INFO: {
struct mp_hwdec_info **arg = data;
*arg = &p->hwdec_info;
diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c
index a974305b85..cee0bc1d46 100644
--- a/video/out/vo_opengl_cb.c
+++ b/video/out/vo_opengl_cb.c
@@ -64,7 +64,6 @@ struct mpv_opengl_cb_context {
mpv_opengl_cb_update_fn update_cb;
void *update_cb_ctx;
struct mp_image *waiting_frame;
- struct mp_image *displayed_frame;
struct mp_image **frame_queue;
int queued_frames;
struct mp_image_params img_params;
@@ -358,7 +357,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
pthread_mutex_lock(&p->ctx->lock);
mp_image_setrefp(&p->ctx->waiting_frame, mpi);
- mp_image_setrefp(&p->ctx->displayed_frame, mpi);
talloc_free(mpi);
pthread_mutex_unlock(&p->ctx->lock);
}
@@ -488,12 +486,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
update(p);
pthread_mutex_unlock(&p->ctx->lock);
return VO_TRUE;
- case VOCTRL_SCREENSHOT: {
- pthread_mutex_lock(&p->ctx->lock);
- *(struct mp_image **)data = mp_image_new_ref(p->ctx->displayed_frame);
- pthread_mutex_unlock(&p->ctx->lock);
- return VO_TRUE;
- }
case VOCTRL_SET_COMMAND_LINE: {
char *arg = data;
return reparse_cmdline(p, arg);
@@ -514,7 +506,6 @@ static void uninit(struct vo *vo)
pthread_mutex_lock(&p->ctx->lock);
forget_frames(p->ctx);
- mp_image_unrefp(&p->ctx->displayed_frame);
p->ctx->img_params = (struct mp_image_params){0};
p->ctx->reconfigured = true;
p->ctx->active = NULL;
diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c
index 9b7605643a..9a06f2e3c4 100644
--- a/video/out/vo_sdl.c
+++ b/video/out/vo_sdl.c
@@ -172,7 +172,6 @@ struct priv {
SDL_Texture *tex;
int tex_swapped;
struct mp_image_params params;
- mp_image_t *ssmpi;
struct mp_rect src_rect;
struct mp_rect dst_rect;
struct mp_osd_res osd_res;
@@ -638,7 +637,6 @@ static void uninit(struct vo *vo)
{
struct priv *vc = vo->priv;
destroy_renderer(vo);
- talloc_free(vc->ssmpi);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
talloc_free(vc);
}
@@ -913,9 +911,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
mp_image_copy(&texmpi, mpi);
SDL_UnlockTexture(vc->tex);
-
- talloc_free(vc->ssmpi);
- vc->ssmpi = mpi;
}
SDL_Rect src, dst;
@@ -941,12 +936,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
draw_osd(vo);
}
-static struct mp_image *get_screenshot(struct vo *vo)
-{
- struct priv *vc = vo->priv;
- return vc->ssmpi ? mp_image_new_ref(vc->ssmpi) : NULL;
-}
-
static struct mp_image *get_window_screenshot(struct vo *vo)
{
struct priv *vc = vo->priv;
@@ -1018,9 +1007,6 @@ 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 mp_image **)data = get_screenshot(vo);
- return true;
case VOCTRL_SCREENSHOT_WIN:
*(struct mp_image **)data = get_window_screenshot(vo);
return true;
diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c
index 1c4b016e6b..de2c975823 100644
--- a/video/out/vo_vaapi.c
+++ b/video/out/vo_vaapi.c
@@ -298,14 +298,6 @@ static void draw_image(struct vo *vo, struct mp_image *mpi)
draw_osd(vo);
}
-static struct mp_image *get_screenshot(struct priv *p)
-{
- struct mp_image *hwimg = p->output_surfaces[p->visible_surface];
- if (!hwimg)
- return NULL;
- return mp_image_new_ref(hwimg);
-}
-
static void free_subpicture(struct priv *p, struct vaapi_osd_image *img)
{
if (img->image.image_id != VA_INVALID_ID)
@@ -541,9 +533,6 @@ 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 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 1a1287c1d7..528756c05f 100644
--- a/video/out/vo_vdpau.c
+++ b/video/out/vo_vdpau.c
@@ -1049,18 +1049,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
forget_frames(vo, true);
return true;
case VOCTRL_SCREENSHOT_WIN:
- case VOCTRL_SCREENSHOT:
- {
if (!status_ok(vo))
return false;
- if (request == VOCTRL_SCREENSHOT_WIN) {
- *(struct mp_image **)data = get_window_screenshot(vo);
- } else {
- *(struct mp_image **)data =
- vc->current_image ? mp_image_new_ref(vc->current_image) : NULL;
- }
+ *(struct mp_image **)data = get_window_screenshot(vo);
return true;
- }
case VOCTRL_GET_PREF_DEINT:
*(int *)data = vc->deint;
return true;
diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c
index ed23f8af3d..9da24ddf3e 100644
--- a/video/out/vo_wayland.c
+++ b/video/out/vo_wayland.c
@@ -268,14 +268,6 @@ static bool redraw_frame(struct priv *p)
return true;
}
-static mp_image_t *get_screenshot(struct priv *p)
-{
- if (!p->original_image)
- return NULL;
-
- return mp_image_new_ref(p->original_image);
-}
-
static bool resize(struct priv *p)
{
struct vo_wayland_state *wl = p->wl;
@@ -689,9 +681,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
}
case VOCTRL_REDRAW_FRAME:
return redraw_frame(p);
- case VOCTRL_SCREENSHOT:
- *(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 32d9b731fd..aa578d4883 100644
--- a/video/out/vo_x11.c
+++ b/video/out/vo_x11.c
@@ -423,16 +423,6 @@ static struct mp_image get_x_buffer(struct priv *p, int buf_index)
return img;
}
-static mp_image_t *get_screenshot(struct vo *vo)
-{
- struct priv *p = vo->priv;
-
- if (!p->original_image)
- return NULL;
-
- return mp_image_new_ref(p->original_image);
-}
-
static void wait_for_completion(struct vo *vo, int max_outstanding)
{
#if HAVE_SHM && HAVE_XEXT
@@ -619,9 +609,6 @@ 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 mp_image **)data = get_screenshot(vo);
- return true;
}
int events = 0;
diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c
index e506fc9359..11c6efc26e 100644
--- a/video/out/vo_xv.c
+++ b/video/out/vo_xv.c
@@ -648,15 +648,6 @@ static void flip_page(struct vo *vo)
XSync(vo->x11->display, False);
}
-static mp_image_t *get_screenshot(struct vo *vo)
-{
- struct xvctx *ctx = vo->priv;
- if (!ctx->original_image)
- return NULL;
-
- return mp_image_new_ref(ctx->original_image);
-}
-
// Note: REDRAW_FRAME can call this with NULL.
static void draw_image(struct vo *vo, mp_image_t *mpi)
{
@@ -839,9 +830,6 @@ 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 mp_image **)data = get_screenshot(vo);
- return true;
}
int events = 0;
int r = vo_x11_control(vo, &events, request, data);