[Libva] [PATCH 16/31] ENC: add BRC frame update kernel for AVC RC logic
Sean V Kelley
seanvk at posteo.de
Tue Jan 10 23:37:58 UTC 2017
From: Pengfei Qu <Pengfei.Qu at intel.com>
Signed-off-by: Pengfei Qu <Pengfei.Qu at intel.com>
Reviewed-by: Sean V Kelley <seanvk at posteo.de>
---
src/gen9_avc_encoder.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 335 insertions(+)
diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c
index fd042c5f..65a4bc95 100755
--- a/src/gen9_avc_encoder.c
+++ b/src/gen9_avc_encoder.c
@@ -2148,3 +2148,338 @@ gen9_avc_kernel_brc_init_reset(VADriverContextP ctx,
return VA_STATUS_SUCCESS;
}
+
+static void
+gen9_avc_set_curbe_brc_frame_update(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct i965_gpe_context *gpe_context,
+ struct intel_encoder_context *encoder_context,
+ void * param)
+{
+ gen9_avc_frame_brc_update_curbe_data *cmd;
+ struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )vme_context->generic_enc_state;
+ struct avc_enc_state * avc_state = (struct avc_enc_state * )vme_context->private_enc_state;
+ struct object_surface *obj_surface;
+ struct gen9_surface_avc *avc_priv_surface;
+ struct avc_param common_param;
+ VAEncSequenceParameterBufferH264 * seq_param = avc_state->seq_param;
+
+ obj_surface = encode_state->reconstructed_object;
+
+ if (!obj_surface || !obj_surface->private_data)
+ return;
+ avc_priv_surface = obj_surface->private_data;
+
+ cmd = i965_gpe_context_map_curbe(gpe_context);
+
+ memcpy(cmd,&gen9_avc_frame_brc_update_curbe_init_data,sizeof(gen9_avc_frame_brc_update_curbe_data));
+
+ cmd->dw5.target_size_flag = 0 ;
+ if(generic_state->brc_init_current_target_buf_full_in_bits > (double)generic_state->brc_init_reset_buf_size_in_bits)
+ {
+ /*overflow*/
+ generic_state->brc_init_current_target_buf_full_in_bits -= (double)generic_state->brc_init_reset_buf_size_in_bits;
+ cmd->dw5.target_size_flag = 1 ;
+ }
+
+ if(generic_state->skip_frame_enbale)
+ {
+ cmd->dw6.num_skip_frames = generic_state->num_skip_frames ;
+ cmd->dw7.size_skip_frames = generic_state->size_skip_frames;
+
+ generic_state->brc_init_current_target_buf_full_in_bits += generic_state->brc_init_reset_input_bits_per_frame * generic_state->num_skip_frames;
+
+ }
+ cmd->dw0.target_size = (unsigned int)generic_state->brc_init_current_target_buf_full_in_bits ;
+ cmd->dw1.frame_number = generic_state->seq_frame_number ;
+ cmd->dw2.size_of_pic_headers = generic_state->herder_bytes_inserted << 3 ;
+ cmd->dw5.cur_frame_type = generic_state->frame_type ;
+ cmd->dw5.brc_flag = 0 ;
+ cmd->dw5.brc_flag |= (avc_priv_surface->is_as_ref)?INTEL_ENCODE_BRCUPDATE_IS_REFERENCE:0 ;
+
+ if(avc_state->multi_pre_enable)
+ {
+ cmd->dw5.brc_flag |= INTEL_ENCODE_BRCUPDATE_IS_ACTUALQP ;
+ cmd->dw14.qp_index_of_cur_pic = avc_priv_surface->frame_idx ; //do not know this. use -1
+ }
+
+ cmd->dw5.max_num_paks = generic_state->num_pak_passes ;
+ if(avc_state->min_max_qp_enable)
+ {
+ switch(generic_state->frame_type)
+ {
+ case SLICE_TYPE_I:
+ cmd->dw6.minimum_qp = avc_state->min_qp_i ;
+ cmd->dw6.maximum_qp = avc_state->max_qp_i ;
+ break;
+ case SLICE_TYPE_P:
+ cmd->dw6.minimum_qp = avc_state->min_qp_p ;
+ cmd->dw6.maximum_qp = avc_state->max_qp_p ;
+ break;
+ case SLICE_TYPE_B:
+ cmd->dw6.minimum_qp = avc_state->min_qp_b ;
+ cmd->dw6.maximum_qp = avc_state->max_qp_b ;
+ break;
+ }
+ }else
+ {
+ cmd->dw6.minimum_qp = 0 ;
+ cmd->dw6.maximum_qp = 0 ;
+ }
+ cmd->dw6.enable_force_skip = avc_state->enable_force_skip ;
+ cmd->dw6.enable_sliding_window = 0 ;
+
+ generic_state->brc_init_current_target_buf_full_in_bits += generic_state->brc_init_reset_input_bits_per_frame;
+
+ if(generic_state->internal_rate_mode == INTEL_BRC_AVBR)
+ {
+ cmd->dw3.start_gadj_frame0 = (unsigned int)((10 * generic_state->avbr_convergence) / (double)150);
+ cmd->dw3.start_gadj_frame1 = (unsigned int)((50 * generic_state->avbr_convergence) / (double)150);
+ cmd->dw4.start_gadj_frame2 = (unsigned int)((100 * generic_state->avbr_convergence) / (double)150);
+ cmd->dw4.start_gadj_frame3 = (unsigned int)((150 * generic_state->avbr_convergence) / (double)150);
+ cmd->dw11.g_rate_ratio_threshold_0 = (unsigned int)((100 - (generic_state->avbr_curracy / (double)30)*(100 - 40)));
+ cmd->dw11.g_rate_ratio_threshold_1 = (unsigned int)((100 - (generic_state->avbr_curracy / (double)30)*(100 - 75)));
+ cmd->dw12.g_rate_ratio_threshold_2 = (unsigned int)((100 - (generic_state->avbr_curracy / (double)30)*(100 - 97)));
+ cmd->dw12.g_rate_ratio_threshold_3 = (unsigned int)((100 + (generic_state->avbr_curracy / (double)30)*(103 - 100)));
+ cmd->dw12.g_rate_ratio_threshold_4 = (unsigned int)((100 + (generic_state->avbr_curracy / (double)30)*(125 - 100)));
+ cmd->dw12.g_rate_ratio_threshold_5 = (unsigned int)((100 + (generic_state->avbr_curracy / (double)30)*(160 - 100)));
+
+ }
+ cmd->dw15.enable_roi = generic_state->brc_roi_enable ;
+
+ memset(&common_param,0,sizeof(common_param));
+ common_param.frame_width_in_pixel = generic_state->frame_width_in_pixel;
+ common_param.frame_height_in_pixel = generic_state->frame_height_in_pixel;
+ common_param.frame_width_in_mbs = generic_state->frame_width_in_mbs;
+ common_param.frame_height_in_mbs = generic_state->frame_height_in_mbs;
+ common_param.frames_per_100s = generic_state->frames_per_100s;
+ common_param.vbv_buffer_size_in_bit = generic_state->vbv_buffer_size_in_bit;
+ common_param.target_bit_rate = generic_state->target_bit_rate;
+
+ cmd->dw19.user_max_frame = i965_avc_get_profile_level_max_frame(&common_param,seq_param->level_idc);
+ i965_gpe_context_unmap_curbe(gpe_context);
+
+ return;
+}
+
+static void
+gen9_avc_send_surface_brc_frame_update(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct i965_gpe_context *gpe_context,
+ struct intel_encoder_context *encoder_context,
+ void * param_brc)
+{
+ struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct gen9_avc_encoder_context * avc_ctx = (struct gen9_avc_encoder_context * )vme_context->private_enc_ctx;
+ struct brc_param * param = (struct brc_param *)param_brc ;
+ struct i965_gpe_context * gpe_context_mbenc = param->gpe_context_mbenc;
+
+
+ /* brc history buffer*/
+ gen9_add_buffer_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_brc_history_buffer,
+ 0,
+ avc_ctx->res_brc_history_buffer.size,
+ 0,
+ GEN9_AVC_FRAME_BRC_UPDATE_HISTORY_INDEX);
+
+ /* previous pak buffer*/
+ gen9_add_buffer_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_brc_pre_pak_statistics_output_buffer,
+ 0,
+ avc_ctx->res_brc_pre_pak_statistics_output_buffer.size,
+ 0,
+ GEN9_AVC_FRAME_BRC_UPDATE_PAK_STATISTICS_OUTPUT_INDEX);
+
+ /* image state command buffer read only*/
+ gen9_add_buffer_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_brc_image_state_read_buffer,
+ 0,
+ avc_ctx->res_brc_image_state_read_buffer.size,
+ 0,
+ GEN9_AVC_FRAME_BRC_UPDATE_IMAGE_STATE_READ_INDEX);
+
+ /* image state command buffer write only*/
+ gen9_add_buffer_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_brc_image_state_write_buffer,
+ 0,
+ avc_ctx->res_brc_image_state_write_buffer.size,
+ 0,
+ GEN9_AVC_FRAME_BRC_UPDATE_IMAGE_STATE_WRITE_INDEX);
+
+ /* Mbenc curbe input buffer */
+ gen9_add_dri_buffer_gpe_surface(ctx,
+ gpe_context,
+ gpe_context_mbenc->dynamic_state.bo,
+ 0,
+ ALIGN(gpe_context_mbenc->curbe.length, 64),
+ gpe_context_mbenc->curbe.offset,
+ GEN9_AVC_FRAME_BRC_UPDATE_MBENC_CURBE_READ_INDEX);
+ /* Mbenc curbe output buffer */
+ gen9_add_dri_buffer_gpe_surface(ctx,
+ gpe_context,
+ gpe_context_mbenc->dynamic_state.bo,
+ 0,
+ ALIGN(gpe_context_mbenc->curbe.length, 64),
+ gpe_context_mbenc->curbe.offset,
+ GEN9_AVC_FRAME_BRC_UPDATE_MBENC_CURBE_WRITE_INDEX);
+
+ /* AVC_ME Distortion 2D surface buffer,input/output. is it res_brc_dist_data_surface*/
+ gen9_add_buffer_2d_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_brc_dist_data_surface,
+ 1,
+ I965_SURFACEFORMAT_R8_UNORM,
+ GEN9_AVC_FRAME_BRC_UPDATE_DISTORTION_INDEX);
+
+ /* BRC const data 2D surface buffer */
+ gen9_add_buffer_2d_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_brc_const_data_buffer,
+ 1,
+ I965_SURFACEFORMAT_R8_UNORM,
+ GEN9_AVC_FRAME_BRC_UPDATE_CONSTANT_DATA_INDEX);
+
+ /* MB statistical data surface*/
+ gen9_add_buffer_gpe_surface(ctx,
+ gpe_context,
+ &avc_ctx->res_mb_status_buffer,
+ 0,
+ avc_ctx->res_mb_status_buffer.size,
+ 0,
+ GEN9_AVC_FRAME_BRC_UPDATE_MB_STATUS_INDEX);
+
+ return;
+}
+
+static VAStatus
+gen9_avc_kernel_brc_frame_update(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+
+{
+ struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct generic_encoder_context * generic_ctx = (struct generic_encoder_context * )vme_context->generic_enc_ctx;
+ struct gen9_avc_encoder_context * avc_ctx = (struct gen9_avc_encoder_context * )vme_context->private_enc_ctx;
+ struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )vme_context->generic_enc_state;
+ struct avc_enc_state * avc_state = (struct avc_enc_state * )vme_context->private_enc_state;
+
+ struct i965_gpe_context *gpe_context;
+ struct gpe_media_object_parameter media_object_param;
+ struct gpe_media_object_inline_data media_object_inline_data;
+ int media_function = 0;
+ int kernel_idx = 0;
+ unsigned int mb_const_data_buffer_in_use,mb_qp_buffer_in_use;
+ unsigned int brc_enabled = 0;
+ unsigned int roi_enable = (generic_state->num_roi > 0)?1:0;
+ unsigned int dirty_roi_enable = ((generic_state->dirty_num_roi > 0) && (generic_state->frame_type == SLICE_TYPE_P) && (0));
+
+ /* the following set the mbenc curbe*/
+ struct mbenc_param curbe_mbenc_param ;
+ struct brc_param curbe_brc_param ;
+
+ mb_const_data_buffer_in_use =
+ generic_state->mb_brc_enabled ||
+ roi_enable ||
+ dirty_roi_enable ||
+ avc_state->mb_qp_data_enable ||
+ avc_state->rolling_intra_refresh_enable;
+ mb_qp_buffer_in_use =
+ generic_state->mb_brc_enabled ||
+ generic_state->brc_roi_enable ||
+ avc_state->mb_qp_data_enable;
+
+ switch(generic_state->kernel_mode)
+ {
+ case INTEL_ENC_KERNEL_NORMAL :
+ {
+ kernel_idx = MBENC_KERNEL_BASE + GEN9_AVC_KERNEL_MBENC_NORMAL_I;
+ break;
+ }
+ case INTEL_ENC_KERNEL_PERFORMANCE :
+ {
+ kernel_idx = MBENC_KERNEL_BASE + GEN9_AVC_KERNEL_MBENC_PERFORMANCE_I;
+ break;
+ }
+ case INTEL_ENC_KERNEL_QUALITY :
+ {
+ kernel_idx = MBENC_KERNEL_BASE + GEN9_AVC_KERNEL_MBENC_QUALITY_I;
+ break;
+ }
+ default:
+ assert(0);
+
+ }
+
+ if(generic_state->frame_type == SLICE_TYPE_P)
+ {
+ kernel_idx += 1;
+ }
+ else if(generic_state->frame_type == SLICE_TYPE_B)
+ {
+ kernel_idx += 2;
+ }
+
+ gpe_context = &(avc_ctx->context_mbenc.gpe_contexts[kernel_idx]);
+ gen8_gpe_context_init(ctx, gpe_context);
+
+ memset(&curbe_mbenc_param,0,sizeof(struct mbenc_param));
+
+ curbe_mbenc_param.mb_const_data_buffer_in_use = mb_const_data_buffer_in_use;
+ curbe_mbenc_param.mb_qp_buffer_in_use = mb_qp_buffer_in_use;
+ curbe_mbenc_param.mbenc_i_frame_dist_in_use = 0;
+ curbe_mbenc_param.brc_enabled = brc_enabled;
+ curbe_mbenc_param.roi_enabled = roi_enable;
+
+ /* set curbe mbenc*/
+ generic_ctx->pfn_set_curbe_mbenc(ctx,encode_state,gpe_context,encoder_context,&curbe_mbenc_param);
+ avc_state->mbenc_curbe_set_in_brc_update = 1;
+
+ /*begin brc frame update*/
+ memset(&curbe_brc_param,0,sizeof(struct brc_param));
+ curbe_brc_param.gpe_context_mbenc = gpe_context;
+ media_function = INTEL_MEDIA_STATE_BRC_UPDATE;
+ kernel_idx = GEN9_AVC_KERNEL_BRC_FRAME_UPDATE;
+ gpe_context = &(avc_ctx->context_brc.gpe_contexts[kernel_idx]);
+ curbe_brc_param.gpe_context_brc_frame_update = gpe_context;
+
+ gen8_gpe_context_init(ctx, gpe_context);
+ gen9_gpe_reset_binding_table(ctx, gpe_context);
+ /*brc copy ignored*/
+
+ /* set curbe frame update*/
+ generic_ctx->pfn_set_curbe_brc_frame_update(ctx,encode_state,gpe_context,encoder_context,&curbe_brc_param);
+
+ /* load brc constant data, is it same as mbenc mb brc constant data? no.*/
+ if(avc_state->multi_pre_enable)
+ {
+ gen9_avc_init_brc_const_data(ctx,encode_state,encoder_context);
+ }else
+ {
+ gen9_avc_init_brc_const_data_old(ctx,encode_state,encoder_context);
+ }
+ /* image state construct*/
+ gen9_avc_set_image_state(ctx,encode_state,encoder_context,&(avc_ctx->res_brc_image_state_read_buffer));
+ /* set surface frame mbenc*/
+ generic_ctx->pfn_send_brc_frame_update_surface(ctx,encode_state,gpe_context,encoder_context,&curbe_brc_param);
+
+
+ gen8_gpe_setup_interface_data(ctx, gpe_context);
+
+ memset(&media_object_param, 0, sizeof(media_object_param));
+ memset(&media_object_inline_data, 0, sizeof(media_object_inline_data));
+ media_object_param.pinline_data = &media_object_inline_data;
+ media_object_param.inline_size = sizeof(media_object_inline_data);
+
+ gen9_avc_run_kernel_media_object(ctx, encoder_context,
+ gpe_context,
+ media_function,
+ &media_object_param);
+
+ return VA_STATUS_SUCCESS;
+}
--
2.11.0
More information about the Libva
mailing list