diff mbox

[FFmpeg-devel,15/26] vaapi_encode: Clean up rate control configuration

Message ID 20180422152921.32510-16-sw@jkqxz.net
State Superseded
Headers show

Commit Message

Mark Thompson April 22, 2018, 3:29 p.m. UTC
Query which modes are supported and select between VBR and CBR based
on that.  Removes all of the codec-specific rate control mode selection
code.  Also ensures that target percentage and window size match the
target bitrate and RC buffer size in all cases where they are not
explicitly specified.
---
 doc/encoders.texi               |   2 -
 libavcodec/vaapi_encode.c       | 166 ++++++++++++++++++++++++++++------------
 libavcodec/vaapi_encode.h       |   4 +-
 libavcodec/vaapi_encode_h264.c  |  12 ---
 libavcodec/vaapi_encode_h265.c  |  12 ---
 libavcodec/vaapi_encode_mjpeg.c |   3 +-
 libavcodec/vaapi_encode_mpeg2.c |   3 +-
 libavcodec/vaapi_encode_vp8.c   |  11 ---
 libavcodec/vaapi_encode_vp9.c   |  11 ---
 9 files changed, 119 insertions(+), 105 deletions(-)

Comments

Xiang, Haihao April 27, 2018, 4:10 a.m. UTC | #1
On Sun, 2018-04-22 at 16:29 +0100, Mark Thompson wrote:
> Query which modes are supported and select between VBR and CBR based

> on that.  Removes all of the codec-specific rate control mode selection

> code.  Also ensures that target percentage and window size match the

> target bitrate and RC buffer size in all cases where they are not

> explicitly specified.

> ---

>  doc/encoders.texi               |   2 -

>  libavcodec/vaapi_encode.c       | 166 ++++++++++++++++++++++++++++-----------

> -

>  libavcodec/vaapi_encode.h       |   4 +-

>  libavcodec/vaapi_encode_h264.c  |  12 ---

>  libavcodec/vaapi_encode_h265.c  |  12 ---

>  libavcodec/vaapi_encode_mjpeg.c |   3 +-

>  libavcodec/vaapi_encode_mpeg2.c |   3 +-

>  libavcodec/vaapi_encode_vp8.c   |  11 ---

>  libavcodec/vaapi_encode_vp9.c   |  11 ---

>  9 files changed, 119 insertions(+), 105 deletions(-)

> 

> diff --git a/doc/encoders.texi b/doc/encoders.texi

> index 62a1509a96..0c0a307987 100644

> --- a/doc/encoders.texi

> +++ b/doc/encoders.texi

> @@ -2643,8 +2643,6 @@ Always encodes using the standard quantisation and

> huffman tables -

>  @item mpeg2_vaapi

>  @option{profile} and @option{level} set the value of

> @emph{profile_and_level_indication}.

>  

> -No rate control is supported.

> -

>  @item vp8_vaapi

>  B-frames are not supported.

>  

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

> index fc83d3db11..6188423935 100644

> --- a/libavcodec/vaapi_encode.c

> +++ b/libavcodec/vaapi_encode.c

> @@ -1207,7 +1207,6 @@ static av_cold int

> vaapi_encode_config_attributes(AVCodecContext *avctx)

>      int i;

>  

>      VAConfigAttrib attr[] = {

> -        { VAConfigAttribRateControl      },

>          { VAConfigAttribEncMaxRefFrames  },

>          { VAConfigAttribEncPackedHeaders },

>      };

> @@ -1231,32 +1230,6 @@ static av_cold int

> vaapi_encode_config_attributes(AVCodecContext *avctx)

>              continue;

>          }

>          switch (attr[i].type) {

> -        case VAConfigAttribRateControl:

> -            // Hack for backward compatibility: CBR was the only

> -            // usable RC mode for a long time, so old drivers will

> -            // only have it.  Normal default options may now choose

> -            // VBR and then fail, however, so override it here with

> -            // CBR if that is the only supported mode.

> -            if (ctx->va_rc_mode == VA_RC_VBR &&

> -                !(attr[i].value & VA_RC_VBR) &&

> -                (attr[i].value & VA_RC_CBR)) {

> -                av_log(avctx, AV_LOG_WARNING, "VBR rate control is "

> -                       "not supported with this driver version; "

> -                       "using CBR instead.\n");

> -                ctx->va_rc_mode = VA_RC_CBR;

> -            }

> -            if (!(ctx->va_rc_mode & attr[i].value)) {

> -                av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x "

> -                       "is not supported (mask: %#x).\n",

> -                       ctx->va_rc_mode, attr[i].value);

> -                return AVERROR(EINVAL);

> -            }

> -            ctx->config_attributes[ctx->nb_config_attributes++] =

> -                (VAConfigAttrib) {

> -                .type  = VAConfigAttribRateControl,

> -                .value = ctx->va_rc_mode,

> -            };

> -            break;

>          case VAConfigAttribEncMaxRefFrames:

>          {

>              unsigned int ref_l0 = attr[i].value & 0xffff;

> @@ -1303,16 +1276,46 @@ static av_cold int

> vaapi_encode_config_attributes(AVCodecContext *avctx)

>  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)

>  {

>      VAAPIEncodeContext *ctx = avctx->priv_data;

> -    int rc_bits_per_second;

> -    int rc_target_percentage;

> -    int rc_window_size;

> -    int hrd_buffer_size;

> -    int hrd_initial_buffer_fullness;

> +    int64_t rc_bits_per_second;

> +    int     rc_target_percentage;

> +    int     rc_window_size;

> +    int64_t hrd_buffer_size;

> +    int64_t hrd_initial_buffer_fullness;

>      int fr_num, fr_den;

> +    VAConfigAttrib rc_attr = { VAConfigAttribRateControl };

> +    VAStatus vas;

> +

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

> +                                ctx->va_profile, ctx->va_entrypoint,

> +                                &rc_attr, 1);

> +    if (vas != VA_STATUS_SUCCESS) {

> +        av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "

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

> +        return AVERROR_EXTERNAL;

> +    }

>  

> -    if (avctx->bit_rate > INT32_MAX) {

> -        av_log(avctx, AV_LOG_ERROR, "Target bitrate of 2^31 bps or "

> -               "higher is not supported.\n");

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

> +        av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "

> +               "supported rate control modes: assuming constant-quality.\n");

> +        ctx->va_rc_mode = VA_RC_CQP;

> +        return 0;

> +    }

> +    if (avctx->flags & AV_CODEC_FLAG_QSCALE ||

> +        avctx->bit_rate <= 0) {

> +        if (rc_attr.value & VA_RC_CQP) {

> +            av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");

> +            ctx->va_rc_mode = VA_RC_CQP;

> +            return 0;

> +        } else {

> +            av_log(avctx, AV_LOG_ERROR, "Driver does not support "

> +                   "constant-quality mode (%#x).\n", rc_attr.value);

> +            return AVERROR(EINVAL);

> +        }

> +    }

> +

> +    if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {

> +        av_log(avctx, AV_LOG_ERROR, "Driver does not support any "

> +               "bitrate-targetted rate control modes.\n");

>          return AVERROR(EINVAL);

>      }

>  

> @@ -1320,27 +1323,90 @@ static av_cold int

> vaapi_encode_init_rate_control(AVCodecContext *avctx)

>          hrd_buffer_size = avctx->rc_buffer_size;

>      else

>          hrd_buffer_size = avctx->bit_rate;

> -    if (avctx->rc_initial_buffer_occupancy)

> +    if (avctx->rc_initial_buffer_occupancy) {

> +        if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {

> +            av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "

> +                   "must have initial buffer size (%d) < "

> +                   "buffer size (%"PRId64").\n",

> +                   avctx->rc_initial_buffer_occupancy, hrd_buffer_size);

> +            return AVERROR(EINVAL);

> +        }

>          hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;

> -    else

> +    } else {

>          hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;

> +    }

> +

> +    if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {

> +        av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have "

> +               "bitrate (%"PRId64") <= maxrate (%"PRId64").\n",

> +               avctx->bit_rate, avctx->rc_max_rate);

> +        return AVERROR(EINVAL);

> +    }

> +

> +    if (avctx->rc_max_rate > avctx->bit_rate) {

> +        if (!(rc_attr.value & VA_RC_VBR)) {

> +            av_log(avctx, AV_LOG_WARNING, "Driver does not support "

> +                   "VBR mode (%#x), using CBR mode instead.\n",

> +                   rc_attr.value);

> +            ctx->va_rc_mode = VA_RC_CBR;

> +        } else {

> +            ctx->va_rc_mode = VA_RC_VBR;

> +        }

> +

> +        rc_bits_per_second   = avctx->rc_max_rate;

> +        rc_target_percentage = (avctx->bit_rate * 100) / avctx->rc_max_rate;

> +

> +    } else if (avctx->rc_max_rate == avctx->bit_rate) {

> +        if (!(rc_attr.value & VA_RC_CBR)) {

> +            av_log(avctx, AV_LOG_WARNING, "Driver does not support "

> +                   "CBR mode (%#x), using VBR mode instead.\n",

> +                   rc_attr.value);

> +            ctx->va_rc_mode = VA_RC_VBR;

> +        } else {

> +            ctx->va_rc_mode = VA_RC_CBR;

> +        }

>  

> -    if (ctx->va_rc_mode == VA_RC_CBR) {

>          rc_bits_per_second   = avctx->bit_rate;

>          rc_target_percentage = 100;

> -        rc_window_size       = 1000;

> +

>      } else {

> -        if (avctx->rc_max_rate < avctx->bit_rate) {

> -            // Max rate is unset or invalid, just use the normal bitrate.

> +        if (rc_attr.value & VA_RC_VBR) {

> +            ctx->va_rc_mode = VA_RC_VBR;

> +

> +            rc_bits_per_second   = avctx->bit_rate + hrd_buffer_size;


Why hrd_buffer_size is added? User may set a large hrd buffer size. 

> +            rc_target_percentage = (avctx->bit_rate * 100) /

> rc_bits_per_second;

> +        } else {

> +            ctx->va_rc_mode = VA_RC_CBR;

> +

>              rc_bits_per_second   = avctx->bit_rate;

>              rc_target_percentage = 100;

> -        } else {

> -            rc_bits_per_second   = avctx->rc_max_rate;

> -            rc_target_percentage = (avctx->bit_rate * 100) /

> rc_bits_per_second;

>          }

> -        rc_window_size = (hrd_buffer_size * 1000) / avctx->bit_rate;

>      }

>  

> +    rc_window_size = ((int64_t)hrd_buffer_size * 100 * 1000) /

> +                   (rc_target_percentage * rc_bits_per_second);


I think it should be (hrd_buffer_size * 1000) / rc_bits_per_second. Could you
explain why is it multiplied by (100 / rc_target_percentage) here?

> +

> +    av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps "

> +           "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR",

> +           rc_target_percentage, rc_bits_per_second, rc_window_size);

> +    av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "

> +           "initial fullness %"PRId64" bits.\n",

> +           hrd_buffer_size, hrd_initial_buffer_fullness);

> +

> +    if (rc_bits_per_second          > UINT32_MAX ||

> +        hrd_buffer_size             > UINT32_MAX ||

> +        hrd_initial_buffer_fullness > UINT32_MAX) {

> +        av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "

> +               "greater are not supported by VAAPI.\n");

> +        return AVERROR(EINVAL);

> +    }

> +

> +    ctx->config_attributes[ctx->nb_config_attributes++] =

> +        (VAConfigAttrib) {

> +        .type  = VAConfigAttribRateControl,

> +        .value = ctx->va_rc_mode,

> +    };

> +

>      ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;

>      ctx->rc_params.rc = (VAEncMiscParameterRateControl) {

>          .bits_per_second   = rc_bits_per_second,

> @@ -1602,6 +1668,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)

>      if (err < 0)

>          goto fail;

>  

> +    err = vaapi_encode_init_rate_control(avctx);

> +    if (err < 0)

> +        goto fail;

> +

>      err = vaapi_encode_config_attributes(avctx);

>      if (err < 0)

>          goto fail;

> @@ -1651,12 +1721,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)

>          goto fail;

>      }

>  

> -    if (ctx->va_rc_mode & ~VA_RC_CQP) {

> -        err = vaapi_encode_init_rate_control(avctx);

> -        if (err < 0)

> -            goto fail;

> -    }

> -

>      if (ctx->codec->configure) {

>          err = ctx->codec->configure(avctx);

>          if (err < 0)

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

> index 35d48eff2f..3fb39113a4 100644

> --- a/libavcodec/vaapi_encode.h

> +++ b/libavcodec/vaapi_encode.h

> @@ -118,8 +118,6 @@ typedef struct VAAPIEncodeContext {

>      // Use low power encoding mode.

>      int             low_power;

>  

> -    // Rate control mode.

> -    unsigned int    va_rc_mode;

>      // Supported packed headers (initially the desired set, modified

>      // later to what is actually supported).

>      unsigned int    va_packed_headers;

> @@ -140,6 +138,8 @@ typedef struct VAAPIEncodeContext {

>      VAProfile       va_profile;

>      // Encoding entrypoint (VAEntryoint*).

>      VAEntrypoint    va_entrypoint;

> +    // Rate control mode.

> +    unsigned int    va_rc_mode;

>  

>      // Configuration attributes to use when creating va_config.

>      VAConfigAttrib  config_attributes[MAX_CONFIG_ATTRIBUTES];

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

> index a20cf15c1e..e75b91eb55 100644

> --- a/libavcodec/vaapi_encode_h264.c

> +++ b/libavcodec/vaapi_encode_h264.c

> @@ -819,10 +819,6 @@ static av_cold int

> vaapi_encode_h264_configure(AVCodecContext *avctx)

>          priv->fixed_qp_p   = 26;

>          priv->fixed_qp_b   = 26;

>  

> -        av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n",

> -               ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",

> -               avctx->bit_rate);

> -

>      } else {

>          av_assert0(0 && "Invalid RC mode.");

>      }

> @@ -928,14 +924,6 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext

> *avctx)

>          return AVERROR_PATCHWELCOME;

>      }

>  

> -    if (avctx->bit_rate > 0) {

> -        if (avctx->rc_max_rate == avctx->bit_rate)

> -            ctx->va_rc_mode = VA_RC_CBR;

> -        else

> -            ctx->va_rc_mode = VA_RC_VBR;

> -    } else

> -        ctx->va_rc_mode = VA_RC_CQP;

> -

>      ctx->va_packed_headers =

>          VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS.

>          VA_ENC_PACKED_HEADER_SLICE    | // Slice headers.

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

> index a818650811..fa9d838bdc 100644

> --- a/libavcodec/vaapi_encode_h265.c

> +++ b/libavcodec/vaapi_encode_h265.c

> @@ -864,10 +864,6 @@ static av_cold int

> vaapi_encode_h265_configure(AVCodecContext *avctx)

>          priv->fixed_qp_p   = 30;

>          priv->fixed_qp_b   = 30;

>  

> -        av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n",

> -               ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",

> -               avctx->bit_rate);

> -

>      } else {

>          av_assert0(0 && "Invalid RC mode.");

>      }

> @@ -924,14 +920,6 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext

> *avctx)

>      if (avctx->level == FF_LEVEL_UNKNOWN)

>          avctx->level = priv->level;

>  

> -    if (avctx->bit_rate > 0) {

> -        if (avctx->rc_max_rate == avctx->bit_rate)

> -            ctx->va_rc_mode = VA_RC_CBR;

> -        else

> -            ctx->va_rc_mode = VA_RC_VBR;

> -    } else

> -        ctx->va_rc_mode = VA_RC_CQP;

> -

>      ctx->va_packed_headers =

>          VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS.

>          VA_ENC_PACKED_HEADER_SLICE;     // Slice headers.

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

> index 3baf5c8915..77104583bf 100644

> --- a/libavcodec/vaapi_encode_mjpeg.c

> +++ b/libavcodec/vaapi_encode_mjpeg.c

> @@ -388,8 +388,6 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext

> *avctx)

>  

>      ctx->codec = &vaapi_encode_type_mjpeg;

>  

> -    ctx->va_rc_mode = VA_RC_CQP;

> -

>      // The JPEG image header - see note above.

>      ctx->va_packed_headers =

>          VA_ENC_PACKED_HEADER_RAW_DATA;

> @@ -402,6 +400,7 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext

> *avctx)

>  

>  static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {

>      { "global_quality", "80" },

> +    { "b",              "0"  },

>      { NULL },

>  };

>  

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

> index 09c3663220..b7189b2d67 100644

> --- a/libavcodec/vaapi_encode_mpeg2.c

> +++ b/libavcodec/vaapi_encode_mpeg2.c

> @@ -615,8 +615,6 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext

> *avctx)

>          return AVERROR(EINVAL);

>      }

>  

> -    ctx->va_rc_mode    = VA_RC_CQP;

> -

>      ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |

>                               VA_ENC_PACKED_HEADER_PICTURE;

>  

> @@ -667,6 +665,7 @@ static const AVOption vaapi_encode_mpeg2_options[] = {

>  };

>  

>  static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = {

> +    { "b",              "0"   },

>      { "bf",             "1"   },

>      { "g",              "120" },

>      { "i_qfactor",      "1"   },

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

> index d9c359a4e1..dd7943133e 100644

> --- a/libavcodec/vaapi_encode_vp8.c

> +++ b/libavcodec/vaapi_encode_vp8.c

> @@ -203,17 +203,6 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext

> *avctx)

>  

>      ctx->codec = &vaapi_encode_type_vp8;

>  

> -    if (avctx->flags & AV_CODEC_FLAG_QSCALE) {

> -        ctx->va_rc_mode = VA_RC_CQP;

> -    } else if (avctx->bit_rate > 0) {

> -        if (avctx->rc_max_rate == avctx->bit_rate)

> -            ctx->va_rc_mode = VA_RC_CBR;

> -        else

> -            ctx->va_rc_mode = VA_RC_VBR;

> -    } else {

> -        ctx->va_rc_mode = VA_RC_CQP;

> -    }

> -

>      // Packed headers are not currently supported.

>      ctx->va_packed_headers = 0;

>  

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

> index eabacbd0fd..794b308fa5 100644

> --- a/libavcodec/vaapi_encode_vp9.c

> +++ b/libavcodec/vaapi_encode_vp9.c

> @@ -227,17 +227,6 @@ static av_cold int vaapi_encode_vp9_init(AVCodecContext

> *avctx)

>  

>      ctx->codec = &vaapi_encode_type_vp9;

>  

> -    if (avctx->flags & AV_CODEC_FLAG_QSCALE) {

> -        ctx->va_rc_mode = VA_RC_CQP;

> -    } else if (avctx->bit_rate > 0) {

> -        if (avctx->bit_rate == avctx->rc_max_rate)

> -            ctx->va_rc_mode = VA_RC_CBR;

> -        else

> -            ctx->va_rc_mode = VA_RC_VBR;

> -    } else {

> -        ctx->va_rc_mode = VA_RC_CQP;

> -    }

> -

>      // Packed headers are not currently supported.

>      ctx->va_packed_headers = 0;

>
Mark Thompson April 27, 2018, 8:07 a.m. UTC | #2
On 27/04/18 05:10, Xiang, Haihao wrote:
> On Sun, 2018-04-22 at 16:29 +0100, Mark Thompson wrote:
>> Query which modes are supported and select between VBR and CBR based
>> on that.  Removes all of the codec-specific rate control mode selection
>> code.  Also ensures that target percentage and window size match the
>> target bitrate and RC buffer size in all cases where they are not
>> explicitly specified.
>> ---
>>  doc/encoders.texi               |   2 -
>>  libavcodec/vaapi_encode.c       | 166 ++++++++++++++++++++++++++++-----------
>> -
>>  libavcodec/vaapi_encode.h       |   4 +-
>>  libavcodec/vaapi_encode_h264.c  |  12 ---
>>  libavcodec/vaapi_encode_h265.c  |  12 ---
>>  libavcodec/vaapi_encode_mjpeg.c |   3 +-
>>  libavcodec/vaapi_encode_mpeg2.c |   3 +-
>>  libavcodec/vaapi_encode_vp8.c   |  11 ---
>>  libavcodec/vaapi_encode_vp9.c   |  11 ---
>>  9 files changed, 119 insertions(+), 105 deletions(-)
>>
>> ...
>> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
>> index fc83d3db11..6188423935 100644
>> --- a/libavcodec/vaapi_encode.c
>> +++ b/libavcodec/vaapi_encode.c
>> ...
>> vaapi_encode_config_attributes(AVCodecContext *avctx)
>>  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
>>  {
>>      VAAPIEncodeContext *ctx = avctx->priv_data;
>> -    int rc_bits_per_second;
>> -    int rc_target_percentage;
>> -    int rc_window_size;
>> -    int hrd_buffer_size;
>> -    int hrd_initial_buffer_fullness;
>> +    int64_t rc_bits_per_second;
>> +    int     rc_target_percentage;
>> +    int     rc_window_size;
>> +    int64_t hrd_buffer_size;
>> +    int64_t hrd_initial_buffer_fullness;
>>      int fr_num, fr_den;
>> +    VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
>> +    VAStatus vas;
>> +
>> +    vas = vaGetConfigAttributes(ctx->hwctx->display,
>> +                                ctx->va_profile, ctx->va_entrypoint,
>> +                                &rc_attr, 1);
>> +    if (vas != VA_STATUS_SUCCESS) {
>> +        av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
>> +               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
>> +        return AVERROR_EXTERNAL;
>> +    }
>>  
>> -    if (avctx->bit_rate > INT32_MAX) {
>> -        av_log(avctx, AV_LOG_ERROR, "Target bitrate of 2^31 bps or "
>> -               "higher is not supported.\n");
>> +    if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
>> +        av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
>> +               "supported rate control modes: assuming constant-quality.\n");
>> +        ctx->va_rc_mode = VA_RC_CQP;
>> +        return 0;
>> +    }
>> +    if (avctx->flags & AV_CODEC_FLAG_QSCALE ||
>> +        avctx->bit_rate <= 0) {
>> +        if (rc_attr.value & VA_RC_CQP) {
>> +            av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
>> +            ctx->va_rc_mode = VA_RC_CQP;
>> +            return 0;
>> +        } else {
>> +            av_log(avctx, AV_LOG_ERROR, "Driver does not support "
>> +                   "constant-quality mode (%#x).\n", rc_attr.value);
>> +            return AVERROR(EINVAL);
>> +        }
>> +    }
>> +
>> +    if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
>> +        av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
>> +               "bitrate-targetted rate control modes.\n");
>>          return AVERROR(EINVAL);
>>      }
>>  
>> @@ -1320,27 +1323,90 @@ static av_cold int
>> vaapi_encode_init_rate_control(AVCodecContext *avctx)
>>          hrd_buffer_size = avctx->rc_buffer_size;
>>      else
>>          hrd_buffer_size = avctx->bit_rate;
>> -    if (avctx->rc_initial_buffer_occupancy)
>> +    if (avctx->rc_initial_buffer_occupancy) {
>> +        if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
>> +            av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
>> +                   "must have initial buffer size (%d) < "
>> +                   "buffer size (%"PRId64").\n",
>> +                   avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
>> +            return AVERROR(EINVAL);
>> +        }
>>          hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
>> -    else
>> +    } else {
>>          hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
>> +    }
>> +
>> +    if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
>> +        av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have "
>> +               "bitrate (%"PRId64") <= maxrate (%"PRId64").\n",
>> +               avctx->bit_rate, avctx->rc_max_rate);
>> +        return AVERROR(EINVAL);
>> +    }
>> +
>> +    if (avctx->rc_max_rate > avctx->bit_rate) {
>> +        if (!(rc_attr.value & VA_RC_VBR)) {
>> +            av_log(avctx, AV_LOG_WARNING, "Driver does not support "
>> +                   "VBR mode (%#x), using CBR mode instead.\n",
>> +                   rc_attr.value);
>> +            ctx->va_rc_mode = VA_RC_CBR;
>> +        } else {
>> +            ctx->va_rc_mode = VA_RC_VBR;
>> +        }
>> +
>> +        rc_bits_per_second   = avctx->rc_max_rate;
>> +        rc_target_percentage = (avctx->bit_rate * 100) / avctx->rc_max_rate;
>> +
>> +    } else if (avctx->rc_max_rate == avctx->bit_rate) {
>> +        if (!(rc_attr.value & VA_RC_CBR)) {
>> +            av_log(avctx, AV_LOG_WARNING, "Driver does not support "
>> +                   "CBR mode (%#x), using VBR mode instead.\n",
>> +                   rc_attr.value);
>> +            ctx->va_rc_mode = VA_RC_VBR;
>> +        } else {
>> +            ctx->va_rc_mode = VA_RC_CBR;
>> +        }
>>  
>> -    if (ctx->va_rc_mode == VA_RC_CBR) {
>>          rc_bits_per_second   = avctx->bit_rate;
>>          rc_target_percentage = 100;
>> -        rc_window_size       = 1000;
>> +
>>      } else {
>> -        if (avctx->rc_max_rate < avctx->bit_rate) {
>> -            // Max rate is unset or invalid, just use the normal bitrate.
>> +        if (rc_attr.value & VA_RC_VBR) {
>> +            ctx->va_rc_mode = VA_RC_VBR;
>> +
>> +            rc_bits_per_second   = avctx->bit_rate + hrd_buffer_size;
> 
> Why hrd_buffer_size is added? User may set a large hrd buffer size. 

Given a buffer size and a target bitrate, the maximum bitrate in a second is achieved by completely filling an empty buffer and also using all the bits available from that second.

>> +            rc_target_percentage = (avctx->bit_rate * 100) /
>> rc_bits_per_second;
>> +        } else {
>> +            ctx->va_rc_mode = VA_RC_CBR;
>> +
>>              rc_bits_per_second   = avctx->bit_rate;
>>              rc_target_percentage = 100;
>> -        } else {
>> -            rc_bits_per_second   = avctx->rc_max_rate;
>> -            rc_target_percentage = (avctx->bit_rate * 100) /
>> rc_bits_per_second;
>>          }
>> -        rc_window_size = (hrd_buffer_size * 1000) / avctx->bit_rate;
>>      }
>>  
>> +    rc_window_size = ((int64_t)hrd_buffer_size * 100 * 1000) /
>> +                   (rc_target_percentage * rc_bits_per_second);
> 
> I think it should be (hrd_buffer_size * 1000) / rc_bits_per_second. Could you
> explain why is it multiplied by (100 / rc_target_percentage) here?

The target bitrate (avctx->bit_rate == rc_bits_per_second * rc_target_percentage / 100) is the fill-rate of the buffer, so that's what we need to divide the buffer size by to find how long it takes to fill and therefore the effective window size.

>> +
>> +    av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps "
>> +           "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR",
>> +           rc_target_percentage, rc_bits_per_second, rc_window_size);
>> +    av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
>> +           "initial fullness %"PRId64" bits.\n",
>> +           hrd_buffer_size, hrd_initial_buffer_fullness);
>> +
>> +    if (rc_bits_per_second          > UINT32_MAX ||
>> +        hrd_buffer_size             > UINT32_MAX ||
>> +        hrd_initial_buffer_fullness > UINT32_MAX) {
>> +        av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
>> +               "greater are not supported by VAAPI.\n");
>> +        return AVERROR(EINVAL);
>> +    }
>> +
>> +    ctx->config_attributes[ctx->nb_config_attributes++] =
>> +        (VAConfigAttrib) {
>> +        .type  = VAConfigAttribRateControl,
>> +        .value = ctx->va_rc_mode,
>> +    };
>> +
>>      ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
>>      ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
>>          .bits_per_second   = rc_bits_per_second,

