On 09/02/2016 03:01 PM, Pengfei Qu wrote:
Signed-off-by: Pengfei Qu<pengfei...@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 */

_______________________________________________
Libva mailing list
Libva@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libva

Reply via email to