[vlc-commits] picture: privatize reference counting

Rémi Denis-Courmont git at videolan.org
Thu Jun 25 23:09:28 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at 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);



More information about the vlc-commits mailing list