On Sun, Apr 10, 2016 at 9:49 AM, Anton Khirnov <an...@khirnov.net> wrote: > 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.
Thats what we call ABR. VBR generally has no bitrate hints but a quality metric of some sort. >> + 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 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel