Get motion vectors of vme output by FEI interface.
Set mv to be 0x8000 when intra MB.

Signed-off-by: Zhong Li <[email protected]>
---
 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);
+       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, 
&current_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
-- 
1.7.9.5

_______________________________________________
Libva mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/libva

Reply via email to