diff mbox

[FFmpeg-devel,v4,1/2] vaapi_encode: Add ROI support

Message ID 20190707192650.7161-1-sw@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson July 7, 2019, 7:26 p.m. UTC
---
 libavcodec/vaapi_encode.c       | 118 ++++++++++++++++++++++++++++++++
 libavcodec/vaapi_encode.h       |  18 +++++
 libavcodec/vaapi_encode_h264.c  |   2 +
 libavcodec/vaapi_encode_h265.c  |   2 +
 libavcodec/vaapi_encode_mpeg2.c |   2 +
 libavcodec/vaapi_encode_vp8.c   |   2 +
 libavcodec/vaapi_encode_vp9.c   |   2 +
 7 files changed, 146 insertions(+)

Comments

Guo, Yejun July 16, 2019, 7:19 a.m. UTC | #1
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of

> Mark Thompson

> Sent: Monday, July 08, 2019 3:27 AM

> To: ffmpeg-devel@ffmpeg.org

> Subject: [FFmpeg-devel] [PATCH v4 1/2] vaapi_encode: Add ROI support

> 

> ---

>  libavcodec/vaapi_encode.c       | 118

> ++++++++++++++++++++++++++++++++

>  libavcodec/vaapi_encode.h       |  18 +++++

>  libavcodec/vaapi_encode_h264.c  |   2 +

>  libavcodec/vaapi_encode_h265.c  |   2 +

>  libavcodec/vaapi_encode_mpeg2.c |   2 +

>  libavcodec/vaapi_encode_vp8.c   |   2 +

>  libavcodec/vaapi_encode_vp9.c   |   2 +

>  7 files changed, 146 insertions(+)

> 

> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c

> index dd2a24de04..41de023226 100644

> --- a/libavcodec/vaapi_encode.c

> +++ b/libavcodec/vaapi_encode.c

> @@ -166,6 +166,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,

>      int err, i;

>      char data[MAX_PARAM_BUFFER_SIZE];

>      size_t bit_len;

> +    av_unused AVFrameSideData *sd;

> 

>      av_log(avctx, AV_LOG_DEBUG, "Issuing encode for

> pic %"PRId64"/%"PRId64" "

>             "as type %s.\n", pic->display_order, pic->encode_order,

> @@ -435,6 +436,71 @@ static int vaapi_encode_issue(AVCodecContext

> *avctx,

>          }

>      }

> 

> +#if VA_CHECK_VERSION(1, 0, 0)

> +    sd = av_frame_get_side_data(pic->input_image,

> +

> AV_FRAME_DATA_REGIONS_OF_INTEREST);

> +    if (sd && ctx->roi_allowed) {

> +        const AVRegionOfInterest *roi;

> +        uint32_t roi_size;

> +        VAEncMiscParameterBufferROI param_roi;

> +        int nb_roi, i, v;

> +

> +        roi = (const AVRegionOfInterest*)sd->data;

> +        roi_size = roi->self_size;

> +        av_assert0(roi_size && sd->size % roi_size == 0);

> +        nb_roi = sd->size / roi_size;

> +        if (nb_roi > ctx->roi_max_regions) {

> +            if (!ctx->roi_warned) {

> +                av_log(avctx, AV_LOG_WARNING, "More ROIs set than "

> +                       "supported by driver (%d > %d).\n",

> +                       nb_roi, ctx->roi_max_regions);

> +                ctx->roi_warned = 1;

> +            }

> +            nb_roi = ctx->roi_max_regions;

> +        }

> +

> +        pic->roi = av_mallocz_array(nb_roi, sizeof(*pic->roi));

> +        if (!pic->roi) {

> +            err = AVERROR(ENOMEM);

> +            goto fail;

> +        }

> +        // For overlapping regions, the first in the array takes priority.

> +        for (i = 0; i < nb_roi; i++) {

> +            roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);

> +

> +            av_assert0(roi->qoffset.den != 0);

> +            v = roi->qoffset.num * ctx->roi_quant_range / roi->qoffset.den;

> +            av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d)

