summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiang, Haihao <haihao.xiang@intel.com>2013-11-26 09:21:11 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2013-12-03 12:00:19 +0800
commitc4063375dd864cc90739603a3547b8b37b78e461 (patch)
treea7028de28f8e59cca1a2024ab978b2f12cb384be
parent4a0f76c5b706fccbc85fadaeee9d785cd7b57d5a (diff)
downloadlibva-intel-driver-c4063375dd864cc90739603a3547b8b37b78e461.tar.gz
libva-intel-driver-c4063375dd864cc90739603a3547b8b37b78e461.tar.bz2
libva-intel-driver-c4063375dd864cc90739603a3547b8b37b78e461.zip
dec/mpeg2: ignore slices which aren't in raster scan order on SNB
Sometimes codec layer incorrectly fills slice parameters due to the corrupted video Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71276 Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
-rwxr-xr-xsrc/gen6_mfd.c34
-rw-r--r--src/i965_decoder_utils.c41
-rw-r--r--src/i965_decoder_utils.h8
3 files changed, 61 insertions, 22 deletions
diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
index afbfc4c..f2b0fdf 100755
--- a/src/gen6_mfd.c
+++ b/src/gen6_mfd.c
@@ -1167,9 +1167,9 @@ gen6_mfd_mpeg2_decode_picture(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
VAPictureParameterBufferMPEG2 *pic_param;
- VASliceParameterBufferMPEG2 *slice_param, *next_slice_param, *next_slice_group_param;
+ VASliceParameterBufferMPEG2 *slice_param, *next_slice_param;
dri_bo *slice_data_bo;
- int i, j;
+ int group_idx = 0, pre_group_idx = -1, element_idx = 0;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
@@ -1188,28 +1188,18 @@ gen6_mfd_mpeg2_decode_picture(VADriverContextP ctx,
gen6_mfd_context->wa_mpeg2_slice_vertical_position =
mpeg2_wa_slice_vertical_position(decode_state, pic_param);
- for (j = 0; j < decode_state->num_slice_params; j++) {
- assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
- slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer;
- slice_data_bo = decode_state->slice_datas[j]->bo;
- gen6_mfd_ind_obj_base_addr_state(ctx, slice_data_bo, MFX_FORMAT_MPEG2, gen6_mfd_context);
-
- if (j == decode_state->num_slice_params - 1)
- next_slice_group_param = NULL;
- else
- next_slice_group_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j + 1]->buffer;
-
- for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
- assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
+ slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[group_idx]->buffer;
- if (i < decode_state->slice_params[j]->num_elements - 1)
- next_slice_param = slice_param + 1;
- else
- next_slice_param = next_slice_group_param;
-
- gen6_mfd_mpeg2_bsd_object(ctx, pic_param, slice_param, next_slice_param, gen6_mfd_context);
- slice_param++;
+ for (; slice_param;) {
+ if (pre_group_idx != group_idx) {
+ slice_data_bo = decode_state->slice_datas[group_idx]->bo;
+ gen6_mfd_ind_obj_base_addr_state(ctx, slice_data_bo, MFX_FORMAT_MPEG2, gen6_mfd_context);
+ pre_group_idx = group_idx;
}
+
+ next_slice_param = intel_mpeg2_find_next_slice(decode_state, pic_param, slice_param, &group_idx, &element_idx);
+ gen6_mfd_mpeg2_bsd_object(ctx, pic_param, slice_param, next_slice_param, gen6_mfd_context);
+ slice_param = next_slice_param;
}
intel_batchbuffer_end_atomic(batch);
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 4ef09b5..41102ba 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -703,3 +703,44 @@ intel_decoder_sanity_check_input(VADriverContextP ctx,
out:
return vaStatus;
}
+
+/*
+ * Return the next slice paramter
+ *
+ * Input:
+ * slice_param: the current slice
+ * *group_idx & *element_idx the current slice position in slice groups
+ * Output:
+ * Return the next slice parameter
+ * *group_idx & *element_idx the next slice position in slice groups,
+ * if the next slice is NULL, *group_idx & *element_idx will be ignored
+ */
+VASliceParameterBufferMPEG2 *
+intel_mpeg2_find_next_slice(struct decode_state *decode_state,
+ VAPictureParameterBufferMPEG2 *pic_param,
+ VASliceParameterBufferMPEG2 *slice_param,
+ int *group_idx,
+ int *element_idx)
+{
+ VASliceParameterBufferMPEG2 *next_slice_param;
+ unsigned int width_in_mbs = ALIGN(pic_param->horizontal_size, 16) / 16;
+ int j = *group_idx, i = *element_idx + 1;
+
+ for (; j < decode_state->num_slice_params; j++) {
+ for (; i < decode_state->slice_params[j]->num_elements; i++) {
+ next_slice_param = ((VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer) + i;
+
+ if ((next_slice_param->slice_vertical_position * width_in_mbs + next_slice_param->slice_horizontal_position) >=
+ (slice_param->slice_vertical_position * width_in_mbs + slice_param->slice_horizontal_position)) {
+ *group_idx = j;
+ *element_idx = i;
+
+ return next_slice_param;
+ }
+ }
+
+ i = 0;
+ }
+
+ return NULL;
+}
diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h
index 2a71f3e..8a9fbe2 100644
--- a/src/i965_decoder_utils.h
+++ b/src/i965_decoder_utils.h
@@ -91,4 +91,12 @@ intel_update_vc1_frame_store_index(VADriverContextP ctx,
struct decode_state *decode_state,
VAPictureParameterBufferVC1 *pic_param,
GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]);
+
+VASliceParameterBufferMPEG2 *
+intel_mpeg2_find_next_slice(struct decode_state *decode_state,
+ VAPictureParameterBufferMPEG2 *pic_param,
+ VASliceParameterBufferMPEG2 *slice_param,
+ int *group_idx,
+ int *element_idx);
+
#endif /* I965_DECODER_UTILS_H */