From 74b6f45ec83116438c32164d0e5cad4e2804e7e9 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Mon, 7 Sep 2009 19:04:47 +0200 Subject: [PATCH 1/1] Added picture_pool_NewExtended. It allows to add callback called before/after a picture is used. --- include/vlc_picture_pool.h | 24 +++++++++++++- src/libvlccore.sym | 1 + src/video_output/vout_pictures.c | 57 ++++++++++++++++++++++++-------- 3 files changed, 68 insertions(+), 14 deletions(-) diff --git a/include/vlc_picture_pool.h b/include/vlc_picture_pool.h index 72469c634e..4bcdc44d24 100644 --- a/include/vlc_picture_pool.h +++ b/include/vlc_picture_pool.h @@ -40,12 +40,34 @@ 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. * 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. * 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[] ) ); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 705ddd7f25..2eeb208bb5 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -297,6 +297,7 @@ picture_NewFromResource picture_pool_Delete picture_pool_Get picture_pool_New +picture_pool_NewExtended picture_pool_NewFromFormat picture_pool_NonEmpty picture_Reset diff --git a/src/video_output/vout_pictures.c b/src/video_output/vout_pictures.c index 16119a90ea..d12e309633 100644 --- a/src/video_output/vout_pictures.c +++ b/src/video_output/vout_pictures.c @@ -1238,6 +1238,10 @@ struct picture_release_sys_t void (*pf_release)( picture_t * ); picture_release_sys_t *p_release_sys; + /* */ + int (*pf_lock)( picture_t * ); + void (*pf_unlock)( picture_t * ); + /* */ int64_t i_tick; }; @@ -1252,28 +1256,37 @@ struct picture_pool_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) ); if( !p_pool ) return NULL; 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) ); + 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 */ assert( p_picture->i_refcount == 1 ); /* Install the new release callback */ picture_release_sys_t *p_release_sys = malloc( sizeof(*p_release_sys) ); - p_release_sys->pf_release = p_picture->pf_release; + if( !p_release_sys ) + abort(); + p_release_sys->pf_release = p_picture->pf_release; p_release_sys->p_release_sys = p_picture->p_release_sys; - p_release_sys->i_tick = 0; + p_release_sys->pf_lock = cfg->lock; + p_release_sys->pf_unlock = cfg->unlock; + p_release_sys->i_tick = 0; p_picture->i_refcount = 0; p_picture->pf_release = PicturePoolPictureRelease; @@ -1283,6 +1296,18 @@ picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] ) p_pool->pp_picture[i] = p_picture; } 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 ) @@ -1340,13 +1365,17 @@ picture_t *picture_pool_Get( picture_pool_t *p_pool ) for( int i = 0; i < p_pool->i_picture; i++ ) { picture_t *p_picture = p_pool->pp_picture[i]; + if( p_picture->i_refcount > 0 ) + continue; - if( p_picture->i_refcount <= 0 ) - { - p_picture->p_release_sys->i_tick = p_pool->i_tick++; - picture_Hold( p_picture ); - return p_picture; - } + 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++; + picture_Hold( p_picture ); + return p_picture; } return NULL; } @@ -1377,6 +1406,8 @@ static void PicturePoolPictureRelease( picture_t *p_picture ) if( --p_picture->i_refcount > 0 ) 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 ); } -- 2.39.2