i965_drv_video: [H.264] fix slice_data_bit_offset
authorXiang, Haihao <haihao.xiang@intel.com>
Wed, 7 Jul 2010 06:29:36 +0000 (14:29 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Wed, 7 Jul 2010 06:54:53 +0000 (14:54 +0800)
VASliceParameterBufferH264.slice_data_bit_offset will point into the part
of slice header if there are some escaped bytes in the slice header. The offset
to slice data is needed for BSD unit so that BSD unit can fetch right slice data
for processing. This fixes conformance case BASQP1_Sony_C.jsv

The method to get the total number of bytes in the slice header is provided by Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>

i965_drv_video/i965_avc_bsd.c

index 5cc0cec..0976439 100644 (file)
@@ -566,11 +566,41 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     ADVANCE_BCS_BATCH(ctx);
 }
 
+/*
+ * Return the bit offset to the first bit of the slice data
+ *
+ * VASliceParameterBufferH264.slice_data_bit_offset will point into the part
+ * of slice header if there are some escaped bytes in the slice header. The offset 
+ * to slice data is needed for BSD unit so that BSD unit can fetch right slice data
+ * for processing. This fixes conformance case BASQP1_Sony_C.jsv
+ */
+static int
+i965_avc_bsd_get_slice_bit_offset(uint8_t *buf, int mode_flag, int in_slice_data_bit_offset)
+{
+    int out_slice_data_bit_offset;
+    int slice_header_size = in_slice_data_bit_offset / 8;
+    int i, j;
+
+    for (i = 0, j = 0; i < slice_header_size; i++, j++) {
+        if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3) {
+            i++, j += 2;
+        }
+    }
+
+    out_slice_data_bit_offset = 8 * j + in_slice_data_bit_offset % 8;
+
+    if (mode_flag == ENTROPY_CABAC)
+        out_slice_data_bit_offset = ALIGN(out_slice_data_bit_offset, 0x8);
+
+    return out_slice_data_bit_offset;
+}
+
 static void
 g4x_avc_bsd_object(VADriverContextP ctx, 
                    struct decode_state *decode_state,
                    VAPictureParameterBufferH264 *pic_param,
-                   VASliceParameterBufferH264 *slice_param)
+                   VASliceParameterBufferH264 *slice_param,
+                   int slice_index)
 {
     int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
     int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
@@ -585,6 +615,7 @@ g4x_avc_bsd_object(VADriverContextP ctx,
         int weighted_pred_idc = 0;
         int first_mb_in_slice = 0;
         int slice_type;
+        uint8_t *slice_data = NULL;
 
         encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
 
@@ -594,10 +625,12 @@ g4x_avc_bsd_object(VADriverContextP ctx,
         } else 
             cmd_len = 8;
 
-        slice_data_bit_offset = slice_param->slice_data_bit_offset;    
-
-        if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC)
-            slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8);
+        dri_bo_map(decode_state->slice_datas[slice_index]->bo, 0);
+        slice_data = (uint8_t *)(decode_state->slice_datas[slice_index]->bo->virtual + slice_param->slice_data_offset);
+        slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data,
+                                                                  pic_param->pic_fields.bits.entropy_coding_mode_flag,
+                                                                  slice_param->slice_data_bit_offset);
+        dri_bo_unmap(decode_state->slice_datas[slice_index]->bo);
 
         if (slice_param->slice_type == SLICE_TYPE_I ||
             slice_param->slice_type == SLICE_TYPE_SI)
@@ -693,7 +726,8 @@ static void
 ironlake_avc_bsd_object(VADriverContextP ctx, 
                         struct decode_state *decode_state,
                         VAPictureParameterBufferH264 *pic_param,
-                        VASliceParameterBufferH264 *slice_param)
+                        VASliceParameterBufferH264 *slice_param,
+                        int slice_index)
 {
     int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
     int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
@@ -711,6 +745,8 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
         int weighted_pred_idc = 0;
         int first_mb_in_slice;
         int slice_type;
+        uint8_t *slice_data = NULL;
+
         encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
 
         if (encrypted) {
@@ -718,10 +754,12 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
         } else 
             counter_value = 0;
 
-        slice_data_bit_offset = slice_param->slice_data_bit_offset;    
-
-        if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC)
-            slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8);
+        dri_bo_map(decode_state->slice_datas[slice_index]->bo, 0);
+        slice_data = (uint8_t *)(decode_state->slice_datas[slice_index]->bo->virtual + slice_param->slice_data_offset);
+        slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data,
+                                                                  pic_param->pic_fields.bits.entropy_coding_mode_flag,
+                                                                  slice_param->slice_data_bit_offset);
+        dri_bo_unmap(decode_state->slice_datas[slice_index]->bo);
 
         if (slice_param->slice_type == SLICE_TYPE_I ||
             slice_param->slice_type == SLICE_TYPE_SI)
@@ -833,14 +871,15 @@ static void
 i965_avc_bsd_object(VADriverContextP ctx, 
                     struct decode_state *decode_state,
                     VAPictureParameterBufferH264 *pic_param,
-                    VASliceParameterBufferH264 *slice_param)
+                    VASliceParameterBufferH264 *slice_param,
+                    int slice_index)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
 
     if (IS_IRONLAKE(i965->intel.device_id))
-        ironlake_avc_bsd_object(ctx, decode_state, pic_param, slice_param);
+        ironlake_avc_bsd_object(ctx, decode_state, pic_param, slice_param, slice_index);
     else
-        g4x_avc_bsd_object(ctx, decode_state, pic_param, slice_param);
+        g4x_avc_bsd_object(ctx, decode_state, pic_param, slice_param, slice_index);
 }
 
 static void
@@ -848,7 +887,7 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx,
                            struct decode_state *decode_state,
                            VAPictureParameterBufferH264 *pic_param)
 {
-    i965_avc_bsd_object(ctx, decode_state, pic_param, NULL);
+    i965_avc_bsd_object(ctx, decode_state, pic_param, NULL, 0);
 }
 
 static void
@@ -1040,7 +1079,7 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state)
 
             i965_avc_bsd_slice_state(ctx, pic_param, slice_param);
             i965_avc_bsd_buf_base_state(ctx, pic_param, slice_param);
-            i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param);
+            i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param, j);
             slice_param++;
         }
     }