diff options
author | wm4 <wm4@nowhere> | 2015-07-03 16:37:01 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-07-03 16:38:12 +0200 |
commit | 561416597e33e2c314f0d69433e955c059ee24eb (patch) | |
tree | dcb24d4a797f6c737475cab79c44b347cb4a5b12 /video | |
parent | b85321d0573ba581694d2e6be1effafee74c11d1 (diff) | |
download | mpv-561416597e33e2c314f0d69433e955c059ee24eb.tar.bz2 mpv-561416597e33e2c314f0d69433e955c059ee24eb.tar.xz |
client API, dxva2: add a workaround for OpenGL fullscreen issues
This is basically a hack for drivers which prevent the mpv DXVA2 decoder
glue from working if OpenGL is in fullscreen mode.
Since it doesn't add any "hard" new API to the client API, some of the
code would be required for a true zero-copy hw decoding pipeline, and
sine it isn't too much code after all, this is probably acceptable.
Diffstat (limited to 'video')
-rw-r--r-- | video/decode/dxva2.c | 1 | ||||
-rw-r--r-- | video/out/gl_common.c | 9 | ||||
-rw-r--r-- | video/out/gl_common.h | 2 | ||||
-rw-r--r-- | video/out/gl_hwdec.c | 4 | ||||
-rw-r--r-- | video/out/gl_hwdec_dxva2.c | 64 |
5 files changed, 80 insertions, 0 deletions
diff --git a/video/decode/dxva2.c b/video/decode/dxva2.c index 62b27671ef..0e99d550ba 100644 --- a/video/decode/dxva2.c +++ b/video/decode/dxva2.c @@ -675,6 +675,7 @@ static int dxva2_init_decoder(struct lavc_ctx *s, int fmt, int w, int h) static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, const char *decoder) { + hwdec_request_api(info, "dxva2"); // we can do without too for (int i = 0; dxva2_modes[i].guid; i++) { const dxva2_mode *mode = &dxva2_modes[i]; if (mp_codec_to_av_codec_id(decoder) == mode->codec) diff --git a/video/out/gl_common.c b/video/out/gl_common.c index 5560fe07e0..c127f16fa3 100644 --- a/video/out/gl_common.c +++ b/video/out/gl_common.c @@ -306,6 +306,15 @@ static const struct gl_functions gl_functions[] = { {0} }, }, + // These don't exist - they are for the sake of mpv internals, and libmpv + // interaction (see libmpv/opengl_cb.h). + { + .extension = "GL_MP_D3D_interfaces", + .functions = (const struct gl_function[]) { + DEF_FN(MPGetD3DInterface), + {0} + }, + }, }; #undef FN_OFFS diff --git a/video/out/gl_common.h b/video/out/gl_common.h index 0df44c75ec..39cde380a4 100644 --- a/video/out/gl_common.h +++ b/video/out/gl_common.h @@ -275,6 +275,8 @@ struct GL { void (GLAPIENTRY *DebugMessageCallback)(MP_GLDEBUGPROC callback, const void *userParam); + + void *(GLAPIENTRY *MPGetD3DInterface)(const char *name); }; #endif /* MPLAYER_GL_COMMON_H */ diff --git a/video/out/gl_hwdec.c b/video/out/gl_hwdec.c index 1d09177cf7..ba15950129 100644 --- a/video/out/gl_hwdec.c +++ b/video/out/gl_hwdec.c @@ -32,6 +32,7 @@ extern const struct gl_hwdec_driver gl_hwdec_vaglx; extern const struct gl_hwdec_driver gl_hwdec_vda; extern const struct gl_hwdec_driver gl_hwdec_vdpau; +extern const struct gl_hwdec_driver gl_hwdec_dxva2; static const struct gl_hwdec_driver *const mpgl_hwdec_drivers[] = { #if HAVE_VAAPI_GLX @@ -43,6 +44,9 @@ static const struct gl_hwdec_driver *const mpgl_hwdec_drivers[] = { #if HAVE_VDA_GL &gl_hwdec_vda, #endif +#if HAVE_DXVA2_HWACCEL + &gl_hwdec_dxva2, +#endif NULL }; diff --git a/video/out/gl_hwdec_dxva2.c b/video/out/gl_hwdec_dxva2.c new file mode 100644 index 0000000000..52a73de1b2 --- /dev/null +++ b/video/out/gl_hwdec_dxva2.c @@ -0,0 +1,64 @@ +#include "common/common.h" + +#include "gl_hwdec.h" +#include "gl_utils.h" +#include "video/d3d.h" +#include "video/hwdec.h" + +// This does not provide real (zero-copy) interop - it merely exists for +// making sure the same D3D device is used for decoding and display, which +// may help with OpenGL fullscreen mode. + +struct priv { + struct mp_d3d_ctx ctx; +}; + +static void destroy(struct gl_hwdec *hw) +{ + struct priv *p = hw->priv; + if (p->ctx.d3d9_device) + IDirect3DDevice9_Release(p->ctx.d3d9_device); +} + +static int create(struct gl_hwdec *hw) +{ + GL *gl = hw->gl; + if (hw->hwctx || !gl->MPGetD3DInterface) + return -1; + + struct priv *p = talloc_zero(hw, struct priv); + hw->priv = p; + + p->ctx.d3d9_device = gl->MPGetD3DInterface("IDirect3DDevice9"); + if (!p->ctx.d3d9_device) + return -1; + + p->ctx.hwctx.type = HWDEC_DXVA2_COPY; + p->ctx.hwctx.d3d_ctx = &p->ctx; + + MP_VERBOSE(hw, "Using libmpv supplied device %p.\n", p->ctx.d3d9_device); + + hw->hwctx = &p->ctx.hwctx; + hw->converted_imgfmt = 0; + return 0; +} + +static int reinit(struct gl_hwdec *hw, struct mp_image_params *params) +{ + return -1; +} + +static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, + GLuint *out_textures) +{ + return -1; +} + +const struct gl_hwdec_driver gl_hwdec_dxva2 = { + .api_name = "dxva2", + .imgfmt = -1, + .create = create, + .reinit = reinit, + .map_image = map_image, + .destroy = destroy, +}; |