Thanks,

- Mark
diff mbox

Patch

diff --git a/doc/encoders.texi b/doc/encoders.texi
index 62a1509a96..0c0a307987 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -2643,8 +2643,6 @@  Always encodes using the standard quantisation and huffman tables -
 @item mpeg2_vaapi
 @option{profile} and @option{level} set the value of @emph{profile_and_level_indication}.
 
-No rate control is supported.
-
 @item vp8_vaapi
 B-frames are not supported.
 
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index fc83d3db11..6188423935 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1207,7 +1207,6 @@  static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx)
     int i;
 
     VAConfigAttrib attr[] = {
-        { VAConfigAttribRateControl      },
         { VAConfigAttribEncMaxRefFrames  },
         { VAConfigAttribEncPackedHeaders },
     };
@@ -1231,32 +1230,6 @@  static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx)
             continue;
         }
         switch (attr[i].type) {
-        case VAConfigAttribRateControl:
-            // Hack for backward compatibility: CBR was the only
-            // usable RC mode for a long time, so old drivers will
-            // only have it.  Normal default options may now choose
-            // VBR and then fail, however, so override it here with
-            // CBR if that is the only supported mode.
-            if (ctx->va_rc_mode == VA_RC_VBR &&
-                !(attr[i].value & VA_RC_VBR) &&
-                (attr[i].value & VA_RC_CBR)) {
-                av_log(avctx, AV_LOG_WARNING, "VBR rate control is "
-                       "not supported with this driver version; "
-                       "using CBR instead.\n");
-                ctx->va_rc_mode = VA_RC_CBR;
-            }
-            if (!(ctx->va_rc_mode & attr[i].value)) {
-                av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x "
-                       "is not supported (mask: %#x).\n",
-                       ctx->va_rc_mode, attr[i].value);
-                return AVERROR(EINVAL);
-            }
-            ctx->config_attributes[ctx->nb_config_attributes++] =
-                (VAConfigAttrib) {
-                .type  = VAConfigAttribRateControl,
-                .value = ctx->va_rc_mode,
-            };
-            break;
         case VAConfigAttribEncMaxRefFrames:
         {
             unsigned int ref_l0 = attr[i].value & 0xffff;
@@ -1303,16 +1276,46 @@  static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx)
 static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
 {
     VAAPIEncodeContext *ctx = avctx->priv_data;
-    int rc_bits_per_second;
-    int rc_target_percentage;
-    int rc_window_size;
-    int hrd_buffer_size;
-    int hrd_initial_buffer_fullness;
+    int64_t rc_bits_per_second;
+    int     rc_target_percentage;
+    int     rc_window_size;
+    int64_t hrd_buffer_size;
+    int64_t hrd_initial_buffer_fullness;
     int fr_num, fr_den;
+    VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
+    VAStatus vas;
+
+    vas = vaGetConfigAttributes(ctx->hwctx->display,
+                                ctx->va_profile, ctx->va_entrypoint,
+                                &rc_attr, 1);
+    if (vas != VA_STATUS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
+               "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
+        return AVERROR_EXTERNAL;
+    }
 
-    if (avctx->bit_rate > INT32_MAX) {
-        av_log(avctx, AV_LOG_ERROR, "Target bitrate of 2^31 bps or "
-               "higher is not supported.\n");
+    if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
+        av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
+               "supported rate control modes: assuming constant-quality.\n");
+        ctx->va_rc_mode = VA_RC_CQP;
+        return 0;
+    }
+    if (avctx->flags & AV_CODEC_FLAG_QSCALE ||
+        avctx->bit_rate <= 0) {
+        if (rc_attr.value & VA_RC_CQP) {
+            av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
+            ctx->va_rc_mode = VA_RC_CQP;
+            return 0;
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "Driver does not support "
+                   "constant-quality mode (%#x).\n", rc_attr.value);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
+        av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
+               "bitrate-targetted rate control modes.\n");
         return AVERROR(EINVAL);
     }
 
@@ -1320,27 +1323,90 @@  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
         hrd_buffer_size = avctx->rc_buffer_size;
     else
         hrd_buffer_size = avctx->bit_rate;
-    if (avctx->rc_initial_buffer_occupancy)
+    if (avctx->rc_initial_buffer_occupancy) {
+        if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
+                   "must have initial buffer size (%d) < "
+                   "buffer size (%"PRId64").\n",
+                   avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
+            return AVERROR(EINVAL);
+        }
         hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
-    else
+    } else {
         hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
+    }
+
+    if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have "
+               "bitrate (%"PRId64") <= maxrate (%"PRId64").\n",
+               avctx->bit_rate, avctx->rc_max_rate);
+        return AVERROR(EINVAL);
+    }
+
+    if (avctx->rc_max_rate > avctx->bit_rate) {
+        if (!(rc_attr.value & VA_RC_VBR)) {
+            av_log(avctx, AV_LOG_WARNING, "Driver does not support "
+                   "VBR mode (%#x), using CBR mode instead.\n",
+                   rc_attr.value);
+            ctx->va_rc_mode = VA_RC_CBR;
+        } else {
+            ctx->va_rc_mode = VA_RC_VBR;
+        }
+
+        rc_bits_per_second   = avctx->rc_max_rate;
+        rc_target_percentage = (avctx->bit_rate * 100) / avctx->rc_max_rate;
+
+    } else if (avctx->rc_max_rate == avctx->bit_rate) {
+        if (!(rc_attr.value & VA_RC_CBR)) {
+            av_log(avctx, AV_LOG_WARNING, "Driver does not support "
+                   "CBR mode (%#x), using VBR mode instead.\n",
+                   rc_attr.value);
+            ctx->va_rc_mode = VA_RC_VBR;
+        } else {
+            ctx->va_rc_mode = VA_RC_CBR;
+        }
 
-    if (ctx->va_rc_mode == VA_RC_CBR) {
         rc_bits_per_second   = avctx->bit_rate;
         rc_target_percentage = 100;
-        rc_window_size       = 1000;
+
     } else {
-        if (avctx->rc_max_rate < avctx->bit_rate) {
-            // Max rate is unset or invalid, just use the normal bitrate.
+        if (rc_attr.value & VA_RC_VBR) {
+            ctx->va_rc_mode = VA_RC_VBR;
+
+            rc_bits_per_second   = avctx->bit_rate + hrd_buffer_size;
+            rc_target_percentage = (avctx->bit_rate * 100) / rc_bits_per_second;
+        } else {
+            ctx->va_rc_mode = VA_RC_CBR;
+
             rc_bits_per_second   = avctx->bit_rate;
             rc_target_percentage = 100;
-        } else {
-            rc_bits_per_second   = avctx->rc_max_rate;
-            rc_target_percentage = (avctx->bit_rate * 100) / rc_bits_per_second;
         }
-        rc_window_size = (hrd_buffer_size * 1000) / avctx->bit_rate;
     }
 
+    rc_window_size = ((int64_t)hrd_buffer_size * 100 * 1000) /
+                   (rc_target_percentage * rc_bits_per_second);
+
+    av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps "
+           "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR",
+           rc_target_percentage, rc_bits_per_second, rc_window_size);
+    av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
+           "initial fullness %"PRId64" bits.\n",
+           hrd_buffer_size, hrd_initial_buffer_fullness);
+
+    if (rc_bits_per_second          > UINT32_MAX ||
+        hrd_buffer_size             > UINT32_MAX ||
+        hrd_initial_buffer_fullness > UINT32_MAX) {
+        av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
+               "greater are not supported by VAAPI.\n");
+        return AVERROR(EINVAL);
+    }
+
+    ctx->config_attributes[ctx->nb_config_attributes++] =
+        (VAConfigAttrib) {
+        .type  = VAConfigAttribRateControl,
+        .value = ctx->va_rc_mode,
+    };
+
     ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
     ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
         .bits_per_second   = rc_bits_per_second,
@@ -1602,6 +1668,10 @@  av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
     if (err < 0)
         goto fail;
 
+    err = vaapi_encode_init_rate_control(avctx);
+    if (err < 0)
+        goto fail;
+
     err = vaapi_encode_config_attributes(avctx);
     if (err < 0)
         goto fail;
@@ -1651,12 +1721,6 @@  av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
         goto fail;
     }
 
-    if (ctx->va_rc_mode & ~VA_RC_CQP) {
-        err = vaapi_encode_init_rate_control(avctx);
-        if (err < 0)
-            goto fail;
-    }
-
     if (ctx->codec->configure) {
         err = ctx->codec->configure(avctx);
         if (err < 0)
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 35d48eff2f..3fb39113a4 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -118,8 +118,6 @@  typedef struct VAAPIEncodeContext {
     // Use low power encoding mode.
     int             low_power;
 
-    // Rate control mode.
-    unsigned int    va_rc_mode;
     // Supported packed headers (initially the desired set, modified
     // later to what is actually supported).
     unsigned int    va_packed_headers;
@@ -140,6 +138,8 @@  typedef struct VAAPIEncodeContext {
     VAProfile       va_profile;
     // Encoding entrypoint (VAEntryoint*).
     VAEntrypoint    va_entrypoint;
+    // Rate control mode.
+    unsigned int    va_rc_mode;
 
     // Configuration attributes to use when creating va_config.
     VAConfigAttrib  config_attributes[MAX_CONFIG_ATTRIBUTES];
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index a20cf15c1e..e75b91eb55 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -819,10 +819,6 @@  static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
         priv->fixed_qp_p   = 26;
         priv->fixed_qp_b   = 26;
 
-        av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n",
-               ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",
-               avctx->bit_rate);
-
     } else {
         av_assert0(0 && "Invalid RC mode.");
     }
@@ -928,14 +924,6 @@  static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
         return AVERROR_PATCHWELCOME;
     }
 
