memory: implemented basic memory limiting functionality

Keeps track of total memory usage and uses it as a guide towards
allocating/reusing more memory.
This commit is contained in:
itsmattkc
2020-08-29 13:34:54 +10:00
parent c99eb68d45
commit 050103a857
5 changed files with 63 additions and 11 deletions
+25 -7
View File
@@ -889,13 +889,15 @@ QWaitCondition *FFmpegDecoderInstance::cache_wait_cond()
return &cache_wait_cond_;
}
bool FFmpegDecoderInstance::IsWorking() const
bool FFmpegDecoderInstance::IsWorking()
{
QMutexLocker locker(&is_working_mutex_);
return is_working_;
}
void FFmpegDecoderInstance::SetWorking(bool working)
{
QMutexLocker locker(&is_working_mutex_);
is_working_ = working;
}
@@ -1113,7 +1115,12 @@ FFmpegFramePool::ElementPtr FFmpegDecoderInstance::RetrieveFrame(const int64_t&
}
// Clear early frames
TruncateCacheRangeTo(second_ts_);
int removed = TruncateCacheRangeTo(second_ts_);
if (removed == 0 && MemoryPoolLimitReached()) {
// Relinquish a frame if we have to conserve memory
RemoveFirstFrame();
}
// Append this frame and signal to other threads that a new frame has arrived
cached_frames_.append(cached);
@@ -1295,19 +1302,30 @@ FFmpegFramePool::ElementPtr FFmpegDecoderInstance::GetFrameFromCache(const int64
void FFmpegDecoderInstance::RemoveFramesBefore(const qint64 &t)
{
// We keep one frame in memory as an identifier for what pts the decoder is up to
while (cached_frames_.size() > 1 && cached_frames_.first()->last_accessed() < t) {
cached_frames_.removeFirst();
cache_at_zero_ = false;
int min_frames = (MemoryPoolLimitReached() && !IsWorking()) ? 0 : 1;
while (cached_frames_.size() > min_frames && cached_frames_.first()->last_accessed() < t) {
RemoveFirstFrame();
}
}
void FFmpegDecoderInstance::TruncateCacheRangeTo(const qint64 &t)
int FFmpegDecoderInstance::TruncateCacheRangeTo(const qint64 &t)
{
int counter = 0;
// We keep one frame in memory as an identifier for what pts the decoder is up to
while (cached_frames_.size() > 1 && (RangeEnd() - RangeStart()) > t) {
RemoveFirstFrame();
counter++;
}
return counter;
}
void FFmpegDecoderInstance::RemoveFirstFrame()
{
cached_frames_.removeFirst();
cache_at_zero_ = false;
}
}
FFmpegDecoderInstance::FFmpegDecoderInstance(const char *filename, int stream_index) :
+4 -2
View File
@@ -62,7 +62,8 @@ public:
FFmpegFramePool::ElementPtr GetFrameFromCache(const int64_t& t) const;
void RemoveFramesBefore(const qint64& t);
void TruncateCacheRangeTo(const qint64& t);
int TruncateCacheRangeTo(const qint64& t);
void RemoveFirstFrame();
AVFormatContext* fmt_ctx() const
{
@@ -90,7 +91,7 @@ public:
QMutex* cache_lock();
QWaitCondition* cache_wait_cond();
bool IsWorking() const;
bool IsWorking();
void SetWorking(bool working);
private:
@@ -119,6 +120,7 @@ private:
int64_t cache_target_time_;
bool is_working_;
QMutex is_working_mutex_;
bool cache_at_zero_;
bool cache_at_eof_;
+1
View File
@@ -37,6 +37,7 @@ set(OLIVE_SOURCES
common/functiontimer.h
common/lerp.h
common/memorypool.h
common/memorypool.cpp
common/qtutils.h
common/qtutils.cpp
common/range.h
+14
View File
@@ -0,0 +1,14 @@
#include "memorypool.h"
OLIVE_NAMESPACE_ENTER
size_t memory_pool_consumption = 0;
QMutex memory_pool_consumption_lock;
bool MemoryPoolLimitReached()
{
QMutexLocker locker(&memory_pool_consumption_lock);
return (memory_pool_consumption >= 2147483648);
}
OLIVE_NAMESPACE_EXIT
+18 -1
View File
@@ -32,6 +32,10 @@
OLIVE_NAMESPACE_ENTER
extern size_t memory_pool_consumption;
extern QMutex memory_pool_consumption_lock;
bool MemoryPoolLimitReached();
template <typename T>
/**
* @brief MemoryPool base class
@@ -198,6 +202,7 @@ public:
Arena(MemoryPool* parent) {
parent_ = parent;
data_ = nullptr;
allocated_sz_ = 0;
}
~Arena() {
@@ -207,6 +212,10 @@ public:
}
delete [] data_;
memory_pool_consumption_lock.lock();
memory_pool_consumption -= allocated_sz_;
memory_pool_consumption_lock.unlock();
}
DISABLE_COPY_MOVE(Arena)
@@ -264,10 +273,16 @@ public:
element_sz_ = ele_sz;
if ((data_ = new char[element_sz_ * nb_elements])) {
allocated_sz_ = element_sz_ * nb_elements;
if ((data_ = new char[allocated_sz_])) {
available_.resize(nb_elements);
available_.fill(true);
memory_pool_consumption_lock.lock();
memory_pool_consumption += allocated_sz_;
memory_pool_consumption_lock.unlock();
return true;
} else {
available_.clear();
@@ -289,6 +304,8 @@ public:
char* data_;
size_t allocated_sz_;
QVector<bool> available_;
QMutex lock_;