[vlc-commits] d3d9_fmt: keep the IDirectXVideoDecoder and DXVA2 DLL while pictures are active
Steve Lhomme
git at videolan.org
Tue Jan 16 16:36:57 CET 2018
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Jan 16 16:28:05 2018 +0100| [bd325fbdcfc6afb2e645f73cfd56903dc6848e65] | committer: Steve Lhomme
d3d9_fmt: keep the IDirectXVideoDecoder and DXVA2 DLL while pictures are active
In some cases the decoder can be freed even though some pictures are still
pending to be displayed/flush in the vout. We need to make sure the DLL and the
decoder module is still available while these pictures are around.
Fixes #19368
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=bd325fbdcfc6afb2e645f73cfd56903dc6848e65
---
modules/codec/avcodec/dxva2.c | 9 +++++----
modules/video_chroma/d3d9_fmt.h | 13 ++++++++++++-
modules/video_output/win32/direct3d9.c | 1 +
3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 029971c488..25de31de83 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -177,12 +177,12 @@ static void d3d9_pic_context_destroy(struct picture_context_t *opaque)
}
}
-static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *);
+static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *, IDirectXVideoDecoder *);
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;
- struct va_pic_context *pic_ctx = CreatePicContext(src_ctx->picsys.surface);
+ struct va_pic_context *pic_ctx = CreatePicContext(src_ctx->picsys.surface, src_ctx->picsys.decoder);
if (unlikely(pic_ctx==NULL))
return NULL;
pic_ctx->va_surface = src_ctx->va_surface;
@@ -190,7 +190,7 @@ static struct picture_context_t *d3d9_pic_context_copy(struct picture_context_t
return &pic_ctx->s;
}
-static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *surface)
+static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *surface, IDirectXVideoDecoder *decoder)
{
struct va_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
if (unlikely(pic_ctx==NULL))
@@ -198,6 +198,7 @@ static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *surface)
pic_ctx->s.destroy = d3d9_pic_context_destroy;
pic_ctx->s.copy = d3d9_pic_context_copy;
pic_ctx->picsys.surface = surface;
+ pic_ctx->picsys.decoder = decoder;
AcquirePictureSys(&pic_ctx->picsys);
return pic_ctx;
}
@@ -205,7 +206,7 @@ static struct va_pic_context *CreatePicContext(IDirect3DSurface9 *surface)
static struct va_pic_context* NewSurfacePicContext(vlc_va_t *va, int surface_index)
{
directx_sys_t *dx_sys = &va->sys->dx_sys;
- struct va_pic_context *pic_ctx = CreatePicContext(dx_sys->hw_surface[surface_index]);
+ struct va_pic_context *pic_ctx = CreatePicContext(dx_sys->hw_surface[surface_index], dx_sys->decoder);
if (unlikely(pic_ctx==NULL))
return NULL;
/* all the resources are acquired during surfaces init, and a second time in
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index dcb37676e0..c7242ad525 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -25,14 +25,19 @@
#include <vlc_picture.h>
+#define COBJMACROS
#include <d3d9.h>
+#include <dxva2api.h>
#include "dxgi_fmt.h"
/* owned by the vout for VLC_CODEC_D3D9_OPAQUE */
struct picture_sys_t
{
- LPDIRECT3DSURFACE9 surface;
+ IDirect3DSurface9 *surface;
+ /* decoder only */
+ IDirectXVideoDecoder *decoder; /* keep a reference while the surface exist */
+ HINSTANCE dxva2_dll;
};
typedef struct
@@ -69,11 +74,17 @@ picture_sys_t *ActivePictureSys(picture_t *p_pic);
static inline void AcquirePictureSys(picture_sys_t *p_sys)
{
IDirect3DSurface9_AddRef(p_sys->surface);
+ if (p_sys->decoder)
+ IDirectXVideoDecoder_AddRef(p_sys->decoder);
+ p_sys->dxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
}
static inline void ReleasePictureSys(picture_sys_t *p_sys)
{
IDirect3DSurface9_Release(p_sys->surface);
+ if (p_sys->decoder)
+ IDirectXVideoDecoder_Release(p_sys->decoder);
+ FreeLibrary(p_sys->dxva2_dll);
}
HRESULT D3D9_CreateDevice(vlc_object_t *, d3d9_handle_t *, HWND,
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index 84df885972..71b517a59d 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -429,6 +429,7 @@ static picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
picture_sys_t *picsys = malloc(sizeof(*picsys));
if (unlikely(picsys == NULL))
goto error;
+ memset(picsys, 0, sizeof(*picsys));
HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(p_d3d9_dev->dev,
fmt->i_width,
More information about the vlc-commits
mailing list