diff options
Diffstat (limited to 'libvo/vo_gl.c')
-rw-r--r-- | libvo/vo_gl.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 5f06cf7148..e99ff4432f 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -1134,6 +1134,57 @@ skip_upload: return VO_TRUE; } +static mp_image_t *get_screenshot(struct vo *vo) +{ + struct gl_priv *p = vo->priv; + GL *gl = p->gl; + + mp_image_t *image = alloc_mpi(p->texture_width, p->texture_height, + p->image_format); + + glDownloadTex(gl, p->target, p->gl_format, p->gl_type, image->planes[0], + image->stride[0]); + + if (p->is_yuv) { + gl->ActiveTexture(GL_TEXTURE1); + glDownloadTex(gl, p->target, p->gl_format, p->gl_type, image->planes[1], + image->stride[1]); + gl->ActiveTexture(GL_TEXTURE2); + glDownloadTex(gl, p->target, p->gl_format, p->gl_type, image->planes[2], + image->stride[2]); + gl->ActiveTexture(GL_TEXTURE0); + } + + image->width = p->image_width; + image->height = p->image_height; + + image->w = p->image_d_width; + image->h = p->image_d_height; + + return image; +} + +static mp_image_t *get_window_screenshot(struct vo *vo) +{ + struct gl_priv *p = vo->priv; + GL *gl = p->gl; + + GLint vp[4]; //x, y, w, h + gl->GetIntegerv(GL_VIEWPORT, vp); + mp_image_t *image = alloc_mpi(vp[2], vp[3], IMGFMT_RGB24); + gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + gl->PixelStorei(GL_PACK_ALIGNMENT, 0); + gl->PixelStorei(GL_PACK_ROW_LENGTH, 0); + gl->ReadBuffer(GL_FRONT); + //flip image while reading + for (int y = 0; y < vp[3]; y++) { + gl->ReadPixels(vp[0], vp[1] + vp[3] - y - 1, vp[2], 1, + GL_RGB, GL_UNSIGNED_BYTE, + image->planes[0] + y * image->stride[0]); + } + return image; +} + static int query_format(struct vo *vo, uint32_t format) { struct gl_priv *p = vo->priv; @@ -1460,6 +1511,14 @@ static int control(struct vo *vo, uint32_t request, void *data) do_render_osd(vo, 2); flip_page(vo); return VO_TRUE; + 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); + return true; + } } return VO_NOTIMPL; } |