> -> %+d.\n",

> +                   roi->top, roi->left, roi->bottom, roi->right, v);

> +

> +            pic->roi[i] = (VAEncROI) {

> +                .roi_rectangle = {

> +                    .x      = roi->left,

> +                    .y      = roi->top,

> +                    .width  = roi->right  - roi->left,

> +                    .height = roi->bottom - roi->top,

> +                },

> +                .roi_value = av_clip_c(v, INT8_MIN, INT8_MAX),

> +            };

> +        }

> +

> +        param_roi = (VAEncMiscParameterBufferROI) {

> +            .num_roi      = nb_roi,

> +            .max_delta_qp = INT8_MAX,

> +            .min_delta_qp = INT8_MIN,

> +            .roi          = pic->roi,

> +            .roi_flags.bits.roi_value_is_qp_delta = 1,

> +        };

> +

> +        err = vaapi_encode_make_misc_param_buffer(avctx, pic,

> +

> VAEncMiscParameterTypeROI,

> +                                                  &param_roi,

> +

> sizeof(param_roi));

> +        if (err < 0)

> +            goto fail;

> +    }

> +#endif

> +

>      vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,

>                           pic->input_surface);

>      if (vas != VA_STATUS_SUCCESS) {

> @@ -500,6 +566,7 @@ fail_at_end:

>      av_freep(&pic->codec_picture_params);

>      av_freep(&pic->param_buffers);

>      av_freep(&pic->slices);

> +    av_freep(&pic->roi);

>      av_frame_free(&pic->recon_image);

>      av_buffer_unref(&pic->output_buffer_ref);

>      pic->output_buffer = VA_INVALID_ID;

> @@ -634,6 +701,7 @@ static int vaapi_encode_free(AVCodecContext *avctx,

> 

>      av_freep(&pic->priv_data);

>      av_freep(&pic->codec_picture_params);

> +    av_freep(&pic->roi);

> 

>      av_free(pic);

> 

> @@ -948,6 +1016,19 @@ static int

> vaapi_encode_check_frame(AVCodecContext *avctx,

>          ctx->crop_warned = 1;

>      }

> 

> +    if (!ctx->roi_allowed) {

> +        AVFrameSideData *sd =

> +            av_frame_get_side_data(frame,

> AV_FRAME_DATA_REGIONS_OF_INTEREST);

> +

> +        if (sd && !ctx->roi_warned) {

> +            if (sd && !ctx->roi_warned) {


looks good except this duplicate code

> +                av_log(avctx, AV_LOG_WARNING, "ROI side data on input

> "

> +                       "frames ignored due to lack of driver

> support.\n");

> +                ctx->roi_warned = 1;

> +            }

> +        }

> +    }

> +

>      return 0;

>  }

> 

> @@ -1942,6 +2023,39 @@ static av_cold int

> vaapi_encode_init_quality(AVCodecContext *avctx)

>      return 0;

>  }

> 

> +static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)

> +{

> +#if VA_CHECK_VERSION(1, 0, 0)

> +    VAAPIEncodeContext *ctx = avctx->priv_data;

> +    VAStatus vas;

> +    VAConfigAttrib attr = { VAConfigAttribEncROI };

> +

> +    vas = vaGetConfigAttributes(ctx->hwctx->display,

> +                                ctx->va_profile,

> +                                ctx->va_entrypoint,

> +                                &attr, 1);

> +    if (vas != VA_STATUS_SUCCESS) {

> +        av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "

> +               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));

> +        return AVERROR_EXTERNAL;

> +    }

> +

> +    if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {

> +        ctx->roi_allowed = 0;

> +    } else {

> +        VAConfigAttribValEncROI roi = {

> +            .value = attr.value,

> +        };

> +

> +        ctx->roi_max_regions = roi.bits.num_roi_regions;

> +        ctx->roi_allowed = ctx->roi_max_regions > 0 &&

> +            (ctx->va_rc_mode == VA_RC_CQP ||

> +             roi.bits.roi_rc_qp_delta_support);

> +    }

> +#endif

> +    return 0;

> +}

> +

>  static void vaapi_encode_free_output_buffer(void *opaque,

>                                              uint8_t *data)

>  {

> @@ -2132,6 +2246,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext

> *avctx)

>      if (err < 0)

>          goto fail;

> 

> +    err = vaapi_encode_init_roi(avctx);

> +    if (err < 0)

> +        goto fail;

> +

>      if (avctx->compression_level >= 0) {

>          err = vaapi_encode_init_quality(avctx);

>          if (err < 0)

> diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h

> index eeec06036b..b9a3defd72 100644

> --- a/libavcodec/vaapi_encode.h

> +++ b/libavcodec/vaapi_encode.h

> @@ -69,6 +69,13 @@ typedef struct VAAPIEncodePicture {

>      int64_t         pts;

>      int             force_idr;

> 

> +#if VA_CHECK_VERSION(1, 0, 0)

> +    // ROI regions.

> +    VAEncROI       *roi;

> +#else

> +    void           *roi;

> +#endif

> +

>      int             type;

>      int             b_depth;

>      int             encode_issued;

> @@ -304,9 +311,20 @@ typedef struct VAAPIEncodeContext {

>      int gop_counter;

>      int end_of_stream;

> 

> +    // Whether the driver supports ROI at all.

> +    int             roi_allowed;

> +    // Maximum number of regions supported by the driver.

> +    int             roi_max_regions;

> +    // Quantisation range for offset calculations.  Set by codec-specific

> +    // code, as it may change based on parameters.

> +    int             roi_quant_range;

> +

>      // The encoder does not support cropping information, so warn about

>      // it the first time we encounter any nonzero crop fields.

>      int             crop_warned;

> +    // If the driver does not support ROI then warn the first time we

> +    // encounter a frame with ROI side data.

> +    int             roi_warned;

>  } VAAPIEncodeContext;

> 

>  enum {

> diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c

> index d1427112ea..f4965d8b09 100644

> --- a/libavcodec/vaapi_encode_h264.c

> +++ b/libavcodec/vaapi_encode_h264.c

> @@ -1130,6 +1130,8 @@ static av_cold int

> vaapi_encode_h264_configure(AVCodecContext *avctx)

>          }

>      }

> 

> +    ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8);

> +

>      return 0;

>  }

> 

> diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c

> index 758bd40a37..538862a9d5 100644

> --- a/libavcodec/vaapi_encode_h265.c

> +++ b/libavcodec/vaapi_encode_h265.c

> @@ -1102,6 +1102,8 @@ static av_cold int

> vaapi_encode_h265_configure(AVCodecContext *avctx)

>          priv->fixed_qp_b   = 30;

>      }

> 

> +    ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8);

> +

>      return 0;

>  }

> 

> diff --git a/libavcodec/vaapi_encode_mpeg2.c

> b/libavcodec/vaapi_encode_mpeg2.c

> index fb1ef71fdc..bac9ea1fa6 100644

> --- a/libavcodec/vaapi_encode_mpeg2.c

> +++ b/libavcodec/vaapi_encode_mpeg2.c

> @@ -552,6 +552,8 @@ static av_cold int

> vaapi_encode_mpeg2_configure(AVCodecContext *avctx)

>      ctx->nb_slices  = ctx->slice_block_rows;

>      ctx->slice_size = 1;

> 

> +    ctx->roi_quant_range = 31;

> +

>      return 0;

>  }

> 

> diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c

> index ddbe4c9075..6e7bf9d106 100644

> --- a/libavcodec/vaapi_encode_vp8.c

> +++ b/libavcodec/vaapi_encode_vp8.c

> @@ -173,6 +173,8 @@ static av_cold int

> vaapi_encode_vp8_configure(AVCodecContext *avctx)

>      else

>          priv->q_index_i = priv->q_index_p;

> 

> +    ctx->roi_quant_range = VP8_MAX_QUANT;

> +

>      return 0;

>  }

> 

> diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c

> index f89fd0d07a..d7f415d704 100644

> --- a/libavcodec/vaapi_encode_vp9.c

> +++ b/libavcodec/vaapi_encode_vp9.c

> @@ -202,6 +202,8 @@ static av_cold int

> vaapi_encode_vp9_configure(AVCodecContext *avctx)

>          priv->q_idx_idr = priv->q_idx_p = priv->q_idx_b = 100;

>      }

> 

> +    ctx->roi_quant_range = VP9_MAX_QUANT;

> +

>      return 0;

>  }

> 

> --

> 2.20.1

> 

> _______________________________________________

> ffmpeg-devel mailing list

> ffmpeg-devel@ffmpeg.org

> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

> 

> To unsubscribe, visit link above, or email

> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Mark Thompson July 28, 2019, 10:24 p.m. UTC | #2
On 16/07/2019 08:19, Guo, Yejun wrote:>> -----Original Message-----
>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of
>> Mark Thompson
>> Sent: Monday, July 08, 2019 3:27 AM
>> To: ffmpeg-devel@ffmpeg.org
>> Subject: [FFmpeg-devel] [PATCH v4 1/2] vaapi_encode: Add ROI support
>>
>> ---
>>  libavcodec/vaapi_encode.c       | 118
>> ++++++++++++++++++++++++++++++++
>>  libavcodec/vaapi_encode.h       |  18 +++++
>>  libavcodec/vaapi_encode_h264.c  |   2 +
>>  libavcodec/vaapi_encode_h265.c  |   2 +
>>  libavcodec/vaapi_encode_mpeg2.c |   2 +
>>  libavcodec/vaapi_encode_vp8.c   |   2 +
>>  libavcodec/vaapi_encode_vp9.c   |   2 +
>>  7 files changed, 146 insertions(+)
>>
>> ...
>> @@ -948,6 +1016,19 @@ static int
>> vaapi_encode_check_frame(AVCodecContext *avctx,
>>          ctx->crop_warned = 1;
>>      }
>>
>> +    if (!ctx->roi_allowed) {
>> +        AVFrameSideData *sd =
>> +            av_frame_get_side_data(frame,
>> AV_FRAME_DATA_REGIONS_OF_INTEREST);
>> +
>> +        if (sd && !ctx->roi_warned) {
>> +            if (sd && !ctx->roi_warned) {
> 
> looks good except this duplicate code

Good catch, fixed.

>> +                av_log(avctx, AV_LOG_WARNING, "ROI side data on input
>> "
>> +                       "frames ignored due to lack of driver
>> support.\n");
>> +                ctx->roi_warned = 1;
>> +            }
>> +        }
>> +    }
>> +
>>      return 0;
>>  }

And set applied with that.

Thank you for reviewing!

- Mark
diff mbox

Patch

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index dd2a24de04..41de023226 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -166,6 +166,7 @@  static int vaapi_encode_issue(AVCodecContext *avctx,
     int err, i;
     char data[MAX_PARAM_BUFFER_SIZE];
     size_t bit_len;
+    av_unused AVFrameSideData *sd;
 
     av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
            "as type %s.\n", pic->display_order, pic->encode_order,
@@ -435,6 +436,71 @@  static int vaapi_encode_issue(AVCodecContext *avctx,
         }
     }
 
