[FFmpeg-cvslog] avcodec/v4l2_(m2m|buffers): Use RefStruct API for context references

Andreas Rheinhardt git at videolan.org
Fri Apr 19 14:54:12 EEST 2024


ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Tue Sep 26 01:11:37 2023 +0200| [f18de5bc4a5721d630449c6dae4bbeebe36d2a82] | committer: Andreas Rheinhardt

avcodec/v4l2_(m2m|buffers): Use RefStruct API for context references

Avoids allocations and therefore error checks; also avoids
indirections and allows to remove the boilerplate code
for creating an object with a dedicated free function.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f18de5bc4a5721d630449c6dae4bbeebe36d2a82
---

 libavcodec/v4l2_buffers.c |  7 +++----
 libavcodec/v4l2_buffers.h |  6 +++---
 libavcodec/v4l2_m2m.c     | 25 +++++++++----------------
 libavcodec/v4l2_m2m.h     |  5 ++---
 4 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
index 2277135699..23474ee143 100644
--- a/libavcodec/v4l2_buffers.c
+++ b/libavcodec/v4l2_buffers.c
@@ -29,6 +29,7 @@
 #include <poll.h>
 #include "libavcodec/avcodec.h"
 #include "libavutil/pixdesc.h"
+#include "refstruct.h"
 #include "v4l2_context.h"
 #include "v4l2_buffers.h"
 #include "v4l2_m2m.h"
@@ -229,7 +230,7 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused)
                 ff_v4l2_buffer_enqueue(avbuf);
         }
 
-        av_buffer_unref(&avbuf->context_ref);
+        ff_refstruct_unref(&avbuf->context_ref);
     }
 }
 
@@ -240,9 +241,7 @@ static int v4l2_buf_increase_ref(V4L2Buffer *in)
     if (in->context_ref)
         atomic_fetch_add(&in->context_refcount, 1);
     else {
-        in->context_ref = av_buffer_ref(s->self_ref);
-        if (!in->context_ref)
-            return AVERROR(ENOMEM);
+        in->context_ref = ff_refstruct_ref(s->self_ref);
 
         in->context_refcount = 1;
     }
diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h
index 3d2ff1b9a5..e35b161309 100644
--- a/libavcodec/v4l2_buffers.h
+++ b/libavcodec/v4l2_buffers.h
@@ -28,7 +28,6 @@
 #include <stddef.h>
 #include <linux/videodev2.h>
 
-#include "libavutil/buffer.h"
 #include "libavutil/frame.h"
 #include "packet.h"
 
@@ -46,8 +45,9 @@ typedef struct V4L2Buffer {
     struct V4L2Context *context;
 
     /* This object is refcounted per-plane, so we need to keep track
-     * of how many context-refs we are holding. */
-    AVBufferRef *context_ref;
+     * of how many context-refs we are holding.
+     * This pointer is a RefStruct reference. */
+    const struct V4L2m2mContext *context_ref;
     atomic_uint context_refcount;
 
     /* keep track of the mmap address and mmap length */
diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c
index ac086a7913..15415cfc4e 100644
--- a/libavcodec/v4l2_m2m.c
+++ b/libavcodec/v4l2_m2m.c
@@ -32,6 +32,7 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/pixfmt.h"
+#include "refstruct.h"
 #include "v4l2_context.h"
 #include "v4l2_fmt.h"
 #include "v4l2_m2m.h"
@@ -247,9 +248,9 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
     return 0;
 }
 
-static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)
+static void v4l2_m2m_destroy_context(FFRefStructOpaque unused, void *context)
 {
-    V4L2m2mContext *s = (V4L2m2mContext*)context;
+    V4L2m2mContext *s = context;
 
     ff_v4l2_context_release(&s->capture);
     sem_destroy(&s->refsync);
@@ -258,8 +259,6 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)
         close(s->fd);
     av_frame_free(&s->frame);
     av_packet_unref(&s->buf_pkt);
-
-    av_free(s);
 }
 
 int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
@@ -283,7 +282,7 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
     ff_v4l2_context_release(&s->output);
 
     s->self_ref = NULL;
-    av_buffer_unref(&priv->context_ref);
+    ff_refstruct_unref(&priv->context);
 
     return 0;
 }
@@ -328,17 +327,11 @@ int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv)
 
 int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s)
 {
-    *s = av_mallocz(sizeof(V4L2m2mContext));
+    *s = ff_refstruct_alloc_ext(sizeof(**s), 0, NULL,
+                                &v4l2_m2m_destroy_context);
     if (!*s)
         return AVERROR(ENOMEM);
 
-    priv->context_ref = av_buffer_create((uint8_t *) *s, sizeof(V4L2m2mContext),
-                                         &v4l2_m2m_destroy_context, NULL, 0);
-    if (!priv->context_ref) {
-        av_freep(s);
-        return AVERROR(ENOMEM);
-    }
-
     /* assign the context */
     priv->context = *s;
     (*s)->priv = priv;
@@ -346,13 +339,13 @@ int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s)
     /* populate it */
     priv->context->capture.num_buffers = priv->num_capture_buffers;
     priv->context->output.num_buffers  = priv->num_output_buffers;
-    priv->context->self_ref = priv->context_ref;
+    priv->context->self_ref = priv->context;
     priv->context->fd = -1;
 
     priv->context->frame = av_frame_alloc();
     if (!priv->context->frame) {
-        av_buffer_unref(&priv->context_ref);
-        *s = NULL; /* freed when unreferencing context_ref */
+        ff_refstruct_unref(&priv->context);
+        *s = NULL; /* freed when unreferencing context */
         return AVERROR(ENOMEM);
     }
 
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
index 04d86d7b92..4ba33dc335 100644
--- a/libavcodec/v4l2_m2m.h
+++ b/libavcodec/v4l2_m2m.h
@@ -62,7 +62,7 @@ typedef struct V4L2m2mContext {
     AVFrame *frame;
 
     /* Reference to self; only valid while codec is active. */
-    AVBufferRef *self_ref;
+    struct V4L2m2mContext *self_ref;
 
     /* reference back to V4L2m2mPriv */
     void *priv;
@@ -71,8 +71,7 @@ typedef struct V4L2m2mContext {
 typedef struct V4L2m2mPriv {
     AVClass *class;
 
-    V4L2m2mContext *context;
-    AVBufferRef    *context_ref;
+    V4L2m2mContext *context;   ///< RefStruct reference
 
     int num_output_buffers;
     int num_capture_buffers;



More information about the ffmpeg-cvslog mailing list