[Libva] [PATCH V2][libva-intel-driver] support VP9 profile2 10bits decoding

peng.chen peng.c.chen at intel.com
Tue Jan 26 23:13:43 PST 2016


v2:
ignore bit_depth for profile0,1
add the support of enum VAProfileVP9Profile2

v1:
initial

Signed-off-by: peng.chen <peng.c.chen at intel.com>
---
 src/gen9_mfd.c           | 51 +++++++++++++++++++++++++++++++++++++++++-------
 src/i965_decoder_utils.c | 27 ++++++++++++++++++++++---
 src/i965_device_info.c   | 12 ++++++++++++
 src/i965_drv_video.c     | 42 +++++++++++++++++++++++++++------------
 src/i965_drv_video.h     |  3 +++
 5 files changed, 113 insertions(+), 22 deletions(-)

diff --git a/src/gen9_mfd.c b/src/gen9_mfd.c
index e9afb22..72c7183 100644
--- a/src/gen9_mfd.c
+++ b/src/gen9_mfd.c
@@ -1341,6 +1341,7 @@ gen9_hcpd_vp9_decode_init(VADriverContextP ctx,
     struct object_surface *obj_surface;
     uint32_t size;
     int width_in_mbs=0, height_in_mbs=0;
+    int bit_depth_minus8 = 0;
 
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
@@ -1352,6 +1353,23 @@ gen9_hcpd_vp9_decode_init(VADriverContextP ctx,
     assert(width_in_mbs > 0 && width_in_mbs <= 256); /* 4K */
     assert(height_in_mbs > 0 && height_in_mbs <= 256);
 
+    if(!(i965->codec_info->vp9_dec_profiles & (1U<<pic_param->profile)))
+        return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+
+    if(pic_param->profile >= 2)
+    {
+        if(pic_param->bit_depth >= 8)
+            bit_depth_minus8 = pic_param->bit_depth - 8;
+
+        if(bit_depth_minus8 == 2)
+        {
+            if(!(i965->codec_info->vp9_dec_chroma_formats & VA_RT_FORMAT_YUV420_10BPP))
+                return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+        }
+        else if((bit_depth_minus8 > 2) || (bit_depth_minus8 == 1) || (bit_depth_minus8 < 0))
+            return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+    }
+
     //Update the frame store buffers with the reference frames information
     intel_update_vp9_frame_store_index(ctx,
                                         decode_state,
@@ -1381,12 +1399,18 @@ gen9_hcpd_vp9_decode_init(VADriverContextP ctx,
 
     gen9_hcpd_init_vp9_surface(ctx, pic_param, obj_surface, gen9_hcpd_context);
 
-    size = gen9_hcpd_context->picture_width_in_ctbs*18; //num_width_in_SB * 18
+    if(pic_param->profile >= 2)
+        size = gen9_hcpd_context->picture_width_in_ctbs*36; //num_width_in_SB * 36
+    else
+        size = gen9_hcpd_context->picture_width_in_ctbs*18; //num_width_in_SB * 18
     size<<=6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer), "line buffer", size);
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer), "tile line buffer", size);
 
-    size = gen9_hcpd_context->picture_height_in_ctbs*17; //num_height_in_SB * 17
+    if(pic_param->profile >= 2)
+        size = gen9_hcpd_context->picture_height_in_ctbs*34; //num_height_in_SB * 17
+    else
+        size = gen9_hcpd_context->picture_height_in_ctbs*17; //num_height_in_SB * 17
     size<<=6;
     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer), "tile column buffer", size);
 
@@ -1437,7 +1461,7 @@ gen9_hcpd_vp9_surface_state(VADriverContextP ctx,
                   (0 << 28) |                   /* surface id */
                   (obj_surface->width - 1));    /* pitch - 1 */
     OUT_BCS_BATCH(batch,
-                  (SURFACE_FORMAT_PLANAR_420_8 << 28) |
+                  (((obj_surface->fourcc == VA_FOURCC_P010) ? SURFACE_FORMAT_P010: SURFACE_FORMAT_PLANAR_420_8) << 28) |
                   y_cb_offset);
     ADVANCE_BCS_BATCH(batch);
 
