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