From 20cf77d8f2a06a15c8e379c4c7e30a065e40067f Mon Sep 17 00:00:00 2001
From: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date: Sat, 9 Oct 2021 19:33:17 -0700
Subject: [PATCH] cache: show background caching in task manager
Allows users to cancel and monitor total progress.
---
app/common/timerange.cpp | 16 +++---
app/common/timerange.h | 9 +++-
app/render/previewautocacher.cpp | 22 +++++++++
app/render/previewautocacher.h | 7 +++
app/task/CMakeLists.txt | 1 +
app/task/customcache/CMakeLists.txt | 22 +++++++++
app/task/customcache/customcachetask.cpp | 62 ++++++++++++++++++++++++
app/task/customcache/customcachetask.h | 58 ++++++++++++++++++++++
8 files changed, 190 insertions(+), 7 deletions(-)
create mode 100644 app/task/customcache/CMakeLists.txt
create mode 100644 app/task/customcache/customcachetask.cpp
create mode 100644 app/task/customcache/customcachetask.h
diff --git a/app/common/timerange.cpp b/app/common/timerange.cpp
index e98da1bb0..c352e476d 100644
--- a/app/common/timerange.cpp
+++ b/app/common/timerange.cpp
@@ -295,8 +295,9 @@ TimeRangeListFrameIterator::TimeRangeListFrameIterator() :
TimeRangeListFrameIterator::TimeRangeListFrameIterator(const TimeRangeList &list, const rational &timebase) :
list_(list),
timebase_(timebase),
- index_(-1),
+ range_index_(-1),
size_(-1),
+ frame_index_(0),
custom_range_(false)
{
if (!list_.isEmpty() && timebase_.isNull()) {
@@ -321,12 +322,15 @@ bool TimeRangeListFrameIterator::GetNext(rational *out)
// If this time is outside the current range, jump to the next one
UpdateIndexIfNecessary();
+ // Increment frame index
+ frame_index_++;
+
return true;
}
bool TimeRangeListFrameIterator::HasNext() const
{
- return index_ < list_.size();
+ return range_index_ < list_.size();
}
int TimeRangeListFrameIterator::size()
@@ -355,11 +359,11 @@ int TimeRangeListFrameIterator::size()
void TimeRangeListFrameIterator::UpdateIndexIfNecessary()
{
- while (index_ < list_.size() && (index_ == -1 || current_ >= list_.at(index_).out())) {
- index_++;
+ while (range_index_ < list_.size() && (range_index_ == -1 || current_ >= list_.at(range_index_).out())) {
+ range_index_++;
- if (index_ < list_.size()) {
- current_ = Timecode::snap_time_to_timebase(list_.at(index_).in(), timebase_, Timecode::kCeil);
+ if (range_index_ < list_.size()) {
+ current_ = Timecode::snap_time_to_timebase(list_.at(range_index_).in(), timebase_, Timecode::kCeil);
}
}
}
diff --git a/app/common/timerange.h b/app/common/timerange.h
index ef1627d8e..abb004853 100644
--- a/app/common/timerange.h
+++ b/app/common/timerange.h
@@ -238,6 +238,11 @@ public:
custom_range_ = e;
}
+ int frame_index() const
+ {
+ return frame_index_;
+ }
+
private:
void UpdateIndexIfNecessary();
@@ -247,10 +252,12 @@ private:
rational current_;
- int index_;
+ int range_index_;
int size_;
+ int frame_index_;
+
bool custom_range_;
};
diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp
index 36fb9289f..86cfaa384 100644
--- a/app/render/previewautocacher.cpp
+++ b/app/render/previewautocacher.cpp
@@ -28,6 +28,8 @@
#include "node/project/project.h"
#include "render/rendermanager.h"
#include "render/renderprocessor.h"
+#include "task/customcache/customcachetask.h"
+#include "task/taskmanager.h"
#include "widget/slider/base/numericsliderbase.h"
namespace olive {
@@ -661,6 +663,12 @@ void PreviewAutoCacher::TryRender()
// Don't render any hash more than once
RenderFrame(hash, t, false, false);
}
+
+ emit SignalCacheProxyTaskProgress(double(queued_frame_iterator_.frame_index()) / double(queued_frame_iterator_.size()));
+
+ if (!queued_frame_iterator_.HasNext()) {
+ emit StopCacheProxyTasks();
+ }
}
// Handle audio tasks
@@ -724,6 +732,14 @@ void PreviewAutoCacher::RequeueFrames()
queued_frame_iterator_.SetCustomRange(use_custom_range_);
+ emit StopCacheProxyTasks();
+
+ CustomCacheTask *cct = new CustomCacheTask(viewer_node_->GetLabelOrName());
+ connect(this, &PreviewAutoCacher::StopCacheProxyTasks, cct, &CustomCacheTask::Finish);
+ connect(this, &PreviewAutoCacher::SignalCacheProxyTaskProgress, cct, &CustomCacheTask::ProgressChanged);
+ connect(cct, &CustomCacheTask::Cancelled, this, &PreviewAutoCacher::CacheProxyTaskCancelled);
+ TaskManager::instance()->AddTask(cct);
+
use_custom_range_ = false;
TryRender();
@@ -764,6 +780,12 @@ void PreviewAutoCacher::AudioAutoCacheEnableChanged(bool e)
}
}
+void PreviewAutoCacher::CacheProxyTaskCancelled()
+{
+ queued_frame_iterator_.reset();
+ RequeueFrames();
+}
+
void PreviewAutoCacher::ForceCacheRange(const TimeRange &range)
{
use_custom_range_ = true;
diff --git a/app/render/previewautocacher.h b/app/render/previewautocacher.h
index f85dfe7c1..246b0d1ff 100644
--- a/app/render/previewautocacher.h
+++ b/app/render/previewautocacher.h
@@ -99,6 +99,11 @@ public:
return queued_frame_iterator_.IsCustomRange() && queued_frame_iterator_.HasNext();
}
+signals:
+ void StopCacheProxyTasks();
+
+ void SignalCacheProxyTaskProgress(double d);
+
private:
void TryRender();
@@ -257,6 +262,8 @@ private slots:
void AudioAutoCacheEnableChanged(bool e);
+ void CacheProxyTaskCancelled();
+
};
}
diff --git a/app/task/CMakeLists.txt b/app/task/CMakeLists.txt
index 954557d8d..640946a68 100644
--- a/app/task/CMakeLists.txt
+++ b/app/task/CMakeLists.txt
@@ -15,6 +15,7 @@
# along with this program. If not, see .
add_subdirectory(conform)
+add_subdirectory(customcache)
add_subdirectory(export)
add_subdirectory(precache)
add_subdirectory(project)
diff --git a/app/task/customcache/CMakeLists.txt b/app/task/customcache/CMakeLists.txt
new file mode 100644
index 000000000..46abd88af
--- /dev/null
+++ b/app/task/customcache/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Olive - Non-Linear Video Editor
+# Copyright (C) 2021 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 .
+
+set(OLIVE_SOURCES
+ ${OLIVE_SOURCES}
+ task/customcache/customcachetask.cpp
+ task/customcache/customcachetask.h
+ PARENT_SCOPE
+)
diff --git a/app/task/customcache/customcachetask.cpp b/app/task/customcache/customcachetask.cpp
new file mode 100644
index 000000000..97d7c07fe
--- /dev/null
+++ b/app/task/customcache/customcachetask.cpp
@@ -0,0 +1,62 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2021 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 "customcachetask.h"
+
+namespace olive {
+
+CustomCacheTask::CustomCacheTask(const QString &sequence_name) :
+ cancelled_through_finish_(false)
+{
+ SetTitle(tr("Caching custom range for \"%1\"").arg(sequence_name));
+}
+
+void CustomCacheTask::Finish()
+{
+ mutex_.lock();
+
+ cancelled_through_finish_ = true;
+ Cancel();
+
+ mutex_.unlock();
+}
+
+bool CustomCacheTask::Run()
+{
+ mutex_.lock();
+
+ while (!IsCancelled()) {
+ wait_cond_.wait(&mutex_);
+ }
+
+ mutex_.unlock();
+
+ return true;
+}
+
+void CustomCacheTask::CancelEvent()
+{
+ if (!cancelled_through_finish_) {
+ emit Cancelled();
+ }
+ wait_cond_.wakeOne();
+}
+
+}
diff --git a/app/task/customcache/customcachetask.h b/app/task/customcache/customcachetask.h
new file mode 100644
index 000000000..e946ae775
--- /dev/null
+++ b/app/task/customcache/customcachetask.h
@@ -0,0 +1,58 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2021 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 CUSTOMCACHETASK_H
+#define CUSTOMCACHETASK_H
+
+#include
+#include
+
+#include "task/task.h"
+
+namespace olive {
+
+class CustomCacheTask : public Task
+{
+ Q_OBJECT
+public:
+ CustomCacheTask(const QString &sequence_name);
+
+ void Finish();
+
+signals:
+ void Cancelled();
+
+protected:
+ virtual bool Run() override;
+
+ virtual void CancelEvent() override;
+
+private:
+ QMutex mutex_;
+
+ QWaitCondition wait_cond_;
+
+ bool cancelled_through_finish_;
+
+};
+
+}
+
+#endif // CUSTOMCACHETASK_H