diff options
author | Stéphane Marchesin <marcheu@chromium.org> | 2014-11-03 20:07:42 -0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2021-09-17 12:23:41 +0800 |
commit | 9d28e6ec0aa239aa23706a670a2ee147314d9923 (patch) | |
tree | 4fec370b7679814759fb752a0528b85ab4cc444c | |
parent | d87db2111a33b157d1913415f15d201cc5182850 (diff) | |
download | libva-intel-driver-9d28e6ec0aa239aa23706a670a2ee147314d9923.tar.gz |
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>
-rw-r--r-- | src/gen6_mfd.c | 11 | ||||
-rw-r--r-- | src/gen75_mfd.c | 11 | ||||
-rw-r--r-- | src/gen7_mfd.c | 11 | ||||
-rw-r--r-- | src/gen8_mfd.c | 11 |
4 files changed, 44 insertions, 0 deletions
diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c index ac15d472..eb73388b 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 fc979e38..58323e29 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 effc9582..2af9e95d 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 9d866aa4..9e9dac4c 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; |