[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