@@ -1455,7 +1479,7 @@ gen9_hcpd_vp9_surface_state(VADriverContextP ctx,
                 ((i + 2) << 28) |                   /* surface id */
                 (obj_surface->width - 1));    /* pitch - 1 */
             OUT_BCS_BATCH(batch,
-                (SURFACE_FORMAT_PLANAR_420_8 << 28) |
+                (((obj_surface->fourcc == VA_FOURCC_P010) ? SURFACE_FORMAT_P010: SURFACE_FORMAT_PLANAR_420_8) << 28) |
                 obj_surface->y_cb_offset);
             ADVANCE_BCS_BATCH(batch);
         }else
@@ -1467,7 +1491,7 @@ gen9_hcpd_vp9_surface_state(VADriverContextP ctx,
                 ((i + 2) << 28) |                   /* surface id */
                 (tmp_obj_surface->width - 1));    /* pitch - 1 */
             OUT_BCS_BATCH(batch,
-                (SURFACE_FORMAT_PLANAR_420_8 << 28) |
+                (((tmp_obj_surface->fourcc == VA_FOURCC_P010) ? SURFACE_FORMAT_P010: SURFACE_FORMAT_PLANAR_420_8) << 28) |
                 tmp_obj_surface->y_cb_offset);
             ADVANCE_BCS_BATCH(batch);
         }
