summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-03-15 14:41:47 +0100
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-03-18 09:10:11 +0100
commit14f70559b516030d141cce09db54cf49d11df9b2 (patch)
tree0282004db9b50b3e174bd2a7b13e8bca0323c581
parent18212d42c5dfee047094ae67914c2b2b630ad99e (diff)
downloadlibva-intel-driver-14f70559b516030d141cce09db54cf49d11df9b2.tar.gz
mpeg2: fix construction of reference frames list (SNB, IVB).
Fix construction of reference frames list for interlaced streams. In this case, the array is indexed by frame store ID >> 1 where bit 0 of frame store ID represents top (0) or bottom (1) field. Besides, current render target can also be used as a reference while decoding the second field. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r--src/gen6_mfd.c25
-rw-r--r--src/gen7_mfd.c25
-rw-r--r--src/i965_decoder_utils.c86
-rw-r--r--src/i965_decoder_utils.h8
-rw-r--r--src/i965_defines.h4
5 files changed, 110 insertions, 38 deletions
diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
index 367294f3..51426baa 100644
--- a/src/gen6_mfd.c
+++ b/src/gen6_mfd.c
@@ -1084,30 +1084,17 @@ gen6_mfd_mpeg2_decode_init(VADriverContextP ctx,
VAPictureParameterBufferMPEG2 *pic_param;
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_surface *obj_surface;
- int i;
dri_bo *bo;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
- /* reference picture */
- obj_surface = SURFACE(pic_param->forward_reference_picture);
-
- if (obj_surface && obj_surface->bo)
- gen6_mfd_context->reference_surface[0].surface_id = pic_param->forward_reference_picture;
- else
- gen6_mfd_context->reference_surface[0].surface_id = VA_INVALID_ID;
-
- obj_surface = SURFACE(pic_param->backward_reference_picture);
-
- if (obj_surface && obj_surface->bo)
- gen6_mfd_context->reference_surface[1].surface_id = pic_param->backward_reference_picture;
- else
- gen6_mfd_context->reference_surface[1].surface_id = gen6_mfd_context->reference_surface[0].surface_id;
-
- /* must do so !!! */
- for (i = 2; i < ARRAY_ELEMS(gen6_mfd_context->reference_surface); i++)
- gen6_mfd_context->reference_surface[i].surface_id = gen6_mfd_context->reference_surface[i % 2].surface_id;
+ mpeg2_set_reference_surfaces(
+ ctx,
+ gen6_mfd_context->reference_surface,
+ decode_state,
+ pic_param
+ );
/* Current decoded picture */
obj_surface = SURFACE(decode_state->current_render_target);
diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c
index 6318ab96..6d3e0440 100644
--- a/src/gen7_mfd.c
+++ b/src/gen7_mfd.c
@@ -1032,30 +1032,17 @@ gen7_mfd_mpeg2_decode_init(VADriverContextP ctx,
VAPictureParameterBufferMPEG2 *pic_param;
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_surface *obj_surface;
- int i;
dri_bo *bo;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferMPEG2 *)decode_state->pic_param->buffer;
- /* reference picture */
- obj_surface = SURFACE(pic_param->forward_reference_picture);
-
- if (obj_surface && obj_surface->bo)
- gen7_mfd_context->reference_surface[0].surface_id = pic_param->forward_reference_picture;
- else
- gen7_mfd_context->reference_surface[0].surface_id = VA_INVALID_ID;
-
- obj_surface = SURFACE(pic_param->backward_reference_picture);
-
- if (obj_surface && obj_surface->bo)
- gen7_mfd_context->reference_surface[1].surface_id = pic_param->backward_reference_picture;
- else
- gen7_mfd_context->reference_surface[1].surface_id = gen7_mfd_context->reference_surface[0].surface_id;
-
- /* must do so !!! */
- for (i = 2; i < ARRAY_ELEMS(gen7_mfd_context->reference_surface); i++)
- gen7_mfd_context->reference_surface[i].surface_id = gen7_mfd_context->reference_surface[i % 2].surface_id;
+ mpeg2_set_reference_surfaces(
+ ctx,
+ gen7_mfd_context->reference_surface,
+ decode_state,
+ pic_param
+ );
/* Current decoded picture */
obj_surface = SURFACE(decode_state->current_render_target);
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 6985c366..047fa62c 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -30,6 +30,27 @@
#include "i965_drv_video.h"
#include "i965_defines.h"
+/* Set reference surface if backing store exists */
+static inline int
+set_ref_frame(
+ struct i965_driver_data *i965,
+ GenFrameStore *ref_frame,
+ VASurfaceID va_surface
+)
+{
+ struct object_surface *obj_surface;
+
+ if (va_surface == VA_INVALID_ID)
+ return 0;
+
+ obj_surface = SURFACE(va_surface);
+ if (!obj_surface || !obj_surface->bo)
+ return 0;
+
+ ref_frame->surface_id = va_surface;
+ return 1;
+}
+
/* Check wether codec layer incorrectly fills in slice_vertical_position */
int
mpeg2_wa_slice_vertical_position(
@@ -70,6 +91,71 @@ mpeg2_wa_slice_vertical_position(
return 0;
}
+/* Build MPEG-2 reference frames array */
+void
+mpeg2_set_reference_surfaces(
+ VADriverContextP ctx,
+ GenFrameStore ref_frames[MAX_GEN_REFERENCE_FRAMES],
+ struct decode_state *decode_state,
+ VAPictureParameterBufferMPEG2 *pic_param
+)
+{
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ VASurfaceID va_surface;
+ unsigned pic_structure, is_second_field, n = 0;
+
+ pic_structure = pic_param->picture_coding_extension.bits.picture_structure;
+ is_second_field = pic_structure != MPEG_FRAME &&
+ !pic_param->picture_coding_extension.bits.is_first_field;
+
+ /* Reference frames are indexed by frame store ID (0:top, 1:bottom) */
+ switch (pic_param->picture_coding_type) {
+ case MPEG_P_PICTURE:
+ if (is_second_field && pic_structure == MPEG_BOTTOM_FIELD) {
+ va_surface = decode_state->current_render_target;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ }
+ va_surface = pic_param->forward_reference_picture;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ break;
+
+ case MPEG_B_PICTURE:
+ va_surface = pic_param->forward_reference_picture;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ va_surface = pic_param->backward_reference_picture;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ break;
+ }
+
+ while (n != 2)
+ ref_frames[n++].surface_id = VA_INVALID_ID;
+
+ if (pic_param->picture_coding_extension.bits.progressive_frame)
+ return;
+
+ /* Bottom field pictures used as reference */
+ switch (pic_param->picture_coding_type) {
+ case MPEG_P_PICTURE:
+ if (is_second_field && pic_structure == MPEG_TOP_FIELD) {
+ va_surface = decode_state->current_render_target;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ }
+ va_surface = pic_param->forward_reference_picture;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ break;
+
+ case MPEG_B_PICTURE:
+ va_surface = pic_param->forward_reference_picture;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ va_surface = pic_param->backward_reference_picture;
+ n += set_ref_frame(i965, &ref_frames[n], va_surface);
+ break;
+ }
+
+ while (n != 4)
+ ref_frames[n++].surface_id = VA_INVALID_ID;
+}
+
/* Generate flat scaling matrices for H.264 decoding */
void
avc_gen_default_iq_matrix(VAIQMatrixBufferH264 *iq_matrix)
diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h
index 1c624c08..0d865231 100644
--- a/src/i965_decoder_utils.h
+++ b/src/i965_decoder_utils.h
@@ -36,6 +36,14 @@ mpeg2_wa_slice_vertical_position(
);
void
+mpeg2_set_reference_surfaces(
+ VADriverContextP ctx,
+ GenFrameStore ref_frames[MAX_GEN_REFERENCE_FRAMES],
+ struct decode_state *decode_state,
+ VAPictureParameterBufferMPEG2 *pic_param
+);
+
+void
avc_gen_default_iq_matrix(VAIQMatrixBufferH264 *iq_matrix);
unsigned int
diff --git a/src/i965_defines.h b/src/i965_defines.h
index d530a5ba..b58260a1 100644
--- a/src/i965_defines.h
+++ b/src/i965_defines.h
@@ -707,6 +707,10 @@
#define MFX_SURFACE_PLANAR_422_8 6
#define MFX_SURFACE_MONOCHROME 12
+#define MPEG_I_PICTURE 1
+#define MPEG_P_PICTURE 2
+#define MPEG_B_PICTURE 3
+
#define MPEG_TOP_FIELD 1
#define MPEG_BOTTOM_FIELD 2
#define MPEG_FRAME 3