frames Previously, when the video renderer received a dirty cache signal, it would proceed to extract all frames from the range and queue them. However, this could be extremely slow for long ranges since it had to iterate through the entire range and calculate the individual frames it contained. Now, we use the same range combining system as audio and automatically calculate the next frame within the range only when necessary. Essentially the same work, but split up over time and done only when needed leading to no discernible UI pause when invalidating cache.
135 lines
3.8 KiB
C++
135 lines
3.8 KiB
C++
/***
|
|
|
|
Olive - Non-Linear Video Editor
|
|
Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
#ifndef VIDEORENDERERBACKEND_H
|
|
#define VIDEORENDERERBACKEND_H
|
|
|
|
#include <QLinkedList>
|
|
|
|
#include "colorprocessorcache.h"
|
|
#include "node/output/viewer/viewer.h"
|
|
#include "renderbackend.h"
|
|
#include "render/pixelformat.h"
|
|
#include "render/rendermodes.h"
|
|
#include "videorenderframecache.h"
|
|
|
|
/**
|
|
* @brief A multithreaded OpenGL based renderer for node systems
|
|
*/
|
|
class VideoRenderBackend : public RenderBackend
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* @brief Renderer Constructor
|
|
*
|
|
* Constructing a Renderer object will not start any threads/backend on its own. Use Start() to do this and Stop()
|
|
* when the Renderer is about to be destroyed.
|
|
*/
|
|
VideoRenderBackend(QObject* parent = nullptr);
|
|
|
|
/**
|
|
* @brief Set parameters of the Renderer
|
|
*
|
|
* The Renderer owns the buffers that are used in the rendering process and this function sets the kind of buffers
|
|
* to use. The Renderer must be stopped when calling this function.
|
|
*/
|
|
void SetParameters(const VideoRenderingParams ¶ms);
|
|
|
|
void SetExportMode(bool enabled);
|
|
|
|
bool IsRendered(const rational& time) const;
|
|
|
|
protected:
|
|
/**
|
|
* @brief Allocate and start the multithreaded backend
|
|
*/
|
|
virtual bool InitInternal() override;
|
|
|
|
/**
|
|
* @brief Terminate and deallocate the multithreaded backend
|
|
*/
|
|
virtual void CloseInternal() override;
|
|
|
|
struct HashTimeMapping {
|
|
rational time;
|
|
QByteArray hash;
|
|
};
|
|
|
|
virtual void ConnectViewer(ViewerOutput* node) override;
|
|
|
|
virtual void DisconnectViewer(ViewerOutput* node) override;
|
|
|
|
const char *GetCachedFrame(const rational& time);
|
|
|
|
virtual NodeInput* GetDependentInput() override;
|
|
|
|
virtual bool CanRender() override;
|
|
|
|
virtual TimeRange PopNextFrameFromQueue() override;
|
|
|
|
VideoRenderFrameCache* frame_cache();
|
|
|
|
const VideoRenderingParams& params() const;
|
|
|
|
/**
|
|
* @brief Internal function for generating the cache ID
|
|
*/
|
|
virtual bool GenerateCacheIDInternal(QCryptographicHash& hash) override;
|
|
|
|
virtual void CacheIDChangedEvent(const QString& id) override;
|
|
|
|
virtual void ConnectWorkerToThis(RenderWorker* processor) override;
|
|
|
|
virtual void EmitCachedFrameReady(const QList<rational> ×, const QVariant& value, qint64 job_time) = 0;
|
|
|
|
bool export_mode_;
|
|
|
|
signals:
|
|
void CachedFrameReady(const rational& time, QVariant value, qint64 job_time);
|
|
void CachedTimeReady(const rational& time, qint64 job_time);
|
|
|
|
private:
|
|
bool TimeIsQueued(const TimeRange &time) const;
|
|
|
|
bool JobIsCurrent(const NodeDependency &dep, const qint64& job_time) const;
|
|
|
|
bool SetFrameHash(const NodeDependency& dep, const QByteArray& hash, const qint64& job_time);
|
|
|
|
VideoRenderingParams params_;
|
|
|
|
QByteArray cache_frame_load_buffer_;
|
|
|
|
VideoRenderFrameCache frame_cache_;
|
|
|
|
rational last_time_requested_;
|
|
|
|
private slots:
|
|
void ThreadCompletedFrame(NodeDependency path, qint64 job_time, QByteArray hash, QVariant value);
|
|
void ThreadCompletedDownload(NodeDependency dep, qint64 job_time, QByteArray hash);
|
|
void ThreadSkippedFrame(NodeDependency dep, qint64 job_time, QByteArray hash);
|
|
void ThreadHashAlreadyExists(NodeDependency dep, qint64 job_time, QByteArray hash);
|
|
|
|
void TruncateFrameCacheLength(const rational& length);
|
|
|
|
};
|
|
|
|
#endif // VIDEORENDERERBACKEND_H
|