[FFmpeg-devel] [PATCH 1/2] lavfi/vaapi: remove duplicated code
Xiang, Haihao
haihao.xiang at intel.com
Mon Jan 16 06:26:53 EET 2023
On Vr, 2023-01-13 at 12:38 +0800, Xiang, Haihao wrote:
> From: Haihao Xiang <haihao.xiang at intel.com>
>
> Add a ff_ function to handle mulitple pipeline parameters. No functional
> changes.
>
> Signed-off-by: Haihao Xiang <haihao.xiang at intel.com>
> ---
> libavfilter/vaapi_vpp.c | 90 ++++++++++++++++--------
> libavfilter/vaapi_vpp.h | 5 ++
> libavfilter/vf_overlay_vaapi.c | 122 +++------------------------------
> 3 files changed, 77 insertions(+), 140 deletions(-)
>
> diff --git a/libavfilter/vaapi_vpp.c b/libavfilter/vaapi_vpp.c
> index 1610df4c85..a323dab8b8 100644
> --- a/libavfilter/vaapi_vpp.c
> +++ b/libavfilter/vaapi_vpp.c
> @@ -588,17 +588,53 @@ int ff_vaapi_vpp_make_param_buffers(AVFilterContext
> *avctx,
> return 0;
> }
>
> +static int vaapi_vpp_render_single_pipeline_buffer(AVFilterContext *avctx,
> + VAProcPipelineParameterBuf
> fer *params,
> + VABufferID *params_id)
> +{
> + VAAPIVPPContext *ctx = avctx->priv;
> + VAStatus vas;
>
> -int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
> - VAProcPipelineParameterBuffer *params,
> - AVFrame *output_frame)
> + vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> + VAProcPipelineParameterBufferType,
> + sizeof(*params), 1, params, params_id);
> + if (vas != VA_STATUS_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
> + "%d (%s).\n", vas, vaErrorStr(vas));
> + *params_id = VA_INVALID_ID;
> +
> + return AVERROR(EIO);
> + }
> + av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",
> *params_id);
> +
> + vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, params_id,
> 1);
> + if (vas != VA_STATUS_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
> + "%d (%s).\n", vas, vaErrorStr(vas));
> + return AVERROR(EIO);
> + }
> +
> + return 0;
> +}
> +
> +int ff_vaapi_vpp_render_pictures(AVFilterContext *avctx,
> + VAProcPipelineParameterBuffer *params_list,
> + int cout,
> + AVFrame *output_frame)
> {
> VAAPIVPPContext *ctx = avctx->priv;
> VASurfaceID output_surface;
> - VABufferID params_id;
> + VABufferID *params_ids;
> VAStatus vas;
> int err;
>
> + params_ids = (VABufferID *)av_malloc_array(cout, sizeof(VABufferID));
> + if (!params_ids)
> + return AVERROR(ENOMEM);
> +
> + for (int i = 0; i < cout; i++)
> + params_ids[i] = VA_INVALID_ID;
> +
> output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
>
> vas = vaBeginPicture(ctx->hwctx->display,
> @@ -610,25 +646,10 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
> goto fail;
> }
>
> - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> - VAProcPipelineParameterBufferType,
> - sizeof(*params), 1, params, ¶ms_id);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_begin;
> - }
> - av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",
> - params_id);
> -
> - vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
> - ¶ms_id, 1);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_begin;
> + for (int i = 0; i < cout; i++) {
> + err = vaapi_vpp_render_single_pipeline_buffer(avctx, ¶ms_list[i],
> ¶ms_ids[i]);
> + if (err)
> + goto fail_after_begin;
> }
>
> vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
> @@ -641,14 +662,17 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
>
> if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
> AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {
> - vas = vaDestroyBuffer(ctx->hwctx->display, params_id);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - // And ignore.
> + for (int i = 0; i < cout && params_ids[i] != VA_INVALID_ID; i++) {
> + vas = vaDestroyBuffer(ctx->hwctx->display, params_ids[i]);
> + if (vas != VA_STATUS_SUCCESS) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer:
> "
> + "%d (%s).\n", vas, vaErrorStr(vas));
> + // And ignore.
> + }
> }
> }
>
> + av_freep(¶ms_ids);
> return 0;
>
> // We want to make sure that if vaBeginPicture has been called, we also
> @@ -656,13 +680,21 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
> // do something else nasty, but once we're in this failure case there
> // isn't much else we can do.
> fail_after_begin:
> - vaRenderPicture(ctx->hwctx->display, ctx->va_context, ¶ms_id, 1);
> + vaRenderPicture(ctx->hwctx->display, ctx->va_context, ¶ms_ids[0], 1);
> fail_after_render:
> vaEndPicture(ctx->hwctx->display, ctx->va_context);
> fail:
> + av_freep(¶ms_ids);
> return err;
> }
>
> +int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
> + VAProcPipelineParameterBuffer *params,
> + AVFrame *output_frame)
> +{
> + return ff_vaapi_vpp_render_pictures(avctx, params, 1, output_frame);
> +}
> +
> void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
> {
> int i;
> diff --git a/libavfilter/vaapi_vpp.h b/libavfilter/vaapi_vpp.h
> index c3da91717c..ead07036dc 100644
> --- a/libavfilter/vaapi_vpp.h
> +++ b/libavfilter/vaapi_vpp.h
> @@ -83,4 +83,9 @@ int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
> VAProcPipelineParameterBuffer *params,
> AVFrame *output_frame);
>
> +int ff_vaapi_vpp_render_pictures(AVFilterContext *avctx,
> + VAProcPipelineParameterBuffer *params_list,
> + int count,
> + AVFrame *output_frame);
> +
> #endif /* AVFILTER_VAAPI_VPP_H */
> diff --git a/libavfilter/vf_overlay_vaapi.c b/libavfilter/vf_overlay_vaapi.c
> index 307f3cf7fc..79cf66d068 100644
> --- a/libavfilter/vf_overlay_vaapi.c
> +++ b/libavfilter/vf_overlay_vaapi.c
> @@ -159,106 +159,6 @@ static int
> overlay_vaapi_build_filter_params(AVFilterContext *avctx)
> return 0;
> }
>
> -static int overlay_vaapi_render_picture(AVFilterContext *avctx,
> - VAProcPipelineParameterBuffer
> *params,
> - VAProcPipelineParameterBuffer
> *subpic_params,
> - AVFrame *output_frame)
> -{
> - VAAPIVPPContext *ctx = avctx->priv;
> - VASurfaceID output_surface;
> - VABufferID params_id;
> - VABufferID subpic_params_id;
> - VAStatus vas;
> - int err = 0;
> -
> - output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
> -
> - vas = vaBeginPicture(ctx->hwctx->display,
> - ctx->va_context, output_surface);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to attach new picture: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail;
> - }
> -
> - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> - VAProcPipelineParameterBufferType,
> - sizeof(*params), 1, params, ¶ms_id);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_begin;
> - }
> - av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",
> - params_id);
> -
> -
> - vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
> - ¶ms_id, 1);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_begin;
> - }
> -
> - if (subpic_params) {
> - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> - VAProcPipelineParameterBufferType,
> - sizeof(*subpic_params), 1, subpic_params,
> &subpic_params_id);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_begin;
> - }
> - av_log(avctx, AV_LOG_DEBUG, "Pipeline subpic parameter buffer is
> %#x.\n",
> - subpic_params_id);
> -
> - vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
> - &subpic_params_id, 1);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to render subpic parameter
> buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_begin;
> - }
> - }
> -
> - vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to start picture processing: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - err = AVERROR(EIO);
> - goto fail_after_render;
> - }
> -
> - if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
> - AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {
> - vas = vaDestroyBuffer(ctx->hwctx->display, params_id);
> - if (vas != VA_STATUS_SUCCESS) {
> - av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
> - "%d (%s).\n", vas, vaErrorStr(vas));
> - // And ignore.
> - }
> - }
> -
> - return 0;
> -
> - // We want to make sure that if vaBeginPicture has been called, we also
> - // call vaRenderPicture and vaEndPicture. These calls may well fail or
> - // do something else nasty, but once we're in this failure case there
> - // isn't much else we can do.
> -fail_after_begin:
> - vaRenderPicture(ctx->hwctx->display, ctx->va_context, ¶ms_id, 1);
> -fail_after_render:
> - vaEndPicture(ctx->hwctx->display, ctx->va_context);
> -fail:
> - return err;
> -}
> -
> static int overlay_vaapi_blend(FFFrameSync *fs)
> {
> AVFilterContext *avctx = fs->parent;
> @@ -267,7 +167,7 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
> VAAPIVPPContext *vpp_ctx = avctx->priv;
> AVFrame *input_main, *input_overlay;
> AVFrame *output;
> - VAProcPipelineParameterBuffer params, subpic_params;
> + VAProcPipelineParameterBuffer params[2];
> VABlendState blend_state = { 0 }; /**< Blend State */
> VARectangle overlay_region, output_region;
> int err;
> @@ -296,7 +196,7 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
> if (err < 0)
> goto fail;
>
> - err = ff_vaapi_vpp_init_params(avctx, ¶ms,
> + err = ff_vaapi_vpp_init_params(avctx, ¶ms[0],
> input_main, output);
> if (err < 0)
> goto fail;
> @@ -308,11 +208,11 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
> .height = output->height,
> };
>
> - params.filters = &vpp_ctx->filter_buffers[0];
> - params.num_filters = vpp_ctx->nb_filter_buffers;
> + params[0].filters = &vpp_ctx->filter_buffers[0];
> + params[0].num_filters = vpp_ctx->nb_filter_buffers;
>
> - params.output_region = &output_region;
> - params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
> + params[0].output_region = &output_region;
> + params[0].output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
>
> if (input_overlay) {
> av_log(avctx, AV_LOG_DEBUG, "Filter overlay: %s, %ux%u
> (%"PRId64").\n",
> @@ -333,17 +233,17 @@ static int overlay_vaapi_blend(FFFrameSync *fs)
> "will crop the overlay image according based on the main
> image.\n");
> }
>
> - memcpy(&subpic_params, ¶ms, sizeof(subpic_params));
> + memcpy(¶ms[1], ¶ms[0], sizeof(params[0]));
>
> blend_state.flags = ctx->blend_flags;
> blend_state.global_alpha = ctx->blend_alpha;
> - subpic_params.blend_state = &blend_state;
> + params[1].blend_state = &blend_state;
>
> - subpic_params.surface = (VASurfaceID)(uintptr_t)input_overlay-
> >data[3];
> - subpic_params.output_region = &overlay_region;
> + params[1].surface = (VASurfaceID)(uintptr_t)input_overlay-
> >data[3];
> + params[1].output_region = &overlay_region;
> }
>
> - err = overlay_vaapi_render_picture(avctx, ¶ms, input_overlay ?
> &subpic_params : NULL, output);
> + err = ff_vaapi_vpp_render_pictures(avctx, params, input_overlay ? 2 : 1,
> output);
> if (err < 0)
> goto fail;
>
Will apply if no comment / objection.
-Haihao
More information about the ffmpeg-devel
mailing list