Quoting Mark Thompson (2016-04-09 18:16:02)
> ---
>  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) {

Strictly speaking, it should be CBR only if maxrate and minrate are also
set and equal to the bitrate. Otherwise it should be VBR with the given
average bitrate. 

> +        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,

rc_initial_buffer_occupancy?

> +            .buffer_size             = avctx->bit_rate * 2,

rc_buffer_size?

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to