[vlc-commits] [Git][videolan/vlc][master] 4 commits: picture_pool: use a vlc_list

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Dec 1 14:05:08 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
922c5f03 by Thomas Guillem at 2024-12-01T13:49:41+00:00
picture_pool: use a vlc_list

This will allow to go past 64 pictures and handle dynamic pools.

- - - - -
f83c76e9 by Thomas Guillem at 2024-12-01T13:49:41+00:00
picture_pool: increase POOL_MAX

- - - - -
9d9520e4 by Thomas Guillem at 2024-12-01T13:49:41+00:00
picture_pool: refactor

No functional changes.

- - - - -
d8a43e85 by Thomas Guillem at 2024-12-01T13:49:41+00:00
picture_pool: create pictures after the pool

Error handling simplification.

- - - - -


3 changed files:

- src/misc/picture.c
- src/misc/picture.h
- src/misc/picture_pool.c


Changes:

=====================================
src/misc/picture.c
=====================================
@@ -229,6 +229,8 @@ static bool picture_InitPrivate(const video_format_t *restrict p_fmt,
     else
         priv->gc.destroy = picture_DestroyDummy;
 
+    priv->pool = NULL;
+
     vlc_ancillary_array_Init(&priv->ancillaries);
 
     return true;


=====================================
src/misc/picture.h
=====================================
@@ -22,6 +22,7 @@
 #include <stddef.h>
 
 #include <vlc_picture.h>
+#include <vlc_list.h>
 struct vlc_ancillary;
 
 typedef struct
@@ -33,6 +34,9 @@ typedef struct
         void *opaque;
     } gc;
 
+    void *pool; /* Only used by picture_pool.c */
+    struct vlc_list pool_node; /* Only used by picture_pool.c */
+
     /** Private ancillary struct. Don't use it directly, but use it via
      * picture_AttachAncillary() and picture_GetAncillary(). */
     struct vlc_ancillary **ancillaries;


=====================================
src/misc/picture_pool.c
=====================================
@@ -35,20 +35,18 @@
 #include <vlc_threads.h>
 #include <vlc_picture_pool.h>
 #include <vlc_atomic.h>
+#include <vlc_list.h>
 #include "picture.h"
 
-#define POOL_MAX (CHAR_BIT * sizeof (unsigned long long))
-
-static_assert ((POOL_MAX & (POOL_MAX - 1)) == 0, "Not a power of two");
+#define POOL_MAX 256
 
 struct picture_pool_t {
     vlc_mutex_t lock;
     vlc_cond_t  wait;
 
-    unsigned long long available;
     vlc_atomic_rc_t    refs;
-    unsigned short     picture_count;
-    picture_t  *picture[];
+    struct vlc_list inuse_list;
+    struct vlc_list available_list;
 };
 
 static void picture_pool_Destroy(picture_pool_t *pool)
@@ -56,29 +54,39 @@ static void picture_pool_Destroy(picture_pool_t *pool)
     if (!vlc_atomic_rc_dec(&pool->refs))
         return;
 
-    aligned_free(pool);
+    assert(vlc_list_is_empty(&pool->inuse_list));
+
+    free(pool);
 }
 
 void picture_pool_Release(picture_pool_t *pool)
 {
-    for (unsigned i = 0; i < pool->picture_count; i++)
-        picture_Release(pool->picture[i]);
+    picture_priv_t *priv;
+    vlc_list_foreach(priv, &pool->available_list, pool_node)
+    {
+        assert(priv->pool == pool);
+        priv->pool = NULL;
+        picture_Release(&priv->picture);
+    }
     picture_pool_Destroy(pool);
 }
 
 static void picture_pool_ReleaseClone(picture_t *clone)
 {
-    picture_priv_t *priv = (picture_priv_t *)clone;
-    uintptr_t sys = (uintptr_t)priv->gc.opaque;
-    picture_pool_t *pool = (void *)(sys & ~(POOL_MAX - 1));
-    unsigned offset = sys & (POOL_MAX - 1);
-    picture_t *picture = pool->picture[offset];
+    picture_priv_t *priv = container_of(clone, picture_priv_t, picture);
+
+    /* Retrieve the original pic that was cloned */
+    picture_t *original = priv->gc.opaque;
+    picture_priv_t *original_priv = container_of(original, picture_priv_t, picture);
 
-    picture_Release(picture);
+    picture_pool_t *pool = original_priv->pool;
+    assert(pool != NULL);
 
     vlc_mutex_lock(&pool->lock);
-    assert(!(pool->available & (1ULL << offset)));
-    pool->available |= 1ULL << offset;
+
+    vlc_list_remove(&original_priv->pool_node);
+    vlc_list_append(&original_priv->pool_node, &pool->available_list);
+
     vlc_cond_signal(&pool->wait);
     vlc_mutex_unlock(&pool->lock);
 
@@ -86,13 +94,10 @@ static void picture_pool_ReleaseClone(picture_t *clone)
 }
 
 static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
-                                            unsigned offset)
+                                            picture_t *picture)
 {
-    picture_t *picture = pool->picture[offset];
-    uintptr_t sys = ((uintptr_t)pool) + offset;
-
     picture_t *clone = picture_InternalClone(picture, picture_pool_ReleaseClone,
-                                 (void*)sys);
+                                             picture);
     if (clone != NULL) {
         assert(!picture_HasChainedPics(clone));
         vlc_atomic_rc_inc(&pool->refs);
@@ -100,28 +105,43 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
     return clone;
 }
 
