diff --git a/app/common/timerange.h b/app/common/timerange.h index 78c95d8db..3a7be3054 100644 --- a/app/common/timerange.h +++ b/app/common/timerange.h @@ -151,6 +151,7 @@ private: class TimeRangeListFrameIterator { public: + TimeRangeListFrameIterator() = default; TimeRangeListFrameIterator(const TimeRangeList &list, const rational &timebase); bool GetNext(rational *out); @@ -168,6 +169,11 @@ public: int size(); + void reset() + { + *this = TimeRangeListFrameIterator(); + } + private: void UpdateIndexIfNecessary(); diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index a27313cfa..567e5ed19 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -274,6 +274,8 @@ void PreviewAutoCacher::VideoRendered() TryRender(); } + QueueNextFrameInRange(1); + delete watcher; } @@ -442,6 +444,7 @@ void PreviewAutoCacher::ClearVideoQueue(bool hard) has_changed_ = true; use_custom_range_ = false; + queued_frame_iterator_.reset(); } void PreviewAutoCacher::ClearAudioQueue(bool hard) @@ -579,31 +582,9 @@ void PreviewAutoCacher::RequeueFrames() } TimeRangeList invalidated = viewer_node_->video_frame_cache()->GetInvalidatedRanges().Intersects(using_range); - TimeRangeListFrameIterator invalidated_ranges(invalidated, viewer_node_->video_frame_cache()->GetTimebase()); + queued_frame_iterator_ = TimeRangeListFrameIterator(invalidated, viewer_node_->video_frame_cache()->GetTimebase()); - rational t; - while (invalidated_ranges.GetNext(&t)) { - const QByteArray& hash = viewer_node_->video_frame_cache()->GetHash(t); - - RenderTicketWatcher* render_task = video_tasks_.key(hash); - - if (t >= using_range.in() - && t < using_range.out()) { - // We want this hash, if we're not already rendering, start render now - if (!render_task && !video_download_tasks_.key(hash)) { - // Don't render any hash more than once - RenderFrame(hash, t, false, false); - } - } else if (render_task) { - // Cancel this frame unless it's already started - QMutexLocker locker(render_task->GetTicket()->lock()); - - if (!render_task->GetTicket()->IsRunning(false)) { - video_tasks_.remove(render_task); - delete render_task; - } - } - } + QueueNextFrameInRange(RenderManager::GetNumberOfIdealConcurrentJobs()); has_changed_ = false; } @@ -777,6 +758,24 @@ void PreviewAutoCacher::ClearQueueRemoveEventInternal(QVectorvideo_frame_cache()->GetHash(t); + + RenderTicketWatcher* render_task = video_tasks_.key(hash); + + // We want this hash, if we're not already rendering, start render now + if (!render_task && !video_download_tasks_.key(hash)) { + // Don't render any hash more than once + RenderFrame(hash, t, false, false); + + max--; + } + } +} + template void PreviewAutoCacher::ClearQueueInternal(T& list, bool hard, Func member) { diff --git a/app/render/previewautocacher.h b/app/render/previewautocacher.h index 7869249ef..e60ca6c2a 100644 --- a/app/render/previewautocacher.h +++ b/app/render/previewautocacher.h @@ -115,6 +115,9 @@ private: void ClearQueueRemoveEventInternal(QMap::iterator it); void ClearQueueRemoveEventInternal(QVector::iterator it); + void QueueNextFrameInRange(int max); + TimeRangeListFrameIterator queued_frame_iterator_; + class QueuedJob { public: enum Type { diff --git a/app/render/rendermanager.h b/app/render/rendermanager.h index 34f8532d9..816394dac 100644 --- a/app/render/rendermanager.h +++ b/app/render/rendermanager.h @@ -123,6 +123,11 @@ public: return backend_; } + static int GetNumberOfIdealConcurrentJobs() + { + return QThread::idealThreadCount(); + } + signals: private: