[FFmpeg-devel] [PATCH 24/42] avcodec/refstruct: Allow to share pools

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Tue Sep 19 22:57:16 EEST 2023


To do this, make FFRefStructPool itself refcounted according
to the RefStruct API.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavcodec/refstruct.c | 29 ++++++++++++++++-------------
 libavcodec/refstruct.h |  5 ++++-
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/libavcodec/refstruct.c b/libavcodec/refstruct.c
index f8d040874d..2108ff8163 100644
--- a/libavcodec/refstruct.c
+++ b/libavcodec/refstruct.c
@@ -187,7 +187,7 @@ static void pool_free(FFRefStructPool *pool)
     pthread_mutex_destroy(&pool->mutex);
     if (pool->free_cb)
         pool->free_cb(pool->opaque);
-    av_free(pool);
+    av_free(get_refcount(pool));
 }
 
 static void pool_free_entry(FFRefStructPool *pool, RefCount *ref)
@@ -278,13 +278,17 @@ void *ff_refstruct_pool_get(FFRefStructPool *pool)
     return ret;
 }
 
-void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
+static void pool_unref(void *ref)
 {
-    FFRefStructPool *pool = *poolp;
-    RefCount *entry;
+    FFRefStructPool *pool = get_userdata(ref);
+    if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
+        pool_free(pool);
+}
 
-    if (!pool)
-        return;
+static void refstruct_pool_uninit(FFRefStructOpaque unused, void *obj)
+{
+    FFRefStructPool *pool = obj;
+    RefCount *entry;
 
     pthread_mutex_lock(&pool->mutex);
     av_assert1(!pool->uninited);
@@ -298,11 +302,6 @@ void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
         pool_free_entry(pool, entry);
         entry = next;
     }
-
-    if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
-        pool_free(pool);
-
-    *poolp = NULL;
 }
 
 FFRefStructPool *ff_refstruct_pool_alloc(size_t size, unsigned flags)
@@ -317,11 +316,13 @@ FFRefStructPool *ff_refstruct_pool_alloc_ext_c(size_t size, unsigned flags,
                                                void (*free_entry_cb)(FFRefStructOpaque opaque, void *obj),
                                                void (*free_cb)(FFRefStructOpaque opaque))
 {
-    FFRefStructPool *pool = av_mallocz(sizeof(*pool));
+    FFRefStructPool *pool = ff_refstruct_alloc_ext(sizeof(*pool), 0, NULL,
+                                                   refstruct_pool_uninit);
     int err;
 
     if (!pool)
         return NULL;
+    get_refcount(pool)->free = pool_unref;
 
     pool->size          = size;
     pool->opaque        = opaque;
@@ -348,7 +349,9 @@ FFRefStructPool *ff_refstruct_pool_alloc_ext_c(size_t size, unsigned flags,
 
     err = pthread_mutex_init(&pool->mutex, NULL);
     if (err) {
-        av_free(pool);
+        // Don't call ff_refstruct_uninit() on pool, as it hasn't been properly
+        // set up and is just a POD right now.
+        av_free(get_refcount(pool));
         return NULL;
     }
     return pool;
diff --git a/libavcodec/refstruct.h b/libavcodec/refstruct.h
index ce3830977f..d525be61e8 100644
--- a/libavcodec/refstruct.h
+++ b/libavcodec/refstruct.h
@@ -285,6 +285,9 @@ void *ff_refstruct_pool_get(FFRefStructPool *pool);
  * @param poolp pointer to a pointer to either NULL or a pool to be freed.
  *              `*poolp` will be set to NULL.
  */
-void ff_refstruct_pool_uninit(FFRefStructPool **poolp);
+static inline void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
+{
+    ff_refstruct_unref(poolp);
+}
 
 #endif /* AVCODEC_REFSTRUCT_H */
-- 
2.34.1



More information about the ffmpeg-devel mailing list