@@ -1571,6 +1595,8 @@ gen9_hcpd_vp9_pic_state(VADriverContextP ctx,
     uint16_t fwidth = 64;
     uint16_t fheight = 64;
     int i;
+    int bit_depth_minus8 = 0;
+
 #define LEN_COMMAND_OWN 12
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer;
@@ -1628,6 +1654,12 @@ gen9_hcpd_vp9_pic_state(VADriverContextP ctx,
     fwidth = (fwidth > frame_width_in_pixel)?frame_width_in_pixel:fwidth;
     fheight = (fheight > frame_height_in_pixel)?frame_height_in_pixel:fheight;
 
+    if(pic_param->profile >= 2)
+    {
+        if(pic_param->bit_depth >= 8)
+            bit_depth_minus8 = pic_param->bit_depth - 8;
+    }
+
     BEGIN_BCS_BATCH(batch, LEN_COMMAND_OWN);
 
     OUT_BCS_BATCH(batch, HCP_VP9_PIC_STATE | (LEN_COMMAND_OWN - 2));
@@ -1660,7 +1692,9 @@ gen9_hcpd_vp9_pic_state(VADriverContextP ctx,
                   adapt_probabilities_flag << 1 |
                   pic_param->pic_fields.bits.frame_type <<0);               /* DW 2 */
     OUT_BCS_BATCH(batch,
-        HCP_VP9_PROFILE0 << 28 |  /* Profile 0 only supports 8 bit 420 only */
+        pic_param->profile << 28 |
+        bit_depth_minus8 << 24 |
+        0 << 22 | /* only support 4:2:0 */
         pic_param->log2_tile_rows << 8 |
         pic_param->log2_tile_columns <<0);                       /* DW 3 */
     // resolution change case
@@ -1933,6 +1967,7 @@ gen9_hcpd_decode_picture(VADriverContextP ctx,
         vaStatus = gen9_hcpd_hevc_decode_picture(ctx, decode_state, gen9_hcpd_context);
         break;
     case VAProfileVP9Profile0:
+    case VAProfileVP9Profile2:
         vaStatus = gen9_hcpd_vp9_decode_picture(ctx, decode_state, gen9_hcpd_context);
         break;
 
@@ -2025,6 +2060,7 @@ gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config
         gen9_hcpd_hevc_context_init(ctx, gen9_hcpd_context);
         break;
     case VAProfileVP9Profile0:
+    case VAProfileVP9Profile2:
         gen9_hcpd_vp9_context_init(ctx, gen9_hcpd_context);
         break;
 
@@ -2040,7 +2076,8 @@ gen9_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
 {
     if (obj_config->profile == VAProfileHEVCMain ||
         obj_config->profile == VAProfileHEVCMain10 ||
-        obj_config->profile == VAProfileVP9Profile0) {
+        obj_config->profile == VAProfileVP9Profile0 ||
+        obj_config->profile == VAProfileVP9Profile2) {
         return gen9_hcpd_context_init(ctx, obj_config);
     } else {
         return gen8_dec_hw_context_init(ctx, obj_config);
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 892f3cf..df0abe2 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -1225,9 +1225,25 @@ vp9_ensure_surface_bo(
 )
 {
     VAStatus va_status = VA_STATUS_SUCCESS;
+    int update = 0;
+    unsigned int fourcc = VA_FOURCC_NV12;
+
+    if(pic_param->profile >= 2)
+    {
+        if(obj_surface->fourcc != VA_FOURCC_P010)
+        {
+            update = 1;
+            fourcc = VA_FOURCC_P010;
+        }
+    }
+    else if(obj_surface->fourcc != VA_FOURCC_NV12)
+    {
+        update = 1;
+        fourcc = VA_FOURCC_NV12;
+    }
 
     /* (Re-)allocate the underlying surface buffer store, if necessary */
-    if (!obj_surface->bo || obj_surface->fourcc != VA_FOURCC_NV12) {
+    if (!obj_surface->bo || update) {
         struct i965_driver_data * const i965 = i965_driver_data(ctx);
 
         i965_destroy_surface_storage(obj_surface);
@@ -1235,7 +1251,7 @@ vp9_ensure_surface_bo(
         va_status = i965_check_alloc_surface_bo(ctx,
                                                 obj_surface,
                                                 i965->codec_info->has_tiled_surface,
-                                                VA_FOURCC_NV12,
+                                                fourcc,
                                                 SUBSAMPLE_YUV420);
     }
 
@@ -1313,6 +1329,7 @@ error:
 //then sets the reference frames in the decode_state
 static VAStatus
 intel_decoder_check_vp9_parameter(VADriverContextP ctx,
+                                   VAProfile profile,
                                    struct decode_state *decode_state)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
@@ -1321,6 +1338,9 @@ intel_decoder_check_vp9_parameter(VADriverContextP ctx,
     struct object_surface *obj_surface;
     int i=0, index=0;
 
+    if((profile - VAProfileVP9Profile0) < pic_param->profile)
+        return va_status;
+
     //Max support upto 4k for BXT
     if ((pic_param->frame_width-1 < 0) || (pic_param->frame_width-1 > 4095))
         return va_status;
@@ -1420,7 +1440,8 @@ intel_decoder_sanity_check_input(VADriverContextP ctx,
         break;
 
     case VAProfileVP9Profile0:
-        vaStatus = intel_decoder_check_vp9_parameter(ctx, decode_state);
+    case VAProfileVP9Profile2:
+        vaStatus = intel_decoder_check_vp9_parameter(ctx, profile, decode_state);
         break;
 
     default:
diff --git a/src/i965_device_info.c b/src/i965_device_info.c
index da95916..a556bba 100644
--- a/src/i965_device_info.c
+++ b/src/i965_device_info.c
@@ -48,10 +48,16 @@
 #define EXTRA_HEVC_DEC_CHROMA_FORMATS \
     (VA_RT_FORMAT_YUV420_10BPP)
 
+#define EXTRA_VP9_DEC_CHROMA_FORMATS \
+    (VA_RT_FORMAT_YUV420_10BPP)
+
 /* Defines VA profile as a 32-bit unsigned integer mask */
 #define VA_PROFILE_MASK(PROFILE) \
     (1U << VAProfile##PROFILE)
 
+#define VP9_PROFILE_MASK(PROFILE) \
+    (1U << PROFILE)
+
 extern struct hw_context *i965_proc_context_init(VADriverContextP, struct object_config *);
 extern struct hw_context *g4x_dec_hw_context_init(VADriverContextP, struct object_config *);
 extern bool genx_render_init(VADriverContextP);
@@ -376,6 +382,8 @@ static struct hw_codec_info bxt_hw_codec_info = {
 
     .h264_mvc_dec_profiles = (VA_PROFILE_MASK(H264StereoHigh) |
                               VA_PROFILE_MASK(H264MultiviewHigh)),
+    .vp9_dec_profiles = VP9_PROFILE_MASK(0),
+
     .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
     .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
     .jpeg_enc_chroma_formats = EXTRA_JPEG_ENC_CHROMA_FORMATS,
@@ -426,10 +434,14 @@ static struct hw_codec_info kbl_hw_codec_info = {
 
     .h264_mvc_dec_profiles = (VA_PROFILE_MASK(H264StereoHigh) |
                               VA_PROFILE_MASK(H264MultiviewHigh)),
+    .vp9_dec_profiles = VP9_PROFILE_MASK(0) |
+                        VP9_PROFILE_MASK(2),
+
     .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
     .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
     .jpeg_enc_chroma_formats = EXTRA_JPEG_ENC_CHROMA_FORMATS,
     .hevc_dec_chroma_formats = EXTRA_HEVC_DEC_CHROMA_FORMATS,
+    .vp9_dec_chroma_formats = EXTRA_VP9_DEC_CHROMA_FORMATS,
 
     .has_mpeg2_decoding = 1,
     .has_mpeg2_encoding = 1,
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 0524eff..c5bec33 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -109,6 +109,10 @@
 #define HAS_VP9_DECODING(ctx)          ((ctx)->codec_info->has_vp9_decoding && \
                                          (ctx)->intel.has_bsd)
 
+#define HAS_VP9_DECODING_PROFILE(ctx, profile)                     \
+    (HAS_VP9_DECODING(ctx) &&                                      \
+     ((ctx)->codec_info->vp9_dec_profiles & (1U << (profile - VAProfileVP9Profile0))))
+
 #define HAS_HEVC10_DECODING(ctx)        ((ctx)->codec_info->has_hevc10_decoding && \
                                          (ctx)->intel.has_bsd)
 
@@ -599,10 +603,14 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileHEVCMain10;
     }
 
-    if(HAS_VP9_DECODING(i965)) {
+    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0)) {
         profile_list[i++] = VAProfileVP9Profile0;
     }
 
+    if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile2)) {
+        profile_list[i++] = VAProfileVP9Profile2;
+    }
+
     if (i965->wrapper_pdrvctx) {
         VAProfile wrapper_list[4];
         int wrapper_num;
@@ -713,18 +721,21 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
         break;
 
     case VAProfileVP9Profile0:
-        if(HAS_VP9_DECODING(i965))
+    case VAProfileVP9Profile2:
+        if(HAS_VP9_DECODING_PROFILE(i965, profile))
             entrypoint_list[n++] = VAEntrypointVLD;
 
-        if (i965->wrapper_pdrvctx) {
-            VAStatus va_status = VA_STATUS_SUCCESS;
-            VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
+        if(profile == VAProfileVP9Profile0) {
+          if (i965->wrapper_pdrvctx) {
+              VAStatus va_status = VA_STATUS_SUCCESS;
+              VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
 
-            CALL_VTABLE(pdrvctx, va_status,
-                        vaQueryConfigEntrypoints(pdrvctx, profile,
-                                                 entrypoint_list,
-                                                 num_entrypoints));
-            return va_status;
+              CALL_VTABLE(pdrvctx, va_status,
+                          vaQueryConfigEntrypoints(pdrvctx, profile,
+                                                   entrypoint_list,
+                                                   num_entrypoints));
+              return va_status;
+          }
         }
 
         break;
@@ -835,9 +846,10 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
         break;
 
     case VAProfileVP9Profile0:
-        if ((HAS_VP9_DECODING(i965)) && (entrypoint == VAEntrypointVLD))
+    case VAProfileVP9Profile2:
+        if ((HAS_VP9_DECODING_PROFILE(i965, profile)) && (entrypoint == VAEntrypointVLD))
             va_status = VA_STATUS_SUCCESS;
-        else if (i965->wrapper_pdrvctx)
+        else if ((profile == VAProfileVP9Profile0) && i965->wrapper_pdrvctx)
             va_status = VA_STATUS_SUCCESS;
         else
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
@@ -888,6 +900,12 @@ i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
             chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
         break;
 
+    case VAProfileVP9Profile0:
+    case VAProfileVP9Profile2:
+        if (HAS_VP9_DECODING_PROFILE(i965, profile) && entrypoint == VAEntrypointVLD)
+            chroma_formats |= i965->codec_info->vp9_dec_chroma_formats;
+        break;
+
     default:
         break;
     }
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 36a9039..c86ace7 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -362,10 +362,13 @@ struct hw_codec_info
     int min_linear_hpitch;
 
     unsigned int h264_mvc_dec_profiles;
+    unsigned int vp9_dec_profiles;
+
     unsigned int h264_dec_chroma_formats;
     unsigned int jpeg_dec_chroma_formats;
     unsigned int jpeg_enc_chroma_formats;
     unsigned int hevc_dec_chroma_formats;
+    unsigned int vp9_dec_chroma_formats;
 
     unsigned int has_mpeg2_decoding:1;
     unsigned int has_mpeg2_encoding:1;
-- 
1.9.1



More information about the Libva mailing list