[Libva] [LIBVA-INTEL-DRIVER][PATCH 09/12] Export the Vp9 encoding profile/entrypoint for KBL
Zhao Yakui
yakui.zhao at intel.com
Tue May 24 12:00:35 UTC 2016
Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Reviewed-by: Sean V Kelley <sean.v.kelley at intel.com>
---
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 932e5be..186443b 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);
@@ -2599,7 +2619,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;
@@ -2626,6 +2655,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)) {
@@ -3240,10 +3272,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.
@@ -3453,11 +3489,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);
}
--
1.8.2.1
More information about the Libva
mailing list