Commit 2b8794fe authored by Jean-Paul Saman's avatar Jean-Paul Saman

codec/avcodec/vaapi*: protect access to VAAPI connection.

Use a static mutex to protect access for libva.
parent f78f3ed3
...@@ -48,7 +48,18 @@ ...@@ -48,7 +48,18 @@
#ifdef HAVE_AVCODEC_VAAPI #ifdef HAVE_AVCODEC_VAAPI
/* Global VAAPI connection state */ /* Global VAAPI connection state */
static vlc_va_conn_t vlc_va_conn = { NULL, 0, 0, 0, 0 }; static vlc_va_conn_t vlc_va_conn = { NULL, 0, 0, 0, 0, NULL, NULL };
static vlc_mutex_t vlc_va_conn_lock = VLC_STATIC_MUTEX;
static void vlc_va_lock(void)
{
vlc_mutex_lock(&vlc_va_conn_lock);
}
static void vlc_va_unlock(void)
{
vlc_mutex_unlock(&vlc_va_conn_lock);
}
/* */ /* */
vlc_va_conn_t *vlc_va_get_conn( void ) vlc_va_conn_t *vlc_va_get_conn( void )
...@@ -58,15 +69,20 @@ vlc_va_conn_t *vlc_va_get_conn( void ) ...@@ -58,15 +69,20 @@ vlc_va_conn_t *vlc_va_get_conn( void )
vlc_va_conn_t *vlc_va_Initialize( const char *display_name ) vlc_va_conn_t *vlc_va_Initialize( const char *display_name )
{ {
vlc_mutex_lock(&vlc_va_conn_lock);
/* connect global to caller */ /* connect global to caller */
vlc_va_conn_t *conn = vlc_va_get_conn(); vlc_va_conn_t *conn = vlc_va_get_conn();
assert(conn); assert(conn);
if (conn->i_ref_count > 0) if (conn->i_ref_count > 0)
{ {
conn->i_ref_count++; conn->i_ref_count++;
vlc_mutex_unlock(&vlc_va_conn_lock);
return conn; return conn;
} }
conn->lock = vlc_va_lock;
conn->unlock = vlc_va_unlock;
/* Create a VA display */ /* Create a VA display */
conn->p_display_x11 = XOpenDisplay(display_name); conn->p_display_x11 = XOpenDisplay(display_name);
if( !conn->p_display_x11 ) if( !conn->p_display_x11 )
...@@ -80,9 +96,11 @@ vlc_va_conn_t *vlc_va_Initialize( const char *display_name ) ...@@ -80,9 +96,11 @@ vlc_va_conn_t *vlc_va_Initialize( const char *display_name )
goto error; goto error;
conn->i_ref_count++; conn->i_ref_count++;
vlc_mutex_unlock(&vlc_va_conn_lock);
return conn; return conn;
error: error:
vlc_mutex_unlock(&vlc_va_conn_lock);
return NULL; return NULL;
} }
......
...@@ -130,6 +130,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) ...@@ -130,6 +130,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->conn = vlc_va_Initialize(NULL); p_va->conn = vlc_va_Initialize(NULL);
if (!p_va->conn) if (!p_va->conn)
goto error; goto error;
p_va->conn->lock();
/* Create a VA configuration */ /* Create a VA configuration */
VAConfigAttrib attrib; VAConfigAttrib attrib;
...@@ -155,14 +156,17 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) ...@@ -155,14 +156,17 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
p_va->conn->i_version_major, p_va->conn->i_version_minor ) < 0 ) p_va->conn->i_version_major, p_va->conn->i_version_minor ) < 0 )
p_va->va.description = NULL; p_va->va.description = NULL;
p_va->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
p_va->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static void DestroySurfaces( vlc_va_vaapi_t *p_va ) static void DestroySurfaces( vlc_va_vaapi_t *p_va )
{ {
p_va->conn->lock();
if( p_va->image.image_id != VA_INVALID_ID ) if( p_va->image.image_id != VA_INVALID_ID )
{ {
CopyCleanCache( &p_va->image_cache ); CopyCleanCache( &p_va->image_cache );
...@@ -186,6 +190,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va ) ...@@ -186,6 +190,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
p_va->p_surface = NULL; p_va->p_surface = NULL;
p_va->i_surface_width = 0; p_va->i_surface_width = 0;
p_va->i_surface_height = 0; p_va->i_surface_height = 0;
p_va->conn->unlock();
} }
static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma, static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
int i_width, int i_height ) int i_width, int i_height )
...@@ -199,6 +204,8 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t ...@@ -199,6 +204,8 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
p_va->image.image_id = VA_INVALID_ID; p_va->image.image_id = VA_INVALID_ID;
p_va->i_context_id = VA_INVALID_ID; p_va->i_context_id = VA_INVALID_ID;
p_va->conn->lock();
/* Create surfaces */ /* Create surfaces */
VASurfaceID pi_surface_id[p_va->i_surface_count]; VASurfaceID pi_surface_id[p_va->i_surface_count];
if( vaCreateSurfaces( p_va->conn->p_display, i_width, i_height, VA_RT_FORMAT_YUV420, if( vaCreateSurfaces( p_va->conn->p_display, i_width, i_height, VA_RT_FORMAT_YUV420,
...@@ -287,9 +294,12 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t ...@@ -287,9 +294,12 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
p_va->i_surface_chroma = i_chroma; p_va->i_surface_chroma = i_chroma;
p_va->i_surface_width = i_width; p_va->i_surface_width = i_width;
p_va->i_surface_height = i_height; p_va->i_surface_height = i_height;
p_va->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
p_va->conn->unlock();
DestroySurfaces( p_va ); DestroySurfaces( p_va );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -324,6 +334,8 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -324,6 +334,8 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
if( !p_va->image_cache.buffer ) if( !p_va->image_cache.buffer )
return VLC_EGENERIC; return VLC_EGENERIC;
p_va->conn->lock();
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3]; VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
#if VA_CHECK_VERSION(0,31,0) #if VA_CHECK_VERSION(0,31,0)
...@@ -331,7 +343,7 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -331,7 +343,7 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
#else #else
if( vaSyncSurface( p_va->conn->p_display, p_va->i_context_id, i_surface_id ) ) if( vaSyncSurface( p_va->conn->p_display, p_va->i_context_id, i_surface_id ) )
#endif #endif
return VLC_EGENERIC; goto error;
/* XXX vaDeriveImage may be better but it is not supported by /* XXX vaDeriveImage may be better but it is not supported by
* my setup. * my setup.
...@@ -340,11 +352,11 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -340,11 +352,11 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
if( vaGetImage( p_va->conn->p_display, i_surface_id, if( vaGetImage( p_va->conn->p_display, i_surface_id,
0, 0, p_va->i_surface_width, p_va->i_surface_height, 0, 0, p_va->i_surface_width, p_va->i_surface_height,
p_va->image.image_id) ) p_va->image.image_id) )
return VLC_EGENERIC; goto error;
void *p_base; void *p_base;
if( vaMapBuffer( p_va->conn->p_display, p_va->image.buf, &p_base ) ) if( vaMapBuffer( p_va->conn->p_display, p_va->image.buf, &p_base ) )
return VLC_EGENERIC; goto error;
const uint32_t i_fourcc = p_va->image.format.fourcc; const uint32_t i_fourcc = p_va->image.format.fourcc;
if( i_fourcc == VA_FOURCC('Y','V','1','2') || if( i_fourcc == VA_FOURCC('Y','V','1','2') ||
...@@ -383,9 +395,14 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -383,9 +395,14 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
} }
if( vaUnmapBuffer( p_va->conn->p_display, p_va->image.buf ) ) if( vaUnmapBuffer( p_va->conn->p_display, p_va->image.buf ) )
return VLC_EGENERIC; goto error;
p_va->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
error:
p_va->conn->unlock();
return VLC_EGENERIC;
} }
static vlc_va_surface_t *FindSurface( vlc_va_t *p_external, const VASurfaceID i_surface_id ) static vlc_va_surface_t *FindSurface( vlc_va_t *p_external, const VASurfaceID i_surface_id )
...@@ -413,6 +430,8 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame * ...@@ -413,6 +430,8 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
p_va->conn->lock();
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3]; VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
#if VA_CHECK_VERSION(0,31,0) #if VA_CHECK_VERSION(0,31,0)
...@@ -420,7 +439,7 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame * ...@@ -420,7 +439,7 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *
#else #else
if( vaSyncSurface( p_va->conn->p_display, p_va->i_context_id, i_surface_id ) ) if( vaSyncSurface( p_va->conn->p_display, p_va->i_context_id, i_surface_id ) )
#endif #endif
return VLC_EGENERIC; goto error;
if (!p_picture->p_sys) if (!p_picture->p_sys)
abort(); abort();
...@@ -430,7 +449,12 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame * ...@@ -430,7 +449,12 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *
if( !p_picture->p_sys->surface ) if( !p_picture->p_sys->surface )
abort(); abort();
p_va->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
error:
p_va->conn->unlock();
return VLC_EGENERIC;
} }
static int Get( vlc_va_t *p_external, AVFrame *p_ff ) static int Get( vlc_va_t *p_external, AVFrame *p_ff )
...@@ -492,8 +516,10 @@ static void Close( vlc_va_vaapi_t *p_va ) ...@@ -492,8 +516,10 @@ static void Close( vlc_va_vaapi_t *p_va )
if( p_va->i_surface_width || p_va->i_surface_height ) if( p_va->i_surface_width || p_va->i_surface_height )
DestroySurfaces( p_va ); DestroySurfaces( p_va );
p_va->conn->lock();
if( p_va->i_config_id != VA_INVALID_ID ) if( p_va->i_config_id != VA_INVALID_ID )
vaDestroyConfig( p_va->conn->p_display, p_va->i_config_id ); vaDestroyConfig( p_va->conn->p_display, p_va->i_config_id );
p_va->conn->unlock();
vlc_va_Terminate( p_va->conn ); vlc_va_Terminate( p_va->conn );
} }
......
...@@ -25,6 +25,9 @@ struct vlc_va_conn_t ...@@ -25,6 +25,9 @@ struct vlc_va_conn_t
int i_version_major; int i_version_major;
int i_version_minor; int i_version_minor;
int i_ref_count; /* for internal use only */ int i_ref_count; /* for internal use only */
void (*lock)(void);
void (*unlock)(void);
}; };
typedef struct typedef struct
......
...@@ -182,11 +182,12 @@ static void subpicture_cache_destroy(vasubpicture_cache_t *cache) ...@@ -182,11 +182,12 @@ static void subpicture_cache_destroy(vasubpicture_cache_t *cache)
* release allocated VA API resources */ * release allocated VA API resources */
static void SubpictureCacheClean(vout_display_t *vd, vlc_va_conn_t *conn, subpicture_cache_t *cache) static void SubpictureCacheClean(vout_display_t *vd, vlc_va_conn_t *conn, subpicture_cache_t *cache)
{ {
vout_display_sys_t *sys = (vout_display_sys_t *)vd->sys;
#ifdef VAAPI_DEBUG #ifdef VAAPI_DEBUG
msg_Dbg(vd, "subpictureCacheClean cache %d", cache->i_id); msg_Dbg(vd, "subpictureCacheClean cache %d", cache->i_id);
#else
VLC_UNUSED(vd);
#endif #endif
sys->conn->lock();
const int num = vlc_array_count(&cache->subpictures); const int num = vlc_array_count(&cache->subpictures);
for (int i = num - 1; i >= 0; i--) for (int i = num - 1; i >= 0; i--)
{ {
...@@ -213,6 +214,7 @@ static void SubpictureCacheClean(vout_display_t *vd, vlc_va_conn_t *conn, subpic ...@@ -213,6 +214,7 @@ static void SubpictureCacheClean(vout_display_t *vd, vlc_va_conn_t *conn, subpic
subpicture_cache_destroy(subpic); subpicture_cache_destroy(subpic);
subpic = NULL; subpic = NULL;
} }
sys->conn->unlock();
} }
/* VA API support functions */ /* VA API support functions */
...@@ -220,6 +222,7 @@ static int VASubtitleFourCC(vout_display_t *vd) ...@@ -220,6 +222,7 @@ static int VASubtitleFourCC(vout_display_t *vd)
{ {
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys; vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
sys->conn->lock();
int num = vaMaxNumSubpictureFormats(sys->conn->p_display); int num = vaMaxNumSubpictureFormats(sys->conn->p_display);
if (num <= 0) if (num <= 0)
goto out_warning; goto out_warning;
...@@ -244,6 +247,7 @@ static int VASubtitleFourCC(vout_display_t *vd) ...@@ -244,6 +247,7 @@ static int VASubtitleFourCC(vout_display_t *vd)
memcpy((void*)&sys->sub_fmt, (void*)&format, sizeof(VAImageFormat)); memcpy((void*)&sys->sub_fmt, (void*)&format, sizeof(VAImageFormat));
free(p_fmt); free(p_fmt);
free(flags); free(flags);
sys->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
...@@ -254,6 +258,7 @@ out: ...@@ -254,6 +258,7 @@ out:
out_warning: out_warning:
msg_Warn(vd, "VAAP-X11 does not support fourcc RGBA subtitles"); msg_Warn(vd, "VAAP-X11 does not support fourcc RGBA subtitles");
sys->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -261,6 +266,8 @@ static int FindVAFourCC(vout_display_t *vd) ...@@ -261,6 +266,8 @@ static int FindVAFourCC(vout_display_t *vd)
{ {
vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys; vout_display_sys_t *sys = (vout_display_sys_t *) vd->sys;
sys->conn->lock();
/* Find and create a supported image chroma */ /* Find and create a supported image chroma */
int i_fmt_count = vaMaxNumImageFormats(sys->conn->p_display); int i_fmt_count = vaMaxNumImageFormats(sys->conn->p_display);
VAImageFormat *p_fmt = calloc(i_fmt_count, sizeof(*p_fmt)); VAImageFormat *p_fmt = calloc(i_fmt_count, sizeof(*p_fmt));
...@@ -293,23 +300,28 @@ static int FindVAFourCC(vout_display_t *vd) ...@@ -293,23 +300,28 @@ static int FindVAFourCC(vout_display_t *vd)
vd->fmt.i_chroma = i_chroma; vd->fmt.i_chroma = i_chroma;
vd->fmt.i_bits_per_pixel = i_bits_per_pixel; vd->fmt.i_bits_per_pixel = i_bits_per_pixel;
sys->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
sys->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static vout_window_t *MakeWindow (vout_display_t *vd) static vout_window_t *MakeWindow (vout_display_t *vd)
{ {
vout_display_sys_t *sys = (vout_display_sys_t *)vd->sys;
vout_window_cfg_t wnd_cfg; vout_window_cfg_t wnd_cfg;
sys->conn->lock();
/* FIXME: Correct vout_window_t display size /* FIXME: Correct vout_window_t display size
* looks like it assumes fullscreen for * looks like it assumes fullscreen for
* vout_display_PlacePicture() to work as expected. */ * vout_display_PlacePicture() to work as expected. */
unsigned int width, height; unsigned int width, height;
int screen = DefaultScreen(vd->sys->conn->p_display_x11); int screen = DefaultScreen(sys->conn->p_display_x11);
width = DisplayWidth(vd->sys->conn->p_display_x11, screen); width = DisplayWidth(sys->conn->p_display_x11, screen);
height = DisplayHeight(vd->sys->conn->p_display_x11, screen); height = DisplayHeight(sys->conn->p_display_x11, screen);
sys->conn->unlock();
memset (&wnd_cfg, 0, sizeof (wnd_cfg)); memset (&wnd_cfg, 0, sizeof (wnd_cfg));
wnd_cfg.type = VOUT_WINDOW_TYPE_XID; wnd_cfg.type = VOUT_WINDOW_TYPE_XID;
...@@ -332,11 +344,15 @@ static int GetWindowSize(vout_display_t *vd, unsigned int *pi_width, unsigned in ...@@ -332,11 +344,15 @@ static int GetWindowSize(vout_display_t *vd, unsigned int *pi_width, unsigned in
int x, y; int x, y;
unsigned int bw, depth; unsigned int bw, depth;
sys->conn->lock();
status = XGetGeometry(sys->conn->p_display_x11, status = XGetGeometry(sys->conn->p_display_x11,
sys->embed->handle.xid, sys->embed->handle.xid,
&root_window, &root_window,
&x, &y, pi_width, pi_height, &x, &y, pi_width, pi_height,
&bw, &depth); &bw, &depth);
sys->conn->unlock();
if (status == 0) if (status == 0)
{ {
msg_Err(vd, "failed getting geometry"); msg_Err(vd, "failed getting geometry");
...@@ -439,8 +455,10 @@ void CloseVaapiX11 (vlc_object_t *obj) ...@@ -439,8 +455,10 @@ void CloseVaapiX11 (vlc_object_t *obj)
if (sys->conn && sys->conn->p_display_x11) if (sys->conn && sys->conn->p_display_x11)
{ {
sys->conn->lock();
XFlush(sys->conn->p_display_x11); XFlush(sys->conn->p_display_x11);
XSync(sys->conn->p_display_x11, False); XSync(sys->conn->p_display_x11, False);
sys->conn->unlock();
} }
if (sys->embed) if (sys->embed)
...@@ -553,12 +571,17 @@ static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *s ...@@ -553,12 +571,17 @@ static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *s
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
sys->conn->lock();
VAStatus status; VAStatus status;
VASubpictureID sub_id = VA_INVALID_ID; VASubpictureID sub_id = VA_INVALID_ID;
status = vaCreateSubpicture(sys->conn->p_display, image->image_id, &sub_id); status = vaCreateSubpicture(sys->conn->p_display, image->image_id, &sub_id);
if (status != VA_STATUS_SUCCESS) if (status != VA_STATUS_SUCCESS)
{
sys->conn->unlock();
return VA_INVALID_ID; return VA_INVALID_ID;
}
bool b_alpha = (flags & VA_SUBPICTURE_GLOBAL_ALPHA); bool b_alpha = (flags & VA_SUBPICTURE_GLOBAL_ALPHA);
bool b_chroma = (flags & VA_SUBPICTURE_CHROMA_KEYING); bool b_chroma = (flags & VA_SUBPICTURE_CHROMA_KEYING);
...@@ -590,6 +613,7 @@ static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *s ...@@ -590,6 +613,7 @@ static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *s
msg_Err(vd, "failed applying chroma valuesto subpicture"); msg_Err(vd, "failed applying chroma valuesto subpicture");
} }
sys->conn->unlock();
return sub_id; return sub_id;
} }
...@@ -619,6 +643,8 @@ static int SubpictureLink(vout_display_t *vd, VASurfaceID surface_id, ...@@ -619,6 +643,8 @@ static int SubpictureLink(vout_display_t *vd, VASurfaceID surface_id,
unsigned int dst_top = video.y + scale_h * region->i_y; unsigned int dst_top = video.y + scale_h * region->i_y;
unsigned int dst_bottom = dst_top + scale_h * region->fmt.i_visible_height; unsigned int dst_bottom = dst_top + scale_h * region->fmt.i_visible_height;
sys->conn->lock();
/* Associate subpicture with surface */ /* Associate subpicture with surface */
VAStatus status; VAStatus status;
status = vaAssociateSubpicture(sys->conn->p_display, vasub_id, status = vaAssociateSubpicture(sys->conn->p_display, vasub_id,
...@@ -629,10 +655,8 @@ static int SubpictureLink(vout_display_t *vd, VASurfaceID surface_id, ...@@ -629,10 +655,8 @@ static int SubpictureLink(vout_display_t *vd, VASurfaceID surface_id,
((video.width - dst_right) / 2), dst_top, ((video.width - dst_right) / 2), dst_top,
dst_right - dst_left, dst_bottom - dst_top, dst_right - dst_left, dst_bottom - dst_top,
flags); flags);
if (status != VA_STATUS_SUCCESS) sys->conn->unlock();
return VLC_EGENERIC; return (status != VA_STATUS_SUCCESS) ? VLC_EGENERIC : VLC_SUCCESS;
return VLC_SUCCESS;
} }
static VAStatus SubpictureUnlink( vlc_va_conn_t *p_connection, VASurfaceID surface_id, static VAStatus SubpictureUnlink( vlc_va_conn_t *p_connection, VASurfaceID surface_id,
...@@ -642,8 +666,10 @@ static VAStatus SubpictureUnlink( vlc_va_conn_t *p_connection, VASurfaceID surfa ...@@ -642,8 +666,10 @@ static VAStatus SubpictureUnlink( vlc_va_conn_t *p_connection, VASurfaceID surfa
if( (surface_id != VA_INVALID_SURFACE) && if( (surface_id != VA_INVALID_SURFACE) &&
(sub_id != VA_INVALID_ID) ) (sub_id != VA_INVALID_ID) )
{ {
p_connection->lock();
status = vaDeassociateSubpicture( p_connection->p_display, sub_id, status = vaDeassociateSubpicture( p_connection->p_display, sub_id,
&surface_id, 1 ); &surface_id, 1 );
p_connection->unlock();
} }
return status; return status;
} }
...@@ -684,10 +710,12 @@ static void CopyPalette(vout_display_t *vd, VAImage *image, video_palette_t *p_p ...@@ -684,10 +710,12 @@ static void CopyPalette(vout_display_t *vd, VAImage *image, video_palette_t *p_p
image->num_palette_entries = entries; image->num_palette_entries = entries;
image->entry_bytes = 4; /* RGBA has 4 components */ image->entry_bytes = 4; /* RGBA has 4 components */
sys->conn->lock();
VAStatus status = vaSetImagePalette(sys->conn->p_display, VAStatus status = vaSetImagePalette(sys->conn->p_display,
image->image_id, (unsigned char *)palette); image->image_id, (unsigned char *)palette);
if (status != VA_STATUS_SUCCESS) if (status != VA_STATUS_SUCCESS)
msg_Err(vd, "failed setting palette. (%d)", status); msg_Err(vd, "failed setting palette. (%d)", status);
sys->conn->unlock();
} }
#endif #endif
...@@ -696,11 +724,16 @@ static int CopyPictureToVAImage(vout_display_t *vd, picture_t *pic, ...@@ -696,11 +724,16 @@ static int CopyPictureToVAImage(vout_display_t *vd, picture_t *pic,
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
sys->conn->lock();
VAStatus status; VAStatus status;
status = vaCreateImage(sys->conn->p_display, fmt, status = vaCreateImage(sys->conn->p_display, fmt,
pic->format.i_width, pic->format.i_height, image); pic->format.i_width, pic->format.i_height, image);
if (status != VA_STATUS_SUCCESS) if (status != VA_STATUS_SUCCESS)
{
sys->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
}
/* Sanity checks */ /* Sanity checks */
if ((image->image_id == VA_INVALID_ID) || if ((image->image_id == VA_INVALID_ID) ||
...@@ -775,12 +808,14 @@ static int CopyPictureToVAImage(vout_display_t *vd, picture_t *pic, ...@@ -775,12 +808,14 @@ static int CopyPictureToVAImage(vout_display_t *vd, picture_t *pic,
goto out_va_free; goto out_va_free;
} }
sys->conn->unlock();
return VLC_SUCCESS; return VLC_SUCCESS;
out_va_free: out_va_free:
vaDestroyImage(sys->conn->p_display, image->image_id); vaDestroyImage(sys->conn->p_display, image->image_id);
image->image_id = VA_INVALID_ID; image->image_id = VA_INVALID_ID;
image->buf = VA_INVALID_ID; image->buf = VA_INVALID_ID;
sys->conn->unlock();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -827,10 +862,12 @@ static int RenderDirectSubpicture(vout_display_t *vd, picture_t *picture, subpic ...@@ -827,10 +862,12 @@ static int RenderDirectSubpicture(vout_display_t *vd, picture_t *picture, subpic
image, sys->sflags); image, sys->sflags);
if (vasub_cache->i_id == VA_INVALID_ID) if (vasub_cache->i_id == VA_INVALID_ID)
{ {
sys->conn->lock();
vaDestroyImage(sys->conn->p_display, image->image_id); vaDestroyImage(sys->conn->p_display, image->image_id);
vasub_cache->i_id = VA_INVALID_ID; vasub_cache->i_id = VA_INVALID_ID;
image->image_id = VA_INVALID_ID; image->image_id = VA_INVALID_ID;
image->buf = VA_INVALID_ID; image->buf = VA_INVALID_ID;
sys->conn->unlock();
subpicture_cache_destroy(vasub_cache); subpicture_cache_destroy(vasub_cache);
vasub_cache = NULL; vasub_cache = NULL;
goto cleanup; goto cleanup;
...@@ -842,11 +879,13 @@ static int RenderDirectSubpicture(vout_display_t *vd, picture_t *picture, subpic ...@@ -842,11 +879,13 @@ static int RenderDirectSubpicture(vout_display_t *vd, picture_t *picture, subpic
vasub_cache->i_id, sys->sflags); vasub_cache->i_id, sys->sflags);
if (err != VLC_SUCCESS) if (err != VLC_SUCCESS)
{ {
sys->conn->lock();
vaDestroySubpicture(sys->conn->p_display, vasub_cache->i_id); vaDestroySubpicture(sys->conn->p_display, vasub_cache->i_id);
vaDestroyImage(sys->conn->p_display, image->image_id); vaDestroyImage(sys->conn->p_display, image->image_id);
vasub_cache->i_id = VA_INVALID_ID; vasub_cache->i_id = VA_INVALID_ID;
image->image_id = VA_INVALID_ID; image->image_id = VA_INVALID_ID;
image->buf = VA_INVALID_ID; image->buf = VA_INVALID_ID;
sys->conn->unlock();
subpicture_cache_destroy(vasub_cache); subpicture_cache_destroy(vasub_cache);
vasub_cache = NULL; vasub_cache = NULL;
goto cleanup; goto cleanup;
...@@ -1126,6 +1165,8 @@ static void DisplayVASurface(vout_display_t *vd, VASurfaceID surface, picture_t ...@@ -1126,6 +1165,8 @@ static void DisplayVASurface(vout_display_t *vd, VASurfaceID surface, picture_t
vout_display_place_t place; vout_display_place_t place;
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false); vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
sys->conn->lock();
VAStatus status; VAStatus status;
status = vaPutSurface(sys->conn->p_display, surface, sys->embed->handle.xid, status = vaPutSurface(sys->conn->p_display, surface, sys->embed->handle.xid,
picture->format.i_x_offset, picture->format.i_y_offset, picture->format.i_x_offset, picture->format.i_y_offset,
...@@ -1139,6 +1180,8 @@ static void DisplayVASurface(vout_display_t *vd, VASurfaceID surface, picture_t ...@@ -1139,6 +1180,8 @@ static void DisplayVASurface(vout_display_t *vd, VASurfaceID surface, picture_t
if (status != VA_STATUS_SUCCESS) if (status != VA_STATUS_SUCCESS)
msg_Err(vd, "failed displaying picture: %d (surface id=%d): %p", msg_Err(vd, "failed displaying picture: %d (surface id=%d): %p",
status, surface, picture); status, surface, picture);
sys->conn->unlock();
} }
static void DisplayPicture(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture) static void DisplayPicture(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment