[Libva] [PATCH] Expose gen6 avc endcoer mv buffer
Gwenole Beauchesne
gb.devel at gmail.com
Fri May 9 03:15:02 PDT 2014
2014-05-08 8:56 GMT+02:00 Zhong Li <zhong.li at intel.com>:
> 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
You are increasing the size of encode_state beyond the size of a page
for no real reason/advantage. Please use a different approach where
Misc param buffers are maintained with a minimal set of members.
Mapping from VA misc buffer types to internal VA driver defs is a more
appropriate thing, for almost free: you just need to convert the buf
type once while parsing/accumulating the misc buffers through
vaRenderPicture() implementation. Next, misc buffers are accessed by
VA intel driver buf types instead.
i.e. this means another preparatory patch before this one.
Thanks,
Gwenole.
More information about the Libva
mailing list