[vlc-devel] [PATCH] DXVA2: lock the buffer pool when getting/releasing a buffer (v3)
Steve Lhomme
robUx4 at videolabs.io
Tue Apr 7 10:24:21 CEST 2015
in frame threading mode, the buffers can be requested from different threads, resulting in a race condition
only needed if thread_safe_callbacks is set in avcodec
--
replaces the previous patches with the same name
---
modules/codec/avcodec/dxva2.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 3f3707e..27abf22 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -263,6 +263,7 @@ typedef struct {
LPDIRECT3DSURFACE9 d3d;
int refcount;
unsigned int order;
+ vlc_mutex_t *p_lock;
} vlc_va_surface_t;
#define VA_DXVA2_MAX_SURFACE_COUNT (64)
@@ -272,6 +273,9 @@ struct vlc_va_sys_t
int width;
int height;
+ bool b_thread_safe;
+ vlc_mutex_t surface_lock;
+
/* DLL */
HINSTANCE hd3d9_dll;
HINSTANCE hdxva2_dll;
@@ -466,6 +470,9 @@ static int Get(vlc_va_t *va, void **opaque, uint8_t **data)
return VLC_EGENERIC;
}
+ if ( sys->b_thread_safe )
+ vlc_mutex_lock( &sys->surface_lock );
+
/* Grab an unused surface, in case none are, try the oldest
* XXX using the oldest is a workaround in case a problem happens with libavcodec */
unsigned i, old;
@@ -487,15 +494,24 @@ static int Get(vlc_va_t *va, void **opaque, uint8_t **data)
surface->order = sys->surface_order++;
*data = (void *)surface->d3d;
*opaque = surface;
+
+ if ( sys->b_thread_safe )
+ vlc_mutex_unlock( &sys->surface_lock );
+
return VLC_SUCCESS;
}
static void Release(void *opaque, uint8_t *data)
{
vlc_va_surface_t *surface = opaque;
+ if ( surface->p_lock )
+ vlc_mutex_lock( surface->p_lock );
surface->refcount--;
(void) data;
+
+ if ( surface->p_lock )
+ vlc_mutex_unlock( surface->p_lock );
}
static void Close(vlc_va_t *va, AVCodecContext *ctx)
@@ -513,6 +529,8 @@ static void Close(vlc_va_t *va, AVCodecContext *ctx)
FreeLibrary(sys->hdxva2_dll);
if (sys->hd3d9_dll)
FreeLibrary(sys->hd3d9_dll);
+ if ( sys->b_thread_safe )
+ vlc_mutex_destroy( &sys->surface_lock );
free((char *)va->description);
free(sys);
@@ -528,6 +546,10 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, const es_format_t *fmt)
sys->codec_id = ctx->codec_id;
(void) fmt;
+ sys->b_thread_safe = ctx->thread_safe_callbacks;
+ if ( sys->b_thread_safe )
+ vlc_mutex_init( &sys->surface_lock );
+
/* Load dll*/
sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
if (!sys->hd3d9_dll) {
@@ -936,6 +958,8 @@ static int DxCreateVideoDecoder(vlc_va_t *va, int codec_id,
surface->d3d = sys->hw_surface[i];
surface->refcount = 0;
surface->order = 0;
+ if ( sys->b_thread_safe )
+ surface->p_lock = &sys->surface_lock;
}
msg_Dbg(va, "IDirectXVideoAccelerationService_CreateSurface succeed with %d surfaces (%dx%d)",
sys->surface_count, fmt->i_width, fmt->i_height);
--
2.3.2
More information about the vlc-devel
mailing list