From c4063375dd864cc90739603a3547b8b37b78e461 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 26 Nov 2013 09:21:11 +0800 Subject: dec/mpeg2: ignore slices which aren't in raster scan order on SNB Sometimes codec layer incorrectly fills slice parameters due to the corrupted video Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71276 Signed-off-by: Xiang, Haihao --- src/gen6_mfd.c | 34 ++++++++++++---------------------- src/i965_decoder_utils.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/i965_decoder_utils.h | 8 ++++++++ 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c index afbfc4c..f2b0fdf 100755 --- a/src/gen6_mfd.c +++ b/src/gen6_mfd.c @@ -1167,9 +1167,9 @@ gen6_mfd_mpeg2_decode_picture(VADriverContextP ctx, { struct intel_batchbuffer *batch = gen6_mfd_context->base.batch; VAPictureParameterBufferMPEG2 *pic_param; - VASliceParameterBufferMPEG2 *slice_param, *next_slice_param, *next_slice_group_param; + VASliceParameterBufferMPEG2 *slice_param, *next_slice_param; dri_bo *slice_data_bo; - int i, j; + int group_idx = 0, pre_group_idx = -1, element_idx = 0; assert(decode_state->pic_param && decode_state->pic_param->buffer); pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer; @@ -1188,28 +1188,18 @@ gen6_mfd_mpeg2_decode_picture(VADriverContextP ctx, gen6_mfd_context->wa_mpeg2_slice_vertical_position = mpeg2_wa_slice_vertical_position(decode_state, pic_param); - for (j = 0; j < decode_state->num_slice_params; j++) { - assert(decode_state->slice_params && decode_state->slice_params[j]->buffer); - slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer; - slice_data_bo = decode_state->slice_datas[j]->bo; - gen6_mfd_ind_obj_base_addr_state(ctx, slice_data_bo, MFX_FORMAT_MPEG2, gen6_mfd_context); - - if (j == decode_state->num_slice_params - 1) - next_slice_group_param = NULL; - else - next_slice_group_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j + 1]->buffer; - - for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { - assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); + slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[group_idx]->buffer; - if (i < decode_state->slice_params[j]->num_elements - 1) - next_slice_param = slice_param + 1; - else - next_slice_param = next_slice_group_param; - - gen6_mfd_mpeg2_bsd_object(ctx, pic_param, slice_param, next_slice_param, gen6_mfd_context); - slice_param++; + for (; slice_param;) { + if (pre_group_idx != group_idx) { + slice_data_bo = decode_state->slice_datas[group_idx]->bo; + gen6_mfd_ind_obj_base_addr_state(ctx, slice_data_bo, MFX_FORMAT_MPEG2, gen6_mfd_context); + pre_group_idx = group_idx; } + + next_slice_param = intel_mpeg2_find_next_slice(decode_state, pic_param, slice_param, &group_idx, &element_idx); + gen6_mfd_mpeg2_bsd_object(ctx, pic_param, slice_param, next_slice_param, gen6_mfd_context); + slice_param = next_slice_param; } intel_batchbuffer_end_atomic(batch); diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c index 4ef09b5..41102ba 100644 --- a/src/i965_decoder_utils.c +++ b/src/i965_decoder_utils.c @@ -703,3 +703,44 @@ intel_decoder_sanity_check_input(VADriverContextP ctx, out: return vaStatus; } + +/* + * Return the next slice paramter + * + * Input: + * slice_param: the current slice + * *group_idx & *element_idx the current slice position in slice groups + * Output: + * Return the next slice parameter + * *group_idx & *element_idx the next slice position in slice groups, + * if the next slice is NULL, *group_idx & *element_idx will be ignored + */ +VASliceParameterBufferMPEG2 * +intel_mpeg2_find_next_slice(struct decode_state *decode_state, + VAPictureParameterBufferMPEG2 *pic_param, + VASliceParameterBufferMPEG2 *slice_param, + int *group_idx, + int *element_idx) +{ + VASliceParameterBufferMPEG2 *next_slice_param; + unsigned int width_in_mbs = ALIGN(pic_param->horizontal_size, 16) / 16; + int j = *group_idx, i = *element_idx + 1; + + for (; j < decode_state->num_slice_params; j++) { + for (; i < decode_state->slice_params[j]->num_elements; i++) { + next_slice_param = ((VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer) + i; + + if ((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)) { + *group_idx = j; + *element_idx = i; + + return next_slice_param; + } + } + + i = 0; + } + + return NULL; +} diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h index 2a71f3e..8a9fbe2 100644 --- a/src/i965_decoder_utils.h +++ b/src/i965_decoder_utils.h @@ -91,4 +91,12 @@ intel_update_vc1_frame_store_index(VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferVC1 *pic_param, GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]); + +VASliceParameterBufferMPEG2 * +intel_mpeg2_find_next_slice(struct decode_state *decode_state, + VAPictureParameterBufferMPEG2 *pic_param, + VASliceParameterBufferMPEG2 *slice_param, + int *group_idx, + int *element_idx); + #endif /* I965_DECODER_UTILS_H */ -- cgit v1.2.3