render: use events to iterate gradually through frame queue

Fixes #1665
This commit is contained in:
itsmattkc
2021-07-12 00:48:26 -07:00
parent 310fd3541a
commit 7ff419b0a3
4 changed files with 37 additions and 24 deletions
+6
View File
@@ -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();
+23 -24
View File
@@ -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(QVector<RenderTicketWatche
Q_UNUSED(it)
}
void PreviewAutoCacher::QueueNextFrameInRange(int max)
{
rational t;
while (max && queued_frame_iterator_.GetNext(&t)) {
const QByteArray& hash = viewer_node_->video_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<typename T, typename Func>
void PreviewAutoCacher::ClearQueueInternal(T& list, bool hard, Func member)
{
+3
View File
@@ -115,6 +115,9 @@ private:
void ClearQueueRemoveEventInternal(QMap<RenderTicketWatcher*, TimeRange>::iterator it);
void ClearQueueRemoveEventInternal(QVector<RenderTicketWatcher*>::iterator it);
void QueueNextFrameInRange(int max);
TimeRangeListFrameIterator queued_frame_iterator_;
class QueuedJob {
public:
enum Type {
+5
View File
@@ -123,6 +123,11 @@ public:
return backend_;
}
static int GetNumberOfIdealConcurrentJobs()
{
return QThread::idealThreadCount();
}
signals:
private: