diff --git a/libavfilter/vaapi_vpp.c b/libavfilter/vaapi_vpp.c
index c5bbc3b85b..647ddc0811 100644
--- a/libavfilter/vaapi_vpp.c
+++ b/libavfilter/vaapi_vpp.c
@@ -248,6 +248,52 @@ int ff_vaapi_vpp_colour_standard(enum AVColorSpace av_cs)
     }
 }
 
+int ff_vaapi_vpp_init_params(AVFilterContext *avctx,
+                             VAProcPipelineParameterBuffer *params,
+                             const AVFrame *input_frame,
+                             AVFrame *output_frame)
+{
+    VAAPIVPPContext *ctx = avctx->priv;
+    VASurfaceID input_surface;
+
+    ctx->input_region = (VARectangle) {
+        .x      = input_frame->crop_left,
+        .y      = input_frame->crop_top,
+        .width  = input_frame->width -
+                 (input_frame->crop_left + input_frame->crop_right),
+        .height = input_frame->height -
+                 (input_frame->crop_top + input_frame->crop_bottom),
+    };
+    output_frame->crop_top    = 0;
+    output_frame->crop_bottom = 0;
+    output_frame->crop_left   = 0;
+    output_frame->crop_right  = 0;
+
+    input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3],
+
+    *params = (VAProcPipelineParameterBuffer) {
+        .surface                 = input_surface,
+        .surface_region          = &ctx->input_region,
+        .surface_color_standard  =
+            ff_vaapi_vpp_colour_standard(input_frame->colorspace),
+        .output_region           = NULL,
+        .output_background_color = VAAPI_VPP_BACKGROUND_BLACK,
+        .output_color_standard   =
+            ff_vaapi_vpp_colour_standard(input_frame->colorspace),
+        .pipeline_flags          = 0,
+        .filter_flags            = VA_FRAME_PICTURE,
+
+        // Filter and reference data filled by the filter itself.
+
+#if VA_CHECK_VERSION(1, 1, 0)
+        .rotation_state = VA_ROTATION_NONE,
+        .mirror_state   = VA_MIRROR_NONE,
+#endif
+    };
+
+    return 0;
+}
+
 int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx,
                                     int type,
                                     const void *data,
@@ -279,12 +325,15 @@ int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx,
 
 int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
                                 VAProcPipelineParameterBuffer *params,
-                                VASurfaceID output_surface)
+                                AVFrame *output_frame)
 {
+    VAAPIVPPContext *ctx = avctx->priv;
+    VASurfaceID output_surface;
     VABufferID params_id;
     VAStatus vas;
-    int err = 0;
-    VAAPIVPPContext *ctx   = avctx->priv;
+    int err;
+
+    output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
 
     vas = vaBeginPicture(ctx->hwctx->display,
                          ctx->va_context, output_surface);
diff --git a/libavfilter/vaapi_vpp.h b/libavfilter/vaapi_vpp.h
index 96f720f07d..1e2b4a1066 100644
--- a/libavfilter/vaapi_vpp.h
+++ b/libavfilter/vaapi_vpp.h
@@ -42,6 +42,7 @@ typedef struct VAAPIVPPContext {
 
     AVBufferRef       *input_frames_ref;
     AVHWFramesContext *input_frames;
+    VARectangle        input_region;
 
     enum AVPixelFormat output_format;
     int output_width;   // computed width
@@ -69,6 +70,11 @@ int ff_vaapi_vpp_config_output(AVFilterLink *outlink);
 
 int ff_vaapi_vpp_colour_standard(enum AVColorSpace av_cs);
 
+int ff_vaapi_vpp_init_params(AVFilterContext *avctx,
+                             VAProcPipelineParameterBuffer *params,
+                             const AVFrame *input_frame,
+                             AVFrame *output_frame);
+
 int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx,
                                     int type,
                                     const void *data,
@@ -77,6 +83,6 @@ int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx,
 
 int ff_vaapi_vpp_render_picture(AVFilterContext *avctx,
                                 VAProcPipelineParameterBuffer *params,
-                                VASurfaceID output_surface);
+                                AVFrame *output_frame);
 
 #endif /* AVFILTER_VAAPI_VPP_H */
diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c
index f67a1c8e79..2c147310c9 100644
--- a/libavfilter/vf_deinterlace_vaapi.c
+++ b/libavfilter/vf_deinterlace_vaapi.c
@@ -181,12 +181,11 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
     VAAPIVPPContext *vpp_ctx = avctx->priv;
     DeintVAAPIContext *ctx   = avctx->priv;
     AVFrame *output_frame    = NULL;
-    VASurfaceID input_surface, output_surface;
+    VASurfaceID input_surface;
     VASurfaceID backward_references[MAX_REFERENCES];
     VASurfaceID forward_references[MAX_REFERENCES];
     VAProcPipelineParameterBuffer params;
     VAProcFilterParameterBufferDeinterlacing *filter_params;
-    VARectangle input_region;
     VAStatus vas;
     void *filter_params_addr = NULL;
     int err, i, field, current_frame_index;
@@ -238,30 +237,10 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
             goto fail;
         }
 
-        output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
-        av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for "
-               "deinterlace output.\n", output_surface);
-
-        memset(&params, 0, sizeof(params));
-
-        input_region = (VARectangle) {
-            .x      = 0,
-            .y      = 0,
-            .width  = input_frame->width,
-            .height = input_frame->height,
-        };
-
-        params.surface = input_surface;
-        params.surface_region = &input_region;
-        params.surface_color_standard =
-            ff_vaapi_vpp_colour_standard(input_frame->colorspace);
-
-        params.output_region = NULL;
-        params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
-        params.output_color_standard = params.surface_color_standard;
-
-        params.pipeline_flags = 0;
-        params.filter_flags   = VA_FRAME_PICTURE;
+        err = ff_vaapi_vpp_init_params(avctx, &params,
+                                       input_frame, output_frame);
+        if (err < 0)
+            goto fail;
 
         if (!ctx->auto_enable || input_frame->interlaced_frame) {
             vas = vaMapBuffer(vpp_ctx->hwctx->display, vpp_ctx->filter_buffers[0],
@@ -301,7 +280,7 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
             params.num_filters = 0;
         }
 
-        err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
+        err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
         if (err < 0)
             goto fail;
 
diff --git a/libavfilter/vf_misc_vaapi.c b/libavfilter/vf_misc_vaapi.c
index e227c9ff6b..6f31a04293 100644
--- a/libavfilter/vf_misc_vaapi.c
+++ b/libavfilter/vf_misc_vaapi.c
@@ -129,9 +129,6 @@ static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
     AVFilterLink *outlink    = avctx->outputs[0];
     VAAPIVPPContext *vpp_ctx = avctx->priv;
     AVFrame *output_frame    = NULL;
-    VASurfaceID input_surface, output_surface;
-    VARectangle input_region;
-
     VAProcPipelineParameterBuffer params;
     int err;
 
@@ -142,10 +139,6 @@ static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
     if (vpp_ctx->va_context == VA_INVALID_ID)
         return AVERROR(EINVAL);
 
-    input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for misc vpp input.\n",
-           input_surface);
-
     output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
                                        vpp_ctx->output_height);
     if (!output_frame) {
@@ -153,34 +146,17 @@ static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
         goto fail;
     }
 
-    output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for misc vpp output.\n",
-           output_surface);
-    memset(&params, 0, sizeof(params));
-    input_region = (VARectangle) {
-        .x      = 0,
-        .y      = 0,
-        .width  = input_frame->width,
-        .height = input_frame->height,
-    };
+    err = ff_vaapi_vpp_init_params(avctx, &params,
+                                   input_frame, output_frame);
+    if (err < 0)
+        goto fail;
 
     if (vpp_ctx->nb_filter_buffers) {
         params.filters     = &vpp_ctx->filter_buffers[0];
         params.num_filters = vpp_ctx->nb_filter_buffers;
     }
-    params.surface = input_surface;
-    params.surface_region = &input_region;
-    params.surface_color_standard =
-        ff_vaapi_vpp_colour_standard(input_frame->colorspace);
-
-    params.output_region = NULL;
-    params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
-    params.output_color_standard = params.surface_color_standard;
-
-    params.pipeline_flags = 0;
-    params.filter_flags = VA_FRAME_PICTURE;
 
-    err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
+    err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
     if (err < 0)
         goto fail;
 
diff --git a/libavfilter/vf_procamp_vaapi.c b/libavfilter/vf_procamp_vaapi.c
index 46f3ab6465..03da360669 100644
--- a/libavfilter/vf_procamp_vaapi.c
+++ b/libavfilter/vf_procamp_vaapi.c
@@ -131,9 +131,7 @@ static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame
     AVFilterLink *outlink    = avctx->outputs[0];
     VAAPIVPPContext *vpp_ctx = avctx->priv;
     AVFrame *output_frame = NULL;
-    VASurfaceID input_surface, output_surface;
     VAProcPipelineParameterBuffer params;
-    VARectangle input_region;
     int err;
 
     av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
@@ -143,10 +141,6 @@ static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame
     if (vpp_ctx->va_context == VA_INVALID_ID)
         return AVERROR(EINVAL);
 
-    input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for procamp input.\n",
-           input_surface);
-
     output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
                                        vpp_ctx->output_height);
     if (!output_frame) {
@@ -154,33 +148,15 @@ static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame
         goto fail;
     }
 
-    output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for procamp output.\n",
-           output_surface);
-    memset(&params, 0, sizeof(params));
-    input_region = (VARectangle) {
-        .x      = 0,
-        .y      = 0,
-        .width  = input_frame->width,
-        .height = input_frame->height,
-    };
-
-    params.surface = input_surface;
-    params.surface_region = &input_region;
-    params.surface_color_standard =
-        ff_vaapi_vpp_colour_standard(input_frame->colorspace);
-
-    params.output_region = NULL;
-    params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
-    params.output_color_standard = params.surface_color_standard;
-
-    params.pipeline_flags = 0;
-    params.filter_flags = VA_FRAME_PICTURE;
+    err = ff_vaapi_vpp_init_params(avctx, &params,
+                                   input_frame, output_frame);
+    if (err < 0)
+        goto fail;
 
     params.filters     = &vpp_ctx->filter_buffers[0];
     params.num_filters = 1;
 
