OSDN Git Service

Encoding: Add one ROI flag and ROI buffer
[android-x86/hardware-intel-common-vaapi.git] / src / gen7_vme.c
index 7b116ad..7927ce1 100644 (file)
@@ -227,7 +227,7 @@ gen7_vme_output_vme_batchbuffer_setup(VADriverContextP ctx,
     int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
 
     vme_context->vme_batchbuffer.num_blocks = width_in_mbs * height_in_mbs + 1;
-    vme_context->vme_batchbuffer.size_block = 32; /* 2 OWORDs */
+    vme_context->vme_batchbuffer.size_block = 64; /* 4 OWORDs */
     vme_context->vme_batchbuffer.pitch = 16;
     vme_context->vme_batchbuffer.bo = dri_bo_alloc(i965->intel.bufmgr, 
                                                    "VME batchbuffer",
@@ -270,6 +270,9 @@ gen7_vme_surface_setup(VADriverContextP ctx,
     /* VME output */
     gen7_vme_output_buffer_setup(ctx, encode_state, 3, encoder_context);
     gen7_vme_output_vme_batchbuffer_setup(ctx, encode_state, 5, encoder_context);
+    intel_h264_setup_cost_surface(ctx, encode_state, encoder_context,
+                                  BINDING_TABLE_OFFSET(INTEL_COST_TABLE_OFFSET),
+                                  SURFACE_STATE_OFFSET(INTEL_COST_TABLE_OFFSET));
 
     return VA_STATUS_SUCCESS;
 }
@@ -371,58 +374,117 @@ static VAStatus gen7_vme_avc_state_setup(VADriverContextP ctx,
     int i;
     VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
     unsigned int is_low_quality = (encoder_context->quality_level == ENCODER_LOW_QUALITY);
+    dri_bo *cost_bo;
+    int slice_type;
+    uint8_t *cost_ptr;
+    int qp;
+
+    slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
+
+    if (slice_type == SLICE_TYPE_I) {
+        cost_bo = vme_context->i_qp_cost_table;
+    } else if (slice_type == SLICE_TYPE_P) {
+        cost_bo = vme_context->p_qp_cost_table;
+    } else {
+        cost_bo = vme_context->b_qp_cost_table;
+    }
 
     mb_cost_table = (unsigned int *)vme_context->vme_state_message;
-    //building VME state message
     dri_bo_map(vme_context->vme_state.bo, 1);
+    dri_bo_map(cost_bo, 0);
     assert(vme_context->vme_state.bo->virtual);
+    assert(cost_bo->virtual);
     vme_state_message = (unsigned int *)vme_context->vme_state.bo->virtual;
 
-    if (((slice_param->slice_type == SLICE_TYPE_P) ||
-        (slice_param->slice_type == SLICE_TYPE_SP) &&
-        !is_low_quality)) {
-        vme_state_message[0] = 0x01010101;
-        vme_state_message[1] = 0x10010101;
-        vme_state_message[2] = 0x0F0F0F0F;
-        vme_state_message[3] = 0x100F0F0F;
-        vme_state_message[4] = 0x01010101;
-        vme_state_message[5] = 0x10010101;
-        vme_state_message[6] = 0x0F0F0F0F;
-        vme_state_message[7] = 0x100F0F0F;
-        vme_state_message[8] = 0x01010101;
-        vme_state_message[9] = 0x10010101;
-        vme_state_message[10] = 0x0F0F0F0F;
-        vme_state_message[11] = 0x000F0F0F;
-        vme_state_message[12] = 0x00;
-        vme_state_message[13] = 0x00;
-    } else {
-        vme_state_message[0] = 0x10010101;
-        vme_state_message[1] = 0x100F0F0F;
-        vme_state_message[2] = 0x10010101;
-        vme_state_message[3] = 0x000F0F0F;
-        vme_state_message[4] = 0;
-        vme_state_message[5] = 0;
-        vme_state_message[6] = 0;
-        vme_state_message[7] = 0;
-        vme_state_message[8] = 0;
-        vme_state_message[9] = 0;
-        vme_state_message[10] = 0;
-        vme_state_message[11] = 0;
-        vme_state_message[12] = 0;
-        vme_state_message[13] = 0;
-    }
+    cost_ptr = (uint8_t *)cost_bo->virtual;
+
+    /* up to 8 VME_SEARCH_PATH_LUT is supported */
+    /* Two subsequent qp will share the same mode/motion-vector cost table */
+    /* the range is from 0-51 */
+    for (i = 0; i < 8; i++)  {
+
+        vme_state_message = (unsigned int *)vme_context->vme_state.bo->virtual +
+                             i * 32;
+        if ((slice_type == SLICE_TYPE_P) && !is_low_quality) {
+            vme_state_message[0] = 0x01010101;
+            vme_state_message[1] = 0x10010101;
+            vme_state_message[2] = 0x0F0F0F0F;
+            vme_state_message[3] = 0x100F0F0F;
+            vme_state_message[4] = 0x01010101;
+            vme_state_message[5] = 0x10010101;
+            vme_state_message[6] = 0x0F0F0F0F;
+            vme_state_message[7] = 0x100F0F0F;
+            vme_state_message[8] = 0x01010101;
+            vme_state_message[9] = 0x10010101;
+            vme_state_message[10] = 0x0F0F0F0F;
+            vme_state_message[11] = 0x000F0F0F;
+            vme_state_message[12] = 0x00;
+            vme_state_message[13] = 0x00;
+        } else {
+            vme_state_message[0] = 0x10010101;
+            vme_state_message[1] = 0x100F0F0F;
+            vme_state_message[2] = 0x10010101;
+            vme_state_message[3] = 0x000F0F0F;
+            vme_state_message[4] = 0;
+            vme_state_message[5] = 0;
+            vme_state_message[6] = 0;
+            vme_state_message[7] = 0;
+            vme_state_message[8] = 0;
+            vme_state_message[9] = 0;
+            vme_state_message[10] = 0;
+            vme_state_message[11] = 0;
+            vme_state_message[12] = 0;
+            vme_state_message[13] = 0;
+        }
 
-    vme_state_message[14] = (mb_cost_table[2] & 0xFFFF);
-    vme_state_message[15] = 0;
-    vme_state_message[16] = mb_cost_table[0];
-    vme_state_message[17] = mb_cost_table[1];
-    vme_state_message[18] = mb_cost_table[3];
-    vme_state_message[19] = mb_cost_table[4];
+        qp = 8 * i;
 
-    for(i = 20; i < 32; i++) {
-        vme_state_message[i] = 0;
+        /* when qp is greater than 51, use the cost_table of qp=51 to fulfill */
+        if (qp > 51) {
+            qp = 51;
+        }
+        /* Setup the four LUT sets for MbMV cost */
+        mb_cost_table = (unsigned int *)(cost_ptr + qp * 32);
+        vme_state_message[14] = (mb_cost_table[2] & 0xFFFF);
+        vme_state_message[16] = mb_cost_table[0];
+        vme_state_message[17] = mb_cost_table[1];
+        vme_state_message[18] = mb_cost_table[3];
+        vme_state_message[19] = mb_cost_table[4];
+
+        qp += 2;
+        if (qp > 51) {
+            qp = 51;
+        }
+        mb_cost_table = (unsigned int *)(cost_ptr + qp * 32);
+        vme_state_message[14] |= ((mb_cost_table[2] & 0xFFFF) << 16);
+        vme_state_message[20] = mb_cost_table[0];
+        vme_state_message[21] = mb_cost_table[1];
+        vme_state_message[22] = mb_cost_table[3];
+        vme_state_message[23] = mb_cost_table[4];
+
+        qp += 2;
+        if (qp > 51) {
+            qp = 51;
+        }
+        vme_state_message[15] = (mb_cost_table[2] & 0xFFFF);
+        vme_state_message[24] = mb_cost_table[0];
+        vme_state_message[25] = mb_cost_table[1];
+        vme_state_message[26] = mb_cost_table[3];
+        vme_state_message[27] = mb_cost_table[4];
+
+        qp += 2;
+        if (qp > 51) {
+            qp = 51;
+        }
+        mb_cost_table = (unsigned int *)(cost_ptr + qp * 32);
+        vme_state_message[15] |= ((mb_cost_table[2] & 0xFFFF) << 16);
+        vme_state_message[28] = mb_cost_table[0];
+        vme_state_message[29] = mb_cost_table[1];
+        vme_state_message[30] = mb_cost_table[3];
+        vme_state_message[31] = mb_cost_table[4];
     }
 
+    dri_bo_unmap(cost_bo);
     dri_bo_unmap( vme_context->vme_state.bo);
     return VA_STATUS_SUCCESS;
 }
@@ -487,7 +549,16 @@ gen7_vme_fill_vme_batchbuffer(VADriverContextP ctx,
     int mb_x = 0, mb_y = 0;
     int i, s, j;
     unsigned int *command_ptr;
+    struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
+    VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
+    VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
+    int qp;
+    int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
 
+    if (encoder_context->rate_control_mode == VA_RC_CQP)
+        qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
+    else
+        qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
 
     dri_bo_map(vme_context->vme_batchbuffer.bo, 1);
     command_ptr = vme_context->vme_batchbuffer.bo->virtual;
@@ -537,7 +608,7 @@ gen7_vme_fill_vme_batchbuffer(VADriverContextP ctx,
                     mb_intra_ub &= ~(INTRA_PRED_AVAIL_FLAG_D);
                 }
 
-                *command_ptr++ = (CMD_MEDIA_OBJECT | (8 - 2));
+                *command_ptr++ = (CMD_MEDIA_OBJECT | (9 - 2));
                 *command_ptr++ = kernel;
                 *command_ptr++ = 0;
                 *command_ptr++ = 0;
@@ -548,6 +619,7 @@ gen7_vme_fill_vme_batchbuffer(VADriverContextP ctx,
                 *command_ptr++ = (mb_width << 16 | mb_y << 8 | mb_x);
                 *command_ptr++ = ((encoder_context->quality_level << 24) | (1 << 16) | transform_8x8_mode_flag | (mb_intra_ub << 8));
 
+                *command_ptr++ = qp;
                 i += 1;
             }
 
@@ -615,7 +687,7 @@ static void gen7_vme_pipeline_programing(VADriverContextP ctx,
     }
 
     if ((pSliceParameter->slice_type == SLICE_TYPE_I) ||
-       (pSliceParameter->slice_type == SLICE_TYPE_I)) {
+       (pSliceParameter->slice_type == SLICE_TYPE_SI)) {
        kernel_shader = AVC_VME_INTRA_SHADER;
     } else if ((pSliceParameter->slice_type == SLICE_TYPE_P) ||
                (pSliceParameter->slice_type == SLICE_TYPE_SP)) {
@@ -669,8 +741,10 @@ static VAStatus gen7_vme_prepare(VADriverContextP ctx,
         (vme_context->h264_level != pSequenceParameter->level_idc)) {
        vme_context->h264_level = pSequenceParameter->level_idc;        
     }
-       
+
     intel_vme_update_mbmv_cost(ctx, encode_state, encoder_context);
+    intel_h264_initialize_mbmv_cost(ctx, encode_state, encoder_context);
+
     /*Setup all the memory object*/
     gen7_vme_surface_setup(ctx, encode_state, is_intra, encoder_context);
     gen7_vme_interface_setup(ctx, encode_state, encoder_context);
@@ -1018,10 +1092,20 @@ gen7_vme_context_destroy(void *context)
     dri_bo_unreference(vme_context->vme_batchbuffer.bo);
     vme_context->vme_batchbuffer.bo = NULL;
 
-    if (vme_context->vme_state_message) {
-       free(vme_context->vme_state_message);
-       vme_context->vme_state_message = NULL;
-    }
+    free(vme_context->vme_state_message);
+    vme_context->vme_state_message = NULL;
+
+    dri_bo_unreference(vme_context->i_qp_cost_table);
+    vme_context->i_qp_cost_table = NULL;
+
+    dri_bo_unreference(vme_context->p_qp_cost_table);
+    vme_context->p_qp_cost_table = NULL;
+
+    dri_bo_unreference(vme_context->b_qp_cost_table);
+    vme_context->b_qp_cost_table = NULL;
+
+    free(vme_context->qp_per_mb);
+    vme_context->qp_per_mb = NULL;
 
     free(vme_context);
 }