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