mirror of https://github.com/mpv-player/mpv
vo_gl: implement screenshots
This commit is contained in:
parent
0440460d0c
commit
28eaf11cf3
|
@ -71,6 +71,7 @@ void glAdjustAlignment(GL *gl, int stride)
|
|||
else
|
||||
gl_alignment = 1;
|
||||
gl->PixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
|
||||
gl->PixelStorei(GL_PACK_ALIGNMENT, gl_alignment);
|
||||
}
|
||||
|
||||
struct gl_name_map_struct {
|
||||
|
@ -634,6 +635,24 @@ void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
|||
gl->TexSubImage2D(target, 0, x, y, w, y_max - y, format, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief download a texture, handling things like stride and slices
|
||||
* \param target texture target, usually GL_TEXTURE_2D
|
||||
* \param format OpenGL format of data
|
||||
* \param type OpenGL type of data
|
||||
* \param dataptr destination memory for download
|
||||
* \param stride data stride (must be positive)
|
||||
* \ingroup gltexture
|
||||
*/
|
||||
void glDownloadTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
||||
void *dataptr, int stride)
|
||||
{
|
||||
// this is not always correct, but should work for MPlayer
|
||||
glAdjustAlignment(gl, stride);
|
||||
gl->PixelStorei(GL_PACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
|
||||
gl->GetTexImage(target, 0, format, type, dataptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setup ATI version of register combiners for YUV to RGB conversion.
|
||||
* \param csp_params parameters used for colorspace conversion
|
||||
|
|
|
@ -256,6 +256,8 @@ int glCreatePPMTex(GL *gl, GLenum target, GLenum fmt, GLint filter,
|
|||
void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
||||
const void *dataptr, int stride,
|
||||
int x, int y, int w, int h, int slice);
|
||||
void glDownloadTex(GL *gl, GLenum target, GLenum format, GLenum type,
|
||||
void *dataptr, int stride);
|
||||
void glDrawTex(GL *gl, GLfloat x, GLfloat y, GLfloat w, GLfloat h,
|
||||
GLfloat tx, GLfloat ty, GLfloat tw, GLfloat th,
|
||||
int sx, int sy, int rect_tex, int is_yv12, int flip);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue