On 10/04/16 09:24, Anton Khirnov wrote: > Quoting Mark Thompson (2016-04-10 10:18:26) >> On 10/04/16 08:49, Anton Khirnov 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. >> >> It's CBR (with a single bitrate control) or nothing, I'm afraid. Would you >> prefer it to reject the setting? > > I see VA_RC_VBR in va.h. Or does that not work? >
Only CBR and CQP work in the Intel driver at the moment. I could change it to actually test what is supported via vaQueryConfigAttributes(), but then what do we do if the user gives just bit_rate and CBR is the only allowed mode? >>>> + 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, >>>> + }; >> >> (Note that the Intel driver ignores these parameters entirely. I include >> them to match the libva example encoder.) >> >>>> + 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? >>> >> >> Sure. Do these have sensible defaults, so I expect "-b 8M" or whatever to >> still work in isolation, or will I need a bit more code to make it do the >> right thing? > > initial_buffer_occupancy defaults to 3/4 of the buffer size, but the > buffer size defaults to zero. So I guess you'll have to handle the > defaults explicitly. Ok, will add. _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel