[vlc-commits] dxva2: the decoder sets the surface in the picture->context, not picture_sys_t
Steve Lhomme
git at videolan.org
Tue Jun 13 15:01:41 CEST 2017
vlc | branch: master | Steve Lhomme <robux4 at videolabs.io> | Mon May 29 16:23:13 2017 +0200| [fd97bea7eed9437843a676bd7f6e6a88543176af] | committer: Jean-Baptiste Kempf
dxva2: the decoder sets the surface in the picture->context, not picture_sys_t
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fd97bea7eed9437843a676bd7f6e6a88543176af
---
modules/codec/avcodec/dxva2.c | 70 ++++++++++++++++++++--------------
modules/video_chroma/d3d9_fmt.h | 11 +++++-
modules/video_chroma/dxa9.c | 10 +++--
modules/video_output/win32/direct3d9.c | 17 +++++++++
4 files changed, 75 insertions(+), 33 deletions(-)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 46e8c6bdc8..e549743110 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 = (struct va_pic_context*)picture->context;
+ directx_va_AddRef(pic_ctx->va_surface);
return VLC_SUCCESS;
}
@@ -222,13 +200,49 @@ static int CheckDevice(vlc_va_t *va)
return VLC_SUCCESS;
}
+static void d3d9_pic_context_destroy(struct picture_context_t *opaque)
+{
+ struct va_pic_context *pic_ctx = (struct va_pic_context*)opaque;
+ if (pic_ctx->va_surface)
+ {
+ ReleasePictureSys(&pic_ctx->picsys);
+ directx_va_Release(pic_ctx->va_surface);
+ free(pic_ctx);
+ }
+}
+
+static struct picture_context_t *CreatePicContext(vlc_va_surface_t *);
+
+static struct picture_context_t *d3d9_pic_context_copy(struct picture_context_t *ctx)
+{
+ struct va_pic_context *src_ctx = (struct va_pic_context*)ctx;
+ return CreatePicContext(src_ctx->va_surface);
+}
+
+static struct picture_context_t *CreatePicContext(vlc_va_surface_t *va_surface)
+{
+ struct va_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
+ if (unlikely(pic_ctx==NULL))
+ return NULL;
+ pic_ctx->va_surface = va_surface;
+ directx_va_AddRef(pic_ctx->va_surface);
+ pic_ctx->s.destroy = d3d9_pic_context_destroy;
+ pic_ctx->s.copy = d3d9_pic_context_copy;
+ pic_ctx->picsys.surface = va_surface->decoderSurface;
+ IDirect3DSurface9_AddRef(pic_ctx->picsys.surface);
+ return &pic_ctx->s;
+}
+
static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
{
vlc_va_surface_t *va_surface = directx_va_Get(va, &va->sys->dx_sys);
if (unlikely(va_surface==NULL))
return VLC_EGENERIC;
+ pic->context = CreatePicContext(va_surface);
+ directx_va_Release(va_surface);
+ if (unlikely(pic->context==NULL))
+ return VLC_EGENERIC;
*data = (uint8_t*)va_surface->decoderSurface;
- pic->p_sys->va_surface = va_surface;
return VLC_SUCCESS;
}
@@ -265,8 +279,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 = (struct va_pic_context*)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..fe960992a0 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -23,13 +23,22 @@
#ifndef VLC_VIDEOCHROMA_D3D9_FMT_H_
#define VLC_VIDEOCHROMA_D3D9_FMT_H_
+#include <vlc_picture.h>
+
typedef struct vlc_va_surface_t vlc_va_surface_t;
/* owned by the vout for VLC_CODEC_D3D9_OPAQUE */
struct picture_sys_t
{
LPDIRECT3DSURFACE9 surface;
- vlc_va_surface_t *va_surface;
+};
+
+/* owned by the hardware decoder */
+struct va_pic_context
+{
+ picture_context_t s;
+ struct picture_sys_t picsys;
+ vlc_va_surface_t *va_surface;
};
static inline void ReleasePictureSys(picture_sys_t *p_sys)
diff --git a/modules/video_chroma/dxa9.c b/modules/video_chroma/dxa9.c
index afd8fc447b..ca30f93563 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')) {
@@ -157,7 +159,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 22e4259a60..a41c0b8ea8 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -465,6 +465,23 @@ 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 = (struct va_pic_context*)picture->context;
+ if (picture->p_sys && pic_ctx->picsys.surface != picture->p_sys->surface)
+ {
+ 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);
More information about the vlc-commits
mailing list