[Libva] [Libva-intel-driver][PATCH 04/18] Check bitrate control related parameters in sequence and misc parameters

Zhao Yakui yakui.zhao at intel.com
Wed Sep 7 03:23:22 UTC 2016


On 09/06/2016 11:41 PM, Xiang, Haihao wrote:
> Currently only used for H.264 encoding
>
> Signed-off-by: Xiang, Haihao<haihao.xiang at intel.com>
> ---
>   src/i965_encoder.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++--
>   src/i965_encoder.h |  12 ++++
>   2 files changed, 190 insertions(+), 6 deletions(-)
>
> diff --git a/src/i965_encoder.c b/src/i965_encoder.c
> index d045881..50f735a 100644
> --- a/src/i965_encoder.c
> +++ b/src/i965_encoder.c
> @@ -293,10 +293,179 @@ intel_encoder_check_jpeg_yuv_surface(VADriverContextP ctx,
>   }
>
>   static VAStatus
> +intel_encoder_check_brc_h264_sequence_parameter(VADriverContextP ctx,
> +                                                struct encode_state *encode_state,
> +                                                struct intel_encoder_context *encoder_context)
> +{
> +    VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
> +    unsigned short num_pframes_in_gop, num_bframes_in_gop;
> +    unsigned int bits_per_second, framerate_per_100s;
> +
> +    if (!encoder_context->is_new_sequence)
> +        return VA_STATUS_SUCCESS;
> +
> +    assert(seq_param);
> +    bits_per_second = seq_param->bits_per_second;
> +    framerate_per_100s = seq_param->time_scale * 100 / (2 * seq_param->num_units_in_tick);
> +    encoder_context->brc.num_iframes_in_gop = 1; // Always 1
> +
> +    if (seq_param->intra_period == 0) { // E.g. IDRPP... / IDR(PBB)... (no IDR/I any more)
> +        if (seq_param->ip_period == 0)
> +            goto error;
> +
> +        encoder_context->brc.gop_size = (unsigned int)(framerate_per_100s / 100.0 + 0.5); // fake
> +        num_pframes_in_gop = (encoder_context->brc.gop_size +
> +                              seq_param->ip_period - 1) / seq_param->ip_period - 1;
> +    } else if (seq_param->intra_period == 1) { // E.g. IDRIII...
> +        encoder_context->brc.gop_size = 1;
> +        num_pframes_in_gop = 0;
> +    } else {
> +        if (seq_param->ip_period == 0)
> +            goto error;
> +
> +        encoder_context->brc.gop_size = seq_param->intra_period;
> +        num_pframes_in_gop = (encoder_context->brc.gop_size +
> +                              seq_param->ip_period - 1) / seq_param->ip_period - 1;
> +    }
> +
> +    num_bframes_in_gop = (encoder_context->brc.gop_size -
> +                          encoder_context->brc.num_iframes_in_gop - num_pframes_in_gop);
> +
> +    if (num_pframes_in_gop != encoder_context->brc.num_pframes_in_gop ||
> +        num_bframes_in_gop != encoder_context->brc.num_bframes_in_gop ||
> +        bits_per_second != encoder_context->brc.bits_per_second ||
> +        framerate_per_100s != encoder_context->brc.framerate_per_100s) {
> +        encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
> +        encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
> +        encoder_context->brc.bits_per_second = bits_per_second;
> +        encoder_context->brc.framerate_per_100s = framerate_per_100s;
> +        encoder_context->brc.need_reset = 1;
> +    }
> +
> +    if (!encoder_context->brc.hrd_buffer_size ||
> +        !encoder_context->brc.hrd_initial_buffer_fullness) {
> +        encoder_context->brc.hrd_buffer_size = seq_param->bits_per_second<<  1;
> +        encoder_context->brc.hrd_initial_buffer_fullness = seq_param->bits_per_second;
> +    }
> +
> +    return VA_STATUS_SUCCESS;
> +
> +error:
> +    return VA_STATUS_ERROR_INVALID_PARAMETER;
> +}
> +
> +static VAStatus
> +intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
> +                                           struct encode_state *encode_state,
> +                                           struct intel_encoder_context *encoder_context)
> +{
> +    if (encoder_context->codec == CODEC_H264 ||
> +        encoder_context->codec == CODEC_H264_MVC)
> +        return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context);
> +
> +    // TODO: other codecs
> +    return VA_STATUS_SUCCESS;
> +}
> +
> +static void
> +intel_encoder_check_rate_control_parameter(VADriverContextP ctx,
> +                                           struct intel_encoder_context *encoder_context,
> +                                           VAEncMiscParameterRateControl *misc)
> +{
> +    // TODO: for VBR
> +    if (encoder_context->brc.bits_per_second != misc->bits_per_second) {
> +        encoder_context->brc.bits_per_second = misc->bits_per_second;
> +        encoder_context->brc.need_reset = 1;
> +    }
> +}
> +
> +static void
> +intel_encoder_check_hrd_parameter(VADriverContextP ctx,
> +                                  struct intel_encoder_context *encoder_context,
> +                                  VAEncMiscParameterHRD *misc)
> +{
> +    if (encoder_context->brc.hrd_buffer_size != misc->buffer_size ||
> +        encoder_context->brc.hrd_initial_buffer_fullness != misc->initial_buffer_fullness) {
> +        encoder_context->brc.hrd_buffer_size = misc->buffer_size;
> +        encoder_context->brc.hrd_initial_buffer_fullness = misc->initial_buffer_fullness;
> +        encoder_context->brc.need_reset = 1;
> +    }
> +}
> +
> +static void
> +intel_encoder_check_framerate_parameter(VADriverContextP ctx,
> +                                        struct intel_encoder_context *encoder_context,
> +                                        VAEncMiscParameterFrameRate *misc)
> +{
> +    int framerate_per_100s;
> +
> +    if (misc->framerate&  0xffff0000)
> +        framerate_per_100s = (misc->framerate&  0xffff) * 100 / ((misc->framerate>>  16)&  0xffff);
> +    else
> +        framerate_per_100s = misc->framerate * 100;
> +
> +    if (encoder_context->brc.framerate_per_100s != framerate_per_100s) {
> +        encoder_context->brc.framerate_per_100s = framerate_per_100s;
> +        encoder_context->brc.need_reset = 1;
> +    }
> +}
> +
> +static VAStatus
> +intel_encoder_check_brc_parameter(VADriverContextP ctx,
> +                                  struct encode_state *encode_state,
> +                                  struct intel_encoder_context *encoder_context)
> +{
> +    VAStatus ret;
> +    VAEncMiscParameterBuffer *misc_param;
> +    int i;
> +
> +    if (!(encoder_context->rate_control_mode&  (VA_RC_CBR | VA_RC_VBR)))
> +        return VA_STATUS_SUCCESS;
> +
> +    ret = intel_encoder_check_brc_sequence_parameter(ctx, encode_state, encoder_context);
> +
> +    if (ret)
> +        return ret;
> +
> +    for (i = 0; i<  ARRAY_ELEMS(encode_state->misc_param); i++) {
> +        if (!encode_state->misc_param[i] || !encode_state->misc_param[i]->buffer)
> +            continue;
> +
> +        misc_param = (VAEncMiscParameterBuffer *)encode_state->misc_param[i]->buffer;
> +
> +        switch (misc_param->type) {
> +        case VAEncMiscParameterTypeFrameRate:
> +            intel_encoder_check_framerate_parameter(ctx,
> +                                                    encoder_context,
> +                                                    (VAEncMiscParameterFrameRate *)misc_param->data);
> +            break;
> +
> +        case VAEncMiscParameterTypeRateControl:
> +            intel_encoder_check_rate_control_parameter(ctx,
> +                                                       encoder_context,
> +                                                       (VAEncMiscParameterRateControl *)misc_param->data);
> +            break;
> +
> +        case VAEncMiscParameterTypeHRD:
> +            intel_encoder_check_hrd_parameter(ctx,
> +                                              encoder_context,
> +                                              (VAEncMiscParameterHRD *)misc_param->data);
> +            break;
> +
> +        default:
> +            break;
> +        }
> +    }
> +
> +    return VA_STATUS_SUCCESS;
> +}
> +
> +static VAStatus
>   intel_encoder_check_misc_parameter(VADriverContextP ctx,
>                                     struct encode_state *encode_state,
>                                     struct intel_encoder_context *encoder_context)
>   {
> +    VAStatus ret = VA_STATUS_SUCCESS;
>
>       if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]&&
>           encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer) {
> @@ -306,14 +475,16 @@ intel_encoder_check_misc_parameter(VADriverContextP ctx,
>
>           if (encoder_context->quality_level == 0)
>               encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
> -        else if (encoder_context->quality_level>  encoder_context->quality_range)
> -            goto error;
> -   }
> +        else if (encoder_context->quality_level>  encoder_context->quality_range) {
> +            ret = VA_STATUS_ERROR_INVALID_PARAMETER;
> +            goto out;
> +        }
> +    }
>
> -    return VA_STATUS_SUCCESS;
> +    ret = intel_encoder_check_brc_parameter(ctx, encode_state, encoder_context);
>
> -error:
> -    return VA_STATUS_ERROR_INVALID_PARAMETER;
> +out:
> +    return ret;
>   }
>
>   static VAStatus
> @@ -782,6 +953,7 @@ intel_encoder_end_picture(VADriverContextP ctx,
>
>       encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
>       encoder_context->num_frames_in_sequence++;
> +    encoder_context->brc.need_reset = 0;
>
>       return VA_STATUS_SUCCESS;
>   }
> diff --git a/src/i965_encoder.h b/src/i965_encoder.h
> index de20ef9..808a336 100644
> --- a/src/i965_encoder.h
> +++ b/src/i965_encoder.h
> @@ -63,6 +63,18 @@ struct intel_encoder_context
>       unsigned int frame_width_in_mbs;
>       unsigned int frame_height_in_mbs;
>
> +    struct {
> +        unsigned short gop_size;
> +        unsigned short num_iframes_in_gop;
> +        unsigned short num_pframes_in_gop;
> +        unsigned short num_bframes_in_gop;
> +        unsigned int bits_per_second;
> +        unsigned int framerate_per_100s;
> +        unsigned int hrd_buffer_size;
> +        unsigned int hrd_initial_buffer_fullness;
> +        unsigned int need_reset;
> +    } brc;
> +

how about naming it as h264_brc? It seems that the above definition is 
mainly for the H264 encoding.
For the other codec it will use the different definition.

Another small concern is which bit_rate should be used if both the SPS 
and Misc_rateControl define the bit-rate?

Thanks
     Yakui

>       void *vme_context;
>       void *mfc_context;
>       void *enc_priv_state;



More information about the Libva mailing list