PR #21423 opened by James Almer (jamrial) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21423 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21423.patch
This way we can ensure a frame reference will always exists for as long as the external library needs the base picture. >From 644f1eaa829956060c2cf589fc7ddee9599a21ca Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Wed, 7 Jan 2026 12:16:27 -0300 Subject: [PATCH] avcodec/lcevc: attach a reference to the source frame to each passed in base picture This way we can ensure a frame reference will always exists for as long as the external library needs the base picture. Signed-off-by: James Almer <[email protected]> --- libavcodec/lcevcdec.c | 46 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c index 4f6d793625..865903bbd9 100644 --- a/libavcodec/lcevcdec.c +++ b/libavcodec/lcevcdec.c @@ -110,6 +110,7 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const AVFrame { FFLCEVCContext *lcevc = frame_ctx->lcevc; const AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_LCEVC); + AVFrame *opaque; LCEVC_PictureHandle picture; LCEVC_ReturnCode res; int ret = 0; @@ -125,9 +126,23 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const AVFrame if (ret < 0) return ret; + opaque = av_frame_clone(in); + if (!opaque) { + LCEVC_FreePicture(lcevc->decoder, picture); + return AVERROR(ENOMEM); + } + + res = LCEVC_SetPictureUserData(lcevc->decoder, picture, opaque); + if (res != LCEVC_Success) { + LCEVC_FreePicture(lcevc->decoder, picture); + av_frame_free(&opaque); + return AVERROR_EXTERNAL; + } + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, picture, -1, NULL); if (res != LCEVC_Success) { LCEVC_FreePicture(lcevc->decoder, picture); + av_frame_free(&opaque); return AVERROR_EXTERNAL; } @@ -184,18 +199,13 @@ static int generate_output(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) return 0; } -static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) +static int lcevc_flush_pictures(FFLCEVCContext *lcevc) { - FFLCEVCContext *lcevc = frame_ctx->lcevc; LCEVC_PictureHandle picture; LCEVC_ReturnCode res; - int ret; - - ret = generate_output(logctx, frame_ctx, out); - if (ret < 0) - return ret; while (1) { + AVFrame *base = NULL; res = LCEVC_ReceiveDecoderBase (lcevc->decoder, &picture); if (res != LCEVC_Success && res != LCEVC_Again) return AVERROR_EXTERNAL; @@ -203,6 +213,9 @@ static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *o if (res == LCEVC_Again) break; + LCEVC_GetPictureUserData(lcevc->decoder, picture, (void **)&base); + av_frame_free(&base); + res = LCEVC_FreePicture(lcevc->decoder, picture); if (res != LCEVC_Success) return AVERROR_EXTERNAL; @@ -211,6 +224,18 @@ static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *o return 0; } +static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) +{ + FFLCEVCContext *lcevc = frame_ctx->lcevc; + int ret; + + ret = generate_output(logctx, frame_ctx, out); + if (ret < 0) + return ret; + + return lcevc_flush_pictures(lcevc); +} + static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, LCEVC_PictureHandle pic, const LCEVC_DecodeInformation *info, const uint8_t *data, uint32_t size, void *logctx) @@ -227,8 +252,11 @@ static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, static void lcevc_free(AVRefStructOpaque unused, void *obj) { FFLCEVCContext *lcevc = obj; - if (lcevc->initialized) + if (lcevc->initialized) { + LCEVC_FlushDecoder(lcevc->decoder); + lcevc_flush_pictures(lcevc); LCEVC_DestroyDecoder(lcevc->decoder); + } memset(lcevc, 0, sizeof(*lcevc)); } @@ -277,7 +305,7 @@ int ff_lcevc_process(void *logctx, AVFrame *frame) if (ret) return ret < 0 ? ret : 0; - lcevc_receive_frame(logctx, frame_ctx, frame); + ret = lcevc_receive_frame(logctx, frame_ctx, frame); if (ret < 0) return ret; -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
