From d9eb6b2063418226242e4e76aa7929fa63030bc6 Mon Sep 17 00:00:00 2001 From: "peng.chen" Date: Wed, 13 Jan 2016 15:31:37 +0800 Subject: VPP P010(10bits) enabling v2: 1, remove VPP P016 related code 2, optimize NV12->P010 3, enable IECP if all DI&DN are disabled v1: initial Signed-off-by: peng.chen --- src/gen75_picture_process.c | 266 +++++++++++++++++++++++++++++++++++--------- src/gen75_vpp_vebox.c | 21 +++- src/i965_device_info.c | 2 +- src/i965_drv_video.c | 17 +++ src/i965_drv_video.h | 1 + 5 files changed, 251 insertions(+), 56 deletions(-) diff --git a/src/gen75_picture_process.c b/src/gen75_picture_process.c index ed50532..802452b 100644 --- a/src/gen75_picture_process.c +++ b/src/gen75_picture_process.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "intel_batchbuffer.h" #include "intel_driver.h" @@ -123,6 +124,15 @@ gen75_proc_picture(VADriverContextP ctx, (VAProcPipelineParameterBuffer *)proc_st->pipeline_param->buffer; struct object_surface *obj_dst_surf = NULL; struct object_surface *obj_src_surf = NULL; + + VAProcPipelineParameterBuffer pipeline_param2; + struct object_surface *stage1_dst_surf = NULL; + struct object_surface *stage2_dst_surf = NULL; + VARectangle src_rect, dst_rect; + VASurfaceID tmp_surfaces[2]; + VASurfaceID out_surface_id1 = VA_INVALID_ID, out_surface_id2 = VA_INVALID_ID; + int num_tmp_surfaces = 0; + VAStatus status; proc_ctx->pipeline_param = pipeline_param; @@ -168,69 +178,221 @@ gen75_proc_picture(VADriverContextP ctx, proc_ctx->surface_pipeline_input_object = obj_src_surf; assert(pipeline_param->num_filters <= 4); + int vpp_stage1 = 0, vpp_stage2 = 1, vpp_stage3 = 0; + + if (pipeline_param->surface_region) { + src_rect.x = pipeline_param->surface_region->x; + src_rect.y = pipeline_param->surface_region->y; + src_rect.width = pipeline_param->surface_region->width; + src_rect.height = pipeline_param->surface_region->height; + } else { + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = obj_src_surf->orig_width; + src_rect.height = obj_src_surf->orig_height; + } + + if (pipeline_param->output_region) { + dst_rect.x = pipeline_param->output_region->x; + dst_rect.y = pipeline_param->output_region->y; + dst_rect.width = pipeline_param->output_region->width; + dst_rect.height = pipeline_param->output_region->height; + } else { + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = obj_dst_surf->orig_width; + dst_rect.height = obj_dst_surf->orig_height; + } + + if(obj_src_surf->fourcc == VA_FOURCC_P010) { + vpp_stage1 = 1; + vpp_stage2 = 0; + vpp_stage3 = 0; + if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL) { + if(src_rect.x != dst_rect.x || + src_rect.y != dst_rect.y || + src_rect.width != dst_rect.width || + src_rect.height != dst_rect.height) + vpp_stage2 = 1; + + if(obj_dst_surf->fourcc != VA_FOURCC_NV12 && + obj_dst_surf->fourcc != VA_FOURCC_P010) + vpp_stage2 = 1; + } + else + vpp_stage2 = 1; + + if(vpp_stage2 == 1) { + if(obj_dst_surf->fourcc == VA_FOURCC_P010) + vpp_stage3 = 1; + } + } + else if(obj_dst_surf->fourcc == VA_FOURCC_P010) { + vpp_stage2 = 1; + vpp_stage3 = 1; + + if((obj_src_surf->fourcc == VA_FOURCC_NV12) && + (pipeline_param->num_filters == 0 || pipeline_param->filters == NULL)) { + if((src_rect.x == dst_rect.x) && + (src_rect.y == dst_rect.y) && + (src_rect.width == dst_rect.width) && + (src_rect.height == dst_rect.height)) + vpp_stage2 = 0; + } + } + + if(vpp_stage1 == 1){ + memset((void *)&pipeline_param2, 0, sizeof(pipeline_param2)); + pipeline_param2.surface = pipeline_param->surface; + pipeline_param2.surface_region = &src_rect; + pipeline_param2.output_region = &src_rect; + pipeline_param2.filter_flags = 0; + pipeline_param2.num_filters = 0; + + proc_ctx->pipeline_param = &pipeline_param2; + + if(vpp_stage2 == 1) { + status = i965_CreateSurfaces(ctx, + obj_src_surf->orig_width, + obj_src_surf->orig_height, + VA_RT_FORMAT_YUV420, + 1, + &out_surface_id1); + assert(status == VA_STATUS_SUCCESS); + tmp_surfaces[num_tmp_surfaces++] = out_surface_id1; + stage1_dst_surf = SURFACE(out_surface_id1); + assert(stage1_dst_surf); + i965_check_alloc_surface_bo(ctx, stage1_dst_surf, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420); + + proc_ctx->surface_render_output_object = stage1_dst_surf; + } + + gen75_vpp_vebox(ctx, proc_ctx); + } + + if((vpp_stage3 == 1) && (vpp_stage2 == 1)) { + status = i965_CreateSurfaces(ctx, + obj_dst_surf->orig_width, + obj_dst_surf->orig_height, + VA_RT_FORMAT_YUV420, + 1, + &out_surface_id2); + assert(status == VA_STATUS_SUCCESS); + tmp_surfaces[num_tmp_surfaces++] = out_surface_id2; + stage2_dst_surf = SURFACE(out_surface_id2); + assert(stage2_dst_surf); + i965_check_alloc_surface_bo(ctx, stage2_dst_surf, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420); + } + VABufferID *filter_id = (VABufferID*) pipeline_param->filters; - - if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL ){ - /* implicity surface format coversion and scaling */ - gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context); - }else if(pipeline_param->num_filters == 1) { - struct object_buffer * obj_buf = BUFFER((*filter_id) + 0); - - assert(obj_buf && obj_buf->buffer_store && obj_buf->buffer_store->buffer); - - if (!obj_buf || - !obj_buf->buffer_store || - !obj_buf->buffer_store->buffer) { - status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; - goto error; - } - - VAProcFilterParameterBuffer* filter = - (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer; - - if (filter->type == VAProcFilterNoiseReduction || - filter->type == VAProcFilterDeinterlacing || - filter->type == VAProcFilterSkinToneEnhancement || - filter->type == VAProcFilterColorBalance){ - gen75_vpp_vebox(ctx, proc_ctx); - }else if(filter->type == VAProcFilterSharpening){ - if (obj_src_surf->fourcc != VA_FOURCC_NV12 || - obj_dst_surf->fourcc != VA_FOURCC_NV12) { - status = VA_STATUS_ERROR_UNIMPLEMENTED; + + if(vpp_stage2 == 1) { + if(stage1_dst_surf != NULL) { + proc_ctx->surface_pipeline_input_object = stage1_dst_surf; + proc_ctx->surface_render_output_object = obj_dst_surf; + + pipeline_param->surface = out_surface_id1; + } + + if(stage2_dst_surf != NULL) { + proc_ctx->surface_render_output_object = stage2_dst_surf; + + proc_st->current_render_target = out_surface_id2; + } + + proc_ctx->pipeline_param = pipeline_param; + + if(pipeline_param->num_filters == 0 || pipeline_param->filters == NULL ){ + /* implicity surface format coversion and scaling */ + + gen75_vpp_fmt_cvt(ctx, profile, codec_state, hw_context); + }else if(pipeline_param->num_filters == 1) { + struct object_buffer * obj_buf = BUFFER((*filter_id) + 0); + + assert(obj_buf && obj_buf->buffer_store && obj_buf->buffer_store->buffer); + + if (!obj_buf || + !obj_buf->buffer_store || + !obj_buf->buffer_store->buffer) { + status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; goto error; } - gen75_vpp_gpe(ctx, proc_ctx); - } - }else if (pipeline_param->num_filters >= 2) { - unsigned int i = 0; - for (i = 0; i < pipeline_param->num_filters; i++){ - struct object_buffer * obj_buf = BUFFER(pipeline_param->filters[i]); - - if (!obj_buf || - !obj_buf->buffer_store || - !obj_buf->buffer_store->buffer) { - status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; - goto error; + VAProcFilterParameterBuffer* filter = + (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer; + + if (filter->type == VAProcFilterNoiseReduction || + filter->type == VAProcFilterDeinterlacing || + filter->type == VAProcFilterSkinToneEnhancement || + filter->type == VAProcFilterColorBalance){ + gen75_vpp_vebox(ctx, proc_ctx); + }else if(filter->type == VAProcFilterSharpening){ + if (proc_ctx->surface_pipeline_input_object->fourcc != VA_FOURCC_NV12 || + proc_ctx->surface_render_output_object->fourcc != VA_FOURCC_NV12) { + status = VA_STATUS_ERROR_UNIMPLEMENTED; + goto error; + } + + gen75_vpp_gpe(ctx, proc_ctx); + } + }else if (pipeline_param->num_filters >= 2) { + unsigned int i = 0; + for (i = 0; i < pipeline_param->num_filters; i++){ + struct object_buffer * obj_buf = BUFFER(pipeline_param->filters[i]); + + if (!obj_buf || + !obj_buf->buffer_store || + !obj_buf->buffer_store->buffer) { + status = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; + goto error; + } + + VAProcFilterParameterBuffer* filter = + (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer; + + if (filter->type != VAProcFilterNoiseReduction && + filter->type != VAProcFilterDeinterlacing && + filter->type != VAProcFilterSkinToneEnhancement && + filter->type != VAProcFilterColorBalance) { + fprintf(stderr, "Do not support multiply filters outside vebox pipeline \n"); + assert(0); + } } + gen75_vpp_vebox(ctx, proc_ctx); + } + } - VAProcFilterParameterBuffer* filter = - (VAProcFilterParameterBuffer*)obj_buf-> buffer_store->buffer; + if(vpp_stage3 == 1) + { + if(vpp_stage2 == 1) { + memset(&pipeline_param2, 0, sizeof(pipeline_param2)); + pipeline_param2.surface = out_surface_id2; + pipeline_param2.surface_region = &dst_rect; + pipeline_param2.output_region = &dst_rect; + pipeline_param2.filter_flags = 0; + pipeline_param2.num_filters = 0; + + proc_ctx->pipeline_param = &pipeline_param2; + proc_ctx->surface_pipeline_input_object = proc_ctx->surface_render_output_object; + proc_ctx->surface_render_output_object = obj_dst_surf; + } + + gen75_vpp_vebox(ctx, proc_ctx); + } - if (filter->type != VAProcFilterNoiseReduction && - filter->type != VAProcFilterDeinterlacing && - filter->type != VAProcFilterSkinToneEnhancement && - filter->type != VAProcFilterColorBalance) { - fprintf(stderr, "Do not support multiply filters outside vebox pipeline \n"); - assert(0); - } - } - gen75_vpp_vebox(ctx, proc_ctx); - } + if (num_tmp_surfaces) + i965_DestroySurfaces(ctx, + tmp_surfaces, + num_tmp_surfaces); return VA_STATUS_SUCCESS; error: + if (num_tmp_surfaces) + i965_DestroySurfaces(ctx, + tmp_surfaces, + num_tmp_surfaces); + return status; } diff --git a/src/gen75_vpp_vebox.c b/src/gen75_vpp_vebox.c index 06c27f8..1b4232d 100644 --- a/src/gen75_vpp_vebox.c +++ b/src/gen75_vpp_vebox.c @@ -1408,7 +1408,9 @@ int hsw_veb_pre_format_convert(VADriverContextP ctx, } else if(obj_surf_input->fourcc == VA_FOURCC_AYUV || obj_surf_input->fourcc == VA_FOURCC_YUY2 || - obj_surf_input->fourcc == VA_FOURCC_NV12){ + obj_surf_input->fourcc == VA_FOURCC_NV12 || + obj_surf_input->fourcc == VA_FOURCC_P010){ + // nothing to do here } else { /* not support other format as input */ @@ -1447,7 +1449,9 @@ int hsw_veb_pre_format_convert(VADriverContextP ctx, proc_ctx->format_convert_flags |= POST_FORMAT_CONVERT; } else if(obj_surf_output->fourcc == VA_FOURCC_AYUV || obj_surf_output->fourcc == VA_FOURCC_YUY2 || - obj_surf_output->fourcc == VA_FOURCC_NV12){ + obj_surf_input->fourcc == VA_FOURCC_NV12 || + obj_surf_input->fourcc == VA_FOURCC_P010){ + /* Nothing to do here */ } else { /* not support other format as input */ @@ -1602,6 +1606,11 @@ gen75_vebox_init_filter_params(VADriverContextP ctx, proc_ctx->is_first_frame = 0; proc_ctx->is_second_field = 0; + if(!proc_ctx->is_di_enabled && !proc_ctx->is_dn_enabled) { + // MUST enable IECP if all DI&DN are disabled + proc_ctx->is_iecp_enabled = 1; + } + /* Check whether we are deinterlacing the second field */ if (proc_ctx->is_di_enabled) { const VAProcFilterParameterBufferDeinterlacing * const deint_params = @@ -2290,7 +2299,8 @@ void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *pro assert(obj_surf->fourcc == VA_FOURCC_NV12 || obj_surf->fourcc == VA_FOURCC_YUY2 || obj_surf->fourcc == VA_FOURCC_AYUV || - obj_surf->fourcc == VA_FOURCC_RGBA); + obj_surf->fourcc == VA_FOURCC_RGBA || + obj_surf->fourcc == VA_FOURCC_P010); if (obj_surf->fourcc == VA_FOURCC_NV12) { surface_format = PLANAR_420_8; @@ -2312,6 +2322,11 @@ void skl_veb_surface_state(VADriverContextP ctx, struct intel_vebox_context *pro surface_pitch = obj_surf->width * 4; is_uv_interleaved = 0; half_pitch_chroma = 0; + } else if (obj_surf->fourcc == VA_FOURCC_P010) { + surface_format = PLANAR_420_16; + surface_pitch = obj_surf->width; + is_uv_interleaved = 1; + half_pitch_chroma = 0; } derived_pitch = surface_pitch; diff --git a/src/i965_device_info.c b/src/i965_device_info.c index 4921922..b14fda9 100644 --- a/src/i965_device_info.c +++ b/src/i965_device_info.c @@ -401,6 +401,7 @@ static struct hw_codec_info bxt_hw_codec_info = { .has_hevc_encoding = 1, .has_hevc10_decoding = 1, .has_vp9_decoding = 1, + .has_vpp_p010 = 1, .num_filters = 5, .filters = { @@ -412,7 +413,6 @@ static struct hw_codec_info bxt_hw_codec_info = { }, }; - struct hw_codec_info * i965_get_codec_info(int devid) { diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index db82b27..cfdce2b 100644 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -112,6 +112,9 @@ #define HAS_HEVC10_DECODING(ctx) ((ctx)->codec_info->has_hevc10_decoding && \ (ctx)->intel.has_bsd) +#define HAS_VPP_P010(ctx) ((ctx)->codec_info->has_vpp_p010 && \ + (ctx)->intel.has_bsd) + static int get_sampling_from_fourcc(unsigned int fourcc); /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */ @@ -878,6 +881,12 @@ i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile, if (HAS_HEVC10_DECODING(i965) && entrypoint == VAEntrypointVLD) chroma_formats |= i965->codec_info->hevc_dec_chroma_formats; break; + + case VAProfileNone: + if(HAS_VPP_P010(i965)) + chroma_formats |= VA_RT_FORMAT_YUV420_10BPP; + break; + default: break; } @@ -5688,6 +5697,14 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx, attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE; attribs[i].value.value.i = VA_FOURCC_YV16; i++; + + if(HAS_VPP_P010(i965)) { + attribs[i].type = VASurfaceAttribPixelFormat; + attribs[i].value.type = VAGenericValueTypeInteger; + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE; + attribs[i].value.value.i = VA_FOURCC_P010; + i++; + } } } } diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h index bdb7512..36a9039 100644 --- a/src/i965_drv_video.h +++ b/src/i965_drv_video.h @@ -388,6 +388,7 @@ struct hw_codec_info unsigned int has_hevc_encoding:1; unsigned int has_hevc10_decoding:1; unsigned int has_vp9_decoding:1; + unsigned int has_vpp_p010:1; unsigned int num_filters; struct i965_filter filters[VAProcFilterCount]; -- cgit v1.2.3