vlc | branch: master | Rémi Denis-Courmont <r...@remlab.net> | Thu Jun 25 23:30:37 2015 +0300| [02676b16b87f78192f053553eca119af8a659731] | committer: Rémi Denis-Courmont
picture: privatize reference counting > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=02676b16b87f78192f053553eca119af8a659731 --- include/vlc_picture.h | 9 --------- src/Makefile.am | 1 + src/misc/picture.c | 48 +++++++++++++++++++++++++++-------------------- src/misc/picture.h | 33 ++++++++++++++++++++++++++++++++ src/misc/picture_pool.c | 24 ++++++++++++++---------- 5 files changed, 76 insertions(+), 39 deletions(-) diff --git a/include/vlc_picture.h b/include/vlc_picture.h index 1e70a59..db9bdf5 100644 --- a/include/vlc_picture.h +++ b/include/vlc_picture.h @@ -32,7 +32,6 @@ */ #include <vlc_es.h> -#include <vlc_atomic.h> /** Description of a planar graphic field */ typedef struct plane_t @@ -99,14 +98,6 @@ struct picture_t * keep track of the picture */ picture_sys_t * p_sys; - /** This way the picture_Release can be overloaded */ - struct - { - atomic_uintptr_t refcount; - void (*pf_destroy)( picture_t * ); - picture_gc_sys_t *p_sys; - } gc; - /** Next picture in a FIFO a pictures */ struct picture_t *p_next; }; diff --git a/src/Makefile.am b/src/Makefile.am index e608e4d..62c54a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -447,6 +447,7 @@ SOURCES_libvlc_common = \ misc/fourcc_list.h \ misc/es_format.c \ misc/picture.c \ + misc/picture.h \ misc/picture_fifo.c \ misc/picture_pool.c \ modules/modules.h \ diff --git a/src/misc/picture.c b/src/misc/picture.c index 7d08c48..0cdbd0e 100644 --- a/src/misc/picture.c +++ b/src/misc/picture.c @@ -34,7 +34,7 @@ #include <assert.h> #include <vlc_common.h> -#include <vlc_picture.h> +#include "picture.h" #include <vlc_image.h> #include <vlc_block.h> @@ -148,9 +148,6 @@ int picture_Setup( picture_t *p_picture, const video_format_t *restrict fmt ) p->i_pixel_pitch = 0; } - atomic_init( &p_picture->gc.refcount, 0 ); - p_picture->gc.p_sys = NULL; - p_picture->i_nb_fields = 2; video_format_Setup( &p_picture->format, fmt->i_chroma, fmt->i_width, fmt->i_height, @@ -219,10 +216,15 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r video_format_CopyCrop( &fmt, p_fmt ); /* */ - picture_t *p_picture = calloc( 1, sizeof(*p_picture) ); - if( !p_picture ) + picture_priv_t *priv = malloc( sizeof (*priv) ); + if( unlikely(priv == NULL) ) return NULL; + picture_t *p_picture = &priv->picture; + + memset( p_picture, 0, sizeof( *p_picture ) ); + p_picture->format = fmt; + /* Make sure the real dimensions are a multiple of 16 */ if( picture_Setup( p_picture, &fmt ) ) { @@ -230,12 +232,17 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r return NULL; } + atomic_init( &priv->gc.refs, 1 ); + priv->gc.opaque = NULL; + if( p_resource ) { p_picture->p_sys = p_resource->p_sys; - p_picture->gc.pf_destroy = p_resource->pf_destroy; - if( p_picture->gc.pf_destroy == NULL ) - p_picture->gc.pf_destroy = picture_DestroyFromResource; + + if( p_resource->pf_destroy != NULL ) + priv->gc.destroy = p_resource->pf_destroy; + else + priv->gc.destroy = picture_DestroyFromResource; for( int i = 0; i < p_picture->i_planes; i++ ) { @@ -251,14 +258,9 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r free( p_picture ); return NULL; } - p_picture->gc.pf_destroy = picture_Destroy; + priv->gc.destroy = picture_Destroy; } - /* */ - p_picture->format = fmt; - - atomic_init( &p_picture->gc.refcount, 1 ); - return p_picture; } @@ -284,7 +286,10 @@ picture_t *picture_New( vlc_fourcc_t i_chroma, int i_width, int i_height, int i_ picture_t *picture_Hold( picture_t *p_picture ) { - uintptr_t refs = atomic_fetch_add( &p_picture->gc.refcount, 1 ); + assert( p_picture != NULL ); + + picture_priv_t *priv = (picture_priv_t *)p_picture; + uintptr_t refs = atomic_fetch_add( &priv->gc.refs, 1 ); assert( refs > 0 ); return p_picture; } @@ -293,19 +298,22 @@ void picture_Release( picture_t *p_picture ) { assert( p_picture != NULL ); - uintptr_t refs = atomic_fetch_sub( &p_picture->gc.refcount, 1 ); + picture_priv_t *priv = (picture_priv_t *)p_picture; + uintptr_t refs = atomic_fetch_sub( &priv->gc.refs, 1 ); assert( refs != 0 ); if( refs > 1 ) return; PictureDestroyContext( p_picture ); - assert( p_picture->gc.pf_destroy != NULL ); - p_picture->gc.pf_destroy( p_picture ); + assert( priv->gc.destroy != NULL ); + priv->gc.destroy( p_picture ); } bool picture_IsReferenced( picture_t *p_picture ) { - return atomic_load( &p_picture->gc.refcount ) > 1; + picture_priv_t *priv = (picture_priv_t *)p_picture; + + return atomic_load( &priv->gc.refs ) > 1; } /***************************************************************************** diff --git a/src/misc/picture.h b/src/misc/picture.h new file mode 100644 index 0000000..369f037 --- /dev/null +++ b/src/misc/picture.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * picture.h: picture internals + ***************************************************************************** + * Copyright (C) 2015 Remi Denis-Courmont + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#include <vlc_picture.h> +#include <vlc_atomic.h> + +typedef struct +{ + picture_t picture; + struct + { + atomic_uintptr_t refs; + void (*destroy)(picture_t *); + picture_gc_sys_t *opaque; + } gc; +} picture_priv_t; diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c index 64c60a9..9a4d7db 100644 --- a/src/misc/picture_pool.c +++ b/src/misc/picture_pool.c @@ -33,6 +33,7 @@ #include <vlc_common.h> #include <vlc_picture_pool.h> +#include "picture.h" /***************************************************************************** * @@ -70,10 +71,10 @@ void picture_pool_Release(picture_pool_t *pool) for (unsigned i = 0; i < pool->picture_count; i++) { picture_t *picture = pool->picture[i]; - picture_gc_sys_t *sys = picture->gc.p_sys; + picture_priv_t *priv = (picture_priv_t *)picture; - picture_Release(sys->picture); - free(sys); + picture_Release(priv->gc.opaque->picture); + free(priv->gc.opaque); free(picture); } @@ -84,7 +85,8 @@ void picture_pool_Release(picture_pool_t *pool) static void picture_pool_ReleasePicture(picture_t *picture) { - picture_gc_sys_t *sys = picture->gc.p_sys; + picture_priv_t *priv = (picture_priv_t *)picture; + picture_gc_sys_t *sys = priv->gc.opaque; picture_pool_t *pool = sys->pool; if (pool->pic_unlock != NULL) @@ -123,7 +125,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool, picture_t *clone = picture_NewFromResource(&picture->format, &res); if (likely(clone != NULL)) - clone->gc.p_sys = sys; + ((picture_priv_t *)clone)->gc.opaque = sys; else free(sys); @@ -163,7 +165,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg if (unlikely(picture == NULL)) abort(); - atomic_init(&picture->gc.refcount, 0); + atomic_init(&((picture_priv_t *)picture)->gc.refs, 0); pool->picture[i] = picture; } @@ -236,7 +238,8 @@ picture_t *picture_pool_Get(picture_pool_t *pool) for (unsigned i = 0; i < pool->picture_count; i++) { picture_t *picture = pool->picture[i]; - picture_gc_sys_t *sys = picture->gc.p_sys; + picture_priv_t *priv = (picture_priv_t *)picture; + picture_gc_sys_t *sys = priv->gc.opaque; uint64_t tick; if (sys->in_use) @@ -256,8 +259,8 @@ picture_t *picture_pool_Get(picture_pool_t *pool) sys->tick = tick; - assert(atomic_load(&picture->gc.refcount) == 0); - atomic_init(&picture->gc.refcount, 1); + assert(atomic_load(&((picture_priv_t *)picture)->gc.refs) == 0); + atomic_init(&((picture_priv_t *)picture)->gc.refs, 1); picture->p_next = NULL; return picture; } @@ -275,7 +278,8 @@ retry: for (unsigned i = 0; i < pool->picture_count; i++) { picture_t *picture = pool->picture[i]; - picture_gc_sys_t *sys = picture->gc.p_sys; + picture_priv_t *priv = (picture_priv_t *)picture; + picture_gc_sys_t *sys = priv->gc.opaque; if (sys->in_use) { vlc_mutex_unlock(&pool->lock); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits