[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