+#if VA_CHECK_VERSION(1, 0, 0)
+    sd = av_frame_get_side_data(pic->input_image,
+                                AV_FRAME_DATA_REGIONS_OF_INTEREST);
+    if (sd && ctx->roi_allowed) {
+        const AVRegionOfInterest *roi;
+        uint32_t roi_size;
+        VAEncMiscParameterBufferROI param_roi;
+        int nb_roi, i, v;
+
+        roi = (const AVRegionOfInterest*)sd->data;
+        roi_size = roi->self_size;
+        av_assert0(roi_size && sd->size % roi_size == 0);
+        nb_roi = sd->size / roi_size;
+        if (nb_roi > ctx->roi_max_regions) {
+            if (!ctx->roi_warned) {
+                av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
+                       "supported by driver (%d > %d).\n",
+                       nb_roi, ctx->roi_max_regions);
+                ctx->roi_warned = 1;
+            }
+            nb_roi = ctx->roi_max_regions;
+        }
+
+        pic->roi = av_mallocz_array(nb_roi, sizeof(*pic->roi));
+        if (!pic->roi) {
+            err = AVERROR(ENOMEM);
+            goto fail;
+        }
+        // For overlapping regions, the first in the array takes priority.
+        for (i = 0; i < nb_roi; i++) {
+            roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
+
+            av_assert0(roi->qoffset.den != 0);
+            v = roi->qoffset.num * ctx->roi_quant_range / roi->qoffset.den;
+            av_log(avctx, AV_LOG_DEBUG, "ROI: (%d,%d)-(%d,%d) -> %+d.\n",
+                   roi->top, roi->left, roi->bottom, roi->right, v);
+
+            pic->roi[i] = (VAEncROI) {
+                .roi_rectangle = {
+                    .x      = roi->left,
+                    .y      = roi->top,
+                    .width  = roi->right  - roi->left,
+                    .height = roi->bottom - roi->top,
+                },
+                .roi_value = av_clip_c(v, INT8_MIN, INT8_MAX),
+            };
+        }
+
+        param_roi = (VAEncMiscParameterBufferROI) {
+            .num_roi      = nb_roi,
+            .max_delta_qp = INT8_MAX,
+            .min_delta_qp = INT8_MIN,
+            .roi          = pic->roi,
+            .roi_flags.bits.roi_value_is_qp_delta = 1,
+        };
+
+        err = vaapi_encode_make_misc_param_buffer(avctx, pic,
+                                                  VAEncMiscParameterTypeROI,
+                                                  &param_roi,
+                                                  sizeof(param_roi));
+        if (err < 0)
+            goto fail;
+    }
+#endif
+
     vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
                          pic->input_surface);
     if (vas != VA_STATUS_SUCCESS) {
@@ -500,6 +566,7 @@  fail_at_end:
     av_freep(&pic->codec_picture_params);
     av_freep(&pic->param_buffers);
     av_freep(&pic->slices);
+    av_freep(&pic->roi);
     av_frame_free(&pic->recon_image);
     av_buffer_unref(&pic->output_buffer_ref);
     pic->output_buffer = VA_INVALID_ID;
@@ -634,6 +701,7 @@  static int vaapi_encode_free(AVCodecContext *avctx,
 
     av_freep(&pic->priv_data);
     av_freep(&pic->codec_picture_params);
+    av_freep(&pic->roi);
 
     av_free(pic);
 
@@ -948,6 +1016,19 @@  static int vaapi_encode_check_frame(AVCodecContext *avctx,
         ctx->crop_warned = 1;
     }
 
+    if (!ctx->roi_allowed) {
+        AVFrameSideData *sd =
+            av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
+
+        if (sd && !ctx->roi_warned) {
+            if (sd && !ctx->roi_warned) {
+                av_log(avctx, AV_LOG_WARNING, "ROI side data on input "
+                       "frames ignored due to lack of driver support.\n");
+                ctx->roi_warned = 1;
+            }
+        }
+    }
+
     return 0;
 }
 
@@ -1942,6 +2023,39 @@  static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(1, 0, 0)
+    VAAPIEncodeContext *ctx = avctx->priv_data;
+    VAStatus vas;
+    VAConfigAttrib attr = { VAConfigAttribEncROI };
+
+    vas = vaGetConfigAttributes(ctx->hwctx->display,
+                                ctx->va_profile,
+                                ctx->va_entrypoint,
+                                &attr, 1);
+    if (vas != VA_STATUS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
+               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
+        return AVERROR_EXTERNAL;
+    }
+
+    if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
+        ctx->roi_allowed = 0;
+    } else {
+        VAConfigAttribValEncROI roi = {
+            .value = attr.value,
+        };
+
+        ctx->roi_max_regions = roi.bits.num_roi_regions;
+        ctx->roi_allowed = ctx->roi_max_regions > 0 &&
+            (ctx->va_rc_mode == VA_RC_CQP ||
+             roi.bits.roi_rc_qp_delta_support);
+    }
+#endif
+    return 0;
+}
+
 static void vaapi_encode_free_output_buffer(void *opaque,
                                             uint8_t *data)
 {
@@ -2132,6 +2246,10 @@  av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
     if (err < 0)
         goto fail;
 
+    err = vaapi_encode_init_roi(avctx);
+    if (err < 0)
+        goto fail;
+
     if (avctx->compression_level >= 0) {
         err = vaapi_encode_init_quality(avctx);
         if (err < 0)
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index eeec06036b..b9a3defd72 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -69,6 +69,13 @@  typedef struct VAAPIEncodePicture {
     int64_t         pts;
     int             force_idr;
 
+#if VA_CHECK_VERSION(1, 0, 0)
+    // ROI regions.
+    VAEncROI       *roi;
+#else
+    void           *roi;
+#endif
+
     int             type;
     int             b_depth;
     int             encode_issued;
@@ -304,9 +311,20 @@  typedef struct VAAPIEncodeContext {
     int gop_counter;
     int end_of_stream;
 
+    // Whether the driver supports ROI at all.
+    int             roi_allowed;
+    // Maximum number of regions supported by the driver.
+    int             roi_max_regions;
+    // Quantisation range for offset calculations.  Set by codec-specific
+    // code, as it may change based on parameters.
+    int             roi_quant_range;
+
     // The encoder does not support cropping information, so warn about
     // it the first time we encounter any nonzero crop fields.
     int             crop_warned;
+    // If the driver does not support ROI then warn the first time we
+    // encounter a frame with ROI side data.
+    int             roi_warned;
 } VAAPIEncodeContext;
 
 enum {
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index d1427112ea..f4965d8b09 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -1130,6 +1130,8 @@  static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
         }
     }
 
+    ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8);
+
     return 0;
 }
 
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 758bd40a37..538862a9d5 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -1102,6 +1102,8 @@  static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
         priv->fixed_qp_b   = 30;
     }
 
