cache: improved queue performance and stability

This commit is contained in:
itsmattkc
2021-03-25 16:57:15 +11:00
parent b137b8e0ac
commit 9b49bea096
6 changed files with 55 additions and 49 deletions
+36 -40
View File
@@ -358,13 +358,6 @@ void PreviewAutoCacher::SetPlayhead(const rational &playhead)
RequeueFrames();
}
void PreviewAutoCacher::ClearQueue(bool wait)
{
ClearHashQueue(wait);
ClearVideoQueue(wait);
ClearAudioQueue(wait);
}
void PreviewAutoCacher::ClearHashQueue(bool wait)
{
auto copy = hash_tasks_;
@@ -539,27 +532,34 @@ void PreviewAutoCacher::RequeueFrames()
QVector<rational> invalidated_ranges = viewer_node_->video_frame_cache()->GetInvalidatedFrames(using_range);
ClearVideoQueue();
foreach (const rational& t, invalidated_ranges) {
const QByteArray& hash = viewer_node_->video_frame_cache()->GetHash(t);
if (t >= using_range.in()
&& t < using_range.out()
&& !currently_caching_hashes_.contains(hash)) {
// Don't render any hash more than once
currently_caching_hashes_.append(hash);
bool currently_caching_hash = currently_caching_hashes_.contains(hash);
RenderTicketWatcher* watcher = new RenderTicketWatcher();
watcher->setProperty("hash", hash);
connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoRendered);
video_tasks_.insert(watcher, hash);
watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_,
color_manager_,
t,
RenderMode::kOffline,
viewer_node_->video_frame_cache(),
false));
if (t >= using_range.in()
&& t < using_range.out()) {
if (!currently_caching_hash) {
// Don't render any hash more than once
currently_caching_hashes_.append(hash);
RenderTicketWatcher* watcher = new RenderTicketWatcher();
watcher->setProperty("hash", hash);
connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoRendered);
video_tasks_.insert(watcher, hash);
watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_,
color_manager_,
t,
RenderMode::kOffline,
viewer_node_->video_frame_cache(),
false));
}
} else if (currently_caching_hash) {
// Cancel this frame unless it's already started
RenderTicketWatcher* watcher = video_tasks_.key(hash);
if (watcher && watcher->HasStarted()) {
watcher->Cancel();
}
}
}
@@ -589,27 +589,23 @@ void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
if (viewer_node_) {
// Cancel any remaining tickets and wait for them to finish
ClearQueue(true);
// Clear autocache lists
{
// We need to wait for these since they work directly on the FrameHashCache. Most of the time
// this is fine, but not if the FrameHashCache gets deleted after this function.
ClearHashQueue(true);
// We need to wait for these since they send signals directly to the FrameHashCache
// which might get deleted after this function.
ClearHashQueue(true);
// This can be cleared normally (frames will be discarded and need to be rendered again)
ClearVideoQueue(false);
// This can be cleared normally (frames will be discarded and need to be rendered again)
ClearVideoQueue(true);
// This can be cleared normally (PCM data will be discarded and need to be rendered again)
ClearAudioQueue(false);
// This can be cleared normally (PCM data will be discarded and need to be rendered again)
ClearAudioQueue(true);
// We'll need to wait for these since they work directly on the FrameHashCache. Frames will
// be in the cache for later use.
ClearVideoDownloadQueue(true);
// We'll need to wait for these since they work directly on the FrameHashCache. Frames will
// be in the cache for later use.
ClearVideoDownloadQueue(true);
// No longer caching any hashes
currently_caching_hashes_.clear();
}
// No longer caching any hashes
currently_caching_hashes_.clear();
// Delete all of our copied nodes
qDeleteAll(created_nodes_);
-9
View File
@@ -74,15 +74,6 @@ public:
*/
void SetPlayhead(const rational& playhead);
/**
* @brief Clears queue of running jobs
*
* Any jobs that haven't run yet are cancelled and will never run. Any jobs that are currently
* running are cancelled, but may not be finished by the time this function returns. If the
* jobs must be finished by the time this function returns, set `wait` to TRUE.
*/
void ClearQueue(bool wait = false);
void ClearHashQueue(bool wait = false);
void ClearVideoQueue(bool wait = false);
void ClearAudioQueue(bool wait = false);
+6
View File
@@ -48,6 +48,12 @@ QVariant RenderTicket::Get()
return result_;
}
bool RenderTicket::HasStarted()
{
QMutexLocker locker(&lock_);
return started_;
}
bool RenderTicket::IsFinished(bool lock)
{
if (lock) {
+2
View File
@@ -52,6 +52,8 @@ public:
QVariant Get();
bool HasStarted();
bool IsFinished(bool lock = true);
bool WasCancelled();
+9
View File
@@ -70,6 +70,15 @@ bool RenderTicketWatcher::IsFinished()
}
}
bool RenderTicketWatcher::HasStarted()
{
if (ticket_) {
return ticket_->HasStarted();
} else {
return false;
}
}
void RenderTicketWatcher::WaitForFinished()
{
if (ticket_) {
+2
View File
@@ -44,6 +44,8 @@ public:
bool IsFinished();
bool HasStarted();
void WaitForFinished();
QVariant Get();