[Libva] [PATCH intel-driver 3/4] decoder: h264: simplify and optimize reference frame store update.

Gwenole Beauchesne gb.devel at gmail.com
Fri May 9 07:34:59 PDT 2014


Simplify and optimize the update process of the reference frame store.
Use less iterations to look up existing objects. Use a cache to store
the free'd slots.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 src/i965_decoder_utils.c | 109 ++++++++++++++++++++---------------------------
 1 file changed, 46 insertions(+), 63 deletions(-)

diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 780d239..63de195 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -351,88 +351,71 @@ gen6_send_avc_ref_idx_state(
 }
 
 void
-intel_update_avc_frame_store_index(VADriverContextP ctx,
-                                   struct decode_state *decode_state,
-                                   VAPictureParameterBufferH264 *pic_param,
-                                   GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES])
+intel_update_avc_frame_store_index(
+    VADriverContextP              ctx,
+    struct decode_state          *decode_state,
+    VAPictureParameterBufferH264 *pic_param,
+    GenFrameStore                 frame_store[MAX_GEN_REFERENCE_FRAMES]
+)
 {
-    int i, j;
-
-    assert(MAX_GEN_REFERENCE_FRAMES == ARRAY_ELEMS(pic_param->ReferenceFrames));
-
-    for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
-        int found = 0;
-
-        if (frame_store[i].surface_id == VA_INVALID_ID ||
-            frame_store[i].obj_surface == NULL)
+    int free_slots[MAX_GEN_REFERENCE_FRAMES];
+    int i, j, n, num_free_slots;
+    bool found;
+
+    /* Remove obsolete entries from the internal DPB */
+    for (i = 0, n = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
+        GenFrameStore * const fs = &frame_store[i];
+        if (fs->surface_id == VA_INVALID_ID || !fs->obj_surface) {
+            free_slots[n++] = i;
             continue;
+        }
 
-        assert(frame_store[i].frame_store_id != -1);
-
-        for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
-            VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[j];
-            if (ref_pic->flags & VA_PICTURE_H264_INVALID)
-                continue;
-
-            if (frame_store[i].surface_id == ref_pic->picture_id) {
-                found = 1;
+        // Find whether the current entry is still a valid reference frame
+        found = false;
+        for (j = 0; j < ARRAY_ELEMS(decode_state->reference_objects); j++) {
+            struct object_surface * const obj_surface =
+                decode_state->reference_objects[j];
+            if (!obj_surface || (found = obj_surface == fs->obj_surface))
                 break;
-            }
         }
 
-        /* remove it from the internal DPB */
+        // ... or remove it
         if (!found) {
-            frame_store[i].surface_id = VA_INVALID_ID;
-            frame_store[i].frame_store_id = -1;
-            frame_store[i].obj_surface = NULL;
+            fs->surface_id = VA_INVALID_ID;
+            fs->obj_surface = NULL;
+            fs->frame_store_id = -1;
+            free_slots[n++] = i;
         }
     }
+    num_free_slots = n;
 
-    for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
-        VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[i];
-        int found = 0;
-
-        if (ref_pic->flags & VA_PICTURE_H264_INVALID ||
-            ref_pic->picture_id == VA_INVALID_SURFACE ||
-            decode_state->reference_objects[i] == NULL)
-            continue;
+    /* Append the new reference frames */
+    for (i = 0, n = 0; i < ARRAY_ELEMS(decode_state->reference_objects); i++) {
+        struct object_surface * const obj_surface =
+            decode_state->reference_objects[i];
+        if (!obj_surface)
+            break;
 
+        // Find whether the current frame is not already in our frame store
+        found = false;
         for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
-            if (frame_store[j].surface_id == ref_pic->picture_id) {
-                found = 1;
+            if ((found = frame_store[j].obj_surface == obj_surface))
                 break;
-            }
         }
 
-        /* add the new reference frame into the internal DPB */
+        // ... or add it
         if (!found) {
-            int frame_idx;
-            int slot_found;
-            struct object_surface *obj_surface = decode_state->reference_objects[i];
-
-            slot_found = 0;
-            frame_idx = -1;
-            /* Find a free frame store index */
-            for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
-                if (frame_store[j].surface_id == VA_INVALID_ID ||
-                    frame_store[j].obj_surface == NULL) {
-                    frame_idx = j;
-                    slot_found = 1;
-                    break;
-                }
+            if (n < num_free_slots) {
+                GenFrameStore * const fs = &frame_store[free_slots[n++]];
+                fs->surface_id = obj_surface->base.id;
+                fs->obj_surface = obj_surface;
+                fs->frame_store_id = fs - frame_store;
+            }
+            else {
+                WARN_ONCE("No free slot found for DPB reference list!!!\n");
             }
-
-
-	    if (slot_found) {
-                frame_store[j].surface_id = ref_pic->picture_id;
-                frame_store[j].frame_store_id = frame_idx;
-                frame_store[j].obj_surface = obj_surface;
-            } else {
-                WARN_ONCE("Not free slot for DPB reference list!!!\n");
-	    }
         }
     }
-
 }
 
 void
-- 
1.9.1



More information about the Libva mailing list