From b663a5861db61aaa7a241cbb8652c9d7ff207951 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 1 Feb 2012 14:26:51 +0800 Subject: [PATCH] Add support for I420, YV12 etc. formatted YUV surface for encoding MFX only supports NV12 formatted YUV surface, so the driver converts I420/YV12 formatted surface to NV12 surface internally. Signed-off-by: Xiang, Haihao --- src/gen6_mfc.c | 2 +- src/gen6_vme.c | 6 ++-- src/gen7_mfc.c | 2 +- src/i965_encoder.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/i965_encoder.h | 2 ++ 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c index b90596b..abc9a92 100644 --- a/src/gen6_mfc.c +++ b/src/gen6_mfc.c @@ -945,7 +945,7 @@ static VAStatus gen6_mfc_avc_prepare(VADriverContextP ctx, } } - obj_surface = SURFACE(encode_state->current_render_target); + obj_surface = SURFACE(encoder_context->input_yuv_surface); assert(obj_surface && obj_surface->bo); mfc_context->uncompressed_picture_source.bo = obj_surface->bo; dri_bo_reference(mfc_context->uncompressed_picture_source.bo); diff --git a/src/gen6_vme.c b/src/gen6_vme.c index 5446ff3..695d326 100644 --- a/src/gen6_vme.c +++ b/src/gen6_vme.c @@ -314,7 +314,7 @@ static VAStatus gen6_vme_surface_setup(VADriverContextP ctx, /*Setup surfaces state*/ /* current picture for encoding */ - obj_surface = SURFACE(encode_state->current_render_target); + obj_surface = SURFACE(encoder_context->input_yuv_surface); assert(obj_surface); gen6_vme_source_surface_state(ctx, 0, obj_surface, encoder_context); gen6_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context); @@ -556,7 +556,7 @@ static VAStatus gen7_vme_surface_setup(VADriverContextP ctx, /*Setup surfaces state*/ /* current picture for encoding */ - obj_surface = SURFACE(encode_state->current_render_target); + obj_surface = SURFACE(encoder_context->input_yuv_surface); assert(obj_surface); gen7_vme_source_surface_state(ctx, 1, obj_surface, encoder_context); gen7_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context); @@ -784,7 +784,7 @@ static int gen6_vme_media_object(VADriverContextP ctx, { struct i965_driver_data *i965 = i965_driver_data(ctx); struct intel_batchbuffer *batch = encoder_context->base.batch; - struct object_surface *obj_surface = SURFACE(encode_state->current_render_target); + struct object_surface *obj_surface = SURFACE(encoder_context->input_yuv_surface); VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer; int mb_width = ALIGN(obj_surface->orig_width, 16) / 16; int len_in_dowrds = 6 + 2; /*6 + n: n is number of inline data*/ diff --git a/src/gen7_mfc.c b/src/gen7_mfc.c index ecfe27f..d55ec54 100644 --- a/src/gen7_mfc.c +++ b/src/gen7_mfc.c @@ -1002,7 +1002,7 @@ gen7_mfc_avc_prepare(VADriverContextP ctx, } } - obj_surface = SURFACE(encode_state->current_render_target); + obj_surface = SURFACE(encoder_context->input_yuv_surface); assert(obj_surface && obj_surface->bo); mfc_context->uncompressed_picture_source.bo = obj_surface->bo; dri_bo_reference(mfc_context->uncompressed_picture_source.bo); diff --git a/src/i965_encoder.c b/src/i965_encoder.c index 7a8390b..0723cbf 100644 --- a/src/i965_encoder.c +++ b/src/i965_encoder.c @@ -42,6 +42,83 @@ extern Bool gen6_mfc_context_init(VADriverContextP ctx, struct intel_encoder_con extern Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context); extern Bool gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context); +VAStatus +i965_DestroySurfaces(VADriverContextP ctx, + VASurfaceID *surface_list, + int num_surfaces); +VAStatus +i965_CreateSurfaces(VADriverContextP ctx, + int width, + int height, + int format, + int num_surfaces, + VASurfaceID *surfaces); + +static void +intel_encoder_check_yuv_surface(VADriverContextP ctx, + VAProfile profile, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_surface src_surface, dst_surface; + struct object_surface *obj_surface; + VAStatus status; + VARectangle rect; + + /* releae the temporary surface */ + if (encoder_context->is_tmp_id) { + i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1); + } + + encoder_context->is_tmp_id = 0; + obj_surface = SURFACE(encode_state->current_render_target); + assert(obj_surface && obj_surface->bo); + + if (obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2')) { + unsigned int tiling = 0, swizzle = 0; + + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle); + + if (tiling == I915_TILING_Y) { + encoder_context->input_yuv_surface = encode_state->current_render_target; + return; + } + } + + rect.x = 0; + rect.y = 0; + rect.width = obj_surface->orig_width; + rect.height = obj_surface->orig_height; + + src_surface.id = encode_state->current_render_target; + src_surface.type = I965_SURFACE_TYPE_SURFACE; + src_surface.flags = I965_SURFACE_FLAG_FRAME; + + status = i965_CreateSurfaces(ctx, + obj_surface->orig_width, + obj_surface->orig_height, + VA_RT_FORMAT_YUV420, + 1, + &encoder_context->input_yuv_surface); + assert(status == VA_STATUS_SUCCESS); + obj_surface = SURFACE(encoder_context->input_yuv_surface); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420); + + dst_surface.id = encoder_context->input_yuv_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); + + encoder_context->is_tmp_id = 1; +} + static void intel_encoder_end_picture(VADriverContextP ctx, VAProfile profile, @@ -52,6 +129,8 @@ intel_encoder_end_picture(VADriverContextP ctx, struct encode_state *encode_state = &codec_state->encode; VAStatus vaStatus; + intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context); + vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context); if (vaStatus == VA_STATUS_SUCCESS) @@ -101,6 +180,8 @@ gen7_enc_hw_context_init(VADriverContextP ctx, VAProfile profile) encoder_context->base.destroy = intel_encoder_context_destroy; encoder_context->base.run = intel_encoder_end_picture; encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER); + encoder_context->input_yuv_surface = VA_INVALID_SURFACE; + encoder_context->is_tmp_id = 0; gen6_vme_context_init(ctx, encoder_context); assert(encoder_context->vme_context); diff --git a/src/i965_encoder.h b/src/i965_encoder.h index b31af98..d4e6165 100644 --- a/src/i965_encoder.h +++ b/src/i965_encoder.h @@ -39,6 +39,8 @@ struct intel_encoder_context { struct hw_context base; + VASurfaceID input_yuv_surface; + int is_tmp_id; void *vme_context; void *mfc_context; void (*vme_context_destroy)(void *vme_context); -- 2.7.4