[Libva] [PATCH V1][libva-intel-driver] support VP9 profile2 10bits decoding
peng.chen
peng.c.chen at intel.com
Sun Jan 24 18:01:16 PST 2016
Signed-off-by: peng.chen <peng.c.chen at intel.com>
---
src/gen9_mfd.c | 44 ++++++++++++++++++++++++++++++++++++++------
src/i965_decoder_utils.c | 21 +++++++++++++++++++--
src/i965_device_info.c | 12 ++++++++++++
src/i965_drv_video.c | 5 +++++
src/i965_drv_video.h | 3 +++
5 files changed, 77 insertions(+), 8 deletions(-)
diff --git a/src/gen9_mfd.c b/src/gen9_mfd.c
index e9afb22..fdd270c 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,22 @@ 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->bit_depth >= 8)
+ bit_depth_minus8 = pic_param->bit_depth - 8;
+ else
+ bit_depth_minus8 = pic_param->bit_depth;
+
+ 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 +1398,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 +1460,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 +1478,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 +1490,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 +1594,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 +1653,11 @@ 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->bit_depth >= 8)
+ bit_depth_minus8 = pic_param->bit_depth - 8;
+ else
+ bit_depth_minus8 = pic_param->bit_depth;
+
BEGIN_BCS_BATCH(batch, LEN_COMMAND_OWN);
OUT_BCS_BATCH(batch, HCP_VP9_PIC_STATE | (LEN_COMMAND_OWN - 2));
@@ -1660,7 +1690,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
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 835d3fd..70f34dd 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -1225,9 +1225,26 @@ vp9_ensure_surface_bo(
)
{
VAStatus va_status = VA_STATUS_SUCCESS;
+ int update = 0;
+ unsigned int fourcc = VA_FOURCC_NV12;
+
+ if(pic_param->profile == 2 ||
+ pic_param->profile == 3)
+ {
+ 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 +1252,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);
}
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 cd616d7..f20b4aa 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -889,6 +889,11 @@ i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
break;
+ case VAProfileVP9Profile0:
+ if (HAS_VP9_DECODING(i965) && 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