@@ -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");
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> --- libavcodec/rkmppdec.c | 46 +++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 30 deletions(-)