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?

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

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

Reply via email to