--- libavcodec/vaapi_encode_h264.c | 99 ++++++++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 24 deletions(-)
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 6a77ab1..a00d478 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -104,7 +104,15 @@ typedef struct VAAPIEncodeH264Context { int64_t idr_pic_count; int64_t last_idr_frame; - // RefPicList management. + // Rate control configuration. + struct { + VAEncMiscParameterBuffer misc; + VAEncMiscParameterRateControl rc; + } rc_params; + struct { + VAEncMiscParameterBuffer misc; + VAEncMiscParameterHRD hrd; + } hrd_params; } VAAPIEncodeH264Context; @@ -506,6 +514,14 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) } else { vseq->frame_cropping_flag = 0; } + + vseq->bits_per_second = avctx->bit_rate; + vseq->num_units_in_tick = avctx->time_base.num; + vseq->time_scale = 2 * avctx->time_base.den; + + vseq->intra_period = ctx->p_per_i * (ctx->b_per_p + 1); + vseq->intra_idr_period = vseq->intra_period; + vseq->ip_period = ctx->b_per_p + 1; } { @@ -695,8 +711,6 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) static const VAConfigAttrib default_config_attributes[] = { { .type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420 }, - { .type = VAConfigAttribRateControl, - .value = VA_RC_CQP }, { .type = VAConfigAttribEncPackedHeaders, .value = (VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_SLICE) }, @@ -745,8 +759,6 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) } ctx->va_entrypoint = VAEntrypointEncSlice; - ctx->va_rc_mode = VA_RC_CQP; - ctx->input_width = avctx->width; ctx->input_height = avctx->height; ctx->aligned_width = FFALIGN(ctx->input_width, 16); @@ -754,30 +766,69 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) priv->mb_width = ctx->aligned_width / 16; priv->mb_height = ctx->aligned_height / 16; - if (avctx->bit_rate > 0) { - av_log(avctx, AV_LOG_ERROR, "Constant bitrate encoding is not " - "supported!\n"); - return AVERROR_PATCHWELCOME; - } - for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { ctx->config_attributes[ctx->nb_config_attributes++] = default_config_attributes[i]; } - priv->fixed_qp_p = avctx->global_quality; - if (avctx->i_quant_factor > 0.0) - priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + - avctx->i_quant_offset) + 0.5); - else - priv->fixed_qp_idr = priv->fixed_qp_p; - if (avctx->b_quant_factor > 0.0) - priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor + - avctx->b_quant_offset) + 0.5); - else - priv->fixed_qp_b = priv->fixed_qp_p; - av_log(avctx, AV_LOG_DEBUG, "QP = %d / %d / %d for IDR / P / B frames.\n", - priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); + if (avctx->bit_rate > 0) { + ctx->va_rc_mode = VA_RC_CBR; + + priv->rc_params.misc.type = VAEncMiscParameterTypeRateControl; + priv->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), + .basic_unit_size = 0, + }; + ctx->global_params[ctx->nb_global_params] = + &priv->rc_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(priv->rc_params); + + priv->hrd_params.misc.type = VAEncMiscParameterTypeHRD; + priv->hrd_params.hrd = (VAEncMiscParameterHRD) { + .initial_buffer_fullness = avctx->bit_rate, + .buffer_size = avctx->bit_rate * 2, + }; + ctx->global_params[ctx->nb_global_params] = + &priv->hrd_params.misc; + ctx->global_params_size[ctx->nb_global_params++] = + sizeof(priv->hrd_params); + + // These still need to be set for pic_init_qp/slice_qp_delta. + priv->fixed_qp_idr = 26; + priv->fixed_qp_p = 26; + priv->fixed_qp_b = 26; + + av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n", + avctx->bit_rate); + + } else { + ctx->va_rc_mode = VA_RC_CQP; + + priv->fixed_qp_p = avctx->global_quality; + if (avctx->i_quant_factor > 0.0) + priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor + + avctx->i_quant_offset) + 0.5); + else + priv->fixed_qp_idr = priv->fixed_qp_p; + if (avctx->b_quant_factor > 0.0) + priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor + + avctx->b_quant_offset) + 0.5); + else + priv->fixed_qp_b = priv->fixed_qp_p; + + av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = " + "%d / %d / %d for IDR / P / B frames.\n", + priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b); + } + ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) { + .type = VAConfigAttribRateControl, + .value = ctx->va_rc_mode, + }; ctx->nb_recon_frames = 20; -- 2.8.0.rc3 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel