[FFmpeg-devel] [PATCH] lavu/buffer: reuse AVBufferRef alloction

Gil Pedersen git at gpost.dk
Wed Nov 18 13:24:09 EET 2020


This is an optimization to av_buffer_replace() to avoid a redundant allocation
when the src and dst are non-NULL.

Instead of doing a unref + ref, the dst buffer is reused and buffer counters
updated accordingly.

Signed-off-by: Gil Pedersen <git at gpost.dk>
---
 libavutil/buffer.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index d67b4bbdaf..8f6ba10168 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -219,26 +219,38 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size)
 int av_buffer_replace(AVBufferRef **pdst, AVBufferRef *src)
 {
     AVBufferRef *dst = *pdst;
-    AVBufferRef *tmp;
+    AVBuffer *b;
 
     if (!src) {
         av_buffer_unref(pdst);
         return 0;
     }
 
-    if (dst && dst->buffer == src->buffer) {
+    if (!dst) {
+        *pdst = av_buffer_ref(src);
+        if (!*pdst)
+            return AVERROR(ENOMEM);
+
+        return 0;
+    }
+
+    if (dst->buffer == src->buffer) {
         /* make sure the data pointers match */
         dst->data = src->data;
         dst->size = src->size;
         return 0;
     }
 
-    tmp = av_buffer_ref(src);
-    if (!tmp)
-        return AVERROR(ENOMEM);
+    b = dst->buffer;
+
+    atomic_fetch_add_explicit(&src->buffer->refcount, 1, memory_order_relaxed);
+
+    if (atomic_fetch_sub_explicit(&b->refcount, 1, memory_order_acq_rel) == 1) {
+        b->free(b->opaque, b->data);
+        av_freep(&b);
+    }
 
-    av_buffer_unref(pdst);
-    *pdst = tmp;
+    *dst = *src;
     return 0;
 }
 
-- 
2.17.1



More information about the ffmpeg-devel mailing list