summaryrefslogtreecommitdiffstats
path: root/video/decode
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-04-27 14:03:30 +0200
committerwm4 <wm4@nowhere>2016-04-27 14:06:50 +0200
commitdff33893f2ea91f425bceeec6596556d569e0370 (patch)
treeadf74118a9b1b00a425beba03a2dcbe39d3f3fc9 /video/decode
parent98969946883e4985f9b65e4987f59c65452a6fe4 (diff)
downloadmpv-dff33893f2ea91f425bceeec6596556d569e0370.tar.bz2
mpv-dff33893f2ea91f425bceeec6596556d569e0370.tar.xz
d3d11va: store texture/subindex in IMGFMT_D3D11VA plane pointers
Basically this gets rid of the need for the accessors in d3d11va.h, and the code can be cleaned up a little bit. Note that libavcodec only defines a ID3D11VideoDecoderOutputView pointer in the last plane pointers, but it tolerates/passes through the other plane pointers we set.
Diffstat (limited to 'video/decode')
-rw-r--r--video/decode/d3d11va.c75
1 files changed, 68 insertions, 7 deletions
diff --git a/video/decode/d3d11va.c b/video/decode/d3d11va.c
index b94869d29b..f20031ff31 100644
--- a/video/decode/d3d11va.c
+++ b/video/decode/d3d11va.c
@@ -25,7 +25,6 @@
#include "video/mp_image_pool.h"
#include "video/hwdec.h"
-#include "video/d3d11va.h"
#include "video/d3d.h"
#include "d3d.h"
@@ -51,6 +50,66 @@ struct priv {
struct mp_image_pool *sw_pool;
};
+struct d3d11va_surface {
+ HMODULE d3d11_dll;
+ ID3D11Texture2D *texture;
+ int subindex;
+ ID3D11VideoDecoderOutputView *surface;
+};
+
+static void d3d11va_release_img(void *arg)
+{
+ struct d3d11va_surface *surface = arg;
+ if (surface->surface)
+ ID3D11VideoDecoderOutputView_Release(surface->surface);
+
+ if (surface->texture)
+ ID3D11Texture2D_Release(surface->texture);
+
+ if (surface->d3d11_dll)
+ FreeLibrary(surface->d3d11_dll);
+
+ talloc_free(surface);
+}
+
+static struct mp_image *d3d11va_new_ref(ID3D11VideoDecoderOutputView *view,
+ int w, int h)
+{
+ if (!view)
+ return NULL;
+ struct d3d11va_surface *surface = talloc_zero(NULL, struct d3d11va_surface);
+
+ surface->d3d11_dll = LoadLibrary(L"d3d11.dll");
+ if (!surface->d3d11_dll)
+ goto fail;
+
+ surface->surface = view;
+ ID3D11VideoDecoderOutputView_AddRef(surface->surface);
+ ID3D11VideoDecoderOutputView_GetResource(
+ surface->surface, (ID3D11Resource **)&surface->texture);
+
+ D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC surface_desc;
+ ID3D11VideoDecoderOutputView_GetDesc(surface->surface, &surface_desc);
+ surface->subindex = surface_desc.Texture2D.ArraySlice;
+
+ struct mp_image *mpi =
+ mp_image_new_custom_ref(NULL, surface, d3d11va_release_img);
+ if (!mpi)
+ abort();
+
+ mp_image_setfmt(mpi, IMGFMT_D3D11VA);
+ mp_image_set_size(mpi, w, h);
+ mpi->planes[0] = NULL;
+ mpi->planes[1] = (void *)surface->texture;
+ mpi->planes[2] = (void *)(intptr_t)surface->subindex;
+ mpi->planes[3] = (void *)surface->surface;
+
+ return mpi;
+fail:
+ d3d11va_release_img(surface);
+ return NULL;
+}
+
static struct mp_image *d3d11va_allocate_image(struct lavc_ctx *s, int w, int h)
{
struct priv *p = s->hwdec_priv;
@@ -67,10 +126,14 @@ static struct mp_image *d3d11va_retrieve_image(struct lavc_ctx *s,
HRESULT hr;
struct priv *p = s->hwdec_priv;
ID3D11Texture2D *staging = p->decoder->staging;
- ID3D11Texture2D *texture = d3d11_texture_in_mp_image(img);
- ID3D11VideoDecoderOutputView *surface = d3d11_surface_in_mp_image(img);
- if (!texture || !surface) {
+ if (img->imgfmt != IMGFMT_D3D11VA)
+ return img;
+
+ ID3D11Texture2D *texture = (void *)img->planes[1];
+ int subindex = (intptr_t)img->planes[2];
+
+ if (!texture) {
MP_ERR(p, "Failed to get Direct3D texture and surface from mp_image\n");
return img;
}
@@ -83,12 +146,10 @@ static struct mp_image *d3d11va_retrieve_image(struct lavc_ctx *s,
}
// copy to the staging texture
- D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC surface_desc;
- ID3D11VideoDecoderOutputView_GetDesc(surface, &surface_desc);
ID3D11DeviceContext_CopySubresourceRegion(
p->device_ctx,
(ID3D11Resource *)staging, 0, 0, 0, 0,
- (ID3D11Resource *)texture, surface_desc.Texture2D.ArraySlice, NULL);
+ (ID3D11Resource *)texture, subindex, NULL);
struct mp_image *sw_img = mp_image_pool_get(p->sw_pool,
p->decoder->mpfmt_decoded,