-picture_pool_t *picture_pool_New(unsigned count, picture_t *const *tab)
+static void picture_pool_AppendPic(picture_pool_t *pool, picture_t *pic)
 {
-    if (unlikely(count > POOL_MAX))
-        return NULL;
+    picture_priv_t *priv = container_of(pic, picture_priv_t, picture);
+    assert(priv->pool == NULL);
+    vlc_list_append(&priv->pool_node, &pool->available_list);
+    priv->pool = pool;
+}
 
-    picture_pool_t *pool;
-    size_t size = sizeof (*pool) + count * sizeof (picture_t *);
+static picture_pool_t *
+picture_pool_NewCommon(void)
+{
+    picture_pool_t *pool = malloc(sizeof(*pool));
 
-    size += (-size) & (POOL_MAX - 1);
-    pool = aligned_alloc(POOL_MAX, size);
     if (unlikely(pool == NULL))
         return NULL;
 
+    vlc_list_init(&pool->inuse_list);
+    vlc_list_init(&pool->available_list);
+
     vlc_mutex_init(&pool->lock);
     vlc_cond_init(&pool->wait);
-    if (count == POOL_MAX)
-        pool->available = ~0ULL;
-    else
-        pool->available = (1ULL << count) - 1;
     vlc_atomic_rc_init(&pool->refs);
-    pool->picture_count = count;
-    memcpy(pool->picture, tab, count * sizeof (picture_t *));
+
+    return pool;
+}
+
+picture_pool_t *picture_pool_New(unsigned count, picture_t *const *tab)
+{
+    if (unlikely(count > POOL_MAX))
+        return NULL;
+
+    picture_pool_t *pool = picture_pool_NewCommon();
+    if (unlikely(pool == NULL))
+        return NULL;
+
+    for (unsigned i = 0; i < count; ++i)
+        picture_pool_AppendPic(pool, tab[i]);
     return pool;
 }
 
@@ -133,25 +153,37 @@ picture_pool_t *picture_pool_NewFromFormat(const video_format_t *fmt,
     if (unlikely(count > POOL_MAX))
         return NULL;
 
-    picture_t *picture[POOL_MAX];
-    unsigned i;
+    picture_pool_t *pool = picture_pool_NewCommon();
+    if (unlikely(pool == NULL))
+        return NULL;
 
-    for (i = 0; i < count; i++) {
-        picture[i] = picture_NewFromFormat(fmt);
-        if (picture[i] == NULL)
-            goto error;
+    for (unsigned i = 0; i < count; ++i)
+    {
+        picture_t *pic = picture_NewFromFormat(fmt);
+        if (pic == NULL)
+        {
+            picture_pool_Release(pool);
+            return NULL;
+        }
+        picture_pool_AppendPic(pool, pic);
     }
 
-    picture_pool_t *pool = picture_pool_New(count, picture);
-    if (!pool)
-        goto error;
-
     return pool;
+}
+
+static picture_t *picture_pool_GetAvailableLocked(picture_pool_t *pool)
+{
+    picture_priv_t *priv = vlc_list_first_entry_or_null(&pool->available_list,
+                                                        picture_priv_t,
+                                                        pool_node);
+    assert(priv != NULL);
 
-error:
-    while (i > 0)
-        picture_Release(picture[--i]);
-    return NULL;
+    assert(priv->pool == pool);
+
+    vlc_list_remove(&priv->pool_node);
+    vlc_list_append(&priv->pool_node, &pool->inuse_list);
+
+    return &priv->picture;
 }
 
 picture_t *picture_pool_Get(picture_pool_t *pool)
@@ -160,17 +192,17 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
     vlc_mutex_lock(&pool->lock);
     assert(vlc_atomic_rc_get(&pool->refs) > 0);
 
-    if (pool->available == 0)
+    if (vlc_list_is_empty(&pool->available_list))
     {
         vlc_mutex_unlock(&pool->lock);
         return NULL;
     }
 
-    int i = stdc_trailing_zeros(pool->available);
-    pool->available &= ~(1ULL << i);
+    picture_t *pic = picture_pool_GetAvailableLocked(pool);
+
     vlc_mutex_unlock(&pool->lock);
 
-    return picture_pool_ClonePicture(pool, i);
+    return picture_pool_ClonePicture(pool, pic);
 }
 
 picture_t *picture_pool_Wait(picture_pool_t *pool)
@@ -178,12 +210,12 @@ picture_t *picture_pool_Wait(picture_pool_t *pool)
     vlc_mutex_lock(&pool->lock);
     assert(vlc_atomic_rc_get(&pool->refs) > 0);
 
-    while (pool->available == 0)
+    while (vlc_list_is_empty(&pool->available_list))
         vlc_cond_wait(&pool->wait, &pool->lock);
 
-    int i = stdc_trailing_zeros(pool->available);
-    pool->available &= ~(1ULL << i);
+    picture_t *pic = picture_pool_GetAvailableLocked(pool);
+
     vlc_mutex_unlock(&pool->lock);
 
-    return picture_pool_ClonePicture(pool, i);
+    return picture_pool_ClonePicture(pool, pic);
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3d80d93f0c49d34707d129e6b5f2e9a304e084ba...d8a43e851c127509a463f1e90907d9362e399010

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3d80d93f0c49d34707d129e6b5f2e9a304e084ba...d8a43e851c127509a463f1e90907d9362e399010
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list