[Libva] [PATCH 14/31] ENC: add const data/table init function for AVC RC logic
Sean V Kelley
seanvk at posteo.de
Tue Jan 10 23:37:56 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 | 434 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 434 insertions(+)
diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c
index e27d8eb5..878345ee 100755
--- a/src/gen9_avc_encoder.c
+++ b/src/gen9_avc_encoder.c
@@ -1496,3 +1496,437 @@ gen9_avc_kernel_scaling(VADriverContextP ctx,
return VA_STATUS_SUCCESS;
}
+/*
+frame/mb brc related function
+*/
+static void
+gen9_avc_init_mfx_avc_img_state(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ struct gen9_mfx_avc_img_state *pstate)
+{
+ 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;
+
+ VAEncSequenceParameterBufferH264 *seq_param = avc_state->seq_param;
+ VAEncPictureParameterBufferH264 *pic_param = avc_state->pic_param;
+
+ memset(pstate, 0, sizeof(*pstate));
+
+ pstate->dw0.dword_length = (sizeof(struct gen9_mfx_avc_img_state)) / 4 -2;
+ pstate->dw0.sub_opcode_b = 0;
+ pstate->dw0.sub_opcode_a = 0;
+ pstate->dw0.command_opcode = 1;
+ pstate->dw0.pipeline = 2;
+ pstate->dw0.command_type = 3;
+
+ pstate->dw1.frame_size_in_mbs = generic_state->frame_width_in_mbs * generic_state->frame_height_in_mbs ;
+
+ pstate->dw2.frame_width_in_mbs_minus1 = generic_state->frame_width_in_mbs - 1;
+ pstate->dw2.frame_height_in_mbs_minus1 = generic_state->frame_height_in_mbs - 1;
+
+ pstate->dw3.image_structure = 0;//frame is zero
+ pstate->dw3.weighted_bipred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
+ pstate->dw3.weighted_pred_flag = pic_param->pic_fields.bits.weighted_pred_flag;
+ pstate->dw3.brc_domain_rate_control_enable = 0;//1,set for vdenc;
+ pstate->dw3.chroma_qp_offset = pic_param->chroma_qp_index_offset;
+ pstate->dw3.second_chroma_qp_offset = pic_param->second_chroma_qp_index_offset;
+
+ pstate->dw4.field_picture_flag = 0;
+ pstate->dw4.mbaff_mode_active = seq_param->seq_fields.bits.mb_adaptive_frame_field_flag;
+ pstate->dw4.frame_mb_only_flag = seq_param->seq_fields.bits.frame_mbs_only_flag;
+ pstate->dw4.transform_8x8_idct_mode_flag = pic_param->pic_fields.bits.transform_8x8_mode_flag;
+ pstate->dw4.direct_8x8_interface_flag = seq_param->seq_fields.bits.direct_8x8_inference_flag;
+ pstate->dw4.constrained_intra_prediction_flag = pic_param->pic_fields.bits.constrained_intra_pred_flag;
+ pstate->dw4.entropy_coding_flag = pic_param->pic_fields.bits.entropy_coding_mode_flag;
+ pstate->dw4.mb_mv_format_flag = 1;
+ pstate->dw4.chroma_format_idc = seq_param->seq_fields.bits.chroma_format_idc;
+ pstate->dw4.mv_unpacked_flag = 1;
+ pstate->dw4.insert_test_flag = 0;
+ pstate->dw4.load_slice_pointer_flag = 0;
+ pstate->dw4.macroblock_stat_enable = 0; /* disable in the first pass */
+ pstate->dw4.minimum_frame_size = 0;
+ pstate->dw5.intra_mb_max_bit_flag = 1;
+ pstate->dw5.inter_mb_max_bit_flag = 1;
+ pstate->dw5.frame_size_over_flag = 1;
+ pstate->dw5.frame_size_under_flag = 1;
+ pstate->dw5.intra_mb_ipcm_flag = 1;
+ pstate->dw5.mb_rate_ctrl_flag = 0; /* Always 0 in VDEnc mode */
+ pstate->dw5.non_first_pass_flag = 0;
+ pstate->dw5.aq_enable = pstate->dw5.aq_rounding = 0;
+ pstate->dw5.aq_chroma_disable = 1;
+ if(pstate->dw4.entropy_coding_flag && (avc_state->tq_enable))
+ {
+ pstate->dw5.aq_enable = avc_state->tq_enable;
+ pstate->dw5.aq_rounding = avc_state->tq_rounding;
+ }else
+ {
+ pstate->dw5.aq_rounding = 0;
+ }
+
+ pstate->dw6.intra_mb_max_size = 2700;
+ pstate->dw6.inter_mb_max_size = 4095;
+
+ pstate->dw8.slice_delta_qp_max0 = 0;
+ pstate->dw8.slice_delta_qp_max1 = 0;
+ pstate->dw8.slice_delta_qp_max2 = 0;
+ pstate->dw8.slice_delta_qp_max3 = 0;
+
+ pstate->dw9.slice_delta_qp_min0 = 0;
+ pstate->dw9.slice_delta_qp_min1 = 0;
+ pstate->dw9.slice_delta_qp_min2 = 0;
+ pstate->dw9.slice_delta_qp_min3 = 0;
+
+ pstate->dw10.frame_bitrate_min = 0;
+ pstate->dw10.frame_bitrate_min_unit = 1;
+ pstate->dw10.frame_bitrate_min_unit_mode = 1;
+ pstate->dw10.frame_bitrate_max = (1 << 14) - 1;
+ pstate->dw10.frame_bitrate_max_unit = 1;
+ pstate->dw10.frame_bitrate_max_unit_mode = 1;
+
+ pstate->dw11.frame_bitrate_min_delta = 0;
+ pstate->dw11.frame_bitrate_max_delta = 0;
+
+ pstate->dw12.vad_error_logic = 1;
+ /* TODO: set paramters DW19/DW20 for slices */
+}
+
+void gen9_avc_set_image_state(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ struct i965_gpe_resource *gpe_resource)
+{
+ struct encoder_vme_mfc_context * pak_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )pak_context->generic_enc_state;
+ char *pdata;
+ int i;
+ unsigned int * data;
+ struct gen9_mfx_avc_img_state cmd;
+
+ pdata = i965_map_gpe_resource(gpe_resource);
+
+ gen9_avc_init_mfx_avc_img_state(ctx,encode_state,encoder_context,&cmd);
+ for(i = 0; i < generic_state->num_pak_passes;i++)
+ {
+
+ if(i == 0)
+ {
+ cmd.dw4.macroblock_stat_enable = 0;
+ cmd.dw5.non_first_pass_flag = 0;
+ }else
+ {
+ cmd.dw4.macroblock_stat_enable = 1;
+ cmd.dw5.non_first_pass_flag = 1;
+ cmd.dw5.intra_mb_ipcm_flag = 1;
+
+ }
+ cmd.dw5.mb_rate_ctrl_flag = 0;
+ memcpy(pdata,&cmd,sizeof(struct gen9_mfx_avc_img_state));
+ data = (unsigned int *)(pdata + sizeof(struct gen9_mfx_avc_img_state));
+ *data = MI_BATCH_BUFFER_END;
+
+ pdata += INTEL_AVC_IMAGE_STATE_CMD_SIZE;
+ }
+ i965_unmap_gpe_resource(gpe_resource);
+ return;
+}
+
+void gen9_avc_set_image_state_non_brc(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ struct i965_gpe_resource *gpe_resource)
+{
+ struct encoder_vme_mfc_context * pak_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )pak_context->generic_enc_state;
+ char *pdata;
+
+ unsigned int * data;
+ struct gen9_mfx_avc_img_state cmd;
+
+ pdata = i965_map_gpe_resource(gpe_resource);
+
+ gen9_avc_init_mfx_avc_img_state(ctx,encode_state,encoder_context,&cmd);
+
+ if(generic_state->curr_pak_pass == 0)
+ {
+ cmd.dw4.macroblock_stat_enable = 0;
+ cmd.dw5.non_first_pass_flag = 0;
+
+ }
+ else
+ {
+ cmd.dw4.macroblock_stat_enable = 1;
+ cmd.dw5.non_first_pass_flag = 0;
+ cmd.dw5.intra_mb_ipcm_flag = 1;
+ }
+
+ cmd.dw5.mb_rate_ctrl_flag = 0;
+ memcpy(pdata,&cmd,sizeof(struct gen9_mfx_avc_img_state));
+ data = (unsigned int *)(pdata + sizeof(struct gen9_mfx_avc_img_state));
+ *data = MI_BATCH_BUFFER_END;
+
+ i965_unmap_gpe_resource(gpe_resource);
+ return;
+}
+
+static void
+gen9_avc_init_brc_const_data(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ 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 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_resource *gpe_resource = NULL;
+ unsigned char * data =NULL;
+ unsigned char * data_tmp = NULL;
+ unsigned int size = 0;
+ unsigned int table_idx = 0;
+ unsigned int block_based_skip_enable = avc_state->block_based_skip_enable;
+ int i = 0;
+
+ struct object_surface *obj_surface;
+ VAEncPictureParameterBufferH264 *pic_param = avc_state->pic_param;
+ VAEncSliceParameterBufferH264 * slice_param = avc_state->slice_param[0];
+ VASurfaceID surface_id;
+ unsigned int transform_8x8_mode_flag = pic_param->pic_fields.bits.transform_8x8_mode_flag;
+
+ gpe_resource = &(avc_ctx->res_brc_const_data_buffer);
+ assert(gpe_resource);
+
+ i965_zero_gpe_resource(gpe_resource);
+
+ data = i965_map_gpe_resource(gpe_resource);
+ assert(data);
+
+ table_idx = slice_type_kernel[generic_state->frame_type];
+
+ /* Fill surface with QP Adjustment table, Distortion threshold table, MaxFrame threshold table, Distortion QP Adjustment Table*/
+ size = sizeof(gen9_avc_qp_adjustment_dist_threshold_max_frame_threshold_dist_qp_adjustment_ipb);
+ memcpy(data,gen9_avc_qp_adjustment_dist_threshold_max_frame_threshold_dist_qp_adjustment_ipb,size*sizeof(unsigned char));
+
+ data += size;
+
+ /* skip threshold table*/
+ size = 128;
+ switch(generic_state->frame_type)
+ {
+ case SLICE_TYPE_P:
+ memcpy(data,gen9_avc_skip_value_p[block_based_skip_enable][transform_8x8_mode_flag],size * sizeof(unsigned char));
+ break;
+ case SLICE_TYPE_B:
+ memcpy(data,gen9_avc_skip_value_b[block_based_skip_enable][transform_8x8_mode_flag],size * sizeof(unsigned char));
+ break;
+ default:
+ /*SLICE_TYPE_I,no change */
+ break;
+ }
+
+ if((generic_state->frame_type != SLICE_TYPE_I) && avc_state->non_ftq_skip_threshold_lut_input_enable)
+ {
+ for(i = 0; i< 52 ; i++)
+ {
+ *(data + 1 + (i * 2)) = (unsigned char)i965_avc_calc_skip_value(block_based_skip_enable,transform_8x8_mode_flag,avc_state->non_ftq_skip_threshold_lut[i]);
+ }
+ }
+ data += size;
+
+ /*fill the qp for ref list*/
+ size = 32 + 32 +32 +160;
+ memset(data,0xff,32);
+ memset(data+32+32,0xff,32);
+ switch(generic_state->frame_type)
+ {
+ case SLICE_TYPE_P:
+ {
+ for(i = 0 ; i < slice_param->num_ref_idx_l0_active_minus1 + 1; i++)
+ {
+ surface_id = slice_param->RefPicList0[i].picture_id;
+ obj_surface = SURFACE(surface_id);
+ if (!obj_surface)
+ break;
+ *(data + i) = avc_state->list_ref_idx[0][i];//?
+ }
+ }
+ break;
+ case SLICE_TYPE_B:
+ {
+ data = data + 32 + 32;
+ for(i = 0 ; i < slice_param->num_ref_idx_l1_active_minus1 + 1; i++)
+ {
+ surface_id = slice_param->RefPicList1[i].picture_id;
+ obj_surface = SURFACE(surface_id);
+ if (!obj_surface)
+ break;
+ *(data + i) = avc_state->list_ref_idx[1][i];//?
+ }
+
+ data = data - 32 - 32;
+
+ for(i = 0 ; i < slice_param->num_ref_idx_l0_active_minus1 + 1; i++)
+ {
+ surface_id = slice_param->RefPicList0[i].picture_id;
+ obj_surface = SURFACE(surface_id);
+ if (!obj_surface)
+ break;
+ *(data + i) = avc_state->list_ref_idx[0][i];//?
+ }
+ }
+ break;
+ default:
+ /*SLICE_TYPE_I,no change */
+ break;
+ }
+ data += size;
+
+ /*mv cost and mode cost*/
+ size = 1664;
+ memcpy(data,(unsigned char *)&gen9_avc_mode_mv_cost_table[table_idx][0][0],size * sizeof(unsigned char));
+
+ if(avc_state->old_mode_cost_enable)
+ { data_tmp = data;
+ for(i = 0; i < 52 ; i++)
+ {
+ *(data_tmp +3) = (unsigned int)gen9_avc_old_intra_mode_cost[i];
+ data_tmp += 16;
+ }
+ }
+
+ if(avc_state->ftq_skip_threshold_lut_input_enable)
+ {
+ for(i = 0; i < 52 ; i++)
+ {
+ *(data + (i * 32) + 24) =
+ *(data + (i * 32) + 25) =
+ *(data + (i * 32) + 27) =
+ *(data + (i * 32) + 28) =
+ *(data + (i * 32) + 29) =
+ *(data + (i * 32) + 30) =
+ *(data + (i * 32) + 31) = avc_state->ftq_skip_threshold_lut[i];
+ }
+
+ }
+ data += size;
+
+ /*ref cost*/
+ size = 128;
+ memcpy(data,(unsigned char *)&gen9_avc_ref_cost[table_idx][0],size * sizeof(unsigned char));
+ data += size;
+
+ /*scaling factor*/
+ size = 64;
+ if(avc_state->adaptive_intra_scaling_enable)
+ {
+ memcpy(data,(unsigned char *)&gen9_avc_adaptive_intra_scaling_factor,size * sizeof(unsigned char));
+ }else
+ {
+ memcpy(data,(unsigned char *)&gen9_avc_intra_scaling_factor,size * sizeof(unsigned char));
+ }
+ i965_unmap_gpe_resource(gpe_resource);
+}
+
+static void
+gen9_avc_init_brc_const_data_old(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 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_resource *gpe_resource = NULL;
+ unsigned int * data =NULL;
+ unsigned int * data_tmp = NULL;
+ unsigned int size = 0;
+ unsigned int table_idx = 0;
+ VAEncPictureParameterBufferH264 *pic_param = avc_state->pic_param;
+ unsigned int block_based_skip_enable = avc_state->block_based_skip_enable;
+ unsigned int transform_8x8_mode_flag = pic_param->pic_fields.bits.transform_8x8_mode_flag;
+ int i = 0;
+
+ gpe_resource = &(avc_ctx->res_brc_const_data_buffer);
+ assert(gpe_resource);
+
+ i965_zero_gpe_resource(gpe_resource);
+
+ data = i965_map_gpe_resource(gpe_resource);
+ assert(data);
+
+ table_idx = slice_type_kernel[generic_state->frame_type];
+
+ /* Fill surface with QP Adjustment table, Distortion threshold table, MaxFrame threshold table, Distortion QP Adjustment Table*/
+ size = sizeof(gen75_avc_qp_adjustment_dist_threshold_max_frame_threshold_dist_qp_adjustment_ipb);
+ memcpy(data,gen75_avc_qp_adjustment_dist_threshold_max_frame_threshold_dist_qp_adjustment_ipb,size*sizeof(unsigned char));
+
+ data += size;
+
+ /* skip threshold table*/
+ size = 128;
+ switch(generic_state->frame_type)
+ {
+ case SLICE_TYPE_P:
+ memcpy(data,gen9_avc_skip_value_p[block_based_skip_enable][transform_8x8_mode_flag],size * sizeof(unsigned char));
+ break;
+ case SLICE_TYPE_B:
+ memcpy(data,gen9_avc_skip_value_b[block_based_skip_enable][transform_8x8_mode_flag],size * sizeof(unsigned char));
+ break;
+ default:
+ /*SLICE_TYPE_I,no change */
+ break;
+ }
+
+ if((generic_state->frame_type != SLICE_TYPE_I) && avc_state->non_ftq_skip_threshold_lut_input_enable)
+ {
+ for(i = 0; i< 52 ; i++)
+ {
+ *(data + 1 + (i * 2)) = (unsigned char)i965_avc_calc_skip_value(block_based_skip_enable,transform_8x8_mode_flag,avc_state->non_ftq_skip_threshold_lut[i]);
+ }
+ }
+ data += size;
+
+ /*fill the qp for ref list*/
+ size = 128;
+ data += size;
+ size = 128;
+ data += size;
+
+ /*mv cost and mode cost*/
+ size = 1664;
+ memcpy(data,(unsigned char *)&gen75_avc_mode_mv_cost_table[table_idx][0][0],size * sizeof(unsigned char));
+
+ if(avc_state->old_mode_cost_enable)
+ { data_tmp = data;
+ for(i = 0; i < 52 ; i++)
+ {
+ *(data_tmp +3) = (unsigned int)gen9_avc_old_intra_mode_cost[i];
+ data_tmp += 16;
+ }
+ }
+
+ if(avc_state->ftq_skip_threshold_lut_input_enable)
+ {
+ for(i = 0; i < 52 ; i++)
+ {
+ *(data + (i * 32) + 24) =
+ *(data + (i * 32) + 25) =
+ *(data + (i * 32) + 27) =
+ *(data + (i * 32) + 28) =
+ *(data + (i * 32) + 29) =
+ *(data + (i * 32) + 30) =
+ *(data + (i * 32) + 31) = avc_state->ftq_skip_threshold_lut[i];
+ }
+
+ }
+ data += size;
+
+ /*ref cost*/
+ size = 128;
+ memcpy(data,(unsigned char *)&gen9_avc_ref_cost[table_idx][0],size * sizeof(unsigned char));
+
+ i965_unmap_gpe_resource(gpe_resource);
+}
--
2.11.0
More information about the Libva
mailing list