diff options
author | wm4 <wm4@nowhere> | 2015-01-22 17:47:14 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-01-22 18:18:23 +0100 |
commit | 74581a61064f56b170e555fa72d9cdca161d2307 (patch) | |
tree | 532223eaa3644b01501d443ebca9011ee12af963 /video/out/gl_hwdec_vda.c | |
parent | e9ac3fc3a1505c4db1773a2a24d35ac41ab69887 (diff) | |
download | mpv-74581a61064f56b170e555fa72d9cdca161d2307.tar.bz2 mpv-74581a61064f56b170e555fa72d9cdca161d2307.tar.xz |
video: handle hwdec screenshots differently
Instead of converting the hw surface to an image in the VO, provide a
generic way to convet hw surfaces, and use this in the screenshot code.
It's all relatively straightforward, except vdpau is being terrible. It
needs a huge chunk of new code, because copying back is not simple.
Diffstat (limited to 'video/out/gl_hwdec_vda.c')
-rw-r--r-- | video/out/gl_hwdec_vda.c | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/video/out/gl_hwdec_vda.c b/video/out/gl_hwdec_vda.c index 4264dff975..d90b3419ae 100644 --- a/video/out/gl_hwdec_vda.c +++ b/video/out/gl_hwdec_vda.c @@ -22,14 +22,42 @@ #include <OpenGL/OpenGL.h> #include <OpenGL/CGLIOSurface.h> -#include "video/decode/dec_video.h" +#include "video/mp_image_pool.h" #include "gl_hwdec.h" struct priv { CVPixelBufferRef pbuf; GLuint gl_texture; + struct mp_hwdec_ctx hwctx; }; +static struct mp_image *download_image(struct mp_hwdec_ctx *ctx, + struct mp_image *hw_image, + struct mp_image_pool *swpool) +{ + if (hw_image->imgfmt != IMGFMT_VDA) + return NULL; + + CVPixelBufferRef pbuf = (CVPixelBufferRef)hw_image->planes[3]; + CVPixelBufferLockBaseAddress(pbuf, 0); + void *base = CVPixelBufferGetBaseAddress(pbuf); + size_t width = CVPixelBufferGetWidth(pbuf); + size_t height = CVPixelBufferGetHeight(pbuf); + size_t stride = CVPixelBufferGetBytesPerRow(pbuf); + + struct mp_image img = {0}; + mp_image_setfmt(&img, IMGFMT_UYVY); + mp_image_set_size(&img, width, height); + img.planes[0] = base; + img.stride[0] = stride; + mp_image_copy_attributes(&img, hw_image); + + struct mp_image *image = mp_image_pool_new_copy(swpool, &img); + CVPixelBufferUnlockBaseAddress(pbuf, 0); + + return image; +} + static bool check_hwdec(struct gl_hwdec *hw) { if (hw->gl_texture_target != GL_TEXTURE_RECTANGLE) { @@ -60,6 +88,9 @@ static int create(struct gl_hwdec *hw) if (!check_hwdec(hw)) return -1; + hw->hwctx = &p->hwctx; + hw->hwctx->download_image = download_image; + GL *gl = hw->gl; gl->GenTextures(1, &p->gl_texture); @@ -104,28 +135,6 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, static void unmap_image(struct gl_hwdec *hw) { } -static struct mp_image *download_image(struct gl_hwdec *hw, - struct mp_image *hw_image) -{ - CVPixelBufferRef pbuf = (CVPixelBufferRef)hw_image->planes[3]; - CVPixelBufferLockBaseAddress(pbuf, 0); - void *base = CVPixelBufferGetBaseAddress(pbuf); - size_t width = CVPixelBufferGetWidth(pbuf); - size_t height = CVPixelBufferGetHeight(pbuf); - size_t stride = CVPixelBufferGetBytesPerRow(pbuf); - - struct mp_image img = {0}; - mp_image_setfmt(&img, IMGFMT_UYVY); - mp_image_set_size(&img, width, height); - img.planes[0] = base; - img.stride[0] = stride; - - struct mp_image *image = mp_image_new_copy(&img); - CVPixelBufferUnlockBaseAddress(pbuf, 0); - - return image; -} - static void destroy(struct gl_hwdec *hw) { struct priv *p = hw->priv; @@ -136,7 +145,6 @@ static void destroy(struct gl_hwdec *hw) p->gl_texture = 0; } - const struct gl_hwdec_driver gl_hwdec_vda = { .api_name = "vda", .imgfmt = IMGFMT_VDA, @@ -144,6 +152,5 @@ const struct gl_hwdec_driver gl_hwdec_vda = { .reinit = reinit, .map_image = map_image, .unmap_image = unmap_image, - .download_image = download_image, .destroy = destroy, }; |