diff mbox series

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

Message ID 20201118112409.9492-1-git@gpost.dk
State New
Headers show
Series [FFmpeg-devel] lavu/buffer: reuse AVBufferRef alloction | expand

Checks

Context Check Description
andriy/PPC64_make success Make finished
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Gil Pedersen Nov. 18, 2020, 11:24 a.m. UTC
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@gpost.dk>
---
 libavutil/buffer.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)
diff mbox series

Patch

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;
 }