Commit b1bd74d2 authored by Steve Lhomme's avatar Steve Lhomme Committed by Jean-Baptiste Kempf

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

(cherry picked from commit bd325fbd)
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <>
parent e0cf7085
......@@ -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;
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
......@@ -25,14 +25,19 @@
#include <vlc_picture.h>
#include <d3d9.h>
#include <dxva2api.h>
#include "dxgi_fmt.h"
/* owned by the vout for VLC_CODEC_D3D9_OPAQUE */
struct picture_sys_t
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)
if (p_sys->decoder)
p_sys->dxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
static inline void ReleasePictureSys(picture_sys_t *p_sys)
if (p_sys->decoder)
HRESULT D3D9_CreateDevice(vlc_object_t *, d3d9_handle_t *, HWND,
......@@ -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,
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment