[Libva] [PATCH 13/31] ENC: add scaling kernel for AVC encoder

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

diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c
index cf1b1234..e27d8eb5 100755
--- a/src/gen9_avc_encoder.c
+++ b/src/gen9_avc_encoder.c
@@ -1195,3 +1195,304 @@ gen9_init_vfe_scoreboard_avc(struct i965_gpe_context *gpe_context,
         gpe_context->vfe_desc7.scoreboard2.delta_y6 = 0xE;
     }
 }
+/*
+VME pipeline related function
+*/
+
+/*
+scaling kernel related function
+*/
+static void
+gen9_avc_set_curbe_scaling4x(VADriverContextP ctx,
+                           struct encode_state *encode_state,
+                           struct i965_gpe_context *gpe_context,
+                           struct intel_encoder_context *encoder_context,
+                           void *param)
+{
+    gen9_avc_scaling4x_curbe_data *curbe_cmd;
+    struct scaling_param *surface_param = (struct scaling_param *)param;
+
+    curbe_cmd = i965_gpe_context_map_curbe(gpe_context);
+
+    if (!curbe_cmd)
+        return;
+
+    memset(curbe_cmd, 0, sizeof(gen9_avc_scaling4x_curbe_data));
+
+    curbe_cmd->dw0.input_picture_width  = surface_param->input_frame_width;
+    curbe_cmd->dw0.input_picture_height = surface_param->input_frame_height;
+
+    curbe_cmd->dw1.input_y_bti = GEN9_AVC_SCALING_FRAME_SRC_Y_INDEX;
+    curbe_cmd->dw2.output_y_bti = GEN9_AVC_SCALING_FRAME_DST_Y_INDEX;
+
+
+    curbe_cmd->dw5.flatness_threshold = 128;
+    curbe_cmd->dw6.enable_mb_flatness_check = surface_param->enable_mb_flatness_check;
+    curbe_cmd->dw7.enable_mb_variance_output = surface_param->enable_mb_variance_output;
+    curbe_cmd->dw8.enable_mb_pixel_average_output = surface_param->enable_mb_pixel_average_output;
+
+    if (curbe_cmd->dw6.enable_mb_flatness_check ||
+        curbe_cmd->dw7.enable_mb_variance_output ||
+        curbe_cmd->dw8.enable_mb_pixel_average_output)
+    {
+        curbe_cmd->dw10.mbv_proc_stat_bti = GEN9_AVC_SCALING_FRAME_MBVPROCSTATS_DST_INDEX;
+    }
+
+    i965_gpe_context_unmap_curbe(gpe_context);
+    return;
+}
+
+static void
+gen9_avc_set_curbe_scaling2x(VADriverContextP ctx,
+                           struct encode_state *encode_state,
+                           struct i965_gpe_context *gpe_context,
+                           struct intel_encoder_context *encoder_context,
+                           void *param)
+{
+    gen9_avc_scaling2x_curbe_data *curbe_cmd;
+    struct scaling_param *surface_param = (struct scaling_param *)param;
+
+    curbe_cmd = i965_gpe_context_map_curbe(gpe_context);
+
+    if (!curbe_cmd)
+        return;
+
+    memset(curbe_cmd, 0, sizeof(gen9_avc_scaling2x_curbe_data));
+
+    curbe_cmd->dw0.input_picture_width  = surface_param->input_frame_width;
+    curbe_cmd->dw0.input_picture_height = surface_param->input_frame_height;
+
+    curbe_cmd->dw8.input_y_bti = GEN9_AVC_SCALING_FRAME_SRC_Y_INDEX;
+    curbe_cmd->dw9.output_y_bti = GEN9_AVC_SCALING_FRAME_DST_Y_INDEX;
+
+    i965_gpe_context_unmap_curbe(gpe_context);
+    return;
+}
+
+static void
+gen9_avc_send_surface_scaling(VADriverContextP ctx,
+                              struct encode_state *encode_state,
+                              struct i965_gpe_context *gpe_context,
+                              struct intel_encoder_context *encoder_context,
+                              void *param)
+{
+    struct scaling_param *surface_param = (struct scaling_param *)param;
+    unsigned int surface_format;
+    unsigned int res_size;
+
+    if (surface_param->scaling_out_use_32unorm_surf_fmt)
+        surface_format = I965_SURFACEFORMAT_R32_UNORM;
+    else if (surface_param->scaling_out_use_16unorm_surf_fmt)
+        surface_format = I965_SURFACEFORMAT_R16_UNORM;
+    else
+        surface_format = I965_SURFACEFORMAT_R8_UNORM;
+
+    gen9_add_2d_gpe_surface(ctx, gpe_context,
+                            surface_param->input_surface,
+                            0, 1, surface_format,
+                            GEN9_AVC_SCALING_FRAME_SRC_Y_INDEX);
+
+    gen9_add_2d_gpe_surface(ctx, gpe_context,
+                            surface_param->output_surface,
+                            0, 1, surface_format,
+                            GEN9_AVC_SCALING_FRAME_DST_Y_INDEX);
+
+    /*add buffer mv_proc_stat, here need change*/
+    if (surface_param->mbv_proc_stat_enabled)
+    {
+        res_size = 16 * (surface_param->input_frame_width/16) * (surface_param->input_frame_height/16) * sizeof(unsigned int);
+
+        gen9_add_buffer_gpe_surface(ctx,
+                                    gpe_context,
+                                    surface_param->pres_mbv_proc_stat_buffer,
+                                    0,
+                                    res_size/4,
+                                    0,
+                                    GEN9_AVC_SCALING_FRAME_MBVPROCSTATS_DST_INDEX);
+    }else if(surface_param->enable_mb_flatness_check)
+    {
+        gen9_add_buffer_2d_gpe_surface(ctx, gpe_context,
+                                       surface_param->pres_flatness_check_surface,
+                                       1,
+                                       I965_SURFACEFORMAT_R8_UNORM,
+                                       GEN9_AVC_SCALING_FRAME_MBVPROCSTATS_DST_INDEX);
+    }
+
+    return;
+}
+
+static VAStatus
+gen9_avc_kernel_scaling(VADriverContextP ctx,
+                        struct encode_state *encode_state,
+                        struct intel_encoder_context *encoder_context,
+                        int hme_type)
+{
+    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 generic_encoder_context * generic_ctx = (struct generic_encoder_context * )vme_context->generic_enc_ctx;
+
+    struct i965_gpe_context *gpe_context;
+    struct scaling_param surface_param;
+    struct object_surface *obj_surface;
+    struct gen9_surface_avc *avc_priv_surface;
+    struct gpe_media_object_walker_parameter media_object_walker_param;
+    struct gpe_encoder_kernel_walker_parameter kernel_walker_param;
+    unsigned int downscaled_width_in_mb, downscaled_height_in_mb;
+    int media_function = 0;
+    int kernel_idx = 0;
+
+    obj_surface = encode_state->reconstructed_object;
+    avc_priv_surface = obj_surface->private_data;
+
+    memset(&surface_param,0,sizeof(struct scaling_param));
+    switch(hme_type)
+    {
+    case INTEL_ENC_HME_4x :
+        {
+            media_function = INTEL_MEDIA_STATE_4X_SCALING;
+            kernel_idx = GEN9_AVC_KERNEL_SCALING_4X_IDX;
+            downscaled_width_in_mb = generic_state->downscaled_width_4x_in_mb;
+            downscaled_height_in_mb = generic_state->downscaled_height_4x_in_mb;
+
+            surface_param.input_surface = encode_state->input_yuv_object ;
+            surface_param.input_frame_width = generic_state->frame_width_in_pixel ;
+            surface_param.input_frame_height = generic_state->frame_height_in_pixel ;
+
+            surface_param.output_surface = avc_priv_surface->scaled_4x_surface_obj ;
+            surface_param.output_frame_width = generic_state->frame_width_4x ;
+            surface_param.output_frame_height = generic_state->frame_height_4x ;
+
+            surface_param.enable_mb_flatness_check = avc_state->flatness_check_enable;
+            surface_param.enable_mb_variance_output = avc_state->mb_status_enable;
+            surface_param.enable_mb_pixel_average_output = avc_state->mb_status_enable;
+
+            surface_param.blk8x8_stat_enabled = 0 ;
+            surface_param.use_4x_scaling  = 1 ;
+            surface_param.use_16x_scaling = 0 ;
+            surface_param.use_32x_scaling = 0 ;
+            break;
+        }
+    case INTEL_ENC_HME_16x :
+        {
+            media_function = INTEL_MEDIA_STATE_16X_SCALING;
+            kernel_idx = GEN9_AVC_KERNEL_SCALING_4X_IDX;
+            downscaled_width_in_mb = generic_state->downscaled_width_16x_in_mb;
+            downscaled_height_in_mb = generic_state->downscaled_height_16x_in_mb;
+
+            surface_param.input_surface = avc_priv_surface->scaled_4x_surface_obj ;
+            surface_param.input_frame_width = generic_state->frame_width_4x ;
+            surface_param.input_frame_height = generic_state->frame_height_4x ;
+
+            surface_param.output_surface = avc_priv_surface->scaled_16x_surface_obj ;
+            surface_param.output_frame_width = generic_state->frame_width_16x ;
+            surface_param.output_frame_height = generic_state->frame_height_16x ;
+
+            surface_param.enable_mb_flatness_check = 0 ;
+            surface_param.enable_mb_variance_output = 0 ;
+            surface_param.enable_mb_pixel_average_output = 0 ;
+
+            surface_param.blk8x8_stat_enabled = 0 ;
+            surface_param.use_4x_scaling  = 0 ;
+            surface_param.use_16x_scaling = 1 ;
+            surface_param.use_32x_scaling = 0 ;
+
+            break;
+        }
+    case INTEL_ENC_HME_32x :
+        {
+            media_function = INTEL_MEDIA_STATE_32X_SCALING;
+            kernel_idx = GEN9_AVC_KERNEL_SCALING_2X_IDX;
+            downscaled_width_in_mb = generic_state->downscaled_width_32x_in_mb;
+            downscaled_height_in_mb = generic_state->downscaled_height_32x_in_mb;
+
+            surface_param.input_surface = avc_priv_surface->scaled_16x_surface_obj ;
+            surface_param.input_frame_width = generic_state->frame_width_16x ;
+            surface_param.input_frame_height = generic_state->frame_height_16x ;
+
+            surface_param.output_surface = avc_priv_surface->scaled_32x_surface_obj ;
+            surface_param.output_frame_width = generic_state->frame_width_32x ;
+            surface_param.output_frame_height = generic_state->frame_height_32x ;
+
+            surface_param.enable_mb_flatness_check = 0 ;
+            surface_param.enable_mb_variance_output = 0 ;
+            surface_param.enable_mb_pixel_average_output = 0 ;
+
+            surface_param.blk8x8_stat_enabled = 0 ;
+            surface_param.use_4x_scaling  = 0 ;
+            surface_param.use_16x_scaling = 0 ;
+            surface_param.use_32x_scaling = 1 ;
+            break;
+        }
+    default :
+        assert(0);
+
+    }
+
+    gpe_context = &(avc_ctx->context_scaling.gpe_contexts[kernel_idx]);
+
+    gen8_gpe_context_init(ctx, gpe_context);
+    gen9_gpe_reset_binding_table(ctx, gpe_context);
+
+    if(surface_param.use_32x_scaling)
+    {
+        generic_ctx->pfn_set_curbe_scaling2x(ctx,encode_state,gpe_context,encoder_context,&surface_param);
+    }else
+    {
+        generic_ctx->pfn_set_curbe_scaling4x(ctx,encode_state,gpe_context,encoder_context,&surface_param);
+    }
+
+    if(surface_param.use_32x_scaling)
+    {
+        surface_param.scaling_out_use_16unorm_surf_fmt = 1 ;
+        surface_param.scaling_out_use_32unorm_surf_fmt = 0 ;
+    }else
+    {
+        surface_param.scaling_out_use_16unorm_surf_fmt = 0 ;
+        surface_param.scaling_out_use_32unorm_surf_fmt = 1 ;
+    }
+
+    if(surface_param.use_4x_scaling)
+    {
+        if(avc_state->mb_status_supported)
+        {
+            surface_param.enable_mb_flatness_check = 0;
+            surface_param.mbv_proc_stat_enabled = (surface_param.use_4x_scaling)?(avc_state->mb_status_enable || avc_state->flatness_check_enable):0 ;
+            surface_param.pres_mbv_proc_stat_buffer = &(avc_ctx->res_mb_status_buffer);
+
+        }else
+        {
+            surface_param.enable_mb_flatness_check = (surface_param.use_4x_scaling)?avc_state->flatness_check_enable:0;
+            surface_param.mbv_proc_stat_enabled = 0 ;
+            surface_param.pres_flatness_check_surface = &(avc_ctx->res_flatness_check_surface);
+        }
+    }
+
+    generic_ctx->pfn_send_scaling_surface(ctx,encode_state,gpe_context,encoder_context,&surface_param);
+
+
+    gen8_gpe_setup_interface_data(ctx, gpe_context);
+
+    memset(&kernel_walker_param, 0, sizeof(kernel_walker_param));
+    if(surface_param.use_32x_scaling)
+    {
+        kernel_walker_param.resolution_x = downscaled_width_in_mb ;
+        kernel_walker_param.resolution_y = downscaled_height_in_mb ;
+    }else
+    {
+        /* the scaling is based on 8x8 blk level */
+        kernel_walker_param.resolution_x = downscaled_width_in_mb * 2;
+        kernel_walker_param.resolution_y = downscaled_height_in_mb * 2;
+    }
+    kernel_walker_param.no_dependency = 1;
+
+    i965_init_media_object_walker_parameter(&kernel_walker_param, &media_object_walker_param);
+
+    gen9_avc_run_kernel_media_object_walker(ctx, encoder_context,
+                                        gpe_context,
+                                        media_function,
+                                        &media_object_walker_param);
+
+    return VA_STATUS_SUCCESS;
+}
-- 
2.11.0



More information about the Libva mailing list