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

Zhao Yakui yakui.zhao at intel.com
Wed Sep 7 05:40:21 UTC 2016


On 09/06/2016 11:46 PM, Xiang, Haihao wrote:
> Signed-off-by: Xiang, Haihao<haihao.xiang at intel.com>

This looks good to me.

Add: Reviewed-by: Zhao Yakui <yakui.zhao at intel.com>

Thanks
> ---
>   src/gen6_mfc.c        |  4 +--
>   src/gen6_mfc_common.c | 76 +++++++++++++++++++++++++++++++++------------------
>   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, 61 insertions(+), 39 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 ccf20a2..9ead818 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;
> +    }
>
> -    target_frame_size = mfc_context->brc.target_frame_size[0][slicetype];
> +    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];
> +
> +    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);
>
> @@ -972,14 +994,14 @@ gen7_vme_walker_fill_vme_batchbuffer(VADriverContextP ctx,
>       unsigned int *command_ptr;
>       struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
>       VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
> -    VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
> +    VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[encoder_context->layer.curr_frame_layer_id]->buffer;
>       int qp,qp_mb,qp_index;
>       int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
>
>       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 e80467d..4bdc195 100644
> --- a/src/gen9_vme.c
> +++ b/src/gen9_vme.c
> @@ -620,7 +620,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;



More information about the Libva mailing list