> On 09/06/2016 11:41 PM, Xiang, Haihao wrote: > > Currently only used for H.264 encoding > > > > Signed-off-by: Xiang, Haihao<[email protected]> > > --- > > 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, > > + VAEncMiscParameterRateC > > ontrol *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, > > + VAEncMiscParameterFrameRat > > e *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_contex > > t, > > + (VAEncMiscPara > > meterFrameRate *)misc_param->data); > > + break; > > + > > + case VAEncMiscParameterTypeRateControl: > > + intel_encoder_check_rate_control_parameter(ctx, > > + encoder_con > > text, > > + (VAEncMiscP > > arameterRateControl *)misc_param->data); > > + break; > > + > > + case VAEncMiscParameterTypeHRD: > > + intel_encoder_check_hrd_parameter(ctx, > > + encoder_context, > > + (VAEncMiscParameterH > > RD *)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.
Other codec also use similar variables in our driver, if a variable e.g. num_bframes_in_gop is not used for VP8/VP9, we can set it to 0 or ignore it. > > Another small concern is which bit_rate should be used if both the > SPS > and Misc_rateControl define the bit-rate? According to the comment for bits_per_second in va_enc_xxx.h, the initial bitrate value is specified by bits_per_second in SPS, but it can be modified later by VAEncMiscParameterRateControl. So both SPS and VAEncMiscParameterRateControl define the bit-rate, the latter should be used. > > Thanks > Yakui > > > void *vme_context; > > void *mfc_context; > > void *enc_priv_state; > _______________________________________________ Libva mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libva
