avcodec/decode: make LCEVC injection available to decoders that don't call ff_get_buffer()

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer
2026-03-27 14:30:53 -03:00
parent 8528c697c7
commit 823c6fc0b8
5 changed files with 46 additions and 44 deletions

View File

@@ -349,7 +349,7 @@ static int amf_amfsurface_to_avframe(AVCodecContext *avctx, AMFSurface* surface,
avctx->sw_pix_fmt = avctx->pix_fmt;
ret = ff_attach_decode_data(frame);
ret = ff_attach_decode_data(avctx, frame);
if (ret < 0)
return ret;
frame->width = avctx->width;

View File

@@ -1620,6 +1620,33 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
}
break;
}
#if CONFIG_LIBLCEVC_DEC
AVCodecInternal *avci = avctx->internal;
DecodeContext *dc = decode_ctx(avci);
dc->lcevc.frame = dc->lcevc.ctx && avctx->codec_type == AVMEDIA_TYPE_VIDEO &&
av_frame_get_side_data(frame, AV_FRAME_DATA_LCEVC);
if (dc->lcevc.frame) {
int ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame,
&dc->lcevc.width, &dc->lcevc.height, avctx);
if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
return ret;
// force get_buffer2() to allocate the base frame using the same dimensions
// as the final enhanced frame, in order to prevent reinitializing the buffer
// pools unnecessarely
if (!ret && dc->lcevc.width && dc->lcevc.height) {
dc->lcevc.base_width = frame->width;
dc->lcevc.base_height = frame->height;
frame->width = dc->lcevc.width;
frame->height = dc->lcevc.height;
} else
dc->lcevc.frame = 0;
}
#endif
return 0;
}
@@ -1655,7 +1682,7 @@ static void decode_data_free(AVRefStructOpaque unused, void *obj)
fdd->hwaccel_priv_free(fdd->hwaccel_priv);
}
int ff_attach_decode_data(AVFrame *frame)
int ff_attach_decode_data(AVCodecContext *avctx, AVFrame *frame)
{
FrameDecodeData *fdd;
@@ -1668,46 +1695,28 @@ int ff_attach_decode_data(AVFrame *frame)
frame->private_ref = fdd;
return 0;
}
static int update_frame_props(AVCodecContext *avctx, AVFrame *frame)
{
#if CONFIG_LIBLCEVC_DEC
AVCodecInternal *avci = avctx->internal;
DecodeContext *dc = decode_ctx(avci);
dc->lcevc.frame = dc->lcevc.ctx && avctx->codec_type == AVMEDIA_TYPE_VIDEO &&
av_frame_get_side_data(frame, AV_FRAME_DATA_LCEVC);
if (!dc->lcevc.frame) {
dc->lcevc.frame = dc->lcevc.ctx && avctx->codec_type == AVMEDIA_TYPE_VIDEO &&
av_frame_get_side_data(frame, AV_FRAME_DATA_LCEVC);
if (dc->lcevc.frame) {
int ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame,
&dc->lcevc.width, &dc->lcevc.height, avctx);
if (ret < 0)
return ret;
if (dc->lcevc.frame) {
int ret = ff_lcevc_parse_frame(dc->lcevc.ctx, frame,
&dc->lcevc.width, &dc->lcevc.height, avctx);
if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
return ret;
// force get_buffer2() to allocate the base frame using the same dimensions
// as the final enhanced frame, in order to prevent reinitializing the buffer
// pools unnecessarely
if (dc->lcevc.width && dc->lcevc.height) {
dc->lcevc.base_width = frame->width;
dc->lcevc.base_height = frame->height;
frame->width = dc->lcevc.width;
frame->height = dc->lcevc.height;
if (!ret && dc->lcevc.width && dc->lcevc.height) {
dc->lcevc.base_width = frame->width;
dc->lcevc.base_height = frame->height;
} else
dc->lcevc.frame = 0;
}
}
#endif
return 0;
}
static int attach_post_process_data(AVCodecContext *avctx, AVFrame *frame)
{
#if CONFIG_LIBLCEVC_DEC
AVCodecInternal *avci = avctx->internal;
DecodeContext *dc = decode_ctx(avci);
if (dc->lcevc.frame) {
FrameDecodeData *fdd = frame->private_ref;
FFLCEVCFrame *frame_ctx;
int ret;
@@ -1797,9 +1806,6 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
}
} else {
avctx->sw_pix_fmt = avctx->pix_fmt;
ret = update_frame_props(avctx, frame);
if (ret < 0)
goto fail;
}
ret = avctx->get_buffer2(avctx, frame, flags);
@@ -1808,11 +1814,7 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
validate_avframe_allocation(avctx, frame);
ret = ff_attach_decode_data(frame);
if (ret < 0)
goto fail;
ret = attach_post_process_data(avctx, frame);
ret = ff_attach_decode_data(avctx, frame);
if (ret < 0)
goto fail;

View File

@@ -86,7 +86,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame);
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
enum AVHWDeviceType dev_type);
int ff_attach_decode_data(AVFrame *frame);
int ff_attach_decode_data(AVCodecContext *avctx, AVFrame *frame);
/**
* Check whether the side-data of src contains a palette of

View File

@@ -176,7 +176,7 @@ static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame,
frame->linesize[0] * FFALIGN(avctx->coded_height, 64);
}
ret = ff_attach_decode_data(frame);
ret = ff_attach_decode_data(avctx, frame);
if (ret < 0)
return ret;

View File

@@ -152,7 +152,7 @@ int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
size_t size = sizeof(VTHWFrame);
uint8_t *data = NULL;
AVBufferRef *buf = NULL;
int ret = ff_attach_decode_data(frame);
int ret = ff_attach_decode_data(avctx, frame);
FrameDecodeData *fdd;
if (ret < 0)
return ret;