[Libva] [PATCH 2/2] h264: fix and simplify REF_IDX_STATE (ILK, SNB, IVB).
Gwenole Beauchesne
gb.devel at gmail.com
Mon Jan 30 10:26:17 PST 2012
Original code was parsing RefPicList0/1 over what was actually available
and filled in, i.e. wrt. num_ref_idx_l0/1_minus1 + 1. Besides, bit 5 of
Reference List Entry set to 1 means a frame, not the opposite.
---
NEWS | 5 ++-
src/Makefile.am | 2 +
src/gen6_mfd.c | 77 +++-------------------------
src/gen7_mfd.c | 77 +++-------------------------
src/i965_avc_bsd.c | 60 +++++----------------
src/i965_decoder_utils.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
src/i965_decoder_utils.h | 45 ++++++++++++++++
7 files changed, 210 insertions(+), 186 deletions(-)
create mode 100644 src/i965_decoder_utils.c
create mode 100644 src/i965_decoder_utils.h
diff --git a/NEWS b/NEWS
index f0244ad..0bb078a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
-libva-driver-intel NEWS -- summary of changes. 2011-10-28
+libva-driver-intel NEWS -- summary of changes. 2012-02-DD
Copyright (C) 2009-2011 Intel Corporation
+Version 1.0.16 - DD.Feb.2012
+* Fix and simplify AVC_REF_IDX_STATE setup (CTG, SNB, IVB)
+
Version 1.0.15 - 28.Oct.2011
* Add auto-generated Debian packaging
* Fix VC-1 decoding (TTFRM packing)
diff --git a/src/Makefile.am b/src/Makefile.am
index c3131a2..013d7ab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,6 +55,7 @@ source_c = \
i965_avc_bsd.c \
i965_avc_hw_scoreboard.c\
i965_avc_ildb.c \
+ i965_decoder_utils.c \
i965_drv_video.c \
i965_encoder.c \
i965_media.c \
@@ -79,6 +80,7 @@ source_h = \
i965_avc_hw_scoreboard.h\
i965_avc_ildb.h \
i965_decoder.h \
+ i965_decoder_utils.h \
i965_defines.h \
i965_drv_video.h \
i965_encoder.h \
diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
index c6b8d4c..f31f9ee 100644
--- a/src/gen6_mfd.c
+++ b/src/gen6_mfd.c
@@ -37,6 +37,7 @@
#include "i965_defines.h"
#include "i965_drv_video.h"
+#include "i965_decoder_utils.h"
#include "gen6_mfd.h"
@@ -782,81 +783,17 @@ gen6_mfd_avc_phantom_slice_state(VADriverContextP ctx,
ADVANCE_BCS_BATCH(batch);
}
-static void
+static inline void
gen6_mfd_avc_ref_idx_state(VADriverContextP ctx,
VAPictureParameterBufferH264 *pic_param,
VASliceParameterBufferH264 *slice_param,
struct gen6_mfd_context *gen6_mfd_context)
{
- struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
- int i, j, num_ref_list;
- struct {
- unsigned char bottom_idc:1;
- unsigned char frame_store_index:4;
- unsigned char field_picture:1;
- unsigned char long_term:1;
- unsigned char non_exist:1;
- } refs[32];
-
- if (slice_param->slice_type == SLICE_TYPE_I ||
- slice_param->slice_type == SLICE_TYPE_SI)
- return;
-
- if (slice_param->slice_type == SLICE_TYPE_P ||
- slice_param->slice_type == SLICE_TYPE_SP) {
- num_ref_list = 1;
- } else {
- num_ref_list = 2;
- }
-
- for (i = 0; i < num_ref_list; i++) {
- VAPictureH264 *va_pic;
-
- if (i == 0) {
- va_pic = slice_param->RefPicList0;
- } else {
- va_pic = slice_param->RefPicList1;
- }
-
- BEGIN_BCS_BATCH(batch, 10);
- OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2));
- OUT_BCS_BATCH(batch, i);
-
- for (j = 0; j < 32; j++) {
- if (va_pic->flags & VA_PICTURE_H264_INVALID) {
- refs[j].non_exist = 1;
- refs[j].long_term = 1;
- refs[j].field_picture = 1;
- refs[j].frame_store_index = 0xf;
- refs[j].bottom_idc = 1;
- } else {
- int frame_idx;
-
- for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen6_mfd_context->reference_surface); frame_idx++) {
- if (gen6_mfd_context->reference_surface[frame_idx].surface_id != VA_INVALID_ID &&
- va_pic->picture_id == gen6_mfd_context->reference_surface[frame_idx].surface_id) {
- assert(frame_idx == gen6_mfd_context->reference_surface[frame_idx].frame_store_id);
- break;
- }
- }
-
- assert(frame_idx < ARRAY_ELEMS(gen6_mfd_context->reference_surface));
-
- refs[j].non_exist = 0;
- refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
- refs[j].field_picture = !!(va_pic->flags &
- (VA_PICTURE_H264_TOP_FIELD |
- VA_PICTURE_H264_BOTTOM_FIELD));
- refs[j].frame_store_index = frame_idx;
- refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
- }
-
- va_pic++;
- }
-
- intel_batchbuffer_data(batch, refs, sizeof(refs));
- ADVANCE_BCS_BATCH(batch);
- }
+ gen6_send_avc_ref_idx_state(
+ gen6_mfd_context->base.batch,
+ slice_param,
+ gen6_mfd_context->reference_surface
+ );
}
static void
diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c
index b8c0261..96bd1c5 100644
--- a/src/gen7_mfd.c
+++ b/src/gen7_mfd.c
@@ -36,6 +36,7 @@
#include "i965_defines.h"
#include "i965_drv_video.h"
+#include "i965_decoder_utils.h"
#include "gen7_mfd.h"
@@ -750,81 +751,17 @@ gen7_mfd_avc_slice_state(VADriverContextP ctx,
ADVANCE_BCS_BATCH(batch);
}
-static void
+static inline void
gen7_mfd_avc_ref_idx_state(VADriverContextP ctx,
VAPictureParameterBufferH264 *pic_param,
VASliceParameterBufferH264 *slice_param,
struct gen7_mfd_context *gen7_mfd_context)
{
- struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
- int i, j, num_ref_list;
- struct {
- unsigned char bottom_idc:1;
- unsigned char frame_store_index:4;
- unsigned char field_picture:1;
- unsigned char long_term:1;
- unsigned char non_exist:1;
- } refs[32];
-
- if (slice_param->slice_type == SLICE_TYPE_I ||
- slice_param->slice_type == SLICE_TYPE_SI)
- return;
-
- if (slice_param->slice_type == SLICE_TYPE_P ||
- slice_param->slice_type == SLICE_TYPE_SP) {
- num_ref_list = 1;
- } else {
- num_ref_list = 2;
- }
-
- for (i = 0; i < num_ref_list; i++) {
- VAPictureH264 *va_pic;
-
- if (i == 0) {
- va_pic = slice_param->RefPicList0;
- } else {
- va_pic = slice_param->RefPicList1;
- }
-
- BEGIN_BCS_BATCH(batch, 10);
- OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2));
- OUT_BCS_BATCH(batch, i);
-
- for (j = 0; j < 32; j++) {
- if (va_pic->flags & VA_PICTURE_H264_INVALID) {
- refs[j].non_exist = 1;
- refs[j].long_term = 1;
- refs[j].field_picture = 1;
- refs[j].frame_store_index = 0xf;
- refs[j].bottom_idc = 1;
- } else {
- int frame_idx;
-
- for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen7_mfd_context->reference_surface); frame_idx++) {
- if (gen7_mfd_context->reference_surface[frame_idx].surface_id != VA_INVALID_ID &&
- va_pic->picture_id == gen7_mfd_context->reference_surface[frame_idx].surface_id) {
- assert(frame_idx == gen7_mfd_context->reference_surface[frame_idx].frame_store_id);
- break;
- }
- }
-
- assert(frame_idx < ARRAY_ELEMS(gen7_mfd_context->reference_surface));
-
- refs[j].non_exist = 0;
- refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
- refs[j].field_picture = !!(va_pic->flags &
- (VA_PICTURE_H264_TOP_FIELD |
- VA_PICTURE_H264_BOTTOM_FIELD));
- refs[j].frame_store_index = frame_idx;
- refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
- }
-
- va_pic++;
- }
-
- intel_batchbuffer_data(batch, refs, sizeof(refs));
- ADVANCE_BCS_BATCH(batch);
- }
+ gen6_send_avc_ref_idx_state(
+ gen7_mfd_context->base.batch,
+ slice_param,
+ gen7_mfd_context->reference_surface
+ );
}
static void
diff --git a/src/i965_avc_bsd.c b/src/i965_avc_bsd.c
index 9fa9649..6f133a3 100644
--- a/src/i965_avc_bsd.c
+++ b/src/i965_avc_bsd.c
@@ -38,6 +38,7 @@
#include "i965_avc_bsd.h"
#include "i965_media_h264.h"
#include "i965_media.h"
+#include "i965_decoder_utils.h"
static void
i965_avc_bsd_free_avc_bsd_surface(void **data)
@@ -259,13 +260,7 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = i965_h264_context->batch;
int present_flag, cmd_len, list, j;
- struct {
- unsigned char bottom_idc:1;
- unsigned char frame_store_index:4;
- unsigned char field_picture:1;
- unsigned char long_term:1;
- unsigned char non_exist:1;
- } refs[32];
+ uint8_t ref_idx_state[32];
char weightoffsets[32 * 6];
/* don't issue SLICE_STATE for intra-prediction decoding */
@@ -302,53 +297,28 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
OUT_BCS_BATCH(batch, present_flag);
for (list = 0; list < 2; list++) {
- int flag;
+ int flag, num_va_pics;
VAPictureH264 *va_pic;
if (list == 0) {
- flag = PRESENT_REF_LIST0;
- va_pic = slice_param->RefPicList0;
+ flag = PRESENT_REF_LIST0;
+ va_pic = slice_param->RefPicList0;
+ num_va_pics = slice_param->num_ref_idx_l0_active_minus1 + 1;
} else {
- flag = PRESENT_REF_LIST1;
- va_pic = slice_param->RefPicList1;
+ flag = PRESENT_REF_LIST1;
+ va_pic = slice_param->RefPicList1;
+ num_va_pics = slice_param->num_ref_idx_l1_active_minus1 + 1;
}
if (!(present_flag & flag))
continue;
- for (j = 0; j < 32; j++) {
- if (va_pic->flags & VA_PICTURE_H264_INVALID) {
- refs[j].non_exist = 1;
- refs[j].long_term = 1;
- refs[j].field_picture = 1;
- refs[j].frame_store_index = 0xf;
- refs[j].bottom_idc = 1;
- } else {
- int frame_idx;
-
- for (frame_idx = 0; frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list); frame_idx++) {
- if (i965_h264_context->fsid_list[frame_idx].surface_id != VA_INVALID_ID &&
- va_pic->picture_id == i965_h264_context->fsid_list[frame_idx].surface_id) {
- assert(frame_idx == i965_h264_context->fsid_list[frame_idx].frame_store_id);
- break;
- }
- }
-
- assert(frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list));
-
- refs[j].non_exist = 0;
- refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
- refs[j].field_picture = !!(va_pic->flags &
- (VA_PICTURE_H264_TOP_FIELD |
- VA_PICTURE_H264_BOTTOM_FIELD));
- refs[j].frame_store_index = frame_idx;
- refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
- }
-
- va_pic++;
- }
-
- intel_batchbuffer_data(batch, refs, sizeof(refs));
+ gen5_fill_avc_ref_idx_state(
+ ref_idx_state,
+ va_pic, num_va_pics,
+ i965_h264_context->fsid_list
+ );
+ intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state));
}
i965_h264_context->weight128_luma_l0 = 0;
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
new file mode 100644
index 0000000..36f51c4
--- /dev/null
+++ b/src/i965_decoder_utils.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2006-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include "intel_batchbuffer.h"
+#include "i965_decoder_utils.h"
+#include "i965_defines.h"
+
+static inline uint8_t
+get_ref_idx_state_1(const VAPictureH264 *va_pic, unsigned int frame_store_id)
+{
+ const unsigned int is_long_term =
+ !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
+ const unsigned int is_top_field =
+ !!(va_pic->flags & VA_PICTURE_H264_TOP_FIELD);
+ const unsigned int is_bottom_field =
+ !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
+
+ return ((is_long_term << 6) |
+ ((is_top_field ^ is_bottom_field ^ 1) << 5) |
+ (frame_store_id << 1) |
+ ((is_top_field ^ 1) & is_bottom_field));
+}
+
+/* Fill in Reference List Entries (Gen5+: ILK, SNB, IVB) */
+void
+gen5_fill_avc_ref_idx_state(
+ uint8_t state[32],
+ const VAPictureH264 ref_list[32],
+ unsigned int ref_list_count,
+ const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]
+)
+{
+ unsigned int i, n, frame_idx;
+
+ for (i = 0, n = 0; i < ref_list_count; i++) {
+ const VAPictureH264 * const va_pic = &ref_list[i];
+
+ if (va_pic->flags & VA_PICTURE_H264_INVALID)
+ continue;
+
+ for (frame_idx = 0; frame_idx < MAX_GEN_REFERENCE_FRAMES; frame_idx++) {
+ const GenFrameStore * const fs = &frame_store[frame_idx];
+ if (fs->surface_id != VA_INVALID_ID &&
+ fs->surface_id == va_pic->picture_id) {
+ assert(frame_idx == fs->frame_store_id);
+ break;
+ }
+ }
+ assert(frame_idx < MAX_GEN_REFERENCE_FRAMES);
+ state[n++] = get_ref_idx_state_1(va_pic, frame_idx);
+ }
+
+ for (; n < 32; n++)
+ state[n] = 0xff;
+}
+
+/* Emit Reference List Entries (Gen6+: SNB, IVB) */
+static void
+gen6_send_avc_ref_idx_state_1(
+ struct intel_batchbuffer *batch,
+ unsigned int list,
+ const VAPictureH264 *ref_list,
+ unsigned int ref_list_count,
+ const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]
+)
+{
+ uint8_t ref_idx_state[32];
+
+ BEGIN_BCS_BATCH(batch, 10);
+ OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2));
+ OUT_BCS_BATCH(batch, list);
+ gen5_fill_avc_ref_idx_state(
+ ref_idx_state,
+ ref_list, ref_list_count,
+ frame_store
+ );
+ intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state));
+ ADVANCE_BCS_BATCH(batch);
+}
+
+void
+gen6_send_avc_ref_idx_state(
+ struct intel_batchbuffer *batch,
+ const VASliceParameterBufferH264 *slice_param,
+ const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]
+)
+{
+ if (slice_param->slice_type == SLICE_TYPE_I ||
+ slice_param->slice_type == SLICE_TYPE_SI)
+ return;
+
+ /* RefPicList0 */
+ gen6_send_avc_ref_idx_state_1(
+ batch, 0,
+ slice_param->RefPicList0, slice_param->num_ref_idx_l0_active_minus1 + 1,
+ frame_store
+ );
+
+ if (slice_param->slice_type != SLICE_TYPE_B)
+ return;
+
+ /* RefPicList1 */
+ gen6_send_avc_ref_idx_state_1(
+ batch, 1,
+ slice_param->RefPicList1, slice_param->num_ref_idx_l1_active_minus1 + 1,
+ frame_store
+ );
+}
diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h
new file mode 100644
index 0000000..6390ecc
--- /dev/null
+++ b/src/i965_decoder_utils.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef I965_DECODER_UTILS_H
+#define I965_DECODER_UTILS_H
+
+#include "i965_decoder.h"
+#include "intel_batchbuffer.h"
+
+void
+gen5_fill_avc_ref_idx_state(
+ uint8_t state[32],
+ const VAPictureH264 ref_list[32],
+ unsigned int ref_list_count,
+ const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]
+);
+
+void
+gen6_send_avc_ref_idx_state(
+ struct intel_batchbuffer *batch,
+ const VASliceParameterBufferH264 *slice_param,
+ const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]
+);
+
+#endif /* I965_DECODER_UTILS_H */
--
1.7.0.4
More information about the Libva
mailing list