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.
This commit is contained in:
wm4 2016-04-27 14:03:30 +02:00
parent 9896994688
commit dff33893f2
5 changed files with 72 additions and 141 deletions

View File

@ -1,99 +0,0 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mp_image.h"
#include "d3d11va.h"
struct d3d11va_surface {
HMODULE d3d11_dll;
ID3D11Texture2D *texture;
int subindex;
ID3D11VideoDecoderOutputView *surface;
};
ID3D11VideoDecoderOutputView *d3d11_surface_in_mp_image(struct mp_image *mpi)
{
return mpi && mpi->imgfmt == IMGFMT_D3D11VA ?
(ID3D11VideoDecoderOutputView *)mpi->planes[3] : NULL;
}
ID3D11Texture2D *d3d11_texture_in_mp_image(struct mp_image *mpi)
{
if (!mpi || mpi->imgfmt != IMGFMT_D3D11VA)
return NULL;
struct d3d11va_surface *surface = (void *)mpi->planes[0];
return surface->texture;
}
int d3d11_subindex_in_mp_image(struct mp_image *mpi)
{
if (!mpi || mpi->imgfmt != IMGFMT_D3D11VA)
return -1;
struct d3d11va_surface *surface = (void *)mpi->planes[0];
return surface->subindex;
}
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);
}
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] = (void *)surface;
mpi->planes[3] = (void *)surface->surface;
return mpi;
fail:
d3d11va_release_img(surface);
return NULL;
}

View File

@ -1,31 +0,0 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MPV_D3D11_H
#define MPV_D3D11_H
#include <d3d11.h>
struct mp_image;
ID3D11VideoDecoderOutputView *d3d11_surface_in_mp_image(struct mp_image *mpi);
ID3D11Texture2D *d3d11_texture_in_mp_image(struct mp_image *mpi);
int d3d11_subindex_in_mp_image(struct mp_image *mpi);
struct mp_image *d3d11va_new_ref(ID3D11VideoDecoderOutputView *view,
int w, int h);
#endif

View File

@ -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,

View File

@ -17,6 +17,8 @@
#include <assert.h>
#include <windows.h>
#include <d3d11.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@ -24,7 +26,6 @@
#include "osdep/timer.h"
#include "osdep/windows_utils.h"
#include "hwdec.h"
#include "video/d3d11va.h"
#include "video/d3d.h"
#include "video/hwdec.h"
@ -352,8 +353,8 @@ static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image,
if (!p->gl_texture)
return -1;
ID3D11Texture2D *d3d_tex = d3d11_texture_in_mp_image(hw_image);
int d3d_subindex = d3d11_subindex_in_mp_image(hw_image);
ID3D11Texture2D *d3d_tex = (void *)hw_image->planes[1];
int d3d_subindex = (intptr_t)hw_image->planes[2];
if (!d3d_tex)
return -1;

View File

@ -286,7 +286,6 @@ def build(ctx):
( "video/mp_image_pool.c" ),
( "video/sws_utils.c" ),
( "video/dxva2.c", "dxva2-hwaccel" ),
( "video/d3d11va.c", "d3d11va-hwaccel" ),
( "video/vaapi.c", "vaapi" ),
( "video/vdpau.c", "vdpau" ),
( "video/vdpau_mixer.c", "vdpau" ),