summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@mplayer2.org>2011-10-06 20:46:01 +0200
committerUoti Urpala <uau@mplayer2.org>2011-11-25 23:56:28 +0200
commit28eaf11cf3b220871b97d9ba40d5058a84bcba09 (patch)
tree15f452ea32fcdbf788147694aa581530066da122
parent0440460d0cb1a65cc890508279b287c97db38a78 (diff)
downloadmpv-28eaf11cf3b220871b97d9ba40d5058a84bcba09.tar.bz2
mpv-28eaf11cf3b220871b97d9ba40d5058a84bcba09.tar.xz
vo_gl: implement screenshots
-rw-r--r--libvo/gl_common.c19
-rw-r--r--libvo/gl_common.h2
-rw-r--r--libvo/vo_gl.c59
3 files changed, 80 insertions, 0 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index bbcbeb2f3b..f433f5642d 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -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 {
@@ -635,6 +636,24 @@ void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
}
/**
+ * \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
* \param text if set use the GL_ATI_text_fragment_shader API as
diff --git a/libvo/gl_common.h b/libvo/gl_common.h
index a56248403a..d1d034b99a 100644
--- a/libvo/gl_common.h
+++ b/libvo/gl_common.h
@@ -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);
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;
}