[Libva] [HEVC10bit ENC V2 3/5] HEVC10bit:conver p010 to nv12 for ME surface
Zhao Yakui
yakui.zhao at intel.com
Fri Sep 2 07:44:49 UTC 2016
On 09/02/2016 03:01 PM, Pengfei Qu wrote:
> Signed-off-by: Pengfei Qu<Pengfei.Qu at intel.com>
> ---
> src/gen9_mfc_hevc.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 127 insertions(+)
>
> diff --git a/src/gen9_mfc_hevc.c b/src/gen9_mfc_hevc.c
> index 6021a7e..bc9225a 100644
> --- a/src/gen9_mfc_hevc.c
> +++ b/src/gen9_mfc_hevc.c
> @@ -2606,11 +2606,133 @@ static bool intel_hcpe_brc_updated_check(struct encode_state *encode_state,
> return true;
> }
>
> +static VAStatus intel_hcpe_yuv_prepare(struct encode_state *encode_state,
> + struct intel_encoder_context *encoder_context)
Can we change name to intel_hcpe_yuv_convert?
It seems that the code will try the following steps to do the P010->NV12
conversion.
1. Call the conversion for the current_render_target(input_yuv_surface)
2. enumerate the reference_frame list to do the conversion
In such case it will always do the conversion even when it already
handles the conversion of P010->NV12 for one reference frame in previous
encoding.
If it is found that the conversion of P010->NV12 is done for one
reference_frame, we can skip it for the performance consideration.
BTW:
Can this function be called in the gen9_hevc_vme_prepare? In such
case the vme_context->driver_context can also be removed.
Thanks
Yakui
> +{
> + struct gen6_vme_context *vme_context = encoder_context->vme_context;
> + VADriverContextP ctx = vme_context->driver_context;
> + struct i965_driver_data *i965 = i965_driver_data(ctx);
> + VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
> + struct i965_surface src_surface, dst_surface;
> + struct object_surface *obj_surface;
> + VAStatus status;
> + VARectangle rect;
> + int i;
> +
> + obj_surface = SURFACE(encode_state->current_render_target);
> + assert(obj_surface&& obj_surface->bo);
> +
> + if (obj_surface->fourcc == VA_FOURCC_P010) {
> +
> + unsigned int tiling = 0, swizzle = 0;
> + dri_bo_get_tiling(obj_surface->bo,&tiling,&swizzle);
> +
> + // convert input
> + rect.x = 0;
> + rect.y = 0;
> + rect.width = obj_surface->orig_width;
> + rect.height = obj_surface->orig_height;
> +
> + src_surface.base = (struct object_base *)obj_surface;
> + src_surface.type = I965_SURFACE_TYPE_SURFACE;
> + src_surface.flags = I965_SURFACE_FLAG_FRAME;
> +
> + if(SURFACE(vme_context->input_yuv_surface_internal) == NULL)
> + {
> + status = i965_CreateSurfaces(ctx,
> + obj_surface->orig_width,
> + obj_surface->orig_height,
> + VA_RT_FORMAT_YUV420,
> + 1,
> +&vme_context->input_yuv_surface_internal);
> + assert(status == VA_STATUS_SUCCESS);
> +
> + if (status != VA_STATUS_SUCCESS)
> + return status;
> + }
> +
> + obj_surface = SURFACE(vme_context->input_yuv_surface_internal);
> + vme_context->input_yuv_object_internal = obj_surface;
> + assert(obj_surface);
> + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
> +
> + dst_surface.base = (struct object_base *)obj_surface;
> + dst_surface.type = I965_SURFACE_TYPE_SURFACE;
> + dst_surface.flags = I965_SURFACE_FLAG_FRAME;
> +
> + status = i965_image_processing(ctx,
> +&src_surface,
> +&rect,
> +&dst_surface,
> +&rect);
> + assert(status == VA_STATUS_SUCCESS);
> +
> + //convert ref P010->NV12
> + for (i = 0; i< 15; i++) {
> + if (pic_param->reference_frames[i].flags& VA_PICTURE_HEVC_INVALID ||
> + pic_param->reference_frames[i].picture_id == VA_INVALID_SURFACE)
> + break;
> + else {
> + obj_surface = SURFACE(pic_param->reference_frames[i].picture_id);
> + assert(obj_surface);
> +
> + if (!obj_surface)
> + return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> + if (obj_surface->bo) {
> + assert(obj_surface->fourcc == VA_FOURCC_P010);
> + rect.x = 0;
> + rect.y = 0;
> + rect.width = obj_surface->orig_width;
> + rect.height = obj_surface->orig_height;
> +
> + src_surface.base = (struct object_base *)obj_surface;
> + src_surface.type = I965_SURFACE_TYPE_SURFACE;
> + src_surface.flags = I965_SURFACE_FLAG_FRAME;
> +
> + if(SURFACE(vme_context->reference_surface_internal[i]) == NULL)
> + {
> + status = i965_CreateSurfaces(ctx,
> + obj_surface->orig_width,
> + obj_surface->orig_height,
> + VA_RT_FORMAT_YUV420,
> + 1,
> +&vme_context->reference_surface_internal[i]);
> + assert(status == VA_STATUS_SUCCESS);
> +
> + if (status != VA_STATUS_SUCCESS)
> + return status;
> + }
> +
> + obj_surface = SURFACE(vme_context->reference_surface_internal[i]);
> + vme_context->reference_objects_internal[i] = obj_surface;
> + assert(obj_surface);
> + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
> +
> + dst_surface.base = (struct object_base *)obj_surface;
> + dst_surface.type = I965_SURFACE_TYPE_SURFACE;
> + dst_surface.flags = I965_SURFACE_FLAG_FRAME;
> +
> + status = i965_image_processing(ctx,
> +&src_surface,
> +&rect,
> +&dst_surface,
> +&rect);
> + assert(status == VA_STATUS_SUCCESS);
> + }
> + }
> + }
> + }
> +
> + return VA_STATUS_SUCCESS;
> +}
> +
> void intel_hcpe_brc_prepare(struct encode_state *encode_state,
> struct intel_encoder_context *encoder_context)
> {
> unsigned int rate_control_mode = encoder_context->rate_control_mode;
> struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
> + VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
>
> if (rate_control_mode == VA_RC_CBR) {
> bool brc_updated;
> @@ -2629,6 +2751,11 @@ void intel_hcpe_brc_prepare(struct encode_state *encode_state,
> if ((mfc_context->vui_hrd.i_cpb_size_value == 0) || brc_updated)
> intel_hcpe_hrd_context_init(encode_state, encoder_context);
> }
> +
> + //internal input check for main10
> + if((seq_param->seq_fields.bits.bit_depth_luma_minus8> 0)
> + || (seq_param->seq_fields.bits.bit_depth_chroma_minus8> 0))
> + intel_hcpe_yuv_prepare(encode_state,encoder_context);
> }
>
> /* HEVC interface API for encoder */
More information about the Libva
mailing list