Commit a844bbbb authored by Jean-Paul Saman's avatar Jean-Paul Saman

codec/avcodec/vaapi: Pass VASurface' s to vaapi-x11 vout

When -V vaapi-x11 is used (and ffmpeg-vaapi-x11 option), then pass
VASurface information in picture->p_sys. This only works with direct
rendering and video filters that directly operate on the picture are
a no go.

* vaapi.c: protect surface->i_refcount
* vaapi_x11.c: use direct rendering
parent 92ba7483
/***************************************************************************** /*****************************************************************************
* vaapi.c: VAAPI helpers for the ffmpeg decoder * vaapi.c: VAAPI helpers for the ffmpeg decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 2009 Laurent Aimar * Copyright (C) 2009-2011 Laurent Aimar
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir_AT_ videolan _DOT_ org> * Authors: Laurent Aimar <fenrir_AT_ videolan _DOT_ org>
...@@ -48,14 +48,6 @@ ...@@ -48,14 +48,6 @@
#ifdef HAVE_AVCODEC_VAAPI #ifdef HAVE_AVCODEC_VAAPI
typedef struct
{
VASurfaceID i_id;
int i_refcount;
unsigned int i_order;
} vlc_va_surface_t;
typedef struct typedef struct
{ {
vlc_va_t va; vlc_va_t va;
...@@ -176,7 +168,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va ) ...@@ -176,7 +168,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
for( int i = 0; i < p_va->i_surface_count && p_va->p_surface; i++ ) for( int i = 0; i < p_va->i_surface_count && p_va->p_surface; i++ )
{ {
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
vlc_mutex_destroy(&p_surface->lock);
if( p_surface->i_id != VA_INVALID_SURFACE ) if( p_surface->i_id != VA_INVALID_SURFACE )
vaDestroySurfaces( p_va->conn->p_display, &p_surface->i_id, 1 ); vaDestroySurfaces( p_va->conn->p_display, &p_surface->i_id, 1 );
} }
...@@ -218,6 +210,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t ...@@ -218,6 +210,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
p_surface->i_id = pi_surface_id[i]; p_surface->i_id = pi_surface_id[i];
p_surface->i_refcount = 0; p_surface->i_refcount = 0;
p_surface->i_order = 0; p_surface->i_order = 0;
vlc_mutex_init(&p_surface->lock);
} }
/* Create a context */ /* Create a context */
...@@ -388,12 +381,33 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff ) ...@@ -388,12 +381,33 @@ static int Extract( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
static vlc_va_surface_t *FindSurface( vlc_va_t *p_external, const VASurfaceID i_surface_id )
{ {
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external); vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
vlc_va_surface_t *p_surface = NULL;
if( !p_va->image_cache.buffer ) for( int i = 0; i < p_va->i_surface_count; i++ )
return VLC_EGENERIC; {
vlc_va_surface_t *p_tmp = &p_va->p_surface[i];
if( p_tmp->i_id == i_surface_id )
{
vlc_mutex_lock(&p_tmp->lock);
/* NOTE: p_tmp->i_refcount can be greater then 1, when surfaces are being reclaimed
* this usually only happens when the vout vaapi-x11 is not instantiated yet.
*/
p_tmp->i_refcount++;
p_surface = p_tmp;
vlc_mutex_unlock(&p_surface->lock);
break;
}
}
return p_surface;
}
static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *p_ff )
{
vlc_va_vaapi_t *p_va = vlc_va_vaapi_Get(p_external);
VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3]; VASurfaceID i_surface_id = (VASurfaceID)(uintptr_t)p_ff->data[3];
...@@ -404,12 +418,19 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame * ...@@ -404,12 +418,19 @@ static int DisplayPicture( vlc_va_t *p_external, picture_t *p_picture, AVFrame *
#endif #endif
return VLC_EGENERIC; return VLC_EGENERIC;
assert(p_picture->p_sys);
if (!p_picture->p_sys) if (!p_picture->p_sys)
return VLC_ENOMEM; return VLC_EGENERIC;
assert( sizeof(p_picture->p_sys) == sizeof(picture_sys_t) ); assert( sizeof(p_picture->p_sys) == sizeof(picture_sys_t) );
p_picture->p_sys->i_surface_id = i_surface_id; /* FindSurface */
p_picture->p_sys->surface = FindSurface( p_external, i_surface_id );
if( !p_picture->p_sys->surface )
return VLC_EGENERIC;
p_picture->format.i_width = p_picture->format.i_visible_width = p_va->i_surface_width;
p_picture->format.i_height = p_picture->format.i_visible_height = p_va->i_surface_height;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -425,7 +446,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -425,7 +446,7 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff )
{ {
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
if( !p_surface->i_refcount ) if( p_surface->i_refcount == 0 )
break; break;
if( p_surface->i_order < p_va->p_surface[i_old].i_order ) if( p_surface->i_order < p_va->p_surface[i_old].i_order )
...@@ -435,9 +456,13 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -435,9 +456,13 @@ static int Get( vlc_va_t *p_external, AVFrame *p_ff )
i = i_old; i = i_old;
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
vlc_mutex_lock(&p_surface->lock);
p_surface->i_refcount = 1; /* NOTE: when the surface is in use and not consumed by vout vaapi-x11,
* then p_surface->i_refcount can be greater then 0. Thus always increment.
*/
p_surface->i_refcount++;
p_surface->i_order = p_va->i_surface_order++; p_surface->i_order = p_va->i_surface_order++;
vlc_mutex_unlock(&p_surface->lock);
/* */ /* */
for( int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ )
...@@ -461,7 +486,11 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff ) ...@@ -461,7 +486,11 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff )
vlc_va_surface_t *p_surface = &p_va->p_surface[i]; vlc_va_surface_t *p_surface = &p_va->p_surface[i];
if( p_surface->i_id == i_surface_id ) if( p_surface->i_id == i_surface_id )
{
vlc_mutex_lock(&p_surface->lock);
p_surface->i_refcount--; p_surface->i_refcount--;
vlc_mutex_unlock(&p_surface->lock);
}
} }
} }
......
This diff is collapsed.
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