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:
parent
f03e66fc99
commit
3a90be39dd
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user