[FFmpeg-devel] [PATCH 49/49] avcodec/v4l2_(m2m|buffers): Use RefStruct API for context references
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Mon Oct 2 21:13:38 EEST 2023
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>
---
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 bac3eb0588..007e725b70 100644
--- a/libavcodec/v4l2_m2m.c
+++ b/libavcodec/v4l2_m2m.c
@@ -31,6 +31,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"
@@ -246,9 +247,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);
@@ -257,8 +258,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)
@@ -282,7 +281,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;
}
@@ -327,17 +326,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;
@@ -345,13 +338,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;
--
2.34.1
More information about the ffmpeg-devel
mailing list