mirror of https://github.com/mpv-player/mpv
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
This commit is contained in:
parent
a6774d3a83
commit
a1d3afb395
|
@ -475,7 +475,7 @@ Video
|
|||
:vdpau: requires ``--vo=vdpau`` or ``--vo=opengl`` (Linux only)
|
||||
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux with Intel GPUs only)
|
||||
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
|
||||
:vda: requires ``--vo=opengl`` or ``--vo=corevideo`` (OS X only)
|
||||
:vda: requires ``--vo=opengl`` (OS X only)
|
||||
|
||||
``auto`` tries to automatically enable hardware decoding using the first
|
||||
available method. This still depends what VO you are using. For example,
|
||||
|
|
|
@ -259,13 +259,6 @@ Available video output drivers are:
|
|||
|
||||
.. note:: This driver is for compatibility with old systems.
|
||||
|
||||
``corevideo`` (Mac OS X 10.6 and later)
|
||||
Mac OS X CoreVideo video output driver. Uses the CoreVideo APIs to fill
|
||||
PixelBuffers and generate OpenGL textures from them (useful as a fallback
|
||||
for ``opengl``).
|
||||
|
||||
.. note:: This driver is for compatibility with old systems.
|
||||
|
||||
``opengl``
|
||||
OpenGL video output driver. It supports extended scaling methods, dithering
|
||||
and color management.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,572 +0,0 @@
|
|||
/*
|
||||
* CoreVideo video output driver
|
||||
* Copyright (c) 2005 Nicolas Plourde <nicolasplourde@gmail.com>
|
||||
* Copyright (c) 2012-2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
|
||||
*
|
||||
* 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 <QuartzCore/QuartzCore.h>
|
||||
#if HAVE_VDA_HWACCEL
|
||||
#include <IOSurface/IOSurface.h>
|
||||
#include <OpenGL/CGLIOSurface.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#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),
|
||||
};
|
12
wscript
12
wscript
|
@ -611,13 +611,6 @@ video_output_features = [
|
|||
'desc': 'OpenGL video outputs',
|
||||
'deps_any': [ 'gl-cocoa', 'gl-x11', 'gl-win32', 'gl-wayland' ],
|
||||
'func': check_true
|
||||
} , {
|
||||
'name': '--corevideo',
|
||||
'desc': 'CoreVideo',
|
||||
'deps': [ 'gl', 'gl-cocoa' ],
|
||||
'func': check_statement('QuartzCore/CoreVideo.h',
|
||||
'CVOpenGLTextureCacheCreate(0, 0, 0, 0, 0, 0)',
|
||||
framework_name=['QuartzCore'])
|
||||
} , {
|
||||
'name': '--vdpau',
|
||||
'desc': 'VDPAU acceleration',
|
||||
|
@ -679,7 +672,6 @@ hwaccel_features = [
|
|||
} , {
|
||||
'name': '--vda-hwaccel',
|
||||
'desc': 'libavcodec VDA hwaccel',
|
||||
'deps': [ 'corevideo' ],
|
||||
'func': compose_checks(
|
||||
check_headers('VideoDecodeAcceleration/VDADecoder.h'),
|
||||
check_statement('libavcodec/vda.h',
|
||||
|
@ -690,7 +682,9 @@ hwaccel_features = [
|
|||
'name': '--vda-gl',
|
||||
'desc': 'VDA with OpenGL',
|
||||
'deps': [ 'gl-cocoa', 'vda-hwaccel' ],
|
||||
'func': check_true
|
||||
# apparently a bug in waf causes msg= to be needed when passing only
|
||||
# framework= (it probably fails to infer it)
|
||||
'func': check_cc(msg='QuartzCore', framework='QuartzCore')
|
||||
}, {
|
||||
'name': '--vdpau-hwaccel',
|
||||
'desc': 'libavcodec VDPAU hwaccel',
|
||||
|
|
|
@ -354,7 +354,6 @@ def build(ctx):
|
|||
( "video/out/pnm_loader.c", "gl" ),
|
||||
( "video/out/vo.c" ),
|
||||
( "video/out/vo_caca.c", "caca" ),
|
||||
( "video/out/vo_corevideo.c", "corevideo"),
|
||||
( "video/out/vo_direct3d.c", "direct3d" ),
|
||||
( "video/out/vo_image.c" ),
|
||||
( "video/out/vo_lavc.c", "encoding" ),
|
||||
|
|
Loading…
Reference in New Issue