summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-04-20 22:12:29 +0200
committerJan Ekström <jeebjp@gmail.com>2018-04-29 02:21:32 +0300
commit0be3a94e0b81d553849f9520f7ee9f2b6e34c6b4 (patch)
tree134776298cf75cab691454409f2c359096ba560b
parent36565c099debbcfdfe800a5c2c1c9c9fada0a48b (diff)
downloadmpv-0be3a94e0b81d553849f9520f7ee9f2b6e34c6b4.tar.bz2
mpv-0be3a94e0b81d553849f9520f7ee9f2b6e34c6b4.tar.xz
vo_libmpv: support GPU rendered screenshots
Like DR, this needed a lot of preparation, and here's the boring glue code that finally implements it.
-rw-r--r--video/out/gpu/libmpv_gpu.c9
-rw-r--r--video/out/libmpv.h2
-rw-r--r--video/out/vo_libmpv.c34
3 files changed, 45 insertions, 0 deletions
diff --git a/video/out/gpu/libmpv_gpu.c b/video/out/gpu/libmpv_gpu.c
index 3674d678c7..f687c97b51 100644
--- a/video/out/gpu/libmpv_gpu.c
+++ b/video/out/gpu/libmpv_gpu.c
@@ -190,6 +190,14 @@ static struct mp_image *get_image(struct render_backend *ctx, int imgfmt,
return gl_video_get_image(p->renderer, imgfmt, w, h, stride_align);
}
+static void screenshot(struct render_backend *ctx, struct vo_frame *frame,
+ struct voctrl_screenshot *args)
+{
+ struct priv *p = ctx->priv;
+
+ gl_video_screenshot(p->renderer, frame, args);
+}
+
static void destroy(struct render_backend *ctx)
{
struct priv *p = ctx->priv;
@@ -217,5 +225,6 @@ const struct render_backend_fns render_backend_gpu = {
.get_target_size = get_target_size,
.render = render,
.get_image = get_image,
+ .screenshot = screenshot,
.destroy = destroy,
};
diff --git a/video/out/libmpv.h b/video/out/libmpv.h
index 4544a278db..dc9d523b23 100644
--- a/video/out/libmpv.h
+++ b/video/out/libmpv.h
@@ -52,6 +52,8 @@ struct render_backend_fns {
void (*reconfig)(struct render_backend *ctx, struct mp_image_params *params);
// Like VOCTRL_RESET.
void (*reset)(struct render_backend *ctx);
+ void (*screenshot)(struct render_backend *ctx, struct vo_frame *frame,
+ struct voctrl_screenshot *args);
// Like vo_driver.get_image().
struct mp_image *(*get_image)(struct render_backend *ctx, int imgfmt,
int w, int h, int stride_align);
diff --git a/video/out/vo_libmpv.c b/video/out/vo_libmpv.c
index ba8a19f947..ef5dc9809e 100644
--- a/video/out/vo_libmpv.c
+++ b/video/out/vo_libmpv.c
@@ -511,6 +511,29 @@ static int query_format(struct vo *vo, int format)
return ok;
}
+static void run_control_on_render_thread(void *p)
+{
+ void **args = p;
+ struct mpv_render_context *ctx = args[0];
+ int request = (intptr_t)args[1];
+ void *data = args[2];
+ int ret = VO_NOTIMPL;
+
+ switch (request) {
+ case VOCTRL_SCREENSHOT: {
+ pthread_mutex_lock(&ctx->lock);
+ struct vo_frame *frame = vo_frame_ref(ctx->cur_frame);
+ pthread_mutex_unlock(&ctx->lock);
+ if (frame && ctx->renderer->fns->screenshot)
+ ctx->renderer->fns->screenshot(ctx->renderer, frame, data);
+ talloc_free(frame);
+ break;
+ }
+ }
+
+ *(int *)args[3] = ret;
+}
+
static int control(struct vo *vo, uint32_t request, void *data)
{
struct vo_priv *p = vo->priv;
@@ -544,6 +567,17 @@ static int control(struct vo *vo, uint32_t request, void *data)
return VO_TRUE;
}
+ // VOCTRLs to be run on the renderer thread (if possible at all).
+ switch (request) {
+ case VOCTRL_SCREENSHOT:
+ if (ctx->dispatch) {
+ int ret;
+ void *args[] = {ctx, (void *)(intptr_t)request, data, &ret};
+ mp_dispatch_run(ctx->dispatch, run_control_on_render_thread, args);
+ return ret;
+ }
+ }
+
int r = VO_NOTIMPL;
pthread_mutex_lock(&ctx->control_lock);
if (ctx->control_cb) {