-    if (avctx->bit_rate > 0) {
-        if (avctx->rc_max_rate == avctx->bit_rate)
-            ctx->va_rc_mode = VA_RC_CBR;
-        else
-            ctx->va_rc_mode = VA_RC_VBR;
-    } else
-        ctx->va_rc_mode = VA_RC_CQP;
-
     ctx->va_packed_headers =
         VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS.
         VA_ENC_PACKED_HEADER_SLICE    | // Slice headers.
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index a818650811..fa9d838bdc 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -864,10 +864,6 @@  static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
         priv->fixed_qp_p   = 30;
         priv->fixed_qp_b   = 30;
 
-        av_log(avctx, AV_LOG_DEBUG, "Using %s-bitrate = %"PRId64" bps.\n",
-               ctx->va_rc_mode == VA_RC_CBR ? "constant" : "variable",
-               avctx->bit_rate);
-
     } else {
         av_assert0(0 && "Invalid RC mode.");
     }
@@ -924,14 +920,6 @@  static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
     if (avctx->level == FF_LEVEL_UNKNOWN)
         avctx->level = priv->level;
 
-    if (avctx->bit_rate > 0) {
-        if (avctx->rc_max_rate == avctx->bit_rate)
-            ctx->va_rc_mode = VA_RC_CBR;
-        else
-            ctx->va_rc_mode = VA_RC_VBR;
-    } else
-        ctx->va_rc_mode = VA_RC_CQP;
-
     ctx->va_packed_headers =
         VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS.
         VA_ENC_PACKED_HEADER_SLICE;     // Slice headers.
diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
index 3baf5c8915..77104583bf 100644
--- a/libavcodec/vaapi_encode_mjpeg.c
+++ b/libavcodec/vaapi_encode_mjpeg.c
@@ -388,8 +388,6 @@  static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx)
 
     ctx->codec = &vaapi_encode_type_mjpeg;
 
-    ctx->va_rc_mode = VA_RC_CQP;
-
     // The JPEG image header - see note above.
     ctx->va_packed_headers =
         VA_ENC_PACKED_HEADER_RAW_DATA;
@@ -402,6 +400,7 @@  static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx)
 
 static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {
     { "global_quality", "80" },
+    { "b",              "0"  },
     { NULL },
 };
 
diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c
index 09c3663220..b7189b2d67 100644
--- a/libavcodec/vaapi_encode_mpeg2.c
+++ b/libavcodec/vaapi_encode_mpeg2.c
@@ -615,8 +615,6 @@  static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    ctx->va_rc_mode    = VA_RC_CQP;
-
     ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |
                              VA_ENC_PACKED_HEADER_PICTURE;
 
@@ -667,6 +665,7 @@  static const AVOption vaapi_encode_mpeg2_options[] = {
 };
 
 static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = {
+    { "b",              "0"   },
     { "bf",             "1"   },
     { "g",              "120" },
     { "i_qfactor",      "1"   },
diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c
index d9c359a4e1..dd7943133e 100644
--- a/libavcodec/vaapi_encode_vp8.c
+++ b/libavcodec/vaapi_encode_vp8.c
@@ -203,17 +203,6 @@  static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx)
 
     ctx->codec = &vaapi_encode_type_vp8;
 
-    if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
-        ctx->va_rc_mode = VA_RC_CQP;
-    } else if (avctx->bit_rate > 0) {
-        if (avctx->rc_max_rate == avctx->bit_rate)
-            ctx->va_rc_mode = VA_RC_CBR;
-        else
-            ctx->va_rc_mode = VA_RC_VBR;
-    } else {
-        ctx->va_rc_mode = VA_RC_CQP;
-    }
-
     // Packed headers are not currently supported.
     ctx->va_packed_headers = 0;
 
diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c
index eabacbd0fd..794b308fa5 100644
--- a/libavcodec/vaapi_encode_vp9.c
+++ b/libavcodec/vaapi_encode_vp9.c
@@ -227,17 +227,6 @@  static av_cold int vaapi_encode_vp9_init(AVCodecContext *avctx)
 
     ctx->codec = &vaapi_encode_type_vp9;
 
-    if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
-        ctx->va_rc_mode = VA_RC_CQP;
-    } else if (avctx->bit_rate > 0) {
-        if (avctx->bit_rate == avctx->rc_max_rate)
-            ctx->va_rc_mode = VA_RC_CBR;
-        else
-            ctx->va_rc_mode = VA_RC_VBR;
-    } else {
-        ctx->va_rc_mode = VA_RC_CQP;
-    }
-
     // Packed headers are not currently supported.
     ctx->va_packed_headers = 0;