From a1d3afb395a8cea5327e3155f32c3d808bd52c49 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sat, 6 Sep 2014 14:01:37 +0200 Subject: vo_corevideo: remove this VO This was kept in the codebase because it is slightly faster than --vo=opengl on really old Intel cards (from the GMA era). Time to kill it, and let it rest. Fixes #1061 --- video/out/vo.c | 4 - video/out/vo_corevideo.c | 572 ----------------------------------------------- 2 files changed, 576 deletions(-) delete mode 100644 video/out/vo_corevideo.c (limited to 'video/out') diff --git a/video/out/vo.c b/video/out/vo.c index f7f0f1664a..09d203ab2f 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -61,7 +61,6 @@ extern const struct vo_driver video_out_caca; extern const struct vo_driver video_out_direct3d; extern const struct vo_driver video_out_direct3d_shaders; extern const struct vo_driver video_out_sdl; -extern const struct vo_driver video_out_corevideo; extern const struct vo_driver video_out_vaapi; extern const struct vo_driver video_out_wayland; @@ -77,9 +76,6 @@ const struct vo_driver *const video_out_drivers[] = &video_out_direct3d_shaders, &video_out_direct3d, #endif -#if HAVE_COREVIDEO - &video_out_corevideo, -#endif #if HAVE_XV &video_out_xv, #endif diff --git a/video/out/vo_corevideo.c b/video/out/vo_corevideo.c deleted file mode 100644 index 4bd67aaec5..0000000000 --- a/video/out/vo_corevideo.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * CoreVideo video output driver - * Copyright (c) 2005 Nicolas Plourde - * Copyright (c) 2012-2013 Stefano Pigozzi - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include -#if HAVE_VDA_HWACCEL -#include -#include -#endif - -#include - -#include "talloc.h" -#include "video/out/vo.h" -#include "sub/osd.h" -#include "options/m_option.h" - -#include "video/csputils.h" -#include "video/vfcap.h" -#include "video/mp_image.h" - -#include "gl_common.h" -#include "gl_osd.h" -#include "cocoa_common.h" - -struct quad { - GLfloat lowerLeft[2]; - GLfloat lowerRight[2]; - GLfloat upperRight[2]; - GLfloat upperLeft[2]; -}; - -struct cv_priv { - CVPixelBufferRef pbuf; - CVOpenGLTextureCacheRef texture_cache; - CVOpenGLTextureRef texture; - OSType pixfmt; -}; - -struct dr_priv { - CVPixelBufferRef pbuf; - bool texture_allocated; - GLuint texture; - GLuint texture_target; -}; - -struct cv_functions { - void (*init)(struct vo *vo); - void (*uninit)(struct vo *vo); - void (*prepare_texture)(struct vo *vo, struct mp_image *mpi); - void (*bind_texture)(struct vo *vo); - void (*unbind_texture)(struct vo *vo); - mp_image_t *(*get_screenshot)(struct vo *vo); - void (*get_colorspace)(struct vo *vo, struct mp_image_params *p); -}; - -struct priv { - MPGLContext *mpglctx; - unsigned int image_width; - unsigned int image_height; - struct mp_rect src_rect; - struct mp_rect dst_rect; - struct mp_osd_res osd_res; - - // state for normal CoreVideo rendering path: uploads mp_image data as - // OpenGL textures. - struct cv_priv cv; - - // state for IOSurface based direct rendering path: accesses the IOSurface - // wrapped by the CVPixelBuffer returned by VDADecoder and directly - // renders it to the screen. - struct dr_priv dr; - - struct quad *quad; - struct mpgl_osd *osd; - double vo_pts; - - // functions to to deal with the the OpenGL texture for containing the - // video frame (behaviour changes depending on the rendering path). - struct cv_functions fns; -}; - -static void resize(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - gl->Viewport(0, 0, vo->dwidth, vo->dheight); - gl->MatrixMode(GL_MODELVIEW); - gl->LoadIdentity(); - gl->Ortho(0, vo->dwidth, vo->dheight, 0, -1, 1); - - vo_get_src_dst_rects(vo, &p->src_rect, &p->dst_rect, &p->osd_res); - - gl->Clear(GL_COLOR_BUFFER_BIT); - vo->want_redraw = true; -} - -static int init_gl(struct vo *vo, uint32_t d_width, uint32_t d_height) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - gl->Disable(GL_BLEND); - gl->Disable(GL_DEPTH_TEST); - gl->DepthMask(GL_FALSE); - gl->Disable(GL_CULL_FACE); - gl->Enable(GL_TEXTURE_2D); - gl->DrawBuffer(GL_BACK); - gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - if (!p->osd) - p->osd = mpgl_osd_init(gl, vo->log, vo->osd); - - resize(vo); - - gl->ClearColor(0.0f, 0.0f, 0.0f, 0.0f); - gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (gl->SwapInterval) - gl->SwapInterval(1); - - return 1; -} - -// map x/y (in range 0..1) to the video texture, and emit OpenGL vertexes -static void video_vertex(struct vo *vo, float x, float y) -{ - struct priv *p = vo->priv; - struct quad *q = p->quad; - GL *gl = p->mpglctx->gl; - - double tx0 = q->upperLeft[0]; - double ty0 = q->upperLeft[1]; - double tw = q->lowerRight[0] - tx0; - double th = q->lowerRight[1] - ty0; - - double sx0 = p->src_rect.x0 / (double)p->image_width; - double sy0 = p->src_rect.y0 / (double)p->image_height; - double sw = (p->src_rect.x1 - p->src_rect.x0) / (double)p->image_width; - double sh = (p->src_rect.y1 - p->src_rect.y0) / (double)p->image_height; - - gl->TexCoord2f(tx0 + (sx0 + x * sw) * tw, - ty0 + (sy0 + y * sh) * th); - gl->Vertex2f(p->dst_rect.x1 * x + p->dst_rect.x0 * (1 - x), - p->dst_rect.y1 * y + p->dst_rect.y0 * (1 - y)); -} - -static void do_render(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - p->fns.bind_texture(vo); - - gl->Begin(GL_QUADS); - video_vertex(vo, 0, 0); - video_vertex(vo, 0, 1); - video_vertex(vo, 1, 1); - video_vertex(vo, 1, 0); - gl->End(); - - p->fns.unbind_texture(vo); - - mpgl_osd_draw_legacy(p->osd, p->vo_pts, p->osd_res); -} - -static void flip_page(struct vo *vo) -{ - struct priv *p = vo->priv; - p->mpglctx->swapGlBuffers(p->mpglctx); - p->mpglctx->gl->Clear(GL_COLOR_BUFFER_BIT); -} - -static void draw_image(struct vo *vo, struct mp_image *mpi) -{ - struct priv *p = vo->priv; - p->vo_pts = mpi->pts; - p->fns.prepare_texture(vo, mpi); - do_render(vo); - talloc_free(mpi); -} - -static void uninit(struct vo *vo) -{ - struct priv *p = vo->priv; - mpgl_osd_destroy(p->osd); - p->fns.uninit(vo); - mpgl_uninit(p->mpglctx); -} - - -static int preinit(struct vo *vo) -{ - struct priv *p = vo->priv; - - *p = (struct priv) { - .mpglctx = mpgl_init(vo, "cocoa"), - .quad = talloc_ptrtype(p, p->quad), - }; - - return 0; -} - -static CFStringRef get_cv_csp_matrix(enum mp_csp format) -{ - switch (format) { - case MP_CSP_BT_601: - return kCVImageBufferYCbCrMatrix_ITU_R_601_4; - case MP_CSP_BT_709: - return kCVImageBufferYCbCrMatrix_ITU_R_709_2; - case MP_CSP_SMPTE_240M: - return kCVImageBufferYCbCrMatrix_SMPTE_240M_1995; - default: - return NULL; - } -} - -static void apply_csp(struct vo *vo, CVPixelBufferRef pbuf) -{ - if (!vo->params) - return; - CFStringRef matrix = get_cv_csp_matrix(vo->params->colorspace); - if (!matrix) - return; - - CVPixelBufferLockBaseAddress(pbuf, 0); - CVBufferSetAttachment(pbuf, kCVImageBufferYCbCrMatrixKey, matrix, - kCVAttachmentMode_ShouldPropagate); - CVPixelBufferUnlockBaseAddress(pbuf, 0); -} - -static void get_colorspace(struct vo *vo, struct mp_image_params *p) -{ - if (vo->params && get_cv_csp_matrix(vo->params->colorspace)) - p->colorspace = vo->params->colorspace; -} - -static int get_image_fmt(struct vo *vo, CVPixelBufferRef pbuf) -{ - OSType pixfmt = CVPixelBufferGetPixelFormatType(pbuf); - switch (pixfmt) { - case kYUVSPixelFormat: return IMGFMT_YUYV; - case k2vuyPixelFormat: return IMGFMT_UYVY; - case k24RGBPixelFormat: return IMGFMT_RGB24; - case k32ARGBPixelFormat: return IMGFMT_ARGB; - case k32BGRAPixelFormat: return IMGFMT_BGRA; - } - MP_ERR(vo, "Failed to convert pixel format. Please contact the " - "developers. PixelFormat: %d\n", pixfmt); - return -1; -} - -static mp_image_t *get_screenshot(struct vo *vo, CVPixelBufferRef pbuf) -{ - int img_fmt = get_image_fmt(vo, pbuf); - if (img_fmt < 0 || !vo->params) return NULL; - - 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, img_fmt); - mp_image_set_size(&img, width, height); - img.planes[0] = base; - img.stride[0] = stride; - - struct mp_image *image = mp_image_new_copy(&img); - if (image) - mp_image_set_attributes(image, vo->params); - CVPixelBufferUnlockBaseAddress(pbuf, 0); - - return image; -} - -static int control(struct vo *vo, uint32_t request, void *data) -{ - struct priv *p = vo->priv; - switch (request) { - case VOCTRL_GET_PANSCAN: - return VO_TRUE; - case VOCTRL_SET_PANSCAN: - resize(vo); - return VO_TRUE; - case VOCTRL_REDRAW_FRAME: - do_render(vo); - return VO_TRUE; - case VOCTRL_GET_COLORSPACE: - p->fns.get_colorspace(vo, data); - 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 = p->fns.get_screenshot(vo); - return VO_TRUE; - } - } - - int events = 0; - int r = p->mpglctx->vo_control(vo, &events, request, data); - if (events & VO_EVENT_RESIZE) - resize(vo); - - return r; -} - -static void dummy_cb(struct vo *vo) { } - -static void cv_uninit(struct vo *vo) -{ - struct priv *p = vo->priv; - CVPixelBufferRelease(p->cv.pbuf); - p->cv.pbuf = NULL; - CVOpenGLTextureRelease(p->cv.texture); - p->cv.texture = NULL; - CVOpenGLTextureCacheRelease(p->cv.texture_cache); - p->cv.texture_cache = NULL; -} - -static void cv_bind_texture(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - gl->Enable(CVOpenGLTextureGetTarget(p->cv.texture)); - gl->BindTexture(CVOpenGLTextureGetTarget(p->cv.texture), - CVOpenGLTextureGetName(p->cv.texture)); - -} - -static void cv_unbind_texture(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - gl->Disable(CVOpenGLTextureGetTarget(p->cv.texture)); -} - -static void upload_opengl_texture(struct vo *vo, struct mp_image *mpi) -{ - struct priv *p = vo->priv; - if (!p->cv.texture_cache || !p->cv.pbuf) { - CVReturn error; - error = CVOpenGLTextureCacheCreate(NULL, 0, vo_cocoa_cgl_context(vo), - vo_cocoa_cgl_pixel_format(vo), 0, &p->cv.texture_cache); - if(error != kCVReturnSuccess) - MP_ERR(vo, "Failed to create OpenGL texture Cache(%d)\n", error); - - error = CVPixelBufferCreateWithBytes(NULL, mpi->w, mpi->h, - p->cv.pixfmt, mpi->planes[0], mpi->stride[0], - NULL, NULL, NULL, &p->cv.pbuf); - if(error != kCVReturnSuccess) - MP_ERR(vo, "Failed to create PixelBuffer(%d)\n", error); - - apply_csp(vo, p->cv.pbuf); - } - - struct quad *q = p->quad; - CVReturn error; - - CVOpenGLTextureRelease(p->cv.texture); - error = CVOpenGLTextureCacheCreateTextureFromImage(NULL, - p->cv.texture_cache, p->cv.pbuf, 0, &p->cv.texture); - if(error != kCVReturnSuccess) - MP_ERR(vo, "Failed to create OpenGL texture(%d)\n", error); - - CVOpenGLTextureGetCleanTexCoords(p->cv.texture, - q->lowerLeft, q->lowerRight, q->upperRight, q->upperLeft); -} - -static mp_image_t *cv_get_screenshot(struct vo *vo) -{ - struct priv *p = vo->priv; - return get_screenshot(vo, p->cv.pbuf); -} - - - -static struct cv_functions cv_functions = { - .init = dummy_cb, - .uninit = cv_uninit, - .bind_texture = cv_bind_texture, - .unbind_texture = cv_unbind_texture, - .prepare_texture = upload_opengl_texture, - .get_screenshot = cv_get_screenshot, - .get_colorspace = get_colorspace, -}; - -#if HAVE_VDA_HWACCEL -static void iosurface_init(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - p->dr.texture_target = GL_TEXTURE_RECTANGLE_ARB; - p->fns.bind_texture(vo); - gl->GenTextures(1, &p->dr.texture); - p->fns.unbind_texture(vo); - - p->dr.texture_allocated = true; -} - -static void iosurface_uninit(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - if (p->dr.texture_allocated) { - gl->DeleteTextures(1, &p->dr.texture); - p->dr.texture_allocated = false; - } -} - -static void iosurface_bind_texture(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - gl->Enable(p->dr.texture_target); - gl->BindTexture(p->dr.texture_target, p->dr.texture); - gl->MatrixMode(GL_TEXTURE); - gl->LoadIdentity(); - gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -} - -static void iosurface_unbind_texture(struct vo *vo) -{ - struct priv *p = vo->priv; - GL *gl = p->mpglctx->gl; - - gl->BindTexture(p->dr.texture_target, 0); - gl->Disable(p->dr.texture_target); -} - -static void extract_texture_from_iosurface(struct vo *vo, struct mp_image *mpi) -{ - struct priv *p = vo->priv; - CVPixelBufferRelease(p->dr.pbuf); - p->dr.pbuf = (CVPixelBufferRef)mpi->planes[3]; - CVPixelBufferRetain(p->dr.pbuf); - IOSurfaceRef surface = CVPixelBufferGetIOSurface(p->dr.pbuf); - MP_DBG(vo, "iosurface id: %d\n", IOSurfaceGetID(surface)); - - p->fns.bind_texture(vo); - - CGLError err = CGLTexImageIOSurface2D( - vo_cocoa_cgl_context(vo), p->dr.texture_target, GL_RGB8, - p->image_width, p->image_height, - GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, surface, 0); - - if (err != kCGLNoError) - MP_ERR(vo, "error creating IOSurface texture: %s (%x)\n", - CGLErrorString(err), glGetError()); - - p->fns.unbind_texture(vo); - - // video_vertex flips the coordinates.. so feed in a flipped quad - *p->quad = (struct quad) { - .lowerRight = { p->image_width, p->image_height }, - .upperLeft = { 0.0, 0.0 }, - }; -} - -static mp_image_t *iosurface_get_screenshot(struct vo *vo) -{ - struct priv *p = vo->priv; - return get_screenshot(vo, p->dr.pbuf); -} - -static void iosurface_get_colorspace(struct vo *vo, struct mp_image_params *p) -{ - p->colorspace = MP_CSP_BT_601; -} - -static struct cv_functions iosurface_functions = { - .init = iosurface_init, - .uninit = iosurface_uninit, - .bind_texture = iosurface_bind_texture, - .unbind_texture = iosurface_unbind_texture, - .prepare_texture = extract_texture_from_iosurface, - .get_screenshot = iosurface_get_screenshot, - .get_colorspace = iosurface_get_colorspace, -}; -#endif /* HAVE_VDA_HWACCEL */ - -struct fmt_entry { - enum mp_imgfmt imgfmt; - OSType cvfmt; - struct cv_functions *funs; -}; - -static const struct fmt_entry supported_fmts[] = { -#if HAVE_VDA_HWACCEL - { IMGFMT_VDA, 0, &iosurface_functions }, -#endif - { IMGFMT_YUYV, kYUVSPixelFormat, &cv_functions }, - { IMGFMT_UYVY, k2vuyPixelFormat, &cv_functions }, - { IMGFMT_RGB24, k24RGBPixelFormat, &cv_functions }, - { IMGFMT_BGRA, k32BGRAPixelFormat, &cv_functions }, - { IMGFMT_NONE, 0, NULL } -}; - -static int reconfig(struct vo *vo, struct mp_image_params *params, int flags) -{ - struct priv *p = vo->priv; - if (p->fns.uninit) - p->fns.uninit(vo); - - for (int i = 0; supported_fmts[i].imgfmt; i++) - if (supported_fmts[i].imgfmt == params->imgfmt) { - p->fns = *supported_fmts[i].funs; - p->cv.pixfmt = supported_fmts[i].cvfmt; - break; - } - - p->image_width = params->w; - p->image_height = params->h; - - int mpgl_caps = MPGL_CAP_GL_LEGACY; - if (!mpgl_config_window(p->mpglctx, mpgl_caps, flags)) - return -1; - - init_gl(vo, vo->dwidth, vo->dheight); - p->fns.init(vo); - - return 0; -} - - -static int query_format(struct vo *vo, uint32_t format) -{ - for (int i = 0; supported_fmts[i].imgfmt; i++) - if (supported_fmts[i].imgfmt == format) - return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; - return 0; -} - -const struct vo_driver video_out_corevideo = { - .name = "corevideo", - .description = "Mac OS X Core Video", - .preinit = preinit, - .query_format = query_format, - .reconfig = reconfig, - .control = control, - .draw_image = draw_image, - .flip_page = flip_page, - .uninit = uninit, - .priv_size = sizeof(struct priv), -}; -- cgit v1.2.3