From f30206f202586a989d0bd10bf0f25023513fe26e Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 13 Sep 2016 16:02:46 +0800 Subject: [PATCH] Update CBR algo for H.264 per tempolar layer v2: rebased Signed-off-by: Xiang, Haihao Tested-by: Luo, Focus Reviewed-by: Zhao Yakui --- 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; -- 2.11.0