[Libva] [PATCH] Expose gen6 avc endcoer mv buffer
Zhong Li
zhong.li at intel.com
Wed May 7 23:56:15 PDT 2014
Support VAEntrypointEncFEIIntel and get motion vectors of gen6 h264 encoding
Signed-off-by: Zhong Li <zhong.li at intel.com>
---
src/gen6_mfc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/gen6_vme.h | 2 ++
src/i965_drv_video.c | 37 +++++++++++++++++++-----------
src/i965_drv_video.h | 4 +++-
4 files changed, 90 insertions(+), 14 deletions(-)
diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
index 21db0a7..c099133 100644
--- a/src/gen6_mfc.c
+++ b/src/gen6_mfc.c
@@ -1357,6 +1357,66 @@ gen6_mfc_avc_pipeline_programing(VADriverContextP ctx,
dri_bo_unreference(slice_batch_bo);
}
+static void
+gen6_mfc_get_slice_motion_vector(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ int slice_index
+ )
+{
+ struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct gen6_vme_context *vme_context = encoder_context->vme_context;
+ VAEncMiscParameterBuffer *misc_param = (VAEncMiscParameterBuffer *)encode_state->misc_param[VAEncMiscParameterTypeFEIFrameControlIntel]->buffer;
+ VAEncMiscParameterFEIFrameControlH264Intel *pFeiFrameControlParameter = (VAEncMiscParameterFEIFrameControlH264Intel *)misc_param->data;
+ VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[slice_index]->buffer;
+ unsigned int *msg = NULL;
+ int i;
+ int slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
+ int is_intra = slice_type == SLICE_TYPE_I;
+ struct object_buffer *mv_buf = BUFFER(pFeiFrameControlParameter->mv_data);
+
+ if (mv_buf && mv_buf->buffer_store && mv_buf->buffer_store->buffer) {
+ unsigned char *mv_buffer = mv_buf->buffer_store->buffer;
+
+ dri_bo_map(vme_context->vme_output.bo , 1);
+ msg = (unsigned int *)vme_context->vme_output.bo->virtual;
+
+ if (is_intra) {
+ memset(mv_buffer, 0, INTER_VME_OUTPUT_MV_IN_BYTES * pSliceParameter->num_macroblocks);
+ } else {
+ msg += pSliceParameter->macroblock_address * INTER_VME_OUTPUT_IN_DWS;
+ msg += 32; /* the first 32 DWs are MVs */
+
+ for (i = 0; i < pSliceParameter->num_macroblocks; i++) {
+ if (msg[0] & INTRA_MB_FLAG_MASK) {
+ memset(mv_buffer, 0, INTER_VME_OUTPUT_MV_IN_BYTES);
+ } else {
+ memcpy(mv_buffer, (char *)(msg - 32), INTER_VME_OUTPUT_MV_IN_BYTES);
+ }
+ mv_buffer += INTER_VME_OUTPUT_MV_IN_BYTES;
+ msg += INTER_VME_OUTPUT_IN_DWS;
+ }
+ }
+ }
+
+ dri_bo_unmap(vme_context->vme_output.bo);
+}
+
+static void
+gen6_mfc_get_motion_vector(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+ int i;
+
+ if (encode_state->misc_param[VAEncMiscParameterTypeFEIFrameControlIntel]
+ && encode_state->misc_param[VAEncMiscParameterTypeFEIFrameControlIntel]->buffer) {
+ for (i = 0; i < encode_state->num_slice_params_ext; i++) {
+ gen6_mfc_get_slice_motion_vector(ctx, encode_state, encoder_context, i);
+ }
+ }
+}
+
VAStatus
gen6_mfc_avc_encode_picture(VADriverContextP ctx,
struct encode_state *encode_state,
@@ -1373,6 +1433,7 @@ gen6_mfc_avc_encode_picture(VADriverContextP ctx,
/*Programing bcs pipeline*/
gen6_mfc_avc_pipeline_programing(ctx, encode_state, encoder_context); //filling the pipeline
gen6_mfc_run(ctx, encode_state, encoder_context);
+ gen6_mfc_get_motion_vector(ctx, encode_state, encoder_context);
if (rate_control_mode == VA_RC_CBR /*|| rate_control_mode == VA_RC_VBR*/) {
gen6_mfc_stop(ctx, encode_state, encoder_context, ¤t_frame_bits_size);
sts = intel_mfc_brc_postpack(encode_state, mfc_context, current_frame_bits_size);
diff --git a/src/gen6_vme.h b/src/gen6_vme.h
index d461982..db3fb27 100644
--- a/src/gen6_vme.h
+++ b/src/gen6_vme.h
@@ -40,6 +40,8 @@
#define INTRA_VME_OUTPUT_IN_DWS (INTRA_VME_OUTPUT_IN_BYTES / 4)
#define INTER_VME_OUTPUT_IN_BYTES 160 /* the first 128 bytes for MVs and the last 32 bytes for other info */
#define INTER_VME_OUTPUT_IN_DWS (INTER_VME_OUTPUT_IN_BYTES / 4)
+#define INTER_VME_OUTPUT_MV_IN_BYTES 128
+#define INTER_VME_OUTPUT_MV_IN_DWs (INTER_VME_OUTPUT_MV_IN_BYTES / 4)
#define MAX_INTERFACE_DESC_GEN6 MAX_GPE_KERNELS
#define MAX_MEDIA_SURFACES_GEN6 34
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index fa51651..9dc5463 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -340,8 +340,10 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
if (HAS_H264_DECODING(i965))
entrypoint_list[n++] = VAEntrypointVLD;
- if (HAS_H264_ENCODING(i965))
+ if (HAS_H264_ENCODING(i965)) {
entrypoint_list[n++] = VAEntrypointEncSlice;
+ entrypoint_list[n++] = VAEntrypointEncFEIIntel;
+ }
break;
case VAProfileH264MultiviewHigh:
@@ -405,7 +407,7 @@ i965_GetConfigAttributes(VADriverContextP ctx,
break;
case VAConfigAttribRateControl:
- if (entrypoint == VAEntrypointEncSlice) {
+ if (entrypoint == VAEntrypointEncFEIIntel || entrypoint == VAEntrypointEncSlice) {
attrib_list[i].value = VA_RC_CQP;
if (profile != VAProfileMPEG2Main &&
@@ -415,13 +417,13 @@ i965_GetConfigAttributes(VADriverContextP ctx,
}
case VAConfigAttribEncPackedHeaders:
- if (entrypoint == VAEntrypointEncSlice) {
+ if (entrypoint == VAEntrypointEncFEIIntel || entrypoint == VAEntrypointEncSlice) {
attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
break;
}
case VAConfigAttribEncMaxRefFrames:
- if (entrypoint == VAEntrypointEncSlice) {
+ if (entrypoint == VAEntrypointEncFEIIntel || entrypoint == VAEntrypointEncSlice) {
attrib_list[i].value = (1 << 16) | (1 << 0);
break;
}
@@ -497,7 +499,8 @@ i965_CreateConfig(VADriverContextP ctx,
case VAProfileH264Main:
case VAProfileH264High:
if ((HAS_H264_DECODING(i965) && VAEntrypointVLD == entrypoint) ||
- (HAS_H264_ENCODING(i965) && VAEntrypointEncSlice == entrypoint)) {
+ (HAS_H264_ENCODING(i965) &&
+ ((VAEntrypointEncFEIIntel == entrypoint) || (VAEntrypointEncSlice == entrypoint)))) {
vaStatus = VA_STATUS_SUCCESS;
} else {
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
@@ -1563,7 +1566,8 @@ i965_CreateContext(VADriverContextP ctx,
obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
assert(i965->codec_info->proc_hw_context_init);
obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
- } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
+ } else if (VAEntrypointEncFEIIntel == obj_config->entrypoint ||
+ VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
obj_context->codec_type = CODEC_ENC;
memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
@@ -1663,6 +1667,7 @@ i965_create_buffer_internal(VADriverContextP ctx,
case VAProcFilterParameterBufferType:
case VAHuffmanTableBufferType:
case VAProbabilityBufferType:
+ case VAEncFEIMVBufferTypeIntel:
/* Ok */
break;
@@ -2326,7 +2331,8 @@ i965_RenderPicture(VADriverContextP ctx,
if (VAEntrypointVideoProc == obj_config->entrypoint) {
vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
- } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
+ } else if (VAEntrypointEncFEIIntel == obj_config->entrypoint ||
+ VAEntrypointEncSlice == obj_config->entrypoint ) {
vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
} else {
vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
@@ -2349,7 +2355,7 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
if (obj_context->codec_type == CODEC_PROC) {
ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
} else if (obj_context->codec_type == CODEC_ENC) {
- ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
+ ASSERT_RET(VAEntrypointEncFEIIntel == obj_config->entrypoint || VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
if (!(obj_context->codec_state.encode.pic_param ||
obj_context->codec_state.encode.pic_param_ext)) {
@@ -4326,7 +4332,8 @@ i965_GetSurfaceAttributes(
attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
}
} else if (IS_GEN6(i965->intel.device_info)) {
- if (obj_config->entrypoint == VAEntrypointEncSlice ||
+ if (obj_config->entrypoint == VAEntrypointEncFEIIntel ||
+ obj_config->entrypoint == VAEntrypointEncSlice ||
obj_config->entrypoint == VAEntrypointVideoProc) {
switch (attrib_list[i].value.value.i) {
case VA_FOURCC_NV12:
@@ -4351,7 +4358,8 @@ i965_GetSurfaceAttributes(
}
} else if (IS_GEN7(i965->intel.device_info) ||
IS_GEN8(i965->intel.device_info)) {
- if (obj_config->entrypoint == VAEntrypointEncSlice ||
+ if (obj_config->entrypoint == VAEntrypointEncFEIIntel ||
+ obj_config->entrypoint == VAEntrypointEncSlice ||
obj_config->entrypoint == VAEntrypointVideoProc) {
switch (attrib_list[i].value.value.i) {
case VA_FOURCC_NV12:
@@ -4488,7 +4496,8 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
attribs[i].value.value.i = VA_FOURCC_NV12;
i++;
- } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
+ } else if (obj_config->entrypoint == VAEntrypointEncFEIIntel ||
+ obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].value.type = VAGenericValueTypeInteger;
@@ -4579,7 +4588,8 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
attribs[i].value.value.i = VA_FOURCC_NV12;
i++;
}
- } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
+ } else if (obj_config->entrypoint == VAEntrypointEncFEIIntel ||
+ obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
attribs[i].type = VASurfaceAttribPixelFormat;
attribs[i].value.type = VAGenericValueTypeInteger;
@@ -4682,7 +4692,8 @@ i965_QuerySurfaceAttributes(VADriverContextP ctx,
attribs[i].value.value.i = VA_FOURCC_NV12;
i++;
}
- } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
+ } else if (obj_config->entrypoint == VAEntrypointEncFEIIntel ||
+ obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
attribs[i].type = VASurfaceAttribPixelFormat;
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 0e32f7d..e2f23c6 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -36,6 +36,7 @@
#include <va/va_vpp.h>
#include <va/va_backend.h>
#include <va/va_backend_vpp.h>
+#include <va/va_intel_fei.h>
#include "i965_mutext.h"
#include "object_heap.h"
@@ -141,13 +142,14 @@ struct encode_state
int num_slice_params_ext;
int last_packed_header_type;
- struct buffer_store *misc_param[16];
+ struct buffer_store *misc_param[1010];
VASurfaceID current_render_target;
struct object_surface *input_yuv_object;
struct object_surface *reconstructed_object;
struct object_buffer *coded_buf_object;
struct object_surface *reference_objects[16]; /* Up to 2 reference surfaces are valid for MPEG-2,*/
+
};
struct proc_state
--
1.7.9.5
More information about the Libva
mailing list