From fd97bea7eed9437843a676bd7f6e6a88543176af Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Mon, 29 May 2017 16:23:13 +0200 Subject: [PATCH] dxva2: the decoder sets the surface in the picture->context, not picture_sys_t Signed-off-by: Jean-Baptiste Kempf --- 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 + 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); -- GitLab