};
break;
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",
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;
else
hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
+ 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.
+ 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;
+ }
+
ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
- .bits_per_second = avctx->bit_rate,
- .target_percentage = 66,
- .window_size = 1000,
- .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40),
- .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18),
+ .bits_per_second = rc_bits_per_second,
+ .target_percentage = rc_target_percentage,
+ .window_size = rc_window_size,
+ .initial_qp = 0,
+ .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
.basic_unit_size = 0,
};
ctx->global_params[ctx->nb_global_params] =