This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch release/8.0 in repository ffmpeg.
commit 8a825fe4155fde5348a5b74ad4559c7160bf165a Author: James Almer <[email protected]> AuthorDate: Wed Jan 7 12:16:27 2026 -0300 Commit: James Almer <[email protected]> CommitDate: Sun Jan 11 20:35:26 2026 -0300 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]> (cherry picked from commit 188521c7ad9e2a82d913770c3102593ebcd3454d) --- libavcodec/lcevcdec.c | 59 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c index 97c1dfc5b7..010a7bc791 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; @@ -129,13 +130,27 @@ 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; + } + #ifdef LCEVC_DEC_VERSION_MAJOR - res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, picture, -1, NULL); + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, picture, -1, opaque); #else - res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, NULL); + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, opaque); #endif if (res != LCEVC_Success) { LCEVC_FreePicture(lcevc->decoder, picture); + av_frame_free(&opaque); return AVERROR_EXTERNAL; } @@ -171,17 +186,16 @@ static int generate_output(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) return AVERROR_EXTERNAL; } + av_frame_unref(out); + av_frame_copy_props(frame_ctx->frame, (AVFrame *)info.baseUserData); + av_frame_move_ref(out, frame_ctx->frame); + out->crop_top = desc.cropTop; out->crop_bottom = desc.cropBottom; out->crop_left = desc.cropLeft; out->crop_right = desc.cropRight; out->sample_aspect_ratio.num = desc.sampleAspectRatioNum; out->sample_aspect_ratio.den = desc.sampleAspectRatioDen; - - av_frame_copy_props(frame_ctx->frame, out); - av_frame_unref(out); - av_frame_move_ref(out, frame_ctx->frame); - out->width = desc.width + out->crop_left + out->crop_right; out->height = desc.height + out->crop_top + out->crop_bottom; @@ -192,18 +206,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; @@ -211,6 +220,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; @@ -219,6 +231,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) @@ -235,8 +259,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)); } @@ -285,7 +312,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; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
