mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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@outlook.com>
This commit is contained in:
parent
fbd1b90b29
commit
f18de5bc4a
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user