+    ctx->roi_quant_range = 51 + 6 * (ctx->profile->depth - 8);
+
     return 0;
 }
 
diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c
index fb1ef71fdc..bac9ea1fa6 100644
--- a/libavcodec/vaapi_encode_mpeg2.c
+++ b/libavcodec/vaapi_encode_mpeg2.c
@@ -552,6 +552,8 @@  static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx)
     ctx->nb_slices  = ctx->slice_block_rows;
     ctx->slice_size = 1;
 
+    ctx->roi_quant_range = 31;
+
     return 0;
 }
 
diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c
index ddbe4c9075..6e7bf9d106 100644
--- a/libavcodec/vaapi_encode_vp8.c
+++ b/libavcodec/vaapi_encode_vp8.c
@@ -173,6 +173,8 @@  static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx)
     else
         priv->q_index_i = priv->q_index_p;
 
+    ctx->roi_quant_range = VP8_MAX_QUANT;
+
     return 0;
 }
 
diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c
index f89fd0d07a..d7f415d704 100644
--- a/libavcodec/vaapi_encode_vp9.c
+++ b/libavcodec/vaapi_encode_vp9.c
@@ -202,6 +202,8 @@  static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx)
         priv->q_idx_idr = priv->q_idx_p = priv->q_idx_b = 100;
     }
 
+    ctx->roi_quant_range = VP9_MAX_QUANT;
+
     return 0;
 }