-    err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
+    err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
     if (err < 0)
         goto fail;
 
diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c
index 3699363140..369daa787b 100644
--- a/libavfilter/vf_scale_vaapi.c
+++ b/libavfilter/vf_scale_vaapi.c
@@ -89,9 +89,7 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
     VAAPIVPPContext *vpp_ctx = avctx->priv;
     ScaleVAAPIContext *ctx   = avctx->priv;
     AVFrame *output_frame    = NULL;
-    VASurfaceID input_surface, output_surface;
     VAProcPipelineParameterBuffer params;
-    VARectangle input_region;
     int err;
 
     av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
@@ -101,10 +99,6 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
     if (vpp_ctx->va_context == VA_INVALID_ID)
         return AVERROR(EINVAL);
 
-    input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for scale input.\n",
-           input_surface);
-
     output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
                                        vpp_ctx->output_height);
     if (!output_frame) {
@@ -112,34 +106,14 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
         goto fail;
     }
 
-    output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for scale output.\n",
-           output_surface);
-
-    memset(&params, 0, sizeof(params));
-
-    input_region = (VARectangle) {
-        .x      = input_frame->crop_left,
-        .y      = input_frame->crop_top,
-        .width  = input_frame->width -
-                 (input_frame->crop_left + input_frame->crop_right),
-        .height = input_frame->height -
-                 (input_frame->crop_top + input_frame->crop_bottom),
-    };
-
-    params.surface = input_surface;
-    params.surface_region = &input_region;
-    params.surface_color_standard =
-        ff_vaapi_vpp_colour_standard(input_frame->colorspace);
-
-    params.output_region = 0;
-    params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
-    params.output_color_standard = params.surface_color_standard;
+    err = ff_vaapi_vpp_init_params(avctx, &params,
+                                   input_frame, output_frame);
+    if (err < 0)
+        goto fail;
 
-    params.pipeline_flags = 0;
-    params.filter_flags = ctx->mode;
+    params.filter_flags |= ctx->mode;
 
-    err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
+    err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
     if (err < 0)
         goto fail;
 
diff --git a/libavfilter/vf_transpose_vaapi.c b/libavfilter/vf_transpose_vaapi.c
index 0e2acc9983..13c1dd6493 100644
--- a/libavfilter/vf_transpose_vaapi.c
+++ b/libavfilter/vf_transpose_vaapi.c
@@ -123,9 +123,6 @@ static int transpose_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_fra
     VAAPIVPPContext *vpp_ctx   = avctx->priv;
     TransposeVAAPIContext *ctx = avctx->priv;
     AVFrame *output_frame      = NULL;
-    VASurfaceID input_surface, output_surface;
-    VARectangle input_region, output_region;
-
     VAProcPipelineParameterBuffer params;
     int err;
 
@@ -139,10 +136,6 @@ static int transpose_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_fra
     if (vpp_ctx->va_context == VA_INVALID_ID)
         return AVERROR(EINVAL);
 
-    input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for transpose vpp input.\n",
-           input_surface);
-
     output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
                                        vpp_ctx->output_height);
     if (!output_frame) {
@@ -150,40 +143,15 @@ static int transpose_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_fra
         goto fail;
     }
 
-    output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
-    av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for transpose vpp output.\n",
-           output_surface);
-    memset(&params, 0, sizeof(params));
-    input_region = (VARectangle) {
-        .x      = 0,
-        .y      = 0,
-        .width  = input_frame->width,
-        .height = input_frame->height,
-    };
-
-    output_region = (VARectangle) {
-        .x      = 0,
-        .y      = 0,
-        .width  = output_frame->width,
-        .height = output_frame->height,
-    };
+    err = ff_vaapi_vpp_init_params(avctx, &params,
+                                   input_frame, output_frame);
+    if (err < 0)
+        goto fail;
 
     params.rotation_state = ctx->rotation_state;
-    params.mirror_state = ctx->mirror_state;
-
-    params.filters     = &vpp_ctx->filter_buffers[0];
-    params.num_filters = vpp_ctx->nb_filter_buffers;
-
-    params.surface = input_surface;
-    params.surface_region = &input_region;
-    params.surface_color_standard =
-        ff_vaapi_vpp_colour_standard(input_frame->colorspace);
-
-    params.output_region = &output_region;
-    params.output_background_color = VAAPI_VPP_BACKGROUND_BLACK;
-    params.output_color_standard = params.surface_color_standard;
+    params.mirror_state   = ctx->mirror_state;
 
-    err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
+    err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
     if (err < 0)
         goto fail;
 
