[Libva] [HEVC10bit ENC V2 3/5] HEVC10bit:conver p010 to nv12 for ME surface

Pengfei Qu Pengfei.Qu at intel.com
Fri Sep 2 07:01:40 UTC 2016


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)
+{
+    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 */
-- 
2.7.4



More information about the Libva mailing list