[vlc-devel] [PATCH 34/39] dxva2: the decoder sets the surface in the picture->context, not picture_sys_t
Steve Lhomme
robux4 at videolabs.io
Fri Jun 2 16:46:37 CEST 2017
---
modules/codec/avcodec/dxva2.c | 55 +++++++++++++++++-----------------
modules/video_chroma/d3d9_fmt.h | 7 +++++
modules/video_chroma/dxa9.c | 10 ++++---
modules/video_output/win32/direct3d9.c | 14 +++++++++
4 files changed, 54 insertions(+), 32 deletions(-)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 48c1027eeb..4d2a0cc1fa 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -178,31 +178,9 @@ void SetupAVCodecContext(vlc_va_t *va)
static int Extract(vlc_va_t *va, picture_t *picture, uint8_t *data)
{
- directx_sys_t *dx_sys = &va->sys->dx_sys;
- LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)data;
- picture_sys_t *p_sys = picture->p_sys;
- LPDIRECT3DSURFACE9 output = p_sys->surface;
-
- assert(d3d != output);
-#ifndef NDEBUG
- LPDIRECT3DDEVICE9 srcDevice, dstDevice;
- IDirect3DSurface9_GetDevice(d3d, &srcDevice);
- IDirect3DSurface9_GetDevice(output, &dstDevice);
- assert(srcDevice == dstDevice);
-#endif
-
- HRESULT hr;
- RECT visibleSource;
- visibleSource.left = 0;
- visibleSource.top = 0;
- visibleSource.right = picture->format.i_visible_width;
- visibleSource.bottom = picture->format.i_visible_height;
- hr = IDirect3DDevice9_StretchRect( dx_sys->d3ddev, d3d, &visibleSource, output, &visibleSource, D3DTEXF_NONE);
- if (FAILED(hr)) {
- msg_Err(va, "Failed to copy the hw surface to the decoder surface (hr=0x%0lx)", hr );
- return VLC_EGENERIC;
- }
-
+ VLC_UNUSED(va); VLC_UNUSED(data);
+ struct va_pic_context *pic_ctx = picture->context;
+ directx_va_AddRef(pic_ctx->va_surface);
return VLC_SUCCESS;
}
@@ -222,13 +200,34 @@ static int CheckDevice(vlc_va_t *va)
return VLC_SUCCESS;
}
+static void d3d9_pic_context_destroy(void *opaque)
+{
+ struct va_pic_context *pic_ctx = opaque;
+ if (pic_ctx->va_surface)
+ {
+ ReleasePictureSys(&pic_ctx->picsys);
+ directx_va_Release(pic_ctx->va_surface);
+ free(pic_ctx);
+ }
+}
+
static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
{
+ struct va_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
+ if (unlikely(pic_ctx==NULL))
+ return VLC_ENOMEM;
+ pic_ctx->pf_destroy = d3d9_pic_context_destroy;
vlc_va_surface_t *va_surface = directx_va_Get(va, &va->sys->dx_sys);
if (unlikely(va_surface==NULL))
+ {
+ free(pic_ctx);
return VLC_EGENERIC;
+ }
*data = (uint8_t*)va_surface->decoderSurface;
- pic->p_sys->va_surface = va_surface;
+ pic_ctx->va_surface = va_surface;
+ pic_ctx->picsys.surface = va_surface->decoderSurface;
+ IDirect3DSurface9_AddRef(va_surface->decoderSurface);
+ pic->context = pic_ctx;
return VLC_SUCCESS;
}
@@ -265,8 +264,8 @@ static void ReleasePic(void *opaque, uint8_t *data)
{
(void)data;
picture_t *pic = opaque;
- directx_va_Release(pic->p_sys->va_surface);
- pic->p_sys->va_surface = NULL;
+ struct va_pic_context *pic_ctx = pic->context;
+ directx_va_Release(pic_ctx->va_surface);
picture_Release(pic);
}
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index fdf778dcd9..67e863539e 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -29,6 +29,13 @@ typedef struct vlc_va_surface_t vlc_va_surface_t;
struct picture_sys_t
{
LPDIRECT3DSURFACE9 surface;
+};
+
+/* owned by the hardware decoder */
+struct va_pic_context
+{
+ void (*pf_destroy)(void *); /* must be first @ref picture_Release() */
+ struct picture_sys_t picsys;
vlc_va_surface_t *va_surface;
};
diff --git a/modules/video_chroma/dxa9.c b/modules/video_chroma/dxa9.c
index ec1e2d27fc..bc4a821c37 100644
--- a/modules/video_chroma/dxa9.c
+++ b/modules/video_chroma/dxa9.c
@@ -70,10 +70,11 @@ static bool GetLock(filter_t *p_filter, LPDIRECT3DSURFACE9 d3d,
static void DXA9_YV12(filter_t *p_filter, picture_t *src, picture_t *dst)
{
copy_cache_t *p_copy_cache = (copy_cache_t*) p_filter->p_sys;
+ picture_sys_t *p_sys = &((struct va_pic_context *)src->context)->picsys;
D3DSURFACE_DESC desc;
D3DLOCKED_RECT lock;
- if (!GetLock(p_filter, src->p_sys->surface, &lock, &desc))
+ if (!GetLock(p_filter, p_sys->surface, &lock, &desc))
return;
if (dst->format.i_chroma == VLC_CODEC_I420) {
@@ -129,16 +130,17 @@ static void DXA9_YV12(filter_t *p_filter, picture_t *src, picture_t *dst)
}
/* */
- IDirect3DSurface9_UnlockRect(src->p_sys->surface);
+ IDirect3DSurface9_UnlockRect(p_sys->surface);
}
static void DXA9_NV12(filter_t *p_filter, picture_t *src, picture_t *dst)
{
copy_cache_t *p_copy_cache = (copy_cache_t*) p_filter->p_sys;
+ picture_sys_t *p_sys = &((struct va_pic_context *)src->context)->picsys;
D3DSURFACE_DESC desc;
D3DLOCKED_RECT lock;
- if (!GetLock(p_filter, src->p_sys->surface, &lock, &desc))
+ if (!GetLock(p_filter, p_sys->surface, &lock, &desc))
return;
if (desc.Format == MAKEFOURCC('N','V','1','2')) {
@@ -156,7 +158,7 @@ static void DXA9_NV12(filter_t *p_filter, picture_t *src, picture_t *dst)
}
/* */
- IDirect3DSurface9_UnlockRect(src->p_sys->surface);
+ IDirect3DSurface9_UnlockRect(p_sys->surface);
}
VIDEO_FILTER_WRAPPER (DXA9_YV12)
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index dacc850c8f..07e865c580 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -465,6 +465,20 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
* wrapper, we can't */
if ( !is_d3d9_opaque(picture->format.i_chroma) )
Direct3D9UnlockSurface(picture);
+ else if (picture->context)
+ {
+ const struct va_pic_context *pic_ctx = picture->context;
+ HRESULT hr;
+ RECT visibleSource;
+ visibleSource.left = 0;
+ visibleSource.top = 0;
+ visibleSource.right = picture->format.i_visible_width;
+ visibleSource.bottom = picture->format.i_visible_height;
+ hr = IDirect3DDevice9_StretchRect( sys->d3ddev, pic_ctx->picsys.surface, &visibleSource, surface, &visibleSource, D3DTEXF_NONE);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Failed to copy the hw surface to the decoder surface (hr=0x%0lx)", hr );
+ }
+ }
/* check if device is still available */
HRESULT hr = IDirect3DDevice9_TestCooperativeLevel(sys->d3ddev);
--
2.12.1
More information about the vlc-devel
mailing list