From 82d2ed8d7da3619c0ea467c06604f5626fc0b901 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 23 Jul 2014 13:46:17 +0800 Subject: Add more check of H264 slice param to avoid GPU hang caused by the incorrect parameter This is to fix the GPU hang in https://bugs.freedesktop.org/show_bug.cgi?id=76363 V1->V2: Use the new check based on Haihao's comment. Discard the current frame with the error slice_param instead of smart fix. In such case it can prompt that the error slice_param can be fixed by the upper-middle. Signed-off-by: Zhao Yakui Tested-by: ValdikSS Reviewed-by: Xiang Haihao (cherry picked from commit 04202281135149a13a32dfb8a902debfac1331fe) --- src/i965_decoder_utils.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c index 0539e08..546285e 100644 --- a/src/i965_decoder_utils.c +++ b/src/i965_decoder_utils.c @@ -754,6 +754,8 @@ intel_decoder_check_avc_parameter(VADriverContextP ctx, VAStatus va_status; struct object_surface *obj_surface; int i; + VASliceParameterBufferH264 *slice_param, *next_slice_param, *next_slice_group_param; + int j; assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)); assert(pic_param->CurrPic.picture_id != VA_INVALID_SURFACE); @@ -802,6 +804,37 @@ intel_decoder_check_avc_parameter(VADriverContextP ctx, } decode_state->reference_objects[i] = obj_surface; } + + for (j = 0; j < decode_state->num_slice_params; j++) { + assert(decode_state->slice_params && decode_state->slice_params[j]->buffer); + slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer; + + if (j == decode_state->num_slice_params - 1) + next_slice_group_param = NULL; + else + next_slice_group_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j + 1]->buffer; + + for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { + + if (i < decode_state->slice_params[j]->num_elements - 1) + next_slice_param = slice_param + 1; + else + next_slice_param = next_slice_group_param; + + if (next_slice_param != NULL) { + /* If the mb position of next_slice is less than or equal to the current slice, + * discard the current frame. + */ + if (next_slice_param->first_mb_in_slice <= slice_param->first_mb_in_slice) { + next_slice_param = NULL; + WARN_ONCE("!!!incorrect slice_param. The first_mb_in_slice of next_slice is less" + " than or equal to that in current slice\n"); + goto error; + } + } + } + } + return VA_STATUS_SUCCESS; error: -- cgit v1.2.3