[Libva] [LIBVA-INTEL-DRIVER][PATCH 11/12] Add the support of CBR/VBR for Vp9 Encoding
Zhao Yakui
yakui.zhao at intel.com
Tue May 24 12:00:37 UTC 2016
Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Reviewed-by: Sean V Kelley <sean.v.kelley at intel.com>
---
src/gen9_vp9_encoder.c | 176 +++++++++++++++++++++++++++++++++++++++++++++----
src/gen9_vp9_encoder.h | 2 +
2 files changed, 165 insertions(+), 13 deletions(-)
diff --git a/src/gen9_vp9_encoder.c b/src/gen9_vp9_encoder.c
index 0351324..e6b1543 100644
--- a/src/gen9_vp9_encoder.c
+++ b/src/gen9_vp9_encoder.c
@@ -3858,22 +3858,170 @@ gen9_encode_vp9_check_parameter(VADriverContextP ctx,
return VA_STATUS_ERROR_UNIMPLEMENTED;
if (vp9_state->brc_enabled) {
- if (!vp9_state->target_bit_rate && seq_param) {
- vp9_state->brc_reset = 1;
- vp9_state->target_bit_rate = seq_param->bits_per_second;
- vp9_state->gop_size = seq_param->intra_period;
+ if (vp9_state->brc_flag_check & VP9_BRC_FAILURE) {
+ WARN_ONCE("Rate control misc_parameter is required for BRC\n");
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
}
- if (vp9_state->target_bit_rate != seq_param->bits_per_second) {
- vp9_state->brc_reset = 1;
- vp9_state->target_bit_rate = seq_param->bits_per_second;
- }
- if (vp9_state->gop_size != seq_param->intra_period) {
- vp9_state->brc_reset = 1;
- vp9_state->gop_size = seq_param->intra_period;
+ if (vp9_state->first_frame) {
+ unsigned int brc_flag;
+ VAEncMiscParameterBuffer *misc_param;
+
+ brc_flag = VP9_BRC_SEQ | VP9_BRC_RC;
+ if ((vp9_state->brc_flag_check & brc_flag) != brc_flag) {
+ WARN_ONCE("SPS/RC misc is required for BRC\n");
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check the corresponding BRC parameter for CBR and VBR */
+ if (encoder_context->rate_control_mode == VA_RC_CBR) {
+ vp9_state->target_bit_rate = seq_param->bits_per_second;
+ vp9_state->gop_size = seq_param->intra_period;
+
+ if (vp9_state->brc_flag_check & VP9_BRC_HRD) {
+ VAEncMiscParameterHRD *misc_param_hrd;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeHRD]->buffer;
+ misc_param_hrd = (VAEncMiscParameterHRD *)misc_param->data;
+
+ vp9_state->init_vbv_buffer_fullness_in_bit = misc_param_hrd->initial_buffer_fullness;
+ vp9_state->vbv_buffer_size_in_bit = misc_param_hrd->buffer_size;
+ }
+
+ if (vp9_state->brc_flag_check & VP9_BRC_FR) {
+ VAEncMiscParameterFrameRate *misc_param_fr;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeFrameRate]->buffer;
+ misc_param_fr = (VAEncMiscParameterFrameRate *)misc_param->data;
+
+ vp9_state->frame_rate = misc_param_fr->framerate;
+ } else {
+ /* Assign the default frame rate */
+ vp9_state->frame_rate = 30;
+ }
+
+ /* RC misc will override HRD parameter */
+ if (vp9_state->brc_flag_check & VP9_BRC_RC) {
+ VAEncMiscParameterRateControl *misc_param_rc;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeRateControl]->buffer;
+ misc_param_rc = (VAEncMiscParameterRateControl *)misc_param->data;
+
+ vp9_state->target_bit_rate = misc_param_rc->bits_per_second;
+ vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
+ misc_param_rc->window_size;
+ vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
+ vp9_state->window_size = misc_param_rc->window_size;
+ }
+ vp9_state->max_bit_rate = vp9_state->target_bit_rate;
+ vp9_state->min_bit_rate = vp9_state->target_bit_rate;
+ } else {
+ /* VBR mode */
+ brc_flag = VP9_BRC_SEQ | VP9_BRC_RC;
+ vp9_state->target_bit_rate = seq_param->bits_per_second;
+ vp9_state->gop_size = seq_param->intra_period;
+
+ if (vp9_state->brc_flag_check & VP9_BRC_FR) {
+ VAEncMiscParameterFrameRate *misc_param_fr;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeFrameRate]->buffer;
+ misc_param_fr = (VAEncMiscParameterFrameRate *)misc_param->data;
+
+ vp9_state->frame_rate = misc_param_fr->framerate;
+ } else {
+ /* Assign the default frame rate */
+ vp9_state->frame_rate = 30;
+ }
+
+ if (vp9_state->brc_flag_check & VP9_BRC_RC) {
+ VAEncMiscParameterRateControl *misc_param_rc;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeRateControl]->buffer;
+ misc_param_rc = (VAEncMiscParameterRateControl *)misc_param->data;
+
+ vp9_state->max_bit_rate = misc_param_rc->bits_per_second;
+ vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
+ misc_param_rc->window_size;
+ vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
+ vp9_state->target_bit_rate = (misc_param_rc->bits_per_second / 100) *
+ misc_param_rc->target_percentage;
+ vp9_state->min_bit_rate = (misc_param_rc->bits_per_second / 100) *
+ (2 * misc_param_rc->target_percentage - 100);
+ vp9_state->target_percentage = misc_param_rc->target_percentage;
+ vp9_state->window_size = misc_param_rc->window_size;
+ }
+ }
}
+ else if (vp9_state->picture_coding_type == KEY_FRAME){
+ VAEncMiscParameterBuffer *misc_param;
+ /* update the BRC parameter only when it is key-frame */
+ /* If the parameter related with RC is changed. Reset BRC */
+ if (vp9_state->brc_flag_check & VP9_BRC_FR) {
+ VAEncMiscParameterFrameRate *misc_param_fr;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeFrameRate]->buffer;
+ misc_param_fr = (VAEncMiscParameterFrameRate *)misc_param->data;
+
+ if (vp9_state->frame_rate != misc_param_fr->framerate) {
+ vp9_state->brc_reset = 1;
+ vp9_state->frame_rate = misc_param_fr->framerate;
+ }
+ }
+
+ /* check the GOP size. And bit_per_second in SPS is ignored */
+ if (vp9_state->brc_flag_check & VP9_BRC_SEQ) {
+ if (vp9_state->gop_size != seq_param->intra_period) {
+ vp9_state->brc_reset = 1;
+ vp9_state->gop_size = seq_param->intra_period;
+ }
+ }
- /* check Misc Rate_Control, Frame_rate buffer */
+ /* update the bit_per_second */
+ if (vp9_state->brc_flag_check & VP9_BRC_RC) {
+ VAEncMiscParameterRateControl *misc_param_rc;
+
+ misc_param = (VAEncMiscParameterBuffer *)
+ encode_state->misc_param[VAEncMiscParameterTypeRateControl]->buffer;
+ misc_param_rc = (VAEncMiscParameterRateControl *)misc_param->data;
+
+ if (encoder_context->rate_control_mode == VA_RC_CBR) {
+ if (vp9_state->target_bit_rate != misc_param_rc->bits_per_second ||
+ vp9_state->window_size != misc_param_rc->window_size) {
+ vp9_state->target_bit_rate = misc_param_rc->bits_per_second;
+ vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
+ misc_param_rc->window_size;
+ vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit * 2;
+ vp9_state->window_size = misc_param_rc->window_size;
+ vp9_state->max_bit_rate = vp9_state->target_bit_rate;
+ vp9_state->min_bit_rate = vp9_state->target_bit_rate;
+ vp9_state->brc_reset = 1;
+ }
+ } else {
+ /* VBR mode */
+ if (vp9_state->max_bit_rate != misc_param_rc->bits_per_second ||
+ vp9_state->target_percentage != misc_param_rc->target_percentage) {
+
+ vp9_state->target_bit_rate = (misc_param_rc->bits_per_second / 100) *
+ misc_param_rc->target_percentage;
+ vp9_state->min_bit_rate = (misc_param_rc->bits_per_second / 100) *
+ (2 * misc_param_rc->target_percentage - 100);
+ vp9_state->max_bit_rate = misc_param_rc->bits_per_second;
+ vp9_state->vbv_buffer_size_in_bit = (misc_param_rc->bits_per_second / 1000) *
+ misc_param_rc->window_size;
+ vp9_state->init_vbv_buffer_fullness_in_bit = vp9_state->vbv_buffer_size_in_bit / 2;
+ vp9_state->target_percentage = misc_param_rc->target_percentage;
+ vp9_state->window_size = misc_param_rc->window_size;
+ vp9_state->brc_reset = 1;
+ }
+ }
+ }
+ }
}
vp9_state->frame_width = pic_param->frame_width_dst;
@@ -3960,7 +4108,8 @@ gen9_encode_vp9_check_parameter(VADriverContextP ctx,
vp9_state->b16xme_enabled = 0;
}
- if (vp9_state->picture_coding_type &&
+ vp9_state->mbenc_keyframe_dist_enabled = 0;
+ if ((vp9_state->picture_coding_type == KEY_FRAME) &&
vp9_state->brc_distortion_buffer_supported)
vp9_state->mbenc_keyframe_dist_enabled = 1;
@@ -5706,6 +5855,7 @@ gen9_vp9_pak_pipeline(VADriverContextP ctx,
vp9_state->vp9_last_frame.intra_only = pic_param->pic_flags.bits.intra_only;
vp9_state->frame_number++;
vp9_state->curr_mv_temporal_index ^= 1;
+ vp9_state->first_frame = 0;
return VA_STATUS_SUCCESS;
}
diff --git a/src/gen9_vp9_encoder.h b/src/gen9_vp9_encoder.h
index 865ada1..ccc9f80 100644
--- a/src/gen9_vp9_encoder.h
+++ b/src/gen9_vp9_encoder.h
@@ -1927,6 +1927,8 @@ struct gen9_vp9_state {
unsigned int adaptive_transform_decision_enabled;
int curr_mode_decision_index;
int target_usage;
+ int window_size;
+ int target_percentage;
unsigned int mb_data_offset;
int curr_pak_pass;
unsigned int brc_flag_check;
--
1.8.2.1
More information about the Libva
mailing list