summaryrefslogtreecommitdiffstats
path: root/video/decode
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-04-27 13:49:47 +0200
committerwm4 <wm4@nowhere>2016-04-27 13:49:47 +0200
commit3706918311ef4cc57b1241e87dcc43d699e960f9 (patch)
treed887022bd92e40274ab956b705a808f02104a705 /video/decode
parentcf9b415173b57befb410ecbe92c298cfe36f0451 (diff)
downloadmpv-3706918311ef4cc57b1241e87dcc43d699e960f9.tar.bz2
mpv-3706918311ef4cc57b1241e87dcc43d699e960f9.tar.xz
vo_opengl: D3D11VA + ANGLE interop
This uses ID3D11VideoProcessor to convert the video to a RGBA surface, which is then bound to ANGLE. Currently ANGLE does not provide any way to bind nv12 surfaces directly, so this will have to do. ID3D11VideoContext1 would give us slightly more control about the colorspace conversion, though it's still not good, and not available in MinGW headers yet. The video processor is created lazily, because we need to have the coded frame size, of which AVFrame and mp_image have no concept of. Doing the creation lazily is less of a pain than somehow hacking the coded frame size into mp_image. I'm not really sure how ID3D11VideoProcessorInputView is supposed to work. We recreate it on every frame, which is simple and hopefully doesn't affect performance.
Diffstat (limited to 'video/decode')
-rw-r--r--video/decode/d3d11va.c33
-rw-r--r--video/decode/dxva2.c3
-rw-r--r--video/decode/vd_lavc.c2
3 files changed, 36 insertions, 2 deletions
diff --git a/video/decode/d3d11va.c b/video/decode/d3d11va.c
index c73ce2cab6..b94869d29b 100644
--- a/video/decode/d3d11va.c
+++ b/video/decode/d3d11va.c
@@ -26,6 +26,7 @@
#include "video/hwdec.h"
#include "video/d3d11va.h"
+#include "video/d3d.h"
#include "d3d.h"
#define ADDITIONAL_SURFACES (4 + HWDEC_DELAY_QUEUE_COUNT)
@@ -449,8 +450,22 @@ static int d3d11va_init(struct lavc_ctx *s)
p->sw_pool = talloc_steal(p, mp_image_pool_new(17));
}
- if (!create_device(s, FALSE))
+ if (s->hwdec_info && s->hwdec_info->hwctx && s->hwdec_info->hwctx->d3d_ctx)
+ p->device = s->hwdec_info->hwctx->d3d_ctx->d3d11_device;
+
+ if (p->device) {
+ ID3D11Device_AddRef(p->device);
+ ID3D11Device_GetImmediateContext(p->device, &p->device_ctx);
+ if (!p->device_ctx)
+ goto fail;
+ MP_VERBOSE(p, "Using VO-supplied device %p.\n", p->device);
+ } else if (s->hwdec->type == HWDEC_D3D11VA) {
+ MP_ERR(p, "No Direct3D device provided for native d3d11 decoding\n");
goto fail;
+ } else {
+ if (!create_device(s, FALSE))
+ goto fail;
+ }
hr = ID3D11DeviceContext_QueryInterface(p->device_ctx,
&IID_ID3D11VideoContext,
@@ -487,9 +502,25 @@ static int d3d11va_probe(struct vd_lavc_hwdec *hwdec,
const char *codec)
{
hwdec_request_api(info, "d3d11va");
+ // d3d11va-copy can do without external context; dxva2 requires it.
+ if (hwdec->type != HWDEC_D3D11VA_COPY) {
+ if (!info || !info->hwctx || !info->hwctx->d3d_ctx ||
+ !info->hwctx->d3d_ctx->d3d11_device)
+ return HWDEC_ERR_NO_CTX;
+ }
return d3d_probe_codec(codec);
}
+const struct vd_lavc_hwdec mp_vd_lavc_d3d11va = {
+ .type = HWDEC_D3D11VA,
+ .image_format = IMGFMT_D3D11VA,
+ .probe = d3d11va_probe,
+ .init = d3d11va_init,
+ .uninit = d3d11va_uninit,
+ .init_decoder = d3d11va_init_decoder,
+ .allocate_image = d3d11va_allocate_image,
+};
+
const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy = {
.type = HWDEC_D3D11VA_COPY,
.image_format = IMGFMT_D3D11VA,
diff --git a/video/decode/dxva2.c b/video/decode/dxva2.c
index 2c98c3abcc..e6499f96f2 100644
--- a/video/decode/dxva2.c
+++ b/video/decode/dxva2.c
@@ -494,7 +494,8 @@ static int dxva2_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
// dxva2-copy can do without external context; dxva2 requires it.
if (hwdec->type != HWDEC_DXVA2_COPY) {
if (!info || !info->hwctx || !info->hwctx->d3d_ctx ||
- info->hwctx->type == HWDEC_DXVA2_COPY)
+ info->hwctx->type == HWDEC_DXVA2_COPY ||
+ !info->hwctx->d3d_ctx->d3d9_device)
return HWDEC_ERR_NO_CTX;
}
return d3d_probe_codec(codec);
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 45aaa22599..810753cf74 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -126,6 +126,7 @@ extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi;
extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy;
extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2;
extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2_copy;
+extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va;
extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy;
static const struct vd_lavc_hwdec mp_vd_lavc_rpi = {
@@ -158,6 +159,7 @@ static const struct vd_lavc_hwdec *const hwdec_list[] = {
&mp_vd_lavc_dxva2_copy,
#endif
#if HAVE_D3D11VA_HWACCEL
+ &mp_vd_lavc_d3d11va,
&mp_vd_lavc_d3d11va_copy,
#endif
#if HAVE_ANDROID