blob: b720719d29c47283057464bbe32a4aed469cf9d4 [file] [log] [blame]
From 836b5f9a9db451e27e767486d841c24ec09645d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= <marcheu@chromium.org>
Date: Mon, 3 Nov 2014 20:07:42 -0800
Subject: [PATCH] Avoid GPU crash with malformed streams
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When streams are malformed, we can get p-frames without any reference
picture. However the code still assumes 1 reference picture at least,
which leads to a GPU crash. To protect against GPU crashes, we force 0
when we have no pictures. Do this on gen6, 7, 7.5 and 8.
BUG=chromium:252389,chroimum:418024
TEST=go to youtube and play http://www.youtube.com/watch?v=6v2L2UGZJAM ; it doesn't crash
Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
Signed-off-by: Sean V Kelley <seanvk@posteo.de>
---
src/gen6_mfd.c | 11 +++++++++++
src/gen75_mfd.c | 11 +++++++++++
src/gen7_mfd.c | 11 +++++++++++
src/gen8_mfd.c | 11 +++++++++++
4 files changed, 44 insertions(+)
diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
index ac15d47..eb73388 100644
--- a/src/gen6_mfd.c
+++ b/src/gen6_mfd.c
@@ -515,6 +515,8 @@ gen6_mfd_avc_slice_state(VADriverContextP ctx,
int first_mb_in_slice = 0, first_mb_in_next_slice = 0;
unsigned int chroma_log2_weight_denom, luma_log2_weight_denom;
int slice_type;
+ int num_surfaces = 0;
+ int i;
if (slice_param->slice_type == SLICE_TYPE_I ||
slice_param->slice_type == SLICE_TYPE_SI) {
@@ -552,6 +554,15 @@ gen6_mfd_avc_slice_state(VADriverContextP ctx,
}
}
+ /* Don't bind a surface which doesn't exist, that crashes the GPU */
+ for (i = 0; i < ARRAY_ELEMS(gen6_mfd_context->reference_surface); i++)
+ if (gen6_mfd_context->reference_surface[i].surface_id != VA_INVALID_ID)
+ num_surfaces ++;
+ if (num_surfaces == 0) {
+ num_ref_idx_l0 = 0;
+ num_ref_idx_l1 = 0;
+ }
+
first_mb_in_slice = slice_param->first_mb_in_slice;
slice_hor_pos = first_mb_in_slice % width_in_mbs;
slice_ver_pos = first_mb_in_slice / width_in_mbs;
diff --git a/src/gen75_mfd.c b/src/gen75_mfd.c
index fc979e3..58323e2 100644
--- a/src/gen75_mfd.c
+++ b/src/gen75_mfd.c
@@ -837,6 +837,8 @@ gen75_mfd_avc_slice_state(VADriverContextP ctx,
pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
int first_mb_in_slice = 0, first_mb_in_next_slice = 0;
int slice_type;
+ int num_surfaces = 0;
+ int i;
if (slice_param->slice_type == SLICE_TYPE_I ||
slice_param->slice_type == SLICE_TYPE_SI) {
@@ -863,6 +865,15 @@ gen75_mfd_avc_slice_state(VADriverContextP ctx,
num_ref_idx_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
}
+ /* Don't bind a surface which doesn't exist, that crashes the GPU */
+ for (i = 0; i < ARRAY_ELEMS(gen7_mfd_context->reference_surface); i++)
+ if (gen7_mfd_context->reference_surface[i].surface_id != VA_INVALID_ID)
+ num_surfaces ++;
+ if (num_surfaces == 0) {
+ num_ref_idx_l0 = 0;
+ num_ref_idx_l1 = 0;
+ }
+
first_mb_in_slice = slice_param->first_mb_in_slice;
slice_hor_pos = first_mb_in_slice % width_in_mbs;
slice_ver_pos = first_mb_in_slice / width_in_mbs;
diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c
index effc958..2af9e95 100644
--- a/src/gen7_mfd.c
+++ b/src/gen7_mfd.c
@@ -531,6 +531,8 @@ gen7_mfd_avc_slice_state(VADriverContextP ctx,
pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
int first_mb_in_slice = 0, first_mb_in_next_slice = 0;
int slice_type;
+ int num_surfaces = 0;
+ int i;
if (slice_param->slice_type == SLICE_TYPE_I ||
slice_param->slice_type == SLICE_TYPE_SI) {
@@ -557,6 +559,15 @@ gen7_mfd_avc_slice_state(VADriverContextP ctx,
num_ref_idx_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
}
+ /* Don't bind a surface which doesn't exist, that crashes the GPU */
+ for (i = 0; i < ARRAY_ELEMS(gen7_mfd_context->reference_surface); i++)
+ if (gen7_mfd_context->reference_surface[i].surface_id != VA_INVALID_ID)
+ num_surfaces ++;
+ if (num_surfaces == 0) {
+ num_ref_idx_l0 = 0;
+ num_ref_idx_l1 = 0;
+ }
+
first_mb_in_slice = slice_param->first_mb_in_slice;
slice_hor_pos = first_mb_in_slice % width_in_mbs;
slice_ver_pos = first_mb_in_slice / width_in_mbs;
diff --git a/src/gen8_mfd.c b/src/gen8_mfd.c
index 9d866aa..9e9dac4 100644
--- a/src/gen8_mfd.c
+++ b/src/gen8_mfd.c
@@ -614,6 +614,8 @@ gen8_mfd_avc_slice_state(VADriverContextP ctx,
pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
int first_mb_in_slice = 0, first_mb_in_next_slice = 0;
int slice_type;
+ int num_surfaces = 0;
+ int i;
if (slice_param->slice_type == SLICE_TYPE_I ||
slice_param->slice_type == SLICE_TYPE_SI) {
@@ -640,6 +642,15 @@ gen8_mfd_avc_slice_state(VADriverContextP ctx,
num_ref_idx_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
}
+ /* Don't bind a surface which doesn't exist, that crashes the GPU */
+ for (i = 0; i < ARRAY_ELEMS(gen7_mfd_context->reference_surface); i++)
+ if (gen7_mfd_context->reference_surface[i].surface_id != VA_INVALID_ID)
+ num_surfaces ++;
+ if (num_surfaces == 0) {
+ num_ref_idx_l0 = 0;
+ num_ref_idx_l1 = 0;
+ }
+
first_mb_in_slice = slice_param->first_mb_in_slice;
slice_hor_pos = first_mb_in_slice % width_in_mbs;
slice_ver_pos = first_mb_in_slice / width_in_mbs;
--
2.29.2.729.g45daf8777d-goog