[Libva] [Libva-intel-driver][PATCH v3 17/18] Update CBR algo for H.264 per tempolar layer

Xiang, Haihao haihao.xiang at intel.com
Tue Sep 13 08:02:46 UTC 2016


v2: rebased

Signed-off-by: Xiang, Haihao <haihao.xiang at intel.com>
Tested-by: Luo, Focus <focus.luo at intel.com>
---
 src/gen6_mfc.c        |  4 +--
 src/gen6_mfc_common.c | 74 +++++++++++++++++++++++++++++++++------------------
 src/gen6_vme.c        |  2 +-
 src/gen75_mfc.c       |  4 +--
 src/gen75_vme.c       |  4 +--
 src/gen7_vme.c        |  2 +-
 src/gen8_mfc.c        |  4 +--
 src/gen8_vme.c        |  2 +-
 src/gen9_vme.c        |  2 +-
 9 files changed, 60 insertions(+), 38 deletions(-)

diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
index 969c726..8077c14 100644
--- a/src/gen6_mfc.c
+++ b/src/gen6_mfc.c
@@ -799,7 +799,7 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
 
     qp_slice = qp;
     if (rate_control_mode == VA_RC_CBR) {
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         if (encode_state->slice_header_index[slice_index] == 0) {
             pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
             qp_slice = qp;
@@ -1189,7 +1189,7 @@ gen6_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
 
     qp_slice = qp;
     if (rate_control_mode == VA_RC_CBR) {
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         if (encode_state->slice_header_index[slice_index] == 0) {
             pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
             /* Use the adjusted qp when slice_header is generated by driver */
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index ff3e3ae..33226a5 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -174,7 +174,7 @@ int intel_mfc_update_hrd(struct encode_state *encode_state,
         return BRC_UNDERFLOW;
     }
     
-    mfc_context->hrd.current_buffer_fullness += mfc_context->brc.bits_per_frame[0];
+    mfc_context->hrd.current_buffer_fullness += mfc_context->brc.bits_per_frame[encoder_context->layer.curr_frame_layer_id];
     if (mfc_context->hrd.buffer_size > 0 && mfc_context->hrd.current_buffer_fullness > mfc_context->hrd.buffer_size) {
         if (mfc_context->brc.mode == VA_RC_VBR)
             mfc_context->hrd.current_buffer_fullness = mfc_context->hrd.buffer_size;
@@ -194,9 +194,8 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
     gen6_brc_status sts = BRC_NO_HRD_VIOLATION;
     VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer; 
     int slicetype = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
-    int qpi = mfc_context->brc.qp_prime_y[0][SLICE_TYPE_I];
-    int qpp = mfc_context->brc.qp_prime_y[0][SLICE_TYPE_P];
-    int qpb = mfc_context->brc.qp_prime_y[0][SLICE_TYPE_B];
+    int curr_frame_layer_id, next_frame_layer_id;
+    int qpi, qpp, qpb;
     int qp; // quantizer of previously encoded slice of current type
     int qpn; // predicted quantizer for next frame of current type in integer format
     double qpf; // predicted quantizer for next frame of current type in float format
@@ -207,15 +206,41 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
      *  y - how far we are from target HRD buffer fullness
      */
     double x, y;
-    double frame_size_alpha;
+    double frame_size_alpha, factor;
 
-    qp = mfc_context->brc.qp_prime_y[0][slicetype];
+    if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0) {
+        curr_frame_layer_id = 0;
+        next_frame_layer_id = 0;
+    } else {
+        curr_frame_layer_id = encoder_context->layer.curr_frame_layer_id;
+        next_frame_layer_id = encoder_context->layer.frame_layer_ids[encoder_context->num_frames_in_sequence % encoder_context->layer.size_frame_layer_ids];
+    }
+
+    /* checking wthether HRD compliance first */
+    sts = intel_mfc_update_hrd(encode_state, encoder_context, frame_bits);
+
+    if (sts == BRC_NO_HRD_VIOLATION) { // no HRD violation
+        /* nothing */
+    } else {
+        next_frame_layer_id = curr_frame_layer_id;
+    }
+
+    if (encoder_context->layer.num_layers < 2 || encoder_context->layer.size_frame_layer_ids == 0)
+        factor = 1.0;
+    else
+        factor = (double)encoder_context->brc.framerate_per_100s[next_frame_layer_id] / encoder_context->brc.framerate_per_100s[encoder_context->layer.num_layers - 1];
+
+    qpi = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I];
+    qpp = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P];
+    qpb = mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B];
 
-    target_frame_size = mfc_context->brc.target_frame_size[0][slicetype];
+    qp = mfc_context->brc.qp_prime_y[next_frame_layer_id][slicetype];
+
+    target_frame_size = mfc_context->brc.target_frame_size[next_frame_layer_id][slicetype];
     if (mfc_context->hrd.buffer_capacity < 5)
         frame_size_alpha = 0;
     else
-        frame_size_alpha = (double)mfc_context->brc.gop_nums[slicetype];
+        frame_size_alpha = (double)mfc_context->brc.gop_nums[slicetype] * factor;
     if (frame_size_alpha > 30) frame_size_alpha = 30;
     frame_size_next = target_frame_size + (double)(target_frame_size - frame_bits) /
         (double)(frame_size_alpha + 1.);
@@ -244,9 +269,6 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
     /* making sure that with QP predictions we did do not leave QPs range */
     BRC_CLIP(qpn, 1, 51);
 
-    /* checking wthether HRD compliance is still met */
-    sts = intel_mfc_update_hrd(encode_state, encoder_context, frame_bits);
-
     /* calculating QP delta as some function*/
     x = mfc_context->hrd.target_buffer_fullness - mfc_context->hrd.current_buffer_fullness;
     if (x > 0) {
@@ -271,23 +293,23 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
         /* correcting QPs of slices of other types */
         if (slicetype == SLICE_TYPE_P) {
             if (abs(qpn + BRC_P_B_QP_DIFF - qpb) > 2)
-                mfc_context->brc.qp_prime_y[0][SLICE_TYPE_B] += (qpn + BRC_P_B_QP_DIFF - qpb) >> 1;
+                mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B] += (qpn + BRC_P_B_QP_DIFF - qpb) >> 1;
             if (abs(qpn - BRC_I_P_QP_DIFF - qpi) > 2)
-                mfc_context->brc.qp_prime_y[0][SLICE_TYPE_I] += (qpn - BRC_I_P_QP_DIFF - qpi) >> 1;
+                mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I] += (qpn - BRC_I_P_QP_DIFF - qpi) >> 1;
         } else if (slicetype == SLICE_TYPE_I) {
             if (abs(qpn + BRC_I_B_QP_DIFF - qpb) > 4)
-                mfc_context->brc.qp_prime_y[0][SLICE_TYPE_B] += (qpn + BRC_I_B_QP_DIFF - qpb) >> 2;
+                mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B] += (qpn + BRC_I_B_QP_DIFF - qpb) >> 2;
             if (abs(qpn + BRC_I_P_QP_DIFF - qpp) > 2)
-                mfc_context->brc.qp_prime_y[0][SLICE_TYPE_P] += (qpn + BRC_I_P_QP_DIFF - qpp) >> 2;
+                mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P] += (qpn + BRC_I_P_QP_DIFF - qpp) >> 2;
         } else { // SLICE_TYPE_B
             if (abs(qpn - BRC_P_B_QP_DIFF - qpp) > 2)
-                mfc_context->brc.qp_prime_y[0][SLICE_TYPE_P] += (qpn - BRC_P_B_QP_DIFF - qpp) >> 1;
+                mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P] += (qpn - BRC_P_B_QP_DIFF - qpp) >> 1;
             if (abs(qpn - BRC_I_B_QP_DIFF - qpi) > 4)
-                mfc_context->brc.qp_prime_y[0][SLICE_TYPE_I] += (qpn - BRC_I_B_QP_DIFF - qpi) >> 2;
+                mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I] += (qpn - BRC_I_B_QP_DIFF - qpi) >> 2;
         }
-        BRC_CLIP(mfc_context->brc.qp_prime_y[0][SLICE_TYPE_I], 1, 51);
-        BRC_CLIP(mfc_context->brc.qp_prime_y[0][SLICE_TYPE_P], 1, 51);
-        BRC_CLIP(mfc_context->brc.qp_prime_y[0][SLICE_TYPE_B], 1, 51);
+        BRC_CLIP(mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_I], 1, 51);
+        BRC_CLIP(mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_P], 1, 51);
+        BRC_CLIP(mfc_context->brc.qp_prime_y[next_frame_layer_id][SLICE_TYPE_B], 1, 51);
     } else if (sts == BRC_UNDERFLOW) { // underflow
         if (qpn <= qp) qpn = qp + 1;
         if (qpn > 51) {
@@ -302,7 +324,7 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
         }
     }
 
-    mfc_context->brc.qp_prime_y[0][slicetype] = qpn;
+    mfc_context->brc.qp_prime_y[next_frame_layer_id][slicetype] = qpn;
 
     return sts;
 }
@@ -312,7 +334,7 @@ static void intel_mfc_hrd_context_init(struct encode_state *encode_state,
 {
     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
     unsigned int rate_control_mode = encoder_context->rate_control_mode;
-    int target_bit_rate = encoder_context->brc.bits_per_second[0];
+    int target_bit_rate = encoder_context->brc.bits_per_second[encoder_context->layer.num_layers - 1];
     
     // current we only support CBR mode.
     if (rate_control_mode == VA_RC_CBR) {
@@ -821,7 +843,7 @@ void intel_vme_update_mbmv_cost(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     if (vme_state_message == NULL)
         return;
@@ -850,7 +872,7 @@ void intel_vme_vp8_update_mbmv_cost(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = q_matrix->quantization_index[0];
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     lambda = intel_lambda_qp(qp * QP_MAX / VP8_QP_MAX);
 
@@ -979,7 +1001,7 @@ gen7_vme_walker_fill_vme_batchbuffer(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
 #define		USE_SCOREBOARD		(1 << 21)
  
@@ -1932,7 +1954,7 @@ intel_h264_enc_roi_config(VADriverContextP ctx,
         int qp;
         int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
 
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         intel_h264_enc_roi_cbr(ctx, qp, pParamROI,encode_state, encoder_context);
 
     } else if (encoder_context->rate_control_mode == VA_RC_CQP){
diff --git a/src/gen6_vme.c b/src/gen6_vme.c
index fb04749..97dc3c9 100644
--- a/src/gen6_vme.c
+++ b/src/gen6_vme.c
@@ -369,7 +369,7 @@ static void gen6_vme_state_setup_fixup(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         vme_state_message[16] = intra_mb_mode_cost_table[pic_param->pic_init_qp + slice_param->slice_qp_delta];
     else
-        vme_state_message[16] = intra_mb_mode_cost_table[mfc_context->brc.qp_prime_y[0][SLICE_TYPE_I]];
+        vme_state_message[16] = intra_mb_mode_cost_table[mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][SLICE_TYPE_I]];
 }
 
 static VAStatus gen6_vme_vme_state_setup(VADriverContextP ctx,
diff --git a/src/gen75_mfc.c b/src/gen75_mfc.c
index 2d6baa6..0fbbe76 100644
--- a/src/gen75_mfc.c
+++ b/src/gen75_mfc.c
@@ -1175,7 +1175,7 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
 
     qp_slice = qp;
     if (rate_control_mode == VA_RC_CBR) {
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         if (encode_state->slice_header_index[slice_index] == 0) {
             pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
             qp_slice = qp;
@@ -1522,7 +1522,7 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
 
     qp_slice = qp;
     if (rate_control_mode == VA_RC_CBR) {
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         if (encode_state->slice_header_index[slice_index] == 0) {
             pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
             qp_slice = qp;
diff --git a/src/gen75_vme.c b/src/gen75_vme.c
index 9223f68..79b1e23 100644
--- a/src/gen75_vme.c
+++ b/src/gen75_vme.c
@@ -441,7 +441,7 @@ static void gen75_vme_state_setup_fixup(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         vme_state_message[0] = intra_mb_mode_cost_table[pic_param->pic_init_qp + slice_param->slice_qp_delta];
     else
-        vme_state_message[0] = intra_mb_mode_cost_table[mfc_context->brc.qp_prime_y[0][SLICE_TYPE_I]];
+        vme_state_message[0] = intra_mb_mode_cost_table[mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][SLICE_TYPE_I]];
 }
 
 static VAStatus gen75_vme_vme_state_setup(VADriverContextP ctx,
@@ -504,7 +504,7 @@ gen75_vme_fill_vme_batchbuffer(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
diff --git a/src/gen7_vme.c b/src/gen7_vme.c
index 7530d19..0362680 100644
--- a/src/gen7_vme.c
+++ b/src/gen7_vme.c
@@ -560,7 +560,7 @@ gen7_vme_fill_vme_batchbuffer(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c
index ef553fb..e4506b6 100644
--- a/src/gen8_mfc.c
+++ b/src/gen8_mfc.c
@@ -1178,7 +1178,7 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
 
     qp_slice = qp;
     if (rate_control_mode == VA_RC_CBR) {
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         if (encode_state->slice_header_index[slice_index] == 0) {
             pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
             qp_slice = qp;
@@ -1535,7 +1535,7 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
 
     qp_slice = qp;
     if (rate_control_mode == VA_RC_CBR) {
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
         if (encode_state->slice_header_index[slice_index] == 0) {
             pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
             qp_slice = qp;
diff --git a/src/gen8_vme.c b/src/gen8_vme.c
index 5ad0243..c79c62b 100644
--- a/src/gen8_vme.c
+++ b/src/gen8_vme.c
@@ -575,7 +575,7 @@ gen8_vme_fill_vme_batchbuffer(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
diff --git a/src/gen9_vme.c b/src/gen9_vme.c
index 6382567..d7262cd 100644
--- a/src/gen9_vme.c
+++ b/src/gen9_vme.c
@@ -623,7 +623,7 @@ gen9_vme_fill_vme_batchbuffer(VADriverContextP ctx,
     if (encoder_context->rate_control_mode == VA_RC_CQP)
         qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
     else
-        qp = mfc_context->brc.qp_prime_y[0][slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
-- 
1.9.1



More information about the Libva mailing list