[Libva] [PATCH 15/31] ENC: add BRC init/reset kernel for AVC RC logic

Sean V Kelley seanvk at posteo.de
Tue Jan 10 23:37:57 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 | 218 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 218 insertions(+)

diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c
index 878345ee..fd042c5f 100755
--- a/src/gen9_avc_encoder.c
+++ b/src/gen9_avc_encoder.c
@@ -1930,3 +1930,221 @@ gen9_avc_init_brc_const_data_old(VADriverContextP ctx,
 
     i965_unmap_gpe_resource(gpe_resource);
 }
+static void
+gen9_avc_set_curbe_brc_init_reset(VADriverContextP ctx,
+                                  struct encode_state *encode_state,
+                                  struct i965_gpe_context *gpe_context,
+                                  struct intel_encoder_context *encoder_context,
+                                  void * param)
+{
+    gen9_avc_brc_init_reset_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;
+    double input_bits_per_frame = 0;
+    double bps_ratio = 0;
+    VAEncSequenceParameterBufferH264 * seq_param = avc_state->seq_param;
+    struct avc_param common_param;
+
+    cmd = i965_gpe_context_map_curbe(gpe_context);
+
+    memcpy(cmd,&gen9_avc_brc_init_reset_curbe_init_data,sizeof(gen9_avc_brc_init_reset_curbe_data));
+
+    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->dw0.profile_level_max_frame = i965_avc_get_profile_level_max_frame(&common_param,seq_param->level_idc);
+    cmd->dw1.init_buf_full_in_bits = generic_state->init_vbv_buffer_fullness_in_bit;
+    cmd->dw2.buf_size_in_bits = generic_state->vbv_buffer_size_in_bit;
+    cmd->dw3.average_bit_rate = generic_state->target_bit_rate * 1000;
+    cmd->dw4.max_bit_rate = generic_state->max_bit_rate * 1000;
+    cmd->dw8.gop_p = (generic_state->gop_ref_distance)?((generic_state->gop_size -1)/generic_state->gop_ref_distance):0;
+    cmd->dw9.gop_b = (generic_state->gop_size - 1 - cmd->dw8.gop_p);
+    cmd->dw9.frame_width_in_bytes = generic_state->frame_width_in_pixel;
+    cmd->dw10.frame_height_in_bytes = generic_state->frame_height_in_pixel;
+    cmd->dw12.no_slices = avc_state->slice_num;
+
+    //VUI
+    if(seq_param->vui_parameters_present_flag && generic_state->internal_rate_mode != INTEL_BRC_AVBR )
+    {
+        cmd->dw4.max_bit_rate = cmd->dw4.max_bit_rate;
+        if(generic_state->internal_rate_mode == INTEL_BRC_CBR)
+        {
+            cmd->dw3.average_bit_rate = cmd->dw4.max_bit_rate;
+
+        }
+
+    }
+    cmd->dw6.frame_rate_m = generic_state->frames_per_100s;
+    cmd->dw7.frame_rate_d = 100;
+    cmd->dw8.brc_flag = 0;
+    cmd->dw8.brc_flag |= (generic_state->mb_brc_enabled)? 0 : 0x8000;
+
+
+    if(generic_state->internal_rate_mode == INTEL_BRC_CBR)
+    { //CBR
+        cmd->dw4.max_bit_rate = cmd->dw3.average_bit_rate;
+        cmd->dw8.brc_flag = cmd->dw8.brc_flag |INTEL_ENCODE_BRCINIT_ISCBR;
+
+    }else if(generic_state->internal_rate_mode == INTEL_BRC_VBR)
+    {//VBR
+        if(cmd->dw4.max_bit_rate < cmd->dw3.average_bit_rate)
+        {
+            cmd->dw4.max_bit_rate = cmd->dw3.average_bit_rate << 1;
+        }
+        cmd->dw8.brc_flag = cmd->dw8.brc_flag |INTEL_ENCODE_BRCINIT_ISVBR;
+
+    }else if(generic_state->internal_rate_mode == INTEL_BRC_AVBR)
+    { //AVBR
+        cmd->dw4.max_bit_rate =cmd->dw3.average_bit_rate;
+        cmd->dw8.brc_flag = cmd->dw8.brc_flag |INTEL_ENCODE_BRCINIT_ISAVBR;
+
+    }
+    //igonre icq/vcm/qvbr
+
+    cmd->dw10.avbr_accuracy = generic_state->avbr_curracy;
+    cmd->dw11.avbr_convergence = generic_state->avbr_convergence;
+
+    //frame bits
+    input_bits_per_frame = (double)(cmd->dw4.max_bit_rate) * (double)(cmd->dw7.frame_rate_d)/(double)(cmd->dw6.frame_rate_m);;
+
+    if(cmd->dw2.buf_size_in_bits == 0)
+    {
+       cmd->dw2.buf_size_in_bits = (unsigned int)(input_bits_per_frame * 4);
+    }
+
+    if(cmd->dw1.init_buf_full_in_bits == 0)
+    {
+       cmd->dw1.init_buf_full_in_bits = cmd->dw2.buf_size_in_bits * 7/8;
+    }
+    if(cmd->dw1.init_buf_full_in_bits < (unsigned int)(input_bits_per_frame * 2))
+    {
+       cmd->dw1.init_buf_full_in_bits = (unsigned int)(input_bits_per_frame * 2);
+    }
+    if(cmd->dw1.init_buf_full_in_bits > cmd->dw2.buf_size_in_bits)
+    {
+       cmd->dw1.init_buf_full_in_bits = cmd->dw2.buf_size_in_bits;
+    }
+
+    //AVBR
+    if(generic_state->internal_rate_mode == INTEL_BRC_AVBR)
+    {
+       cmd->dw2.buf_size_in_bits = 2 * generic_state->target_bit_rate * 1000;
+       cmd->dw1.init_buf_full_in_bits = (unsigned int)(3 * cmd->dw2.buf_size_in_bits/4);
+
+    }
+
+    bps_ratio = input_bits_per_frame / (cmd->dw2.buf_size_in_bits/30.0);
+    bps_ratio = (bps_ratio < 0.1)? 0.1:(bps_ratio > 3.5)?3.5:bps_ratio;
+
+
+    cmd->dw16.deviation_threshold_0_pand_b = (unsigned int)(-50 * pow(0.90,bps_ratio));
+    cmd->dw16.deviation_threshold_1_pand_b = (unsigned int)(-50 * pow(0.66,bps_ratio));
+    cmd->dw16.deviation_threshold_2_pand_b = (unsigned int)(-50 * pow(0.46,bps_ratio));
+    cmd->dw16.deviation_threshold_3_pand_b = (unsigned int)(-50 * pow(0.3, bps_ratio));
+    cmd->dw17.deviation_threshold_4_pand_b = (unsigned int)(50 *  pow(0.3, bps_ratio));
+    cmd->dw17.deviation_threshold_5_pand_b = (unsigned int)(50 * pow(0.46, bps_ratio));
+    cmd->dw17.deviation_threshold_6_pand_b = (unsigned int)(50 * pow(0.7,  bps_ratio));
+    cmd->dw17.deviation_threshold_7_pand_b = (unsigned int)(50 * pow(0.9,  bps_ratio));
+    cmd->dw18.deviation_threshold_0_vbr = (unsigned int)(-50 * pow(0.9, bps_ratio));
+    cmd->dw18.deviation_threshold_1_vbr = (unsigned int)(-50 * pow(0.7, bps_ratio));
+    cmd->dw18.deviation_threshold_2_vbr = (unsigned int)(-50 * pow(0.5, bps_ratio));
+    cmd->dw18.deviation_threshold_3_vbr = (unsigned int)(-50 * pow(0.3, bps_ratio));
+    cmd->dw19.deviation_threshold_4_vbr = (unsigned int)(100 * pow(0.4, bps_ratio));
+    cmd->dw19.deviation_threshold_5_vbr = (unsigned int)(100 * pow(0.5, bps_ratio));
+    cmd->dw19.deviation_threshold_6_vbr = (unsigned int)(100 * pow(0.75,bps_ratio));
+    cmd->dw19.deviation_threshold_7_vbr = (unsigned int)(100 * pow(0.9, bps_ratio));
+    cmd->dw20.deviation_threshold_0_i = (unsigned int)(-50 * pow(0.8, bps_ratio));
+    cmd->dw20.deviation_threshold_1_i = (unsigned int)(-50 * pow(0.6, bps_ratio));
+    cmd->dw20.deviation_threshold_2_i = (unsigned int)(-50 * pow(0.34,bps_ratio));
+    cmd->dw20.deviation_threshold_3_i = (unsigned int)(-50 * pow(0.2, bps_ratio));
+    cmd->dw21.deviation_threshold_4_i = (unsigned int)(50 * pow(0.2,  bps_ratio));
+    cmd->dw21.deviation_threshold_5_i = (unsigned int)(50 * pow(0.4,  bps_ratio));
+    cmd->dw21.deviation_threshold_6_i = (unsigned int)(50 * pow(0.66, bps_ratio));
+    cmd->dw21.deviation_threshold_7_i = (unsigned int)(50 * pow(0.9,  bps_ratio));
+
+    cmd->dw22.sliding_window_size = generic_state->window_size;
+
+    i965_gpe_context_unmap_curbe(gpe_context);
+
+    return;
+}
+
+static void
+gen9_avc_send_surface_brc_init_reset(VADriverContextP ctx,
+                                     struct encode_state *encode_state,
+                                     struct i965_gpe_context *gpe_context,
+                                     struct intel_encoder_context *encoder_context,
+                                     void * param_mbenc)
+{
+    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;
+
+    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_BRC_INIT_RESET_HISTORY_INDEX);
+
+    gen9_add_buffer_2d_gpe_surface(ctx,
+                                   gpe_context,
+                                   &avc_ctx->res_brc_dist_data_surface,
+                                   1,
+                                   I965_SURFACEFORMAT_R8_UNORM,
+                                   GEN9_AVC_BRC_INIT_RESET_DISTORTION_INDEX);
+
+    return;
+}
+
+static VAStatus
+gen9_avc_kernel_brc_init_reset(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 generic_encoder_context * generic_ctx = (struct generic_encoder_context * )vme_context->generic_enc_ctx;
+
+    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 = GEN9_AVC_KERNEL_BRC_INIT;
+
+    media_function = INTEL_MEDIA_STATE_BRC_INIT_RESET;
+
+    if(generic_state->brc_inited)
+        kernel_idx = GEN9_AVC_KERNEL_BRC_RESET;
+
+    gpe_context = &(avc_ctx->context_brc.gpe_contexts[kernel_idx]);
+
+    gen8_gpe_context_init(ctx, gpe_context);
+    gen9_gpe_reset_binding_table(ctx, gpe_context);
+
+    generic_ctx->pfn_set_curbe_brc_init_reset(ctx,encode_state,gpe_context,encoder_context,NULL);
+
+    generic_ctx->pfn_send_brc_init_reset_surface(ctx,encode_state,gpe_context,encoder_context,NULL);
+
+    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