summaryrefslogtreecommitdiff
path: root/src/i965_decoder_utils.c
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2014-05-06 15:28:29 +0200
committerXiang, Haihao <haihao.xiang@intel.com>2014-06-16 11:53:35 +0800
commitd2e843eed7fa31d86e196fb0e07b9cd3c377c969 (patch)
treeb9ef0a71077b6c986651c9f6ef87d51bea4d2833 /src/i965_decoder_utils.c
parenta35d3c2d8f006d4b019881a23ad57819eeb7d62e (diff)
downloadlibva-intel-driver-d2e843eed7fa31d86e196fb0e07b9cd3c377c969.tar.gz
decoder: h264: simplify and optimize reference frame store updates.
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. Prerequisite: the reference_objects[] array was previously arranged in a way that the element at index i is exactly the object_surface that corresponds to the VA surface identified by the VAPictureH264.picture_id located at index i in the ReferenceFrames[] array. Theory of operations: 1. Obsolete entries are removed first, i.e. entries in the internal DPB that no longer have a match in the supplied ReferenceFrames[] array. That obsolete entry index is stored in a local cache: free_slots[]. 2. This cache is completed with entries considered as "invalid" or "not present", sequentially while traversing the frame store for obsolete entries. At the end of this removal process, the free_slots[] array represents all possible indices in there that could be re-used for new reference frames to track. 3. The list of ReferenceFrames[] objects is traversed for new entries that are not already in the frame store. If an entry needs to be added, it is placed at the index obtained from the next free_slots[] element. There is no need to traverse the frame store array again, the next available slot can be known from that free_slots[] cache. v2: dropped the superfluous "found" variable [Yakui] v3: renamed "free_slots" array to "free_refs", which now holds GenFrameStore entries Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com> (cherry picked from commit 70ecad1264255123df99b472891e8ee90399013c)
Diffstat (limited to 'src/i965_decoder_utils.c')
-rw-r--r--src/i965_decoder_utils.c108
1 files changed, 44 insertions, 64 deletions
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 8aada54c..c7791520 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -420,88 +420,68 @@ 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)
+ GenFrameStore *free_refs[MAX_GEN_REFERENCE_FRAMES];
+ int i, j, n, num_free_refs;
+
+ /* 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_refs[n++] = fs;
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
+ 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 && obj_surface == fs->obj_surface)
break;
- }
}
- /* remove it from the internal DPB */
- if (!found) {
- frame_store[i].surface_id = VA_INVALID_ID;
- frame_store[i].frame_store_id = -1;
- frame_store[i].obj_surface = NULL;
+ // ... or remove it
+ if (j == ARRAY_ELEMS(decode_state->reference_objects)) {
+ fs->surface_id = VA_INVALID_ID;
+ fs->obj_surface = NULL;
+ fs->frame_store_id = -1;
+ free_refs[n++] = fs;
}
}
+ num_free_refs = 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)
+ /* 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)
continue;
+ // Find whether the current frame is not already in our frame store
for (j = 0; j < MAX_GEN_REFERENCE_FRAMES; j++) {
- if (frame_store[j].surface_id == ref_pic->picture_id) {
- found = 1;
+ GenFrameStore * const fs = &frame_store[j];
+ if (fs->obj_surface == obj_surface)
break;
- }
}
- /* add the new reference frame into the internal DPB */
- 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;
- }
+ // ... or add it
+ if (j == MAX_GEN_REFERENCE_FRAMES) {
+ if (n < num_free_refs) {
+ GenFrameStore * const fs = free_refs[n++];
+ fs->surface_id = obj_surface->base.id;
+ fs->obj_surface = obj_surface;
+ fs->frame_store_id = fs - frame_store;
+ continue;
}
-
-
- 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");
- }
+ WARN_ONCE("No free slot found for DPB reference list!!!\n");
}
}
-
}
void