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?

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

Thanks,

- Mark

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

Reply via email to