[Libva] [PATCH V2][libva-intel-driver 1/2] VPP P010(10bits) enabling

peng.chen peng.c.chen at intel.com
Tue Jan 12 23:31:37 PST 2016


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 <peng.c.chen at intel.com>
---
 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..8699fc5 100644
--- a/src/gen75_picture_process.c
+++ b/src/gen75_picture_process.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <string.h>
 
 #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];
-- 
1.9.1



More information about the Libva mailing list