From 55ce72a89cd21ef22d3a30d9185bf393fa8e9cfe Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 May 2016 08:00:35 -0400 Subject: Export the Vp9 encoding profile/entrypoint for KBL Signed-off-by: Zhao Yakui Reviewed-by: Sean V Kelley --- src/i965_device_info.c | 1 + src/i965_drv_video.c | 51 +++++++++++++++++++++++++---- src/i965_drv_video.h | 2 ++ src/i965_encoder.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 6 deletions(-) diff --git a/src/i965_device_info.c b/src/i965_device_info.c index 0d9f2cd..96ea43c 100644 --- a/src/i965_device_info.c +++ b/src/i965_device_info.c @@ -468,6 +468,7 @@ static struct hw_codec_info kbl_hw_codec_info = { .has_hevc10_decoding = 1, .has_vp9_decoding = 1, .has_vpp_p010 = 1, + .has_vp9_encoding = 1, .num_filters = 5, .filters = { diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index 7ee889a..2788cce 100644 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -48,6 +48,8 @@ #include "i965_decoder.h" #include "i965_encoder.h" +#include "gen9_vp9_encapi.h" + #define CONFIG_ID_OFFSET 0x01000000 #define CONTEXT_ID_OFFSET 0x02000000 #define SURFACE_ID_OFFSET 0x04000000 @@ -122,6 +124,9 @@ #define HAS_VPP_P010(ctx) ((ctx)->codec_info->has_vpp_p010 && \ (ctx)->intel.has_bsd) +#define HAS_VP9_ENCODING(ctx) ((ctx)->codec_info->has_vp9_encoding && \ + (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) */ @@ -604,7 +609,8 @@ i965_QueryConfigProfiles(VADriverContextP ctx, profile_list[i++] = VAProfileHEVCMain10; } - if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0)) { + if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) || + HAS_VP9_ENCODING(i965)) { profile_list[i++] = VAProfileVP9Profile0; } @@ -729,6 +735,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx, if(HAS_VP9_DECODING_PROFILE(i965, profile)) entrypoint_list[n++] = VAEntrypointVLD; + if (HAS_VP9_ENCODING(i965)) + entrypoint_list[n++] = VAEntrypointEncSlice; + if(profile == VAProfileVP9Profile0) { if (i965->wrapper_pdrvctx) { VAStatus va_status = VA_STATUS_SUCCESS; @@ -854,6 +863,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile, case VAProfileVP9Profile2: if ((HAS_VP9_DECODING_PROFILE(i965, profile)) && (entrypoint == VAEntrypointVLD)) va_status = VA_STATUS_SUCCESS; + else if ((HAS_VP9_ENCODING(i965)) && (entrypoint == VAEntrypointEncSlice)) + va_status = VA_STATUS_SUCCESS; else if ((profile == VAProfileVP9Profile0) && i965->wrapper_pdrvctx) va_status = VA_STATUS_SUCCESS; else @@ -977,6 +988,8 @@ i965_GetConfigAttributes(VADriverContextP ctx, attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA | VA_ENC_PACKED_HEADER_SLICE); } + else if (profile == VAProfileVP9Profile0) + attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA; break; } else if (entrypoint == VAEntrypointEncPicture) { @@ -2216,9 +2229,12 @@ i965_CreateContext(VADriverContextP ctx, obj_context->codec_state.encode.slice_index = 0; packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders); - if (packed_attrib) + if (packed_attrib) { obj_context->codec_state.encode.packed_header_flag = packed_attrib->value; - else { + if (obj_config->profile == VAProfileVP9Profile0) + obj_context->codec_state.encode.packed_header_flag = + packed_attrib->value & VA_ENC_PACKED_HEADER_RAW_DATA; + } else { /* use the default value. SPS/PPS/RAWDATA is passed from user * while Slice_header data is generated by driver. */ @@ -2226,6 +2242,10 @@ i965_CreateContext(VADriverContextP ctx, VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_RAW_DATA; + + /* it is not used for VP9 */ + if (obj_config->profile == VAProfileVP9Profile0) + obj_context->codec_state.encode.packed_header_flag = 0; } assert(i965->codec_info->enc_hw_context_init); obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config); @@ -2601,7 +2621,16 @@ i965_MapBuffer(VADriverContextP ctx, coded_buffer_segment->status_support) { vaStatus = obj_context->hw_context->get_status(ctx, obj_context->hw_context, coded_buffer_segment); } else { - if (coded_buffer_segment->codec == CODEC_H264 || + + if (coded_buffer_segment->codec == CODEC_VP9) { + + if (obj_context == NULL) + return VA_STATUS_ERROR_ENCODING_ERROR; + + gen9_vp9_get_coded_status(ctx, (char *)coded_buffer_segment, + obj_context->hw_context); + } + else if (coded_buffer_segment->codec == CODEC_H264 || coded_buffer_segment->codec == CODEC_H264_MVC) { delimiter0 = H264_DELIMITER0; delimiter1 = H264_DELIMITER1; @@ -2628,6 +2657,9 @@ i965_MapBuffer(VADriverContextP ctx, ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE); } + if(coded_buffer_segment->codec == CODEC_VP9) { + /* it is already handled */ + } else if(coded_buffer_segment->codec == CODEC_JPEG) { for(i = 0; i < obj_buffer->size_element - header_offset - 1 - 0x1000; i++) { if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) { @@ -3242,10 +3274,14 @@ i965_encoder_render_picture(VADriverContextP ctx, vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; return vaStatus; } + if (encode->last_packed_header_type == VAEncPackedHeaderRawData || encode->last_packed_header_type == VAEncPackedHeaderSlice) { vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext); + if (obj_config->profile == VAProfileVP9Profile0) + break; + /* When the PACKED_SLICE_HEADER flag is passed, it will use * the packed_slice_header as the delimeter to decide how * the packed rawdata is inserted for the given slice. @@ -3455,11 +3491,14 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context) if (!(obj_context->codec_state.encode.seq_param || obj_context->codec_state.encode.seq_param_ext) && (VAEntrypointEncPicture != obj_config->entrypoint)) { - return VA_STATUS_ERROR_INVALID_PARAMETER; + /* The seq_param is not mandatory for VP9 encoding */ + if (obj_config->profile != VAProfileVP9Profile0) + return VA_STATUS_ERROR_INVALID_PARAMETER; } if ((obj_context->codec_state.encode.num_slice_params <=0) && (obj_context->codec_state.encode.num_slice_params_ext <=0) && - (obj_config->profile != VAProfileVP8Version0_3)) { + ((obj_config->profile != VAProfileVP8Version0_3) && + (obj_config->profile != VAProfileVP9Profile0))) { return VA_STATUS_ERROR_INVALID_PARAMETER; } diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h index 93f9921..b8d61a1 100644 --- a/src/i965_drv_video.h +++ b/src/i965_drv_video.h @@ -400,6 +400,7 @@ struct hw_codec_info unsigned int has_vp9_decoding:1; unsigned int has_vpp_p010:1; unsigned int has_lp_h264_encoding:1; + unsigned int has_vp9_encoding:1; unsigned int lp_h264_brc_mode; @@ -490,6 +491,7 @@ va_enc_packed_type_to_idx(int packed_type); #define CODEC_JPEG 3 #define CODEC_VP8 4 #define CODEC_HEVC 5 +#define CODEC_VP9 6 #define H264_DELIMITER0 0x00 #define H264_DELIMITER1 0x00 diff --git a/src/i965_encoder.c b/src/i965_encoder.c index cee27fa..1088f08 100644 --- a/src/i965_encoder.c +++ b/src/i965_encoder.c @@ -42,6 +42,8 @@ #include "gen9_mfc.h" #include "gen9_vdenc.h" +#include "gen9_vp9_encapi.h" + extern Bool gen6_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context); extern Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context); extern Bool gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context); @@ -558,6 +560,76 @@ intel_encoder_check_hevc_parameter(VADriverContextP ctx, error: return VA_STATUS_ERROR_INVALID_PARAMETER; } + +static VAStatus +intel_encoder_check_vp9_parameter(VADriverContextP ctx, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + VAEncPictureParameterBufferVP9 *pic_param; + struct object_surface *obj_surface; + struct object_buffer *obj_buffer; + int i = 0; + int is_key_frame = 0; + int index; + + if (encode_state->pic_param_ext == NULL || + encode_state->pic_param_ext->buffer == NULL) + return VA_STATUS_ERROR_INVALID_PARAMETER; + + pic_param = (VAEncPictureParameterBufferVP9 *)encode_state->pic_param_ext->buffer; + + obj_surface = SURFACE(pic_param->reconstructed_frame); + + if (!obj_surface) + goto error; + + encode_state->reconstructed_object = obj_surface; + obj_buffer = BUFFER(pic_param->coded_buf); + + if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo) + goto error; + + encode_state->coded_buf_object = obj_buffer; + + is_key_frame = !pic_param->pic_flags.bits.frame_type; + if (!is_key_frame && !pic_param->pic_flags.bits.intra_only) { + /* slot 0 is for last reference frame */ + index = pic_param->ref_flags.bits.ref_last_idx; + obj_surface = SURFACE(pic_param->reference_frames[index]); + if (obj_surface && obj_surface->bo) + encode_state->reference_objects[i++] = obj_surface; + else + encode_state->reference_objects[i++] = NULL; + + /* slot 1 is for golden reference frame */ + index = pic_param->ref_flags.bits.ref_gf_idx; + obj_surface = SURFACE(pic_param->reference_frames[index]); + if (obj_surface && obj_surface->bo) + encode_state->reference_objects[i++] = obj_surface; + else + encode_state->reference_objects[i++] = NULL; + + /* slot 2 is alt reference frame */ + index = pic_param->ref_flags.bits.ref_arf_idx; + obj_surface = SURFACE(pic_param->reference_frames[index]); + if (obj_surface && obj_surface->bo) + encode_state->reference_objects[i++] = obj_surface; + else + encode_state->reference_objects[i++] = NULL; + } + + for ( ; i < 16; i++) + encode_state->reference_objects[i] = NULL; + + return VA_STATUS_SUCCESS; + +error: + return VA_STATUS_ERROR_INVALID_PARAMETER; +} + + static VAStatus intel_encoder_sanity_check_input(VADriverContextP ctx, VAProfile profile, @@ -611,6 +683,13 @@ intel_encoder_sanity_check_input(VADriverContextP ctx, vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context); break; } + + case VAProfileVP9Profile0: { + vaStatus = intel_encoder_check_vp9_parameter(ctx, encode_state, encoder_context); + if (vaStatus != VA_STATUS_SUCCESS) + goto out; + break; + } default: vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; break; @@ -739,6 +818,10 @@ intel_enc_hw_context_init(VADriverContextP ctx, encoder_context->codec = CODEC_HEVC; break; + case VAProfileVP9Profile0: + encoder_context->codec = CODEC_VP9; + break; + default: /* Never get here */ assert(0); @@ -814,6 +897,10 @@ gen9_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config) return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_hcpe_context_init); } else if (obj_config->profile == VAProfileJPEGBaseline) return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init); + else if (obj_config->profile == VAProfileVP9Profile0) + return intel_enc_hw_context_init(ctx, obj_config, + gen9_vp9_vme_context_init, + gen9_vp9_pak_context_init); else return intel_enc_hw_context_init(ctx, obj_config, gen9_vme_context_init, gen9_mfc_context_init); } -- cgit v1.2.3