[Libva] [PATCH 3/3] Expose h264 encoder motion vector buffer on IVB
lizhong
zhong.li at intel.com
Tue May 13 18:26:28 PDT 2014
No, function gen6_mfc_get_motion_vector() always be called,
but if FEI misc param isn't set or mv buffer isn't created, it will do
nothing.
BTW, I find a error in this patch:
dri_bo_unmap(vme_context->vme_output.bo) should be in if{}.
I will update this patch.
Thanks
Zhong
On 05/14/2014 08:58 AM, Zhao, Yakui wrote:
> On Tue, 2014-05-13 at 03:20 -0600, Zhong Li wrote:
>> Get motion vectors of vme output by FEI interface.
>> Set mv to be 0x8000 when intra MB.
>>
>> Signed-off-by: Zhong Li <zhong.li at intel.com>
>> ---
>> src/gen6_mfc.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> src/gen6_vme.h | 2 ++
>> 2 files changed, 75 insertions(+)
>>
>> diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
>> index 21db0a7..6ad26a9 100644
>> --- a/src/gen6_mfc.c
>> +++ b/src/gen6_mfc.c
>> @@ -1357,6 +1357,78 @@ 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,
>> + int misc_param_idx
>> + )
>> +{
>> + 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[misc_param_idx]->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;
>> + unsigned int *intra_mv = (unsigned int *)malloc(INTER_VME_OUTPUT_MV_IN_BYTES);
>> +
>> + dri_bo_map(vme_context->vme_output.bo , 1);
>> + msg = (unsigned int *)vme_context->vme_output.bo->virtual;
>> +
>> + for (i = 0; i < 32; i++) {
>> + intra_mv[i] = 0x80008000; //for intra mb, set mv.x and mv.y to be 0x8000
>> + }
>> +
>> + if (is_intra) {
>> + for (i = 0; i < pSliceParameter->num_macroblocks; i++) {
>> + memcpy(mv_buffer, intra_mv, INTER_VME_OUTPUT_MV_IN_BYTES);
>> + mv_buffer += INTER_VME_OUTPUT_MV_IN_BYTES;
>> + }
>> + } 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) {
>> + memcpy(mv_buffer, intra_mv, 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;
>> + }
>> + }
>> +
>> + free(intra_mv);
>> + }
>> +
>> + 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;
>> + int misc_param_idx = va_enc_misc_param_type_to_idx(VAEncMiscParameterTypeFEIFrameControlIntel);
>> +
>> + if (encode_state->misc_param[misc_param_idx]
>> + && encode_state->misc_param[misc_param_idx]->buffer) {
>> + for (i = 0; i < encode_state->num_slice_params_ext; i++) {
>> + gen6_mfc_get_slice_motion_vector(ctx, encode_state, encoder_context, i, misc_param_idx);
>> + }
>> + }
>> +}
>> +
>> VAStatus
>> gen6_mfc_avc_encode_picture(VADriverContextP ctx,
>> struct encode_state *encode_state,
>> @@ -1373,6 +1445,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);
>
> Is it called only when it is in VAEntrypointEncFEIIntel encoding mode?
>
>> + 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
>
More information about the Libva
mailing list