From ab53aaf20496dc29ec3169ba84ad37e54807f1a9 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 7 Jul 2010 14:29:36 +0800 Subject: [PATCH] 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 --- i965_avc_bsd.c | 69 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/i965_avc_bsd.c b/i965_avc_bsd.c index 5cc0cec..0976439 100644 --- a/i965_avc_bsd.c +++ b/i965_avc_bsd.c @@ -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++; } } -- 2.7.4