OSDN Git Service

Update CBR algo for H.264 per tempolar layer
[android-x86/hardware-intel-common-vaapi.git] / src / gen6_mfc_common.c
index 1641db6..33226a5 100644 (file)
@@ -94,34 +94,22 @@ static void intel_mfc_brc_init(struct encode_state *encode_state,
                                struct intel_encoder_context* encoder_context)
 {
     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
-    double bitrate = encoder_context->brc.bits_per_second[0];
-    double framerate = (double)encoder_context->brc.framerate_per_100s[0] / 100.0;
+    double bitrate, framerate;
+    double qp1_size = 0.1 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
+    double qp51_size = 0.001 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
+    double bpf, factor;
     int inum = encoder_context->brc.num_iframes_in_gop,
         pnum = encoder_context->brc.num_pframes_in_gop,
         bnum = encoder_context->brc.num_bframes_in_gop; /* Gop structure: number of I, P, B frames in the Gop. */
     int intra_period = encoder_context->brc.gop_size;
-    double qp1_size = 0.1 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
-    double qp51_size = 0.001 * 8 * 3 * encoder_context->frame_width_in_pixel * encoder_context->frame_height_in_pixel / 2;
-    double bpf;
     int i;
 
     mfc_context->brc.mode = encoder_context->rate_control_mode;
 
-    for (i = 0; i < 3; i++) {
-        mfc_context->brc.qp_prime_y[i] = 26;
-    }
-
-    mfc_context->brc.target_frame_size[SLICE_TYPE_I] = (int)((double)((bitrate * intra_period)/framerate) /
-                                                             (double)(inum + BRC_PWEIGHT * pnum + BRC_BWEIGHT * bnum));
-    mfc_context->brc.target_frame_size[SLICE_TYPE_P] = BRC_PWEIGHT * mfc_context->brc.target_frame_size[SLICE_TYPE_I];
-    mfc_context->brc.target_frame_size[SLICE_TYPE_B] = BRC_BWEIGHT * mfc_context->brc.target_frame_size[SLICE_TYPE_I];
-
     mfc_context->brc.gop_nums[SLICE_TYPE_I] = inum;
     mfc_context->brc.gop_nums[SLICE_TYPE_P] = pnum;
     mfc_context->brc.gop_nums[SLICE_TYPE_B] = bnum;
 
-    bpf = mfc_context->brc.bits_per_frame = bitrate/framerate;
-
     mfc_context->hrd.buffer_size = encoder_context->brc.hrd_buffer_size;
     mfc_context->hrd.current_buffer_fullness =
         (double)(encoder_context->brc.hrd_initial_buffer_fullness < mfc_context->hrd.buffer_size) ?
@@ -130,26 +118,53 @@ static void intel_mfc_brc_init(struct encode_state *encode_state,
     mfc_context->hrd.buffer_capacity = (double)mfc_context->hrd.buffer_size/qp1_size;
     mfc_context->hrd.violation_noted = 0;
 
-    if ((bpf > qp51_size) && (bpf < qp1_size)) {
-        mfc_context->brc.qp_prime_y[SLICE_TYPE_P] = 51 - 50*(bpf - qp51_size)/(qp1_size - qp51_size);
-    }
-    else if (bpf >= qp1_size)
-        mfc_context->brc.qp_prime_y[SLICE_TYPE_P] = 1;
-    else if (bpf <= qp51_size)
-        mfc_context->brc.qp_prime_y[SLICE_TYPE_P] = 51;
+    for (i = 0; i < encoder_context->layer.num_layers; i++) {
+        mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I] = 26;
+        mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 26;
+        mfc_context->brc.qp_prime_y[i][SLICE_TYPE_B] = 26;
+
+        if (i == 0) {
+            bitrate = encoder_context->brc.bits_per_second[0];
+            framerate = (double)encoder_context->brc.framerate_per_100s[0] / 100.0;
+        } else {
+            bitrate = (encoder_context->brc.bits_per_second[i] - encoder_context->brc.bits_per_second[i - 1]);
+            framerate = (double)(encoder_context->brc.framerate_per_100s[i] - encoder_context->brc.framerate_per_100s[i - 1]) / 100.0;
+        }
+
+        if (i == encoder_context->layer.num_layers - 1)
+            factor = 1.0;
+        else
+            factor = (double)encoder_context->brc.framerate_per_100s[i] / encoder_context->brc.framerate_per_100s[i + 1];
+
+        mfc_context->brc.target_frame_size[i][SLICE_TYPE_I] = (int)((double)((bitrate * intra_period * factor)/framerate) /
+                                                                    (double)(inum + BRC_PWEIGHT * pnum * factor + BRC_BWEIGHT * bnum * factor));
+        mfc_context->brc.target_frame_size[i][SLICE_TYPE_P] = BRC_PWEIGHT * mfc_context->brc.target_frame_size[i][SLICE_TYPE_I];
+        mfc_context->brc.target_frame_size[i][SLICE_TYPE_B] = BRC_BWEIGHT * mfc_context->brc.target_frame_size[i][SLICE_TYPE_I];
+
+        bpf = mfc_context->brc.bits_per_frame[i] = bitrate/framerate;
+
+        if ((bpf > qp51_size) && (bpf < qp1_size)) {
+            mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 51 - 50*(bpf - qp51_size)/(qp1_size - qp51_size);
+        }
+        else if (bpf >= qp1_size)
+            mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 1;
+        else if (bpf <= qp51_size)
+            mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P] = 51;
 
-    mfc_context->brc.qp_prime_y[SLICE_TYPE_I] = mfc_context->brc.qp_prime_y[SLICE_TYPE_P];
-    mfc_context->brc.qp_prime_y[SLICE_TYPE_B] = mfc_context->brc.qp_prime_y[SLICE_TYPE_I];
+        mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I] = mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P];
+        mfc_context->brc.qp_prime_y[i][SLICE_TYPE_B] = mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I];
 
-    BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_I], 1, 51);
-    BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_P], 1, 51);
-    BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_B], 1, 51);
+        BRC_CLIP(mfc_context->brc.qp_prime_y[i][SLICE_TYPE_I], 1, 51);
+        BRC_CLIP(mfc_context->brc.qp_prime_y[i][SLICE_TYPE_P], 1, 51);
+        BRC_CLIP(mfc_context->brc.qp_prime_y[i][SLICE_TYPE_B], 1, 51);
+    }
 }
 
 int intel_mfc_update_hrd(struct encode_state *encode_state,
-                         struct gen6_mfc_context *mfc_context,
+                         struct intel_encoder_context *encoder_context,
                          int frame_bits)
 {
+    struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
     double prev_bf = mfc_context->hrd.current_buffer_fullness;
 
     mfc_context->hrd.current_buffer_fullness -= frame_bits;
@@ -159,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;
+    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;
@@ -172,15 +187,15 @@ int intel_mfc_update_hrd(struct encode_state *encode_state,
 }
 
 int intel_mfc_brc_postpack(struct encode_state *encode_state,
-                           struct gen6_mfc_context *mfc_context,
+                           struct intel_encoder_context *encoder_context,
                            int frame_bits)
 {
+    struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
     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[SLICE_TYPE_I];
-    int qpp = mfc_context->brc.qp_prime_y[SLICE_TYPE_P];
-    int qpb = mfc_context->brc.qp_prime_y[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
@@ -191,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;
+
+    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);
 
-    qp = mfc_context->brc.qp_prime_y[slicetype];
+    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[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.);
@@ -228,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, mfc_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) {
@@ -255,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[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[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[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[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[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[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[SLICE_TYPE_I], 1, 51);
-        BRC_CLIP(mfc_context->brc.qp_prime_y[SLICE_TYPE_P], 1, 51);
-        BRC_CLIP(mfc_context->brc.qp_prime_y[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) {
@@ -286,7 +324,7 @@ int intel_mfc_brc_postpack(struct encode_state *encode_state,
         }
     }
 
-    mfc_context->brc.qp_prime_y[slicetype] = qpn;
+    mfc_context->brc.qp_prime_y[next_frame_layer_id][slicetype] = qpn;
 
     return sts;
 }
@@ -296,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) {
@@ -805,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[slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
     if (vme_state_message == NULL)
         return;
@@ -834,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[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);
 
@@ -963,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[slice_type];
+        qp = mfc_context->brc.qp_prime_y[encoder_context->layer.curr_frame_layer_id][slice_type];
 
 #define                USE_SCOREBOARD          (1 << 21)
  
@@ -1916,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[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){