summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2012-10-21 16:25:42 +0200
committerwm4 <wm4@nowhere>2012-10-24 21:56:34 +0200
commit281989d38437d2a54810bf8638073d8a8cd0dfa0 (patch)
tree07c964be9b9c370ea536e77924f02d73056c1bdb
parent6bea013e27c705ad0bc39f7da22b4ac4eabd7890 (diff)
downloadmpv-281989d38437d2a54810bf8638073d8a8cd0dfa0.tar.bz2
mpv-281989d38437d2a54810bf8638073d8a8cd0dfa0.tar.xz
vo_corevideo: add screenshot capability
Added screenshot capability to the corevideo VO by sending back the raw data from the CVPixelBuffer. Also added "screenshot window" functionality from the other OpenGL based VOs, which uses glReadPixels to read image data back. This was moved to gl_common to avoid duplication.
-rw-r--r--libvo/gl_common.c18
-rw-r--r--libvo/gl_common.h3
-rw-r--r--libvo/vo_corevideo.m48
-rw-r--r--libvo/vo_opengl.c19
-rw-r--r--libvo/vo_opengl_old.c23
5 files changed, 71 insertions, 40 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index 3031dc5967..055b386639 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -1965,6 +1965,24 @@ void glDrawTex(GL *gl, GLfloat x, GLfloat y, GLfloat w, GLfloat h,
gl->End();
}
+mp_image_t *glGetWindowScreenshot(GL *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;
+}
+
#ifdef CONFIG_GL_COCOA
#include "cocoa_common.h"
diff --git a/libvo/gl_common.h b/libvo/gl_common.h
index fd80b69126..d9f227c6aa 100644
--- a/libvo/gl_common.h
+++ b/libvo/gl_common.h
@@ -33,6 +33,8 @@
#include "video_out.h"
#include "csputils.h"
+#include "libmpcodecs/mp_image.h"
+
#if defined(CONFIG_GL_COCOA) && !defined(CONFIG_GL_X11)
#ifdef GL_VERSION_3_0
#include <OpenGL/gl3.h>
@@ -72,6 +74,7 @@ void glDrawTex(GL *gl, GLfloat x, GLfloat y, GLfloat w, GLfloat h,
int sx, int sy, int rect_tex, int is_yv12, int flip);
int loadGPUProgram(GL *gl, GLenum target, char *prog);
void glCheckError(GL *gl, const char *info);
+mp_image_t *glGetWindowScreenshot(GL *gl);
/** \addtogroup glconversion
* \{ */
diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m
index 06010cad49..fb9350cc47 100644
--- a/libvo/vo_corevideo.m
+++ b/libvo/vo_corevideo.m
@@ -344,6 +344,46 @@ static void set_yuv_colorspace(struct vo *vo)
vo->want_redraw = true;
}
+static int get_image_fmt(struct vo *vo)
+{
+ struct priv *p = vo->priv;
+ switch (p->pixelFormat) {
+ case kYUVSPixelFormat: return IMGFMT_YUY2;
+ case k24RGBPixelFormat: return IMGFMT_RGB24;
+ case k32ARGBPixelFormat: return IMGFMT_ARGB;
+ case k32BGRAPixelFormat: return IMGFMT_BGRA;
+ }
+ mp_msg(MSGT_VO, MSGL_ERR, "[vo_corevideo] Failed to convert pixel format. "
+ "Please contact the developers. PixelFormat: %d\n", p->pixelFormat);
+ return -1;
+}
+
+static mp_image_t *get_screenshot(struct vo *vo)
+{
+ int img_fmt = get_image_fmt(vo);
+ if (img_fmt < 0) return NULL;
+
+ struct priv *p = vo->priv;
+ void *base = CVPixelBufferGetBaseAddress(p->pixelBuffer);
+
+ size_t width = CVPixelBufferGetWidth(p->pixelBuffer);
+ size_t height = CVPixelBufferGetHeight(p->pixelBuffer);
+ size_t stride = CVPixelBufferGetBytesPerRow(p->pixelBuffer);
+ size_t image_size = stride * height;
+
+ mp_image_t *image = alloc_mpi(width, height, img_fmt);
+ memcpy(image->planes[0], base, image_size);
+ image->stride[0] = stride;
+
+ image->width = width;
+ image->height = height;
+
+ image->w = vo->aspdat.prew;
+ image->h = vo->aspdat.preh;
+
+ return image;
+}
+
static int control(struct vo *vo, uint32_t request, void *data)
{
struct priv *p = vo->priv;
@@ -377,6 +417,14 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_GET_YUV_COLORSPACE:
*(struct mp_csp_details *)data = p->colorspace;
return VO_TRUE;
+ case VOCTRL_SCREENSHOT: {
+ struct voctrl_screenshot_args *args = data;
+ if (args->full_window)
+ args->out_image = glGetWindowScreenshot(p->mpglctx->gl);
+ else
+ args->out_image = get_screenshot(vo);
+ return VO_TRUE;
+ }
}
return VO_NOTIMPL;
}
diff --git a/libvo/vo_opengl.c b/libvo/vo_opengl.c
index df82a239d1..8b1b6aaa35 100644
--- a/libvo/vo_opengl.c
+++ b/libvo/vo_opengl.c
@@ -1403,23 +1403,6 @@ static mp_image_t *get_screenshot(struct gl_priv *p)
return image;
}
-static mp_image_t *get_window_screenshot(struct gl_priv *p)
-{
- GL *gl = p->gl;
-
- mp_image_t *image = alloc_mpi(p->vp_w, p->vp_h, IMGFMT_RGB24);
- gl->PixelStorei(GL_PACK_ALIGNMENT, 4);
- gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
- gl->ReadBuffer(GL_FRONT);
- // flip image while reading
- for (int y = 0; y < p->vp_h; y++) {
- gl->ReadPixels(p->vp_x, p->vp_y + p->vp_h - y - 1, p->vp_w, 1,
- GL_RGB, GL_UNSIGNED_BYTE,
- image->planes[0] + y * image->stride[0]);
- }
- return image;
-}
-
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
{
struct gl_priv *p = ctx;
@@ -1842,7 +1825,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_SCREENSHOT: {
struct voctrl_screenshot_args *args = data;
if (args->full_window)
- args->out_image = get_window_screenshot(p);
+ args->out_image = glGetWindowScreenshot(p->gl);
else
args->out_image = get_screenshot(p);
return true;
diff --git a/libvo/vo_opengl_old.c b/libvo/vo_opengl_old.c
index ac104a3cde..e83d45a692 100644
--- a/libvo/vo_opengl_old.c
+++ b/libvo/vo_opengl_old.c
@@ -835,27 +835,6 @@ static mp_image_t *get_screenshot(struct vo *vo)
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;
@@ -1158,7 +1137,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_SCREENSHOT: {
struct voctrl_screenshot_args *args = data;
if (args->full_window)
- args->out_image = get_window_screenshot(vo);
+ args->out_image = glGetWindowScreenshot(p->gl);
else
args->out_image = get_screenshot(vo);
return true;