Commit 47c66d7e authored by Xiang, Haihao's avatar Xiang, Haihao

i965_drv_video: fix GPU hang issue when decoding field coded MPEG2 picture.

Signed-off-by: default avatarXiang, Haihao <haihao.xiang@intel.com>
parent 1628a5c6
......@@ -1303,15 +1303,24 @@ gen6_mfd_mpeg2_bsd_object(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
unsigned int width_in_mbs = ALIGN(pic_param->horizontal_size, 16) / 16;
unsigned int height_in_mbs = ALIGN(pic_param->vertical_size, 16) / 16;
int mb_count;
int mb_count, vpos0, hpos0, vpos1, hpos1, is_field_pic = 0;
if (next_slice_param == NULL)
mb_count = width_in_mbs * height_in_mbs -
(slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position);
else
mb_count = (next_slice_param->slice_vertical_position * width_in_mbs + next_slice_param->slice_horizontal_position) -
(slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position);
if (pic_param->picture_coding_extension.bits.picture_structure == MPEG_TOP_FIELD ||
pic_param->picture_coding_extension.bits.picture_structure == MPEG_BOTTOM_FIELD)
is_field_pic = 1;
vpos0 = slice_param->slice_vertical_position / (1 + is_field_pic);
hpos0 = slice_param->slice_horizontal_position;
if (next_slice_param == NULL) {
vpos1 = ALIGN(pic_param->vertical_size, 16) / 16 / (1 + is_field_pic);
hpos1 = 0;
} else {
vpos1 = next_slice_param->slice_vertical_position / (1 + is_field_pic);
hpos1 = next_slice_param->slice_horizontal_position;
}
mb_count = (vpos1 * width_in_mbs + hpos1) - (vpos0 * width_in_mbs + hpos0);
BEGIN_BCS_BATCH(batch, 5);
OUT_BCS_BATCH(batch, MFD_MPEG2_BSD_OBJECT | (5 - 2));
......@@ -1320,8 +1329,8 @@ gen6_mfd_mpeg2_bsd_object(VADriverContextP ctx,
OUT_BCS_BATCH(batch,
slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
OUT_BCS_BATCH(batch,
slice_param->slice_horizontal_position << 24 |
slice_param->slice_vertical_position << 16 |
hpos0 << 24 |
vpos0 << 16 |
mb_count << 8 |
(next_slice_param == NULL) << 5 |
(next_slice_param == NULL) << 3 |
......
......@@ -1258,15 +1258,24 @@ gen7_mfd_mpeg2_bsd_object(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
unsigned int width_in_mbs = ALIGN(pic_param->horizontal_size, 16) / 16;
unsigned int height_in_mbs = ALIGN(pic_param->vertical_size, 16) / 16;
int mb_count;
int mb_count, vpos0, hpos0, vpos1, hpos1, is_field_pic = 0;
if (next_slice_param == NULL)
mb_count = width_in_mbs * height_in_mbs -
(slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position);
else
mb_count = (next_slice_param->slice_vertical_position * width_in_mbs + next_slice_param->slice_horizontal_position) -
(slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position);
if (pic_param->picture_coding_extension.bits.picture_structure == MPEG_TOP_FIELD ||
pic_param->picture_coding_extension.bits.picture_structure == MPEG_BOTTOM_FIELD)
is_field_pic = 1;
vpos0 = slice_param->slice_vertical_position / (1 + is_field_pic);
hpos0 = slice_param->slice_horizontal_position;
if (next_slice_param == NULL) {
vpos1 = ALIGN(pic_param->vertical_size, 16) / 16 / (1 + is_field_pic);
hpos1 = 0;
} else {
vpos1 = next_slice_param->slice_vertical_position / (1 + is_field_pic);
hpos1 = next_slice_param->slice_horizontal_position;
}
mb_count = (vpos1 * width_in_mbs + hpos1) - (vpos0 * width_in_mbs + hpos0);
BEGIN_BCS_BATCH(batch, 5);
OUT_BCS_BATCH(batch, MFD_MPEG2_BSD_OBJECT | (5 - 2));
......@@ -1275,8 +1284,8 @@ gen7_mfd_mpeg2_bsd_object(VADriverContextP ctx,
OUT_BCS_BATCH(batch,
slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
OUT_BCS_BATCH(batch,
slice_param->slice_horizontal_position << 24 |
slice_param->slice_vertical_position << 16 |
hpos0 << 24 |
vpos0 << 16 |
mb_count << 8 |
(next_slice_param == NULL) << 5 |
(next_slice_param == NULL) << 3 |
......
......@@ -696,6 +696,10 @@
#define MFX_SURFACE_PLANAR_420_8 4
#define MFX_SURFACE_MONOCHROME 12
#define MPEG_TOP_FIELD 1
#define MPEG_BOTTOM_FIELD 2
#define MPEG_FRAME 3
#define URB_SIZE(intel) (IS_GEN7(intel->device_id) ? 4096 : \
IS_GEN6(intel->device_id) ? 1024 : \
IS_IRONLAKE(intel->device_id) ? 1024 : \
......
......@@ -40,10 +40,6 @@
#define MAX_INTERFACE_DESC 16
#define MAX_MEDIA_SURFACES 34
#define MPEG_TOP_FIELD 1
#define MPEG_BOTTOM_FIELD 2
#define MPEG_FRAME 3
struct decode_state;
struct i965_media_context
......
......@@ -877,15 +877,27 @@ i965_media_mpeg2_objects(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = media_context->base.batch;
VASliceParameterBufferMPEG2 *slice_param;
VAPictureParameterBufferMPEG2 *pic_param;
int i, j;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
for (j = 0; j < decode_state->num_slice_params; j++) {
assert(decode_state->slice_params[j] && decode_state->slice_params[j]->buffer);
assert(decode_state->slice_datas[j] && decode_state->slice_datas[j]->bo);
slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer;
for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
int vpos, hpos, is_field_pic = 0;
if (pic_param->picture_coding_extension.bits.picture_structure == MPEG_TOP_FIELD ||
pic_param->picture_coding_extension.bits.picture_structure == MPEG_BOTTOM_FIELD)
is_field_pic = 1;
assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
vpos = slice_param->slice_vertical_position / (1 + is_field_pic);
hpos = slice_param->slice_horizontal_position;
BEGIN_BATCH(batch, 6);
OUT_BATCH(batch, CMD_MEDIA_OBJECT | 4);
......@@ -895,8 +907,8 @@ i965_media_mpeg2_objects(VADriverContextP ctx,
I915_GEM_DOMAIN_SAMPLER, 0,
slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3));
OUT_BATCH(batch,
((slice_param->slice_horizontal_position << 24) |
(slice_param->slice_vertical_position << 16) |
((hpos << 24) |
(vpos << 16) |
(127 << 8) |
(slice_param->macroblock_offset & 0x7)));
OUT_BATCH(batch, slice_param->quantiser_scale_code << 24);
......
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