diff options
author | Pengfei Qu <Pengfei.Qu@intel.com> | 2016-12-28 10:35:02 +0800 |
---|---|---|
committer | Sean V Kelley <seanvk@posteo.de> | 2017-01-10 15:21:48 -0800 |
commit | 68452120cd8fd9699149b29cf8b029c477ea7930 (patch) | |
tree | 39a0b153ff0e01a9da5413385a04d831fd1e4671 | |
parent | cba5f7c56de012b97cbe7f2a31e26450d33b9eb6 (diff) |
ENC: add scaling kernel for AVC encoder
Signed-off-by: Pengfei Qu <Pengfei.Qu@intel.com>
Reviewed-by: Sean V Kelley <seanvk@posteo.de>
-rwxr-xr-x | src/gen9_avc_encoder.c | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c index cf1b123..e27d8eb 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; +} |