Commit 02676b16 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

picture: privatize reference counting

parent e29f8ecf
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
*/ */
#include <vlc_es.h> #include <vlc_es.h>
#include <vlc_atomic.h>
/** Description of a planar graphic field */ /** Description of a planar graphic field */
typedef struct plane_t typedef struct plane_t
...@@ -99,14 +98,6 @@ struct picture_t ...@@ -99,14 +98,6 @@ struct picture_t
* keep track of the picture */ * keep track of the picture */
picture_sys_t * p_sys; 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 */ /** Next picture in a FIFO a pictures */
struct picture_t *p_next; struct picture_t *p_next;
}; };
......
...@@ -447,6 +447,7 @@ SOURCES_libvlc_common = \ ...@@ -447,6 +447,7 @@ SOURCES_libvlc_common = \
misc/fourcc_list.h \ misc/fourcc_list.h \
misc/es_format.c \ misc/es_format.c \
misc/picture.c \ misc/picture.c \
misc/picture.h \
misc/picture_fifo.c \ misc/picture_fifo.c \
misc/picture_pool.c \ misc/picture_pool.c \
modules/modules.h \ modules/modules.h \
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <assert.h> #include <assert.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_picture.h> #include "picture.h"
#include <vlc_image.h> #include <vlc_image.h>
#include <vlc_block.h> #include <vlc_block.h>
...@@ -148,9 +148,6 @@ int picture_Setup( picture_t *p_picture, const video_format_t *restrict fmt ) ...@@ -148,9 +148,6 @@ int picture_Setup( picture_t *p_picture, const video_format_t *restrict fmt )
p->i_pixel_pitch = 0; p->i_pixel_pitch = 0;
} }
atomic_init( &p_picture->gc.refcount, 0 );
p_picture->gc.p_sys = NULL;
p_picture->i_nb_fields = 2; p_picture->i_nb_fields = 2;
video_format_Setup( &p_picture->format, fmt->i_chroma, fmt->i_width, fmt->i_height, 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 ...@@ -219,10 +216,15 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
video_format_CopyCrop( &fmt, p_fmt ); video_format_CopyCrop( &fmt, p_fmt );
/* */ /* */
picture_t *p_picture = calloc( 1, sizeof(*p_picture) ); picture_priv_t *priv = malloc( sizeof (*priv) );
if( !p_picture ) if( unlikely(priv == NULL) )
return 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 */ /* Make sure the real dimensions are a multiple of 16 */
if( picture_Setup( p_picture, &fmt ) ) if( picture_Setup( p_picture, &fmt ) )
{ {
...@@ -230,12 +232,17 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r ...@@ -230,12 +232,17 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
return NULL; return NULL;
} }
atomic_init( &priv->gc.refs, 1 );
priv->gc.opaque = NULL;
if( p_resource ) if( p_resource )
{ {
p_picture->p_sys = p_resource->p_sys; p_picture->p_sys = p_resource->p_sys;
p_picture->gc.pf_destroy = p_resource->pf_destroy;
if( p_picture->gc.pf_destroy == NULL ) if( p_resource->pf_destroy != NULL )
p_picture->gc.pf_destroy = picture_DestroyFromResource; priv->gc.destroy = p_resource->pf_destroy;
else
priv->gc.destroy = picture_DestroyFromResource;
for( int i = 0; i < p_picture->i_planes; i++ ) 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 ...@@ -251,14 +258,9 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
free( p_picture ); free( p_picture );
return NULL; 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; return p_picture;
} }
...@@ -284,7 +286,10 @@ picture_t *picture_New( vlc_fourcc_t i_chroma, int i_width, int i_height, int i_ ...@@ -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 ) 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 ); assert( refs > 0 );
return p_picture; return p_picture;
} }
...@@ -293,19 +298,22 @@ void picture_Release( picture_t *p_picture ) ...@@ -293,19 +298,22 @@ void picture_Release( picture_t *p_picture )
{ {
assert( p_picture != NULL ); 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 ); assert( refs != 0 );
if( refs > 1 ) if( refs > 1 )
return; return;
PictureDestroyContext( p_picture ); PictureDestroyContext( p_picture );
assert( p_picture->gc.pf_destroy != NULL ); assert( priv->gc.destroy != NULL );
p_picture->gc.pf_destroy( p_picture ); priv->gc.destroy( p_picture );
} }
bool picture_IsReferenced( picture_t *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;
} }
/***************************************************************************** /*****************************************************************************
......
/*****************************************************************************
* 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;
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_picture_pool.h> #include <vlc_picture_pool.h>
#include "picture.h"
/***************************************************************************** /*****************************************************************************
* *
...@@ -70,10 +71,10 @@ void picture_pool_Release(picture_pool_t *pool) ...@@ -70,10 +71,10 @@ void picture_pool_Release(picture_pool_t *pool)
for (unsigned i = 0; i < pool->picture_count; i++) { for (unsigned i = 0; i < pool->picture_count; i++) {
picture_t *picture = pool->picture[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); picture_Release(priv->gc.opaque->picture);
free(sys); free(priv->gc.opaque);
free(picture); free(picture);
} }
...@@ -84,7 +85,8 @@ void picture_pool_Release(picture_pool_t *pool) ...@@ -84,7 +85,8 @@ void picture_pool_Release(picture_pool_t *pool)
static void picture_pool_ReleasePicture(picture_t *picture) 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; picture_pool_t *pool = sys->pool;
if (pool->pic_unlock != NULL) if (pool->pic_unlock != NULL)
...@@ -123,7 +125,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool, ...@@ -123,7 +125,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
picture_t *clone = picture_NewFromResource(&picture->format, &res); picture_t *clone = picture_NewFromResource(&picture->format, &res);
if (likely(clone != NULL)) if (likely(clone != NULL))
clone->gc.p_sys = sys; ((picture_priv_t *)clone)->gc.opaque = sys;
else else
free(sys); free(sys);
...@@ -163,7 +165,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg ...@@ -163,7 +165,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
if (unlikely(picture == NULL)) if (unlikely(picture == NULL))
abort(); abort();
atomic_init(&picture->gc.refcount, 0); atomic_init(&((picture_priv_t *)picture)->gc.refs, 0);
pool->picture[i] = picture; pool->picture[i] = picture;
} }
...@@ -236,7 +238,8 @@ picture_t *picture_pool_Get(picture_pool_t *pool) ...@@ -236,7 +238,8 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
for (unsigned i = 0; i < pool->picture_count; i++) { for (unsigned i = 0; i < pool->picture_count; i++) {
picture_t *picture = pool->picture[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; uint64_t tick;
if (sys->in_use) if (sys->in_use)
...@@ -256,8 +259,8 @@ picture_t *picture_pool_Get(picture_pool_t *pool) ...@@ -256,8 +259,8 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
sys->tick = tick; sys->tick = tick;
assert(atomic_load(&picture->gc.refcount) == 0); assert(atomic_load(&((picture_priv_t *)picture)->gc.refs) == 0);
atomic_init(&picture->gc.refcount, 1); atomic_init(&((picture_priv_t *)picture)->gc.refs, 1);
picture->p_next = NULL; picture->p_next = NULL;
return picture; return picture;
} }
...@@ -275,7 +278,8 @@ retry: ...@@ -275,7 +278,8 @@ retry:
for (unsigned i = 0; i < pool->picture_count; i++) { for (unsigned i = 0; i < pool->picture_count; i++) {
picture_t *picture = pool->picture[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) { if (sys->in_use) {
vlc_mutex_unlock(&pool->lock); vlc_mutex_unlock(&pool->lock);
......
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