| From ff5214770c90e030e1ba8473bac3d1e3e6ce86ef 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 |
| |
| 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 5ab2db0..f99ff44 100755 |
| --- 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 6d8ff82..d5f786e 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 9cf4402..233688b 100755 |
| --- 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 2d650a3..4f4f9b9 100644 |
| --- a/src/gen8_mfd.c |
| +++ b/src/gen8_mfd.c |
| @@ -599,6 +599,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) { |
| @@ -625,6 +627,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.1.4 |
| |