/*** Olive - Non-Linear Video Editor Copyright (C) 2022 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "framemanager.h" #include #include namespace olive { FrameManager* FrameManager::instance_ = nullptr; const int FrameManager::kFrameLifetime = 5000; void FrameManager::CreateInstance() { instance_ = new FrameManager(); } void FrameManager::DestroyInstance() { delete instance_; instance_ = nullptr; } FrameManager *FrameManager::instance() { return instance_; } char *FrameManager::Allocate(int size) { if (instance()) { return instance()->AllocateFromPool(size); } else { return new char[size]; } } void FrameManager::Deallocate(int size, char *buffer) { if (instance()) { instance()->DeallocateToPool(size, buffer); } else { delete [] buffer; } } FrameManager::FrameManager() { clear_timer_.setInterval(kFrameLifetime); connect(&clear_timer_, &QTimer::timeout, this, &FrameManager::GarbageCollection); clear_timer_.start(); } char *FrameManager::AllocateFromPool(int size) { QMutexLocker locker(&mutex_); std::list& buffer_list = pool_[size]; char* buf = nullptr; if (buffer_list.empty()) { buf = new char[size]; } else { // Take this buffer from the list buf = buffer_list.front().data; buffer_list.pop_front(); } return buf; } void FrameManager::DeallocateToPool(int size, char *buffer) { QMutexLocker locker(&mutex_); std::list& buffer_list = pool_[size]; buffer_list.push_back({QDateTime::currentMSecsSinceEpoch(), buffer}); } void FrameManager::GarbageCollection() { QMutexLocker locker(&mutex_); qint64 min_life = QDateTime::currentMSecsSinceEpoch() - kFrameLifetime; for (auto it=pool_.begin(); it!=pool_.end(); it++) { std::list& list = it->second; while (list.size() > 0 && list.front().time < min_life) { delete [] list.front().data; list.pop_front(); } } } FrameManager::~FrameManager() { QMutexLocker locker(&mutex_); for (auto it=pool_.begin(); it!=pool_.end(); it++) { std::list& list = it->second; for (auto jt=list.begin(); jt!=list.end(); jt++) { delete [] (*jt).data; } } pool_.clear(); } }