[vlc-commits] picture_pool: remove one allocation per cloned picture

Rémi Denis-Courmont git at videolan.org
Sun Jun 28 10:57:48 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Jun 27 16:55:24 2015 +0300| [7d3cd8d06d26ddab5433fb112da0584720de17c0] | committer: Rémi Denis-Courmont

picture_pool: remove one allocation per cloned picture

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7d3cd8d06d26ddab5433fb112da0584720de17c0
---

 include/vlc_picture.h   |    6 ------
 src/misc/picture.h      |    2 +-
 src/misc/picture_pool.c |   51 ++++++++++++++++-------------------------------
 3 files changed, 18 insertions(+), 41 deletions(-)

diff --git a/include/vlc_picture.h b/include/vlc_picture.h
index db9bdf5..b8d4a5a 100644
--- a/include/vlc_picture.h
+++ b/include/vlc_picture.h
@@ -56,12 +56,6 @@ typedef struct plane_t
  */
 #define PICTURE_PLANE_MAX (VOUT_MAX_PLANES)
 
-
-/**
- * A private definition to help overloading picture release
- */
-typedef struct picture_gc_sys_t picture_gc_sys_t;
-
 /**
  * Video picture
  */
diff --git a/src/misc/picture.h b/src/misc/picture.h
index 369f037..cf51113 100644
--- a/src/misc/picture.h
+++ b/src/misc/picture.h
@@ -28,6 +28,6 @@ typedef struct
     {
         atomic_uintptr_t refs;
         void (*destroy)(picture_t *);
-        picture_gc_sys_t *opaque;
+        void *opaque;
     } gc;
 } picture_priv_t;
diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index 17b4b41..797e979 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -22,10 +22,6 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
@@ -37,13 +33,7 @@
 #include <vlc_picture_pool.h>
 #include "picture.h"
 
-/*****************************************************************************
- *
- *****************************************************************************/
-struct picture_gc_sys_t {
-    picture_pool_t *pool;
-    unsigned offset;
-};
+static const uintptr_t pool_max = CHAR_BIT * sizeof (unsigned long long);
 
 struct picture_pool_t {
     int       (*pic_lock)(picture_t *);
@@ -72,26 +62,26 @@ void picture_pool_Release(picture_pool_t *pool)
         picture_Release(pool->picture[i]);
 
     vlc_mutex_destroy(&pool->lock);
-    free(pool);
+    vlc_free(pool);
 }
 
 static void picture_pool_ReleasePicture(picture_t *picture)
 {
     picture_priv_t *priv = (picture_priv_t *)picture;
-    picture_gc_sys_t *sys = priv->gc.opaque;
-    picture_pool_t *pool = sys->pool;
+    uintptr_t sys = (uintptr_t)priv->gc.opaque;
+    picture_pool_t *pool = (void *)(sys & ~(pool_max - 1));
+    unsigned offset = sys & (pool_max - 1);
 
     if (pool->pic_unlock != NULL)
-        pool->pic_unlock(pool->picture[sys->offset]);
+        pool->pic_unlock(pool->picture[offset]);
 
     vlc_mutex_lock(&pool->lock);
-    assert(!(pool->available & (1ULL << sys->offset)));
-    pool->available |= 1ULL << sys->offset;
+    assert(!(pool->available & (1ULL << offset)));
+    pool->available |= 1ULL << offset;
     vlc_mutex_unlock(&pool->lock);
 
     picture_pool_Release(pool);
 
-    free(sys);
     free(picture);
 }
 
@@ -99,13 +89,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
                                             unsigned offset)
 {
     picture_t *picture = pool->picture[offset];
-    picture_gc_sys_t *sys = malloc(sizeof(*sys));
-    if (unlikely(sys == NULL))
-        return NULL;
-
-    sys->pool = pool;
-    sys->offset = offset;
-
+    uintptr_t sys = ((uintptr_t)pool) + offset;
     picture_resource_t res = {
         .p_sys = picture->p_sys,
         .pf_destroy = picture_pool_ReleasePicture,
@@ -119,20 +103,17 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
 
     picture_t *clone = picture_NewFromResource(&picture->format, &res);
     if (likely(clone != NULL))
-        ((picture_priv_t *)clone)->gc.opaque = sys;
-    else
-        free(sys);
-
+        ((picture_priv_t *)clone)->gc.opaque = (void *)sys;
     return clone;
 }
 
 picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg)
 {
-    if (unlikely(cfg->picture_count > CHAR_BIT * sizeof (unsigned long long)))
+    if (unlikely(cfg->picture_count > pool_max))
         return NULL;
 
-    picture_pool_t *pool = malloc(sizeof (*pool)
-                                  + cfg->picture_count * sizeof (picture_t *));
+    picture_pool_t *pool = vlc_memalign(pool_max,
+        sizeof (*pool) + cfg->picture_count * sizeof (picture_t *));
     if (unlikely(pool == NULL))
         return NULL;
 
@@ -265,9 +246,11 @@ unsigned picture_pool_GetSize(const picture_pool_t *pool)
 
 picture_t *picture_pool_Deref(picture_t *picture)
 {
-    picture_priv_t *priv = (picture_priv_t *)picture;
+    uintptr_t sys = (uintptr_t)((picture_priv_t *)picture)->gc.opaque;
+    picture_pool_t *pool = (void *)(sys & ~(pool_max - 1));
+    unsigned offset = sys & (pool_max - 1);
 
-    return priv->gc.opaque->pool->picture[priv->gc.opaque->offset];
+    return pool->picture[offset];
 }
 
 void picture_pool_Enum(picture_pool_t *pool, void (*cb)(void *, picture_t *),



More information about the vlc-commits mailing list