[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