diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2014-06-06 00:07:07 +0200 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2014-06-06 00:33:35 +0200 |
commit | 7afea4ad3620bcb9bf4349b8b07964297a1a369a (patch) | |
tree | 0f7a04b43d147fd605888fec03285d9e134ffef5 | |
parent | 67dd066df02ea88de1329eea32f43d5ef2b4f057 (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.c | 77 |
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"); } } |