Commit 74b6f45e authored by Laurent Aimar's avatar Laurent Aimar

Added picture_pool_NewExtended.

It allows to add callback called before/after a picture is used.
parent 4f49f2aa
...@@ -40,12 +40,34 @@ ...@@ -40,12 +40,34 @@
typedef struct picture_pool_t picture_pool_t; typedef struct picture_pool_t picture_pool_t;
/** /**
* It creates a picture_pool_t wrapping the given arrays of picture. * Picture pool configuration
*/
typedef struct {
int picture_count;
picture_t **picture;
int (*lock)(picture_t *);
void (*unlock)(picture_t *);
} picture_pool_configuration_t;
/**
* It creates a picture_pool_t wrapping the given configuration.
* *
* It is usefull to avoid useless picture creations/destructions. * It is usefull to avoid useless picture creations/destructions.
* The given picture must not have a reference count greater than 1. * The given picture must not have a reference count greater than 1.
* The pool takes ownership of the picture and MUST not be used directly. * The pool takes ownership of the picture and MUST not be used directly.
* When deleted, the pool will release the pictures using picture_Release. * When deleted, the pool will release the pictures using picture_Release.
* If defined, picture_pool_configuration_t::lock will be called before
* a picture is used, and picture_pool_configuration_t::unlock will be called
* as soon as a picture is unused. They are allowed to modify picture_t::p and
* access picture_t::p_sys.
*/
VLC_EXPORT( picture_pool_t *, picture_pool_NewExtended, ( const picture_pool_configuration_t * ) );
/**
* It creates a picture_pool_t wrapping the given arrays of picture.
*
* It is provided as convenience.
*/ */
VLC_EXPORT( picture_pool_t *, picture_pool_New, ( int i_picture, picture_t *pp_picture[] ) ); VLC_EXPORT( picture_pool_t *, picture_pool_New, ( int i_picture, picture_t *pp_picture[] ) );
......
...@@ -297,6 +297,7 @@ picture_NewFromResource ...@@ -297,6 +297,7 @@ picture_NewFromResource
picture_pool_Delete picture_pool_Delete
picture_pool_Get picture_pool_Get
picture_pool_New picture_pool_New
picture_pool_NewExtended
picture_pool_NewFromFormat picture_pool_NewFromFormat
picture_pool_NonEmpty picture_pool_NonEmpty
picture_Reset picture_Reset
......
...@@ -1238,6 +1238,10 @@ struct picture_release_sys_t ...@@ -1238,6 +1238,10 @@ struct picture_release_sys_t
void (*pf_release)( picture_t * ); void (*pf_release)( picture_t * );
picture_release_sys_t *p_release_sys; picture_release_sys_t *p_release_sys;
/* */
int (*pf_lock)( picture_t * );
void (*pf_unlock)( picture_t * );
/* */ /* */
int64_t i_tick; int64_t i_tick;
}; };
...@@ -1252,27 +1256,36 @@ struct picture_pool_t ...@@ -1252,27 +1256,36 @@ struct picture_pool_t
static void PicturePoolPictureRelease( picture_t * ); static void PicturePoolPictureRelease( picture_t * );
picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] ) picture_pool_t *picture_pool_NewExtended( const picture_pool_configuration_t *cfg )
{ {
picture_pool_t *p_pool = calloc( 1, sizeof(*p_pool) ); picture_pool_t *p_pool = calloc( 1, sizeof(*p_pool) );
if( !p_pool ) if( !p_pool )
return NULL; return NULL;
p_pool->i_tick = 1; p_pool->i_tick = 1;
p_pool->i_picture = i_picture; p_pool->i_picture = cfg->picture_count;
p_pool->pp_picture = calloc( p_pool->i_picture, sizeof(*p_pool->pp_picture) ); p_pool->pp_picture = calloc( p_pool->i_picture, sizeof(*p_pool->pp_picture) );
if( !p_pool->pp_picture )
{
free( p_pool );
return NULL;
}
for( int i = 0; i < i_picture; i++ ) for( int i = 0; i < cfg->picture_count; i++ )
{ {
picture_t *p_picture = pp_picture[i]; picture_t *p_picture = cfg->picture[i];
/* The pool must be the only owner of the picture */ /* The pool must be the only owner of the picture */
assert( p_picture->i_refcount == 1 ); assert( p_picture->i_refcount == 1 );
/* Install the new release callback */ /* Install the new release callback */
picture_release_sys_t *p_release_sys = malloc( sizeof(*p_release_sys) ); picture_release_sys_t *p_release_sys = malloc( sizeof(*p_release_sys) );
if( !p_release_sys )
abort();
p_release_sys->pf_release = p_picture->pf_release; p_release_sys->pf_release = p_picture->pf_release;
p_release_sys->p_release_sys = p_picture->p_release_sys; p_release_sys->p_release_sys = p_picture->p_release_sys;
p_release_sys->pf_lock = cfg->lock;
p_release_sys->pf_unlock = cfg->unlock;
p_release_sys->i_tick = 0; p_release_sys->i_tick = 0;
p_picture->i_refcount = 0; p_picture->i_refcount = 0;
...@@ -1283,6 +1296,18 @@ picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] ) ...@@ -1283,6 +1296,18 @@ picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] )
p_pool->pp_picture[i] = p_picture; p_pool->pp_picture[i] = p_picture;
} }
return p_pool; return p_pool;
}
picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] )
{
picture_pool_configuration_t cfg;
memset( &cfg, 0, sizeof(cfg) );
cfg.picture_count = i_picture;
cfg.picture = pp_picture;
return picture_pool_NewExtended( &cfg );
} }
picture_pool_t *picture_pool_NewFromFormat( const video_format_t *p_fmt, int i_picture ) picture_pool_t *picture_pool_NewFromFormat( const video_format_t *p_fmt, int i_picture )
...@@ -1340,14 +1365,18 @@ picture_t *picture_pool_Get( picture_pool_t *p_pool ) ...@@ -1340,14 +1365,18 @@ picture_t *picture_pool_Get( picture_pool_t *p_pool )
for( int i = 0; i < p_pool->i_picture; i++ ) for( int i = 0; i < p_pool->i_picture; i++ )
{ {
picture_t *p_picture = p_pool->pp_picture[i]; picture_t *p_picture = p_pool->pp_picture[i];
if( p_picture->i_refcount > 0 )
continue;
if( p_picture->i_refcount <= 0 ) picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
{ if( p_release_sys->pf_lock && p_release_sys->pf_lock(p_picture) )
continue;
/* */
p_picture->p_release_sys->i_tick = p_pool->i_tick++; p_picture->p_release_sys->i_tick = p_pool->i_tick++;
picture_Hold( p_picture ); picture_Hold( p_picture );
return p_picture; return p_picture;
} }
}
return NULL; return NULL;
} }
...@@ -1377,6 +1406,8 @@ static void PicturePoolPictureRelease( picture_t *p_picture ) ...@@ -1377,6 +1406,8 @@ static void PicturePoolPictureRelease( picture_t *p_picture )
if( --p_picture->i_refcount > 0 ) if( --p_picture->i_refcount > 0 )
return; return;
/* Nothing to do for the moment */ picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
if( p_release_sys->pf_unlock )
p_release_sys->pf_unlock( p_picture );
} }
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