From c4deca0af3b14d13a303a5e761a9b5d15a56f1dc Mon Sep 17 00:00:00 2001 From: "peng.chen" Date: Wed, 27 Jan 2016 15:13:43 +0800 Subject: support VP9 profile2 10bits decoding v2: ignore bit_depth for profile0,1 add the support of enum VAProfileVP9Profile2 v1: initial Signed-off-by: peng.chen (cherry picked from commit f6fe8428cc395771659a010222d0e3774b876535) --- 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<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 53f599f..6ac1d0c 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); @@ -377,6 +383,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, @@ -427,10 +435,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; -- cgit v1.2.3