decoder/renderer: use memory cache and single decoder to optimize frames for
cycles
This commit is contained in:
@@ -24,7 +24,7 @@ bool AudioBackend::InitInternal()
|
||||
// Initiate one thread per CPU core
|
||||
for (int i=0;i<threads().size();i++) {
|
||||
// Create one processor object for each thread
|
||||
AudioWorker* processor = new AudioWorker();
|
||||
AudioWorker* processor = new AudioWorker(decoder_cache());
|
||||
processor->SetParameters(params());
|
||||
processors_.append(processor);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "audioworker.h"
|
||||
|
||||
AudioWorker::AudioWorker(QObject *parent) :
|
||||
AudioRenderWorker(parent)
|
||||
AudioWorker::AudioWorker(DecoderCache* decoder_cache, QObject *parent) :
|
||||
AudioRenderWorker(decoder_cache, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class AudioWorker : public AudioRenderWorker
|
||||
{
|
||||
public:
|
||||
AudioWorker(QObject* parent = nullptr);
|
||||
AudioWorker(DecoderCache* decoder_cache, QObject* parent = nullptr);
|
||||
|
||||
protected:
|
||||
virtual void FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable* table) override;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "audio/audiomanager.h"
|
||||
|
||||
AudioRenderWorker::AudioRenderWorker(QObject *parent) :
|
||||
RenderWorker(parent)
|
||||
AudioRenderWorker::AudioRenderWorker(DecoderCache* decoder_cache, QObject *parent) :
|
||||
RenderWorker(decoder_cache, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class AudioRenderWorker : public RenderWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioRenderWorker(QObject* parent = nullptr);
|
||||
AudioRenderWorker(DecoderCache* decoder_cache, QObject* parent = nullptr);
|
||||
|
||||
void SetParameters(const AudioRenderingParams& audio_params);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ bool OpenGLBackend::InitInternal()
|
||||
// Initiate one thread per CPU core
|
||||
for (int i=0;i<threads().size();i++) {
|
||||
// Create one processor object for each thread
|
||||
OpenGLWorker* processor = new OpenGLWorker(frame_cache());
|
||||
OpenGLWorker* processor = new OpenGLWorker(frame_cache(), decoder_cache());
|
||||
processor->SetParameters(params());
|
||||
processors_.append(processor);
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include "render/colormanager.h"
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
OpenGLWorker::OpenGLWorker(VideoRenderFrameCache *frame_cache, QObject *parent) :
|
||||
VideoRenderWorker(frame_cache, parent)
|
||||
OpenGLWorker::OpenGLWorker(VideoRenderFrameCache *frame_cache, DecoderCache* decoder_cache, QObject *parent) :
|
||||
VideoRenderWorker(frame_cache, decoder_cache, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
class OpenGLWorker : public VideoRenderWorker {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OpenGLWorker(VideoRenderFrameCache* frame_cache,
|
||||
OpenGLWorker(VideoRenderFrameCache* frame_cache, DecoderCache *decoder_cache,
|
||||
QObject* parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
@@ -83,6 +83,8 @@ void RenderBackend::Close()
|
||||
|
||||
threads_.clear();
|
||||
processors_.clear();
|
||||
|
||||
decoder_cache_.Clear();
|
||||
}
|
||||
|
||||
const QString &RenderBackend::GetError() const
|
||||
@@ -375,6 +377,11 @@ void RenderBackend::SetWorkerBusyState(RenderWorker *worker, bool busy)
|
||||
processor_busy_state_.replace(processors_.indexOf(worker), busy);
|
||||
}
|
||||
|
||||
DecoderCache *RenderBackend::decoder_cache()
|
||||
{
|
||||
return &decoder_cache_;
|
||||
}
|
||||
|
||||
bool RenderBackend::AllProcessorsAreAvailable() const
|
||||
{
|
||||
foreach (bool busy, processor_busy_state_) {
|
||||
|
||||
@@ -96,10 +96,14 @@ protected:
|
||||
bool WorkerIsBusy(RenderWorker* worker) const;
|
||||
void SetWorkerBusyState(RenderWorker* worker, bool busy);
|
||||
|
||||
DecoderCache* decoder_cache();
|
||||
|
||||
TimeRangeList cache_queue_;
|
||||
|
||||
QVector<RenderWorker*> processors_;
|
||||
|
||||
DecoderCache decoder_cache_;
|
||||
|
||||
bool compiled_;
|
||||
|
||||
QHash<TimeRange, qint64> render_job_info_;
|
||||
|
||||
@@ -18,41 +18,11 @@ public:
|
||||
|
||||
bool Has(K key) const {return values_.contains(key);}
|
||||
|
||||
private:
|
||||
QHash<K, V> values_;
|
||||
};
|
||||
void Lock() { lock_.lock(); }
|
||||
|
||||
template<class K, class V>
|
||||
class ThreadSafeRenderCache
|
||||
{
|
||||
public:
|
||||
ThreadSafeRenderCache() = default;
|
||||
void Unlock() { lock_.unlock(); }
|
||||
|
||||
void Clear() {
|
||||
lock_.lock();
|
||||
values_.clear();
|
||||
lock_.unlock();
|
||||
}
|
||||
|
||||
void Add(K key, V val) {
|
||||
lock_.lock();
|
||||
values_.insert(key, val);
|
||||
lock_.unlock();
|
||||
}
|
||||
|
||||
V Get(K key) {
|
||||
lock_.lock();
|
||||
V val = values_.value(key);
|
||||
lock_.unlock();
|
||||
return val;
|
||||
}
|
||||
|
||||
bool Has(K key) {
|
||||
lock_.lock();
|
||||
bool has = values_.contains(key);
|
||||
lock_.unlock();
|
||||
return has;
|
||||
}
|
||||
QMutex* lock() { return &lock_; }
|
||||
|
||||
private:
|
||||
QHash<K, V> values_;
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
#include "node/block/block.h"
|
||||
|
||||
RenderWorker::RenderWorker(QObject *parent) :
|
||||
RenderWorker::RenderWorker(DecoderCache *decoder_cache, QObject *parent) :
|
||||
QObject(parent),
|
||||
started_(false)
|
||||
started_(false),
|
||||
decoder_cache_(decoder_cache)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,8 +28,6 @@ void RenderWorker::Close()
|
||||
{
|
||||
CloseInternal();
|
||||
|
||||
decoder_cache_.Clear();
|
||||
|
||||
started_ = false;
|
||||
}
|
||||
|
||||
@@ -61,14 +60,22 @@ StreamPtr RenderWorker::ResolveStreamFromInput(NodeInput *input)
|
||||
|
||||
DecoderPtr RenderWorker::ResolveDecoderFromInput(StreamPtr stream)
|
||||
{
|
||||
QMutexLocker locker(decoder_cache_->lock());
|
||||
|
||||
// Access a map of Node inputs and decoder instances and retrieve a frame!
|
||||
DecoderPtr decoder = decoder_cache_.Get(stream.get());
|
||||
DecoderPtr decoder = decoder_cache_->Get(stream.get());
|
||||
|
||||
if (decoder == nullptr && stream != nullptr) {
|
||||
// Create a new Decoder here
|
||||
decoder = Decoder::CreateFromID(stream->footage()->decoder());
|
||||
decoder->set_stream(stream);
|
||||
decoder_cache_.Add(stream.get(), decoder);
|
||||
|
||||
if (decoder->Open()) {
|
||||
decoder_cache_->Add(stream.get(), decoder);
|
||||
} else {
|
||||
decoder = nullptr;
|
||||
qWarning() << "Failed to open decoder for" << stream->footage()->filename();
|
||||
}
|
||||
}
|
||||
|
||||
return decoder;
|
||||
|
||||
@@ -13,7 +13,7 @@ class RenderWorker : public QObject, public CancelableObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RenderWorker(QObject* parent = nullptr);
|
||||
RenderWorker(DecoderCache* decoder_cache, QObject* parent = nullptr);
|
||||
|
||||
DISABLE_COPY_MOVE(RenderWorker)
|
||||
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
|
||||
bool started_;
|
||||
|
||||
DecoderCache decoder_cache_;
|
||||
DecoderCache* decoder_cache_;
|
||||
|
||||
NodeDependency path_;
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "project/project.h"
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
VideoRenderWorker::VideoRenderWorker(VideoRenderFrameCache *frame_cache, QObject *parent) :
|
||||
RenderWorker(parent),
|
||||
VideoRenderWorker::VideoRenderWorker(VideoRenderFrameCache *frame_cache, DecoderCache* decoder_cache, QObject *parent) :
|
||||
RenderWorker(decoder_cache, parent),
|
||||
frame_cache_(frame_cache),
|
||||
operating_mode_(kHashRenderCache)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
kHashRenderCache = 0x7
|
||||
};
|
||||
|
||||
VideoRenderWorker(VideoRenderFrameCache* frame_cache, QObject* parent = nullptr);
|
||||
VideoRenderWorker(VideoRenderFrameCache* frame_cache, DecoderCache *decoder_cache, QObject* parent = nullptr);
|
||||
|
||||
void SetParameters(const VideoRenderingParams& video_params);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user