[FFmpeg-cvslog] avcodec/rkmppdec: Use RefStruct API for references to decoder itself

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


ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Sun Sep 24 14:05:42 2023 +0200| [1427e6750025c4f753155ab8487e4c432a8da255] | committer: Andreas Rheinhardt

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 at outlook.com>

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

 libavcodec/rkmppdec.c | 46 ++++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index 4e14d09c7c..e137e7e820 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -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");



More information about the ffmpeg-cvslog mailing list