From: Xiang, Haihao Date: Tue, 14 Jun 2011 01:49:44 +0000 (+0800) Subject: i965_drv_video: fix GPU hang issue when decoding field coded MPEG2 picture. X-Git-Tag: libva-1.0.14~27 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=47c66d7ed68bebb0ad6f5ef7279f69eeefadcd12;p=platform%2Fupstream%2Flibva.git i965_drv_video: fix GPU hang issue when decoding field coded MPEG2 picture. Signed-off-by: Xiang, Haihao --- diff --git a/i965_drv_video/gen6_mfd.c b/i965_drv_video/gen6_mfd.c index e6abb32..9a5ab56 100644 --- a/i965_drv_video/gen6_mfd.c +++ b/i965_drv_video/gen6_mfd.c @@ -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 | diff --git a/i965_drv_video/gen7_mfd.c b/i965_drv_video/gen7_mfd.c index d2933a2..1fa6c2f 100644 --- a/i965_drv_video/gen7_mfd.c +++ b/i965_drv_video/gen7_mfd.c @@ -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 | diff --git a/i965_drv_video/i965_defines.h b/i965_drv_video/i965_defines.h index a14e111..509ae9e 100644 --- a/i965_drv_video/i965_defines.h +++ b/i965_drv_video/i965_defines.h @@ -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 : \ diff --git a/i965_drv_video/i965_media.h b/i965_drv_video/i965_media.h index 2bb6bb2..e309d5b 100644 --- a/i965_drv_video/i965_media.h +++ b/i965_drv_video/i965_media.h @@ -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 diff --git a/i965_drv_video/i965_media_mpeg2.c b/i965_drv_video/i965_media_mpeg2.c index d2a51aa..bc3e048 100644 --- a/i965_drv_video/i965_media_mpeg2.c +++ b/i965_drv_video/i965_media_mpeg2.c @@ -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);