summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2014-06-06 00:07:07 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2014-06-06 00:33:35 +0200
commit7afea4ad3620bcb9bf4349b8b07964297a1a369a (patch)
tree0f7a04b43d147fd605888fec03285d9e134ffef5
parent67dd066df02ea88de1329eea32f43d5ef2b4f057 (diff)
decoder: h264: optimize frame store updates.16.h264.mvc-r5
Optimize lookups for the "is the reference frame still in our Frame Store?" case. This is made possible because we maintain the frame store id in the the VA surface private data too. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r--src/i965_decoder_utils.c77
1 files changed, 34 insertions, 43 deletions
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index a488abb..6f91f3b 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -510,71 +510,62 @@ intel_update_avc_frame_store_index(
)
{
GenFrameStore *free_refs[MAX_GEN_REFERENCE_FRAMES];
- int i, j, n, num_free_refs;
+ uint32_t used_refs = 0, add_refs = 0;
+ int i, n, num_free_refs;
const int poc = avc_get_picture_poc(&pic_param->CurrPic);
- /* 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;
+ /* Tag entries that are still available in our Frame Store */
+ for (i = 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 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;
+ GenAvcSurface * const avc_surface = obj_surface->private_data;
+ if (avc_surface->frame_store_id >= 0) {
+ GenFrameStore * const fs =
+ &frame_store[avc_surface->frame_store_id];
+ if (fs->surface_id == obj_surface->base.id) {
+ fs->obj_surface = obj_surface;
+ fs->ref_poc = poc;
+ used_refs |= 1 << fs->frame_store_id;
+ continue;
+ }
}
+ add_refs |= 1 << i;
+ }
- // ... or remove it
- if (j == ARRAY_ELEMS(decode_state->reference_objects)) {
+ /* Build and sort out the list of retired candidates. The resulting
+ list is ordered by increasing POC when they were last used */
+ for (i = 0, n = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
+ if (!(used_refs & (1 << i))) {
+ GenFrameStore * const fs = &frame_store[i];
fs->obj_surface = NULL;
free_refs[n++] = fs;
}
}
num_free_refs = n;
-
- /* Sort the free refs by increasing POC when they were last used */
qsort(&free_refs[0], n, sizeof(free_refs[0]), compare_avc_ref_store_func);
/* 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)
+ if (!obj_surface || !(add_refs & (1 << i)))
continue;
- // Find whether the current frame is not already in our frame store
GenAvcSurface * const avc_surface = obj_surface->private_data;
- if (avc_surface->frame_store_id >= 0) {
- GenFrameStore * const fs =
- &frame_store[avc_surface->frame_store_id];
- if (fs->surface_id == obj_surface->base.id) {
- fs->obj_surface = obj_surface;
- fs->ref_poc = poc;
- continue;
- }
- }
-
- // ... or add it (pick the next free slot)
- for (;;) {
- if (n < num_free_refs) {
- GenFrameStore * const fs = free_refs[n++];
- if (fs->obj_surface)
- continue;
- fs->surface_id = obj_surface->base.id;
- fs->obj_surface = obj_surface;
- fs->frame_store_id = fs - frame_store;
- fs->ref_poc = poc;
- avc_surface->frame_store_id = fs->frame_store_id;
- break;
- }
- WARN_ONCE("No free slot found for DPB reference list!!!\n");
+ 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;
+ fs->ref_poc = poc;
+ avc_surface->frame_store_id = fs->frame_store_id;
+ continue;
}
+ WARN_ONCE("No free slot found for DPB reference list!!!\n");
}
}