From 3a8a509f1a68cebb23e3598dc0b97c722b60e6e9 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 3 Jan 2020 21:17:20 +1100 Subject: [PATCH] clear frame caches and renderers if the viewer node is ever changed Clears the state if a viewer node is disconnected. --- app/render/backend/videorenderbackend.cpp | 2 ++ app/render/backend/videorenderframecache.cpp | 13 +++++++++++++ app/render/backend/videorenderframecache.h | 2 ++ app/widget/viewer/viewer.cpp | 18 ++++++++++++------ app/widget/viewer/viewer.h | 2 ++ app/widget/viewer/viewerglwidget.cpp | 10 +++++----- 6 files changed, 36 insertions(+), 11 deletions(-) diff --git a/app/render/backend/videorenderbackend.cpp b/app/render/backend/videorenderbackend.cpp index 950ae6a92..fc895e6e8 100644 --- a/app/render/backend/videorenderbackend.cpp +++ b/app/render/backend/videorenderbackend.cpp @@ -60,6 +60,8 @@ void VideoRenderBackend::DisconnectViewer(ViewerOutput *node) disconnect(node, &ViewerOutput::VideoChangedBetween, this, &VideoRenderBackend::InvalidateCache); disconnect(node, &ViewerOutput::VideoGraphChanged, this, &VideoRenderBackend::QueueRecompile); disconnect(node, &ViewerOutput::LengthChanged, this, &VideoRenderBackend::TruncateFrameCacheLength); + + frame_cache_.Clear(); } const VideoRenderingParams &VideoRenderBackend::params() const diff --git a/app/render/backend/videorenderframecache.cpp b/app/render/backend/videorenderframecache.cpp index fa6434c11..1fc8fb3cb 100644 --- a/app/render/backend/videorenderframecache.cpp +++ b/app/render/backend/videorenderframecache.cpp @@ -10,6 +10,17 @@ VideoRenderFrameCache::VideoRenderFrameCache() } +void VideoRenderFrameCache::Clear() +{ + time_hash_map_.clear(); + + currently_caching_lock_.lock(); + currently_caching_list_.clear(); + currently_caching_lock_.unlock(); + + cache_id_.clear(); +} + bool VideoRenderFrameCache::HasHash(const QByteArray &hash) { return QFileInfo::exists(CachePathName(hash)) && !IsCaching(hash); @@ -43,6 +54,8 @@ bool VideoRenderFrameCache::TryCache(const rational& time, const QByteArray &has void VideoRenderFrameCache::SetCacheID(const QString &id) { + Clear(); + cache_id_ = id; } diff --git a/app/render/backend/videorenderframecache.h b/app/render/backend/videorenderframecache.h index f4c9e204d..1e53f2a82 100644 --- a/app/render/backend/videorenderframecache.h +++ b/app/render/backend/videorenderframecache.h @@ -10,6 +10,8 @@ class VideoRenderFrameCache public: VideoRenderFrameCache(); + void Clear(); + /** * @brief Return whether a frame with this hash already exists */ diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 9683d9601..51c7bece6 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -142,7 +142,6 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man disconnect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase); disconnect(viewer_node_, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot); disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot); - disconnect(viewer_node_, &ViewerOutput::LengthChanged, ruler_, &TimeRuler::SetCacheStatusLength); disconnect(viewer_node_, &ViewerOutput::VideoChangedBetween, ruler_, &TimeRuler::CacheInvalidatedRange); // Effectively disables the viewer and clears the state @@ -153,19 +152,18 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man viewer_node_ = node; - // Set texture to new texture (or null if no viewer node is available) - UpdateTextureFromNode(GetTime()); - video_renderer_->SetViewerNode(viewer_node_); audio_renderer_->SetViewerNode(viewer_node_); + // Set texture to new texture (or null if no viewer node is available) + UpdateTextureFromNode(GetTime()); + if (viewer_node_ != nullptr) { SetTimebase(viewer_node_->video_params().time_base()); connect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase); connect(viewer_node_, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot); connect(viewer_node_, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot); - connect(viewer_node_, &ViewerOutput::LengthChanged, ruler_, &TimeRuler::SetCacheStatusLength); connect(viewer_node_, &ViewerOutput::VideoChangedBetween, ruler_, &TimeRuler::CacheInvalidatedRange); SizeChangedSlot(viewer_node_->video_params().width(), viewer_node_->video_params().height()); @@ -181,6 +179,11 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man video_renderer_->SetParameters(VideoRenderingParams(viewer_node_->video_params(), PixelFormat::PIX_FMT_RGBA16F, RenderMode::kOffline, 2)); audio_renderer_->SetParameters(AudioRenderingParams(viewer_node_->audio_params(), SAMPLE_FMT_FLT)); + + // Reload cache into these renderers + // FIXME: Slow, rather than invalidate, we should probably serialize the cache into and out of files + video_renderer_->InvalidateCache(0, viewer_node_->Length()); + //audio_renderer_->InvalidateCache(0, viewer_node_->Length()); } } @@ -225,12 +228,14 @@ void ViewerWidget::UpdateTimeInternal(int64_t i) controls_->SetTime(i); - if (viewer_node_ != nullptr) { + if (viewer_node_ != nullptr && last_time_ != i) { UpdateTextureFromNode(time_set); PushScrubbedAudio(); } + last_time_ = i; + emit TimeChanged(i); } @@ -436,6 +441,7 @@ void ViewerWidget::SizeChangedSlot(int width, int height) void ViewerWidget::LengthChangedSlot(const rational &length) { controls_->SetEndTime(Timecode::time_to_timestamp(length, time_base_)); + ruler_->SetCacheStatusLength(length); } void ViewerWidget::resizeEvent(QResizeEvent *event) diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 36bd04ec9..563740c47 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -173,6 +173,8 @@ private: qint64 frame_cache_job_time_; + int64_t last_time_; + private slots: void RulerTimeChange(int64_t); diff --git a/app/widget/viewer/viewerglwidget.cpp b/app/widget/viewer/viewerglwidget.cpp index 2f226ef1e..8229e1a4e 100644 --- a/app/widget/viewer/viewerglwidget.cpp +++ b/app/widget/viewer/viewerglwidget.cpp @@ -123,11 +123,6 @@ void ViewerGLWidget::initializeGL() void ViewerGLWidget::paintGL() { - // We only draw if we have a pipeline - if (!pipeline_ || !texture_) { - return; - } - // Get functions attached to this context (they will already be initialized) QOpenGLFunctions* f = context()->functions(); @@ -135,6 +130,11 @@ void ViewerGLWidget::paintGL() f->glClearColor(0.0f, 0.0f, 0.0f, 0.0f); f->glClear(GL_COLOR_BUFFER_BIT); + // We only draw if we have a pipeline + if (!pipeline_ || !texture_) { + return; + } + // Bind retrieved texture f->glBindTexture(GL_TEXTURE_2D, texture_->texture());