summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2014-07-23 13:46:17 +0800
committerZhao, Yakui <yakui.zhao@intel.com>2014-07-23 15:58:45 +0800
commit82d2ed8d7da3619c0ea467c06604f5626fc0b901 (patch)
tree4f3529be9e729ba9fe0825913f608eacf825e530
parentc5cb17ea86f0065a939d3636dd26651c93d497c8 (diff)
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 <yakui.zhao@intel.com> Tested-by: ValdikSS <iam@valdikss.org.ru> Reviewed-by: Xiang Haihao <haihao.xiang@intel.com> (cherry picked from commit 04202281135149a13a32dfb8a902debfac1331fe)
-rw-r--r--src/i965_decoder_utils.c33
1 files changed, 33 insertions, 0 deletions
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: