Commit 849d20db authored by Xiang, Haihao's avatar Xiang, Haihao

i965_drv_video: [H.264] fix slice_data_bit_offset

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>
parent daf6ed6f
...@@ -566,11 +566,41 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx, ...@@ -566,11 +566,41 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
ADVANCE_BCS_BATCH(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 static void
g4x_avc_bsd_object(VADriverContextP ctx, g4x_avc_bsd_object(VADriverContextP ctx,
struct decode_state *decode_state, struct decode_state *decode_state,
VAPictureParameterBufferH264 *pic_param, 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 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 */ int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
...@@ -585,6 +615,7 @@ g4x_avc_bsd_object(VADriverContextP ctx, ...@@ -585,6 +615,7 @@ g4x_avc_bsd_object(VADriverContextP ctx,
int weighted_pred_idc = 0; int weighted_pred_idc = 0;
int first_mb_in_slice = 0; int first_mb_in_slice = 0;
int slice_type; int slice_type;
uint8_t *slice_data = NULL;
encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */ encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
...@@ -594,10 +625,12 @@ g4x_avc_bsd_object(VADriverContextP ctx, ...@@ -594,10 +625,12 @@ g4x_avc_bsd_object(VADriverContextP ctx,
} else } else
cmd_len = 8; cmd_len = 8;
slice_data_bit_offset = slice_param->slice_data_bit_offset; 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);
if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC) slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data,
slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8); 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 || if (slice_param->slice_type == SLICE_TYPE_I ||
slice_param->slice_type == SLICE_TYPE_SI) slice_param->slice_type == SLICE_TYPE_SI)
...@@ -693,7 +726,8 @@ static void ...@@ -693,7 +726,8 @@ static void
ironlake_avc_bsd_object(VADriverContextP ctx, ironlake_avc_bsd_object(VADriverContextP ctx,
struct decode_state *decode_state, struct decode_state *decode_state,
VAPictureParameterBufferH264 *pic_param, 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 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 */ int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
...@@ -711,6 +745,8 @@ ironlake_avc_bsd_object(VADriverContextP ctx, ...@@ -711,6 +745,8 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
int weighted_pred_idc = 0; int weighted_pred_idc = 0;
int first_mb_in_slice; int first_mb_in_slice;
int slice_type; int slice_type;
uint8_t *slice_data = NULL;
encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */ encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
if (encrypted) { if (encrypted) {
...@@ -718,10 +754,12 @@ ironlake_avc_bsd_object(VADriverContextP ctx, ...@@ -718,10 +754,12 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
} else } else
counter_value = 0; counter_value = 0;
slice_data_bit_offset = slice_param->slice_data_bit_offset; 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);
if (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_CABAC) slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data,
slice_data_bit_offset = ALIGN(slice_data_bit_offset, 0x8); 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 || if (slice_param->slice_type == SLICE_TYPE_I ||
slice_param->slice_type == SLICE_TYPE_SI) slice_param->slice_type == SLICE_TYPE_SI)
...@@ -833,14 +871,15 @@ static void ...@@ -833,14 +871,15 @@ static void
i965_avc_bsd_object(VADriverContextP ctx, i965_avc_bsd_object(VADriverContextP ctx,
struct decode_state *decode_state, struct decode_state *decode_state,
VAPictureParameterBufferH264 *pic_param, VAPictureParameterBufferH264 *pic_param,
VASliceParameterBufferH264 *slice_param) VASliceParameterBufferH264 *slice_param,
int slice_index)
{ {
struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_driver_data *i965 = i965_driver_data(ctx);
if (IS_IRONLAKE(i965->intel.device_id)) 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 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 static void
...@@ -848,7 +887,7 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx, ...@@ -848,7 +887,7 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx,
struct decode_state *decode_state, struct decode_state *decode_state,
VAPictureParameterBufferH264 *pic_param) 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 static void
...@@ -1040,7 +1079,7 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state) ...@@ -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_slice_state(ctx, pic_param, slice_param);
i965_avc_bsd_buf_base_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++; slice_param++;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment