libobs: Deallocate lingering unused cache frames

This fixes an issue where cache frames would not free at all after
having been allocated with no upper limit on the cached frame size.  If
cached frames go unused for a specific period of time, they are
deallocated and removed from the cache.

This is preferable to having an upper cache limit due to the potential
for async delay filtering.
This commit is contained in:
jp9000 2015-03-27 00:02:18 -07:00
parent f03e66fc99
commit 3a90be39dd
2 changed files with 22 additions and 0 deletions

View File

@ -277,6 +277,7 @@ extern void obs_context_data_setname(struct obs_context_data *context,
struct async_frame {
struct obs_source_frame *frame;
long unused_count;
bool used;
};

View File

@ -1629,6 +1629,23 @@ static inline void free_async_cache(struct obs_source *source)
da_resize(source->async_frames, 0);
}
#define MAX_UNUSED_FRAME_DURATION 5
/* frees frame allocations if they haven't been used for a specific period
* of time */
static void clean_cache(obs_source_t *source)
{
for (size_t i = source->async_cache.num; i > 0; i--) {
struct async_frame *af = &source->async_cache.array[i - 1];
if (!af->used) {
if (++af->unused_count == MAX_UNUSED_FRAME_DURATION) {
obs_source_frame_destroy(af->frame);
da_erase(source->async_cache, i - 1);
}
}
}
}
static inline struct obs_source_frame *cache_video(struct obs_source *source,
const struct obs_source_frame *frame)
{
@ -1652,10 +1669,13 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source,
if (!af->used) {
new_frame = af->frame;
af->used = true;
af->unused_count = 0;
break;
}
}
clean_cache(source);
if (!new_frame) {
struct async_frame new_af;
@ -1663,6 +1683,7 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source,
frame->width, frame->height);
new_af.frame = new_frame;
new_af.used = true;
new_af.unused_count = 0;
new_frame->refs = 1;
da_push_back(source->async_cache, &new_af);