/*** 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 . ***/ #ifndef RENDERBACKEND_H #define RENDERBACKEND_H #include #include "config/config.h" #include "dialog/rendercancel/rendercancel.h" #include "decodercache.h" #include "node/graph.h" #include "node/output/viewer/viewer.h" #include "render/backend/colorprocessorcache.h" #include "renderticket.h" #include "renderticketwatcher.h" #include "renderworker.h" OLIVE_NAMESPACE_ENTER class RenderBackend : public QObject { Q_OBJECT public: RenderBackend(QObject* parent = nullptr); virtual ~RenderBackend() override; void Close(); ViewerOutput* GetViewerNode() const { return viewer_node_; } void SetViewerNode(ViewerOutput* viewer_node); void SetAutoCacheEnabled(bool e) { autocache_enabled_ = e; } bool IsAutoCachePaused() const { return autocache_paused_; } void SetAutoCachePaused(bool paused) { autocache_paused_ = paused; if (autocache_paused_) { // Pause the autocache ClearVideoQueue(); } else { // Unpause the cache AutoCacheRequeueFrames(); } } void AutoCacheRange(const TimeRange& range); void AutoCacheRequeueFrames(); void SetAutoCachePlayhead(const rational& playhead) { autocache_range_ = TimeRange(playhead - Config::Current()["DiskCacheBehind"].value(), playhead + Config::Current()["DiskCacheAhead"].value()); autocache_has_changed_ = true; use_custom_autocache_range_ = false; AutoCacheRequeueFrames(); } void SetRenderMode(RenderMode::Mode e) { render_mode_ = e; } void SetPreviewGenerationEnabled(bool e) { generate_audio_previews_ = e; } void ProcessUpdateQueue(); /** * @brief Asynchronously generate a hash at a given time */ RenderTicketPtr Hash(const QVector ×, bool prioritize = false); /** * @brief Asynchronously generate a frame at a given time */ RenderTicketPtr RenderFrame(const rational& time, bool prioritize = false, const QByteArray& hash = QByteArray()); /** * @brief Asynchronously generate a chunk of audio */ RenderTicketPtr RenderAudio(const TimeRange& r, bool prioritize = false); const VideoParams& GetVideoParams() const { return video_params_; } const AudioParams& GetAudioParams() const { return audio_params_; } void SetVideoParams(const VideoParams& params); void SetAudioParams(const AudioParams& params); void SetForceDownloadResolution(bool e) { video_force_download_resolution_ = e; } void SetVideoDownloadMatrix(const QMatrix4x4& mat) { video_download_matrix_ = mat; } static std::list SplitRangeIntoChunks(const TimeRange& r); public slots: void NodeGraphChanged(NodeInput *source); void ClearVideoQueue(); void ClearAudioQueue(); void ClearQueue(); signals: protected: virtual RenderWorker* CreateNewWorker() = 0; private: void CopyNodeInputValue(NodeInput* input); Node *CopyNodeConnections(Node *src_node); void CopyNodeMakeConnection(NodeInput *src_input, NodeInput *dst_input); void ClearQueueOfType(RenderTicket::Type type); void SetHashes(FrameHashCache* cache, const QVector& times, const QVector& hashes, qint64 job_time); ViewerOutput* viewer_node_; // VIDEO MEMBERS VideoParams video_params_; bool video_force_download_resolution_; QMatrix4x4 video_download_matrix_; // AUDIO MEMBERS AudioParams audio_params_; QList graph_update_queue_; QHash copy_map_; ViewerOutput* copied_viewer_node_; std::list render_queue_; std::list running_tickets_; struct WorkerData { RenderWorker* worker; bool busy; }; QVector workers_; bool autocache_enabled_; bool autocache_paused_; bool generate_audio_previews_; RenderMode::Mode render_mode_; TimeRange autocache_range_; bool autocache_has_changed_; bool use_custom_autocache_range_; TimeRange custom_autocache_range_; static QVector instances_; static QMutex instance_lock_; static RenderBackend* active_instance_; static QThreadPool thread_pool_; void SetActiveInstance(); QMap > autocache_hash_tasks_; QList*> autocache_hash_process_tasks_; QMap autocache_audio_tasks_; QMap autocache_video_tasks_; QMap*, QByteArray> autocache_video_download_tasks_; QVector autocache_currently_caching_hashes_; private slots: void WorkerFinished(); void RunNextJob(); void TicketFinished(); void WorkerGeneratedWaveform(OLIVE_NAMESPACE::RenderTicketPtr ticket, OLIVE_NAMESPACE::TrackOutput* track, OLIVE_NAMESPACE::AudioVisualWaveform samples, OLIVE_NAMESPACE::TimeRange range); void AutoCacheVideoInvalidated(const OLIVE_NAMESPACE::TimeRange &range); void AutoCacheAudioInvalidated(const OLIVE_NAMESPACE::TimeRange &range); void AutoCacheHashesGenerated(); void AutoCacheHashesProcessed(); void AutoCacheAudioRendered(); void AutoCacheVideoRendered(); void AutoCacheVideoDownloaded(); }; OLIVE_NAMESPACE_EXIT #endif // RENDERBACKEND_H