avcodec/rkmppdec: Use RefStruct API for references to decoder itself

Avoids boilerplate code when creating the context
and avoids allocations and therefore whole error paths
when creating references to it. Also avoids an indirection
and improves type-safety.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2023-09-24 14:05:42 +02:00
parent 9a0614c7bd
commit 1427e67500
1 changed files with 16 additions and 30 deletions

View File

@ -30,6 +30,7 @@
#include "codec_internal.h"
#include "decode.h"
#include "hwconfig.h"
#include "refstruct.h"
#include "libavutil/buffer.h"
#include "libavutil/common.h"
#include "libavutil/frame.h"
@ -57,12 +58,12 @@ typedef struct {
typedef struct {
AVClass *av_class;
AVBufferRef *decoder_ref;
RKMPPDecoder *decoder; ///< RefStruct reference
} RKMPPDecodeContext;
typedef struct {
MppFrame frame;
AVBufferRef *decoder_ref;
const RKMPPDecoder *decoder_ref; ///< RefStruct reference
} RKMPPFrameContext;
static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
@ -90,7 +91,7 @@ static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat)
static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
RKMPPDecoder *decoder = rk_context->decoder;
int ret;
MppPacket packet;
@ -125,13 +126,13 @@ static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, in
static int rkmpp_close_decoder(AVCodecContext *avctx)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
av_buffer_unref(&rk_context->decoder_ref);
ff_refstruct_unref(&rk_context->decoder);
return 0;
}
static void rkmpp_release_decoder(void *opaque, uint8_t *data)
static void rkmpp_release_decoder(FFRefStructOpaque unused, void *obj)
{
RKMPPDecoder *decoder = (RKMPPDecoder *)data;
RKMPPDecoder *decoder = obj;
if (decoder->mpi) {
decoder->mpi->reset(decoder->ctx);
@ -146,8 +147,6 @@ static void rkmpp_release_decoder(void *opaque, uint8_t *data)
av_buffer_unref(&decoder->frames_ref);
av_buffer_unref(&decoder->device_ref);
av_free(decoder);
}
static int rkmpp_init_decoder(AVCodecContext *avctx)
@ -162,19 +161,13 @@ static int rkmpp_init_decoder(AVCodecContext *avctx)
avctx->pix_fmt = AV_PIX_FMT_DRM_PRIME;
// create a decoder and a ref to it
decoder = av_mallocz(sizeof(RKMPPDecoder));
decoder = ff_refstruct_alloc_ext(sizeof(*decoder), 0,
NULL, rkmpp_release_decoder);
if (!decoder) {
ret = AVERROR(ENOMEM);
goto fail;
}
rk_context->decoder_ref = av_buffer_create((uint8_t *)decoder, sizeof(*decoder), rkmpp_release_decoder,
NULL, AV_BUFFER_FLAG_READONLY);
if (!rk_context->decoder_ref) {
av_free(decoder);
ret = AVERROR(ENOMEM);
goto fail;
}
rk_context->decoder = decoder;
av_log(avctx, AV_LOG_DEBUG, "Initializing RKMPP decoder.\n");
@ -270,7 +263,7 @@ fail:
static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
RKMPPDecoder *decoder = rk_context->decoder;
int ret;
// handle EOF
@ -312,7 +305,7 @@ static void rkmpp_release_frame(void *opaque, uint8_t *data)
RKMPPFrameContext *framecontext = (RKMPPFrameContext *)framecontextref->data;
mpp_frame_deinit(&framecontext->frame);
av_buffer_unref(&framecontext->decoder_ref);
ff_refstruct_unref(&framecontext->decoder_ref);
av_buffer_unref(&framecontextref);
av_free(desc);
@ -321,7 +314,7 @@ static void rkmpp_release_frame(void *opaque, uint8_t *data)
static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
RKMPPDecoder *decoder = rk_context->decoder;
RKMPPFrameContext *framecontext = NULL;
AVBufferRef *framecontextref = NULL;
int ret;
@ -449,11 +442,6 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
// MPP decoder needs to be closed only when all frames have been released.
framecontext = (RKMPPFrameContext *)framecontextref->data;
framecontext->decoder_ref = av_buffer_ref(rk_context->decoder_ref);
if (!framecontext->decoder_ref) {
ret = AVERROR(ENOMEM);
goto fail;
}
framecontext->frame = mppframe;
frame->data[0] = (uint8_t *)desc;
@ -464,6 +452,7 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
ret = AVERROR(ENOMEM);
goto fail;
}
framecontext->decoder_ref = ff_refstruct_ref(rk_context->decoder);
frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);
if (!frame->hw_frames_ctx) {
@ -488,9 +477,6 @@ fail:
if (mppframe)
mpp_frame_deinit(&mppframe);
if (framecontext)
av_buffer_unref(&framecontext->decoder_ref);
if (framecontextref)
av_buffer_unref(&framecontextref);
@ -503,7 +489,7 @@ fail:
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
RKMPPDecoder *decoder = rk_context->decoder;
int ret = MPP_NOK;
AVPacket pkt = {0};
RK_S32 usedslots, freeslots;
@ -543,7 +529,7 @@ static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
static void rkmpp_flush(AVCodecContext *avctx)
{
RKMPPDecodeContext *rk_context = avctx->priv_data;
RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
RKMPPDecoder *decoder = rk_context->decoder;
int ret = MPP_NOK;
av_log(avctx, AV_LOG_DEBUG, "Flush.\n");