diff mbox series

[FFmpeg-devel,1/2] lavfi/vaapi: remove duplicated code

Message ID 20230113043831.2389116-1-haihao.xiang@intel.com
State Accepted
Commit f1a8d3b0b62355a492ab869b6b695478b4da4544
Headers show
Series [FFmpeg-devel,1/2] lavfi/vaapi: remove duplicated code | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished

Commit Message

Xiang, Haihao Jan. 13, 2023, 4:38 a.m. UTC
From: Haihao Xiang <haihao.xiang@intel.com>

Add a ff_ function to handle mulitple pipeline parameters. No functional
changes.

Signed-off-by: Haihao Xiang <haihao.xiang@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(-)

Comments

Xiang, Haihao Jan. 16, 2023, 4:26 a.m. UTC | #1
On Vr, 2023-01-13 at 12:38 +0800, Xiang, Haihao wrote:
> From: Haihao Xiang <haihao.xiang@intel.com>
> 
> Add a ff_ function to handle mulitple pipeline parameters. No functional
> changes.
> 
> Signed-off-by: Haihao Xiang <haihao.xiang@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, &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 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));
> -        err = AVERROR(EIO);
> -        goto fail_after_begin;
> +    for (int i = 0; i < cout; i++) {
> +        err = vaapi_vpp_render_single_pipeline_buffer(avctx, &params_list[i],
> &params_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(&params_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, &params_id, 1);
> +    vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_ids[0], 1);
>  fail_after_render:
>      vaEndPicture(ctx->hwctx->display, ctx->va_context);
>  fail:
> +    av_freep(&params_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, &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 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));
> -        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, &params_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, &params,
> +    err = ff_vaapi_vpp_init_params(avctx, &params[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, &params, sizeof(subpic_params));
> +        memcpy(&params[1], &params[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, &params, 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
diff mbox series

Patch

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,
+                                                   VAProcPipelineParameterBuffer *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, &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 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));
-        err = AVERROR(EIO);
-        goto fail_after_begin;
+    for (int i = 0; i < cout; i++) {
+        err = vaapi_vpp_render_single_pipeline_buffer(avctx, &params_list[i], &params_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(&params_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, &params_id, 1);
+    vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_ids[0], 1);
 fail_after_render:
     vaEndPicture(ctx->hwctx->display, ctx->va_context);
 fail:
+    av_freep(&params_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, &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 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));
-        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, &params_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, &params,
+    err = ff_vaapi_vpp_init_params(avctx, &params[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, &params, sizeof(subpic_params));
+        memcpy(&params[1], &params[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, &params, input_overlay ? &subpic_params : NULL, output);
+    err = ff_vaapi_vpp_render_pictures(avctx, params, input_overlay ? 2 : 1, output);
     if (err < 0)
         goto fail;