From c7fb4d0eb6bd6f5c3dd80c9784cb530b9581ce26 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Wed, 13 Sep 2023 21:32:28 +0200 Subject: [PATCH] avcodec/nvdec: Use RefStruct API for decoder_ref Avoids allocations and error checks as well as the boilerplate code for creating an AVBuffer with a custom free callback. Also increases type safety. Reviewed-by: Anton Khirnov Tested-by: Timo Rothenpieler Signed-off-by: Andreas Rheinhardt --- libavcodec/nvdec.c | 50 ++++++++++++++++++---------------------------- libavcodec/nvdec.h | 4 ++-- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index a477449d14..0ec8e896a6 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -35,6 +35,7 @@ #include "decode.h" #include "nvdec.h" #include "internal.h" +#include "refstruct.h" #if !NVDECAPI_CHECK_VERSION(9, 0) #define cudaVideoSurfaceFormat_YUV444 2 @@ -161,9 +162,9 @@ static int nvdec_test_capabilities(NVDECDecoder *decoder, return 0; } -static void nvdec_decoder_free(void *opaque, uint8_t *data) +static void nvdec_decoder_free(FFRefStructOpaque unused, void *obj) { - NVDECDecoder *decoder = (NVDECDecoder*)data; + NVDECDecoder *decoder = obj; if (decoder->decoder) { void *logctx = decoder->hw_device_ref->data; @@ -177,33 +178,24 @@ static void nvdec_decoder_free(void *opaque, uint8_t *data) av_buffer_unref(&decoder->hw_device_ref); cuvid_free_functions(&decoder->cvdl); - - av_freep(&decoder); } -static int nvdec_decoder_create(AVBufferRef **out, AVBufferRef *hw_device_ref, +static int nvdec_decoder_create(NVDECDecoder **out, AVBufferRef *hw_device_ref, CUVIDDECODECREATEINFO *params, void *logctx) { AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)hw_device_ref->data; AVCUDADeviceContext *device_hwctx = hw_device_ctx->hwctx; - AVBufferRef *decoder_ref; NVDECDecoder *decoder; CUcontext dummy; int ret; - decoder = av_mallocz(sizeof(*decoder)); + decoder = ff_refstruct_alloc_ext(sizeof(*decoder), 0, + NULL, nvdec_decoder_free); if (!decoder) return AVERROR(ENOMEM); - decoder_ref = av_buffer_create((uint8_t*)decoder, sizeof(*decoder), - nvdec_decoder_free, NULL, AV_BUFFER_FLAG_READONLY); - if (!decoder_ref) { - av_freep(&decoder); - return AVERROR(ENOMEM); - } - decoder->hw_device_ref = av_buffer_ref(hw_device_ref); if (!decoder->hw_device_ref) { ret = AVERROR(ENOMEM); @@ -237,11 +229,11 @@ static int nvdec_decoder_create(AVBufferRef **out, AVBufferRef *hw_device_ref, goto fail; } - *out = decoder_ref; + *out = decoder; return 0; fail: - av_buffer_unref(&decoder_ref); + ff_refstruct_unref(&decoder); return ret; } @@ -275,7 +267,7 @@ int ff_nvdec_decode_uninit(AVCodecContext *avctx) ctx->nb_slices = 0; ctx->slice_offsets_allocated = 0; - av_buffer_unref(&ctx->decoder_ref); + ff_refstruct_unref(&ctx->decoder); av_buffer_pool_uninit(&ctx->decoder_pool); return 0; @@ -408,7 +400,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size; params.ulNumOutputSurfaces = unsafe_output ? frames_ctx->initial_pool_size : 1; - ret = nvdec_decoder_create(&ctx->decoder_ref, frames_ctx->device_ref, ¶ms, avctx); + ret = nvdec_decoder_create(&ctx->decoder, frames_ctx->device_ref, ¶ms, avctx); if (ret < 0) { if (params.ulNumDecodeSurfaces > 32) { av_log(avctx, AV_LOG_WARNING, "Using more than 32 (%d) decode surfaces might cause nvdec to fail.\n", @@ -420,7 +412,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) return ret; } - decoder = (NVDECDecoder*)ctx->decoder_ref->data; + decoder = ctx->decoder; decoder->unsafe_output = unsafe_output; decoder->real_hw_frames_ref = real_hw_frames_ref; real_hw_frames_ref = NULL; @@ -453,8 +445,8 @@ static void nvdec_fdd_priv_free(void *priv) return; av_buffer_unref(&cf->idx_ref); - av_buffer_unref(&cf->decoder_ref); av_buffer_unref(&cf->ref_idx_ref); + ff_refstruct_unref(&cf->decoder); av_freep(&priv); } @@ -462,7 +454,7 @@ static void nvdec_fdd_priv_free(void *priv) static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data) { NVDECFrame *unmap_data = (NVDECFrame*)data; - NVDECDecoder *decoder = (NVDECDecoder*)unmap_data->decoder_ref->data; + NVDECDecoder *decoder = unmap_data->decoder; void *logctx = decoder->hw_device_ref->data; CUdeviceptr devptr = (CUdeviceptr)opaque; int ret; @@ -478,8 +470,8 @@ static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data) finish: av_buffer_unref(&unmap_data->idx_ref); - av_buffer_unref(&unmap_data->decoder_ref); av_buffer_unref(&unmap_data->ref_idx_ref); + ff_refstruct_unref(&unmap_data->decoder); av_free(unmap_data); } @@ -487,7 +479,7 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) { FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; NVDECFrame *cf = (NVDECFrame*)fdd->hwaccel_priv; - NVDECDecoder *decoder = (NVDECDecoder*)cf->decoder_ref->data; + NVDECDecoder *decoder = cf->decoder; AVHWFramesContext *hwctx = (AVHWFramesContext *)frame->hw_frames_ctx->data; @@ -534,11 +526,11 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) goto copy_fail; unmap_data->idx = cf->idx; - if (!(unmap_data->idx_ref = av_buffer_ref(cf->idx_ref)) || - !(unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref))) { + if (!(unmap_data->idx_ref = av_buffer_ref(cf->idx_ref))) { ret = AVERROR(ENOMEM); goto copy_fail; } + unmap_data->decoder = ff_refstruct_ref(cf->decoder); av_pix_fmt_get_chroma_sub_sample(hwctx->sw_format, &shift_h, &shift_v); for (i = 0; frame->linesize[i]; i++) { @@ -583,11 +575,7 @@ int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame) if (!cf) return AVERROR(ENOMEM); - cf->decoder_ref = av_buffer_ref(ctx->decoder_ref); - if (!cf->decoder_ref) { - ret = AVERROR(ENOMEM); - goto fail; - } + cf->decoder = ff_refstruct_ref(ctx->decoder); cf->idx_ref = av_buffer_pool_get(ctx->decoder_pool); if (!cf->idx_ref) { @@ -645,7 +633,7 @@ fail: int ff_nvdec_end_frame(AVCodecContext *avctx) { NVDECContext *ctx = avctx->internal->hwaccel_priv_data; - NVDECDecoder *decoder = (NVDECDecoder*)ctx->decoder_ref->data; + NVDECDecoder *decoder = ctx->decoder; void *logctx = avctx; CUVIDPICPARAMS *pp = &ctx->pic_params; diff --git a/libavcodec/nvdec.h b/libavcodec/nvdec.h index 66f3ca59e7..efacb5b691 100644 --- a/libavcodec/nvdec.h +++ b/libavcodec/nvdec.h @@ -46,7 +46,7 @@ typedef struct NVDECFrame { unsigned int ref_idx; AVBufferRef *idx_ref; AVBufferRef *ref_idx_ref; - AVBufferRef *decoder_ref; + struct NVDECDecoder *decoder; ///< RefStruct reference } NVDECFrame; typedef struct NVDECContext { @@ -54,7 +54,7 @@ typedef struct NVDECContext { AVBufferPool *decoder_pool; - AVBufferRef *decoder_ref; + struct NVDECDecoder *decoder; ///< RefStruct reference uint8_t *bitstream; int bitstream_len;