[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