cache: attempt to automatically re-match hashes on invalidate

This code is slow and unoptimized. Will require some more work.
This commit is contained in:
itsmattkc
2020-05-21 16:49:02 +10:00
parent cb72736f52
commit 34fade9d81
7 changed files with 73 additions and 21 deletions
+5
View File
@@ -66,6 +66,11 @@ class TimeRangeList : public QList<TimeRange> {
public:
TimeRangeList() = default;
TimeRangeList(std::initializer_list<TimeRange> r) :
QList<TimeRange>(r)
{
}
void InsertTimeRange(const TimeRange& range);
void RemoveTimeRange(const TimeRange& range);
+31
View File
@@ -29,6 +29,7 @@
#include "codec/frame.h"
#include "common/filefunctions.h"
#include "common/timecodefunctions.h"
#include "render/diskmanager.h"
OLIVE_NAMESPACE_ENTER
@@ -104,6 +105,36 @@ QString FrameHashCache::GetFormatExtension(const PixelFormat::Format &f)
}
}
QList<rational> FrameHashCache::GetFrameListFromTimeRange(TimeRangeList range_list, const rational &timebase)
{
QList<rational> times;
while (!range_list.isEmpty()) {
const TimeRange& range = range_list.first();
rational time = range.in();
rational snapped = Timecode::snap_time_to_timebase(time, timebase);
rational next;
if (snapped > time) {
next = snapped;
snapped -= timebase;
} else {
next = snapped + timebase;
}
times.append(snapped);
range_list.RemoveTimeRange(TimeRange(snapped, next));
}
return times;
}
QList<rational> FrameHashCache::GetFrameListFromTimeRange(const TimeRangeList &range) const
{
return GetFrameListFromTimeRange(range, timebase_);
}
void FrameHashCache::SaveCacheFrame(const QByteArray& hash,
char* data,
const VideoRenderingParams& vparam)
+3
View File
@@ -66,6 +66,9 @@ public:
static QString GetFormatExtension(const PixelFormat::Format& f);
static QList<rational> GetFrameListFromTimeRange(TimeRangeList range_list, const rational& timebase);
QList<rational> GetFrameListFromTimeRange(const TimeRangeList &range) const;
protected:
virtual void LengthChangedEvent(const rational& old, const rational& newlen) override;
+1 -3
View File
@@ -85,9 +85,7 @@ bool ExportTask::Run()
}
// Start render process
TimeRangeList ranges;
ranges.InsertTimeRange(range);
Render(ranges, mat, params_.audio_enabled());
Render({range}, mat, params_.audio_enabled());
bool success = true;
+3 -18
View File
@@ -73,25 +73,10 @@ void RenderTask::Render(const TimeRangeList& range_to_cache,
QLinkedList<TimeHashFuturePair> hash_list;
{
TimeRangeList range_list = range_to_cache;
while (!range_list.isEmpty()) {
const TimeRange& range = range_list.first();
QList<rational> times = viewer_->video_frame_cache()->GetFrameListFromTimeRange(range_to_cache);
const rational& timebase = viewer_->video_params().time_base();
rational time = range.in();
rational snapped = Timecode::snap_time_to_timebase(time, timebase);
rational next;
if (snapped > time) {
next = snapped;
snapped -= timebase;
} else {
next = snapped + timebase;
}
hash_list.append({snapped, backend.Hash(snapped, false)});
range_list.RemoveTimeRange(TimeRange(snapped, next));
foreach (const rational& r, times) {
hash_list.append({r, backend.Hash(r, false)});
}
}
+26
View File
@@ -732,6 +732,24 @@ void ViewerWidget::RendererGeneratedFrameForQueue()
}
}
void ViewerWidget::HashGenerated()
{
QFutureWatcher<QByteArray>* watcher = static_cast<QFutureWatcher<QByteArray>*>(sender());
if (hash_watchers_.contains(watcher)) {
QString cache_fn = GetConnectedNode()->video_frame_cache()->CachePathName(watcher->result(), GetCurrentPixelFormat());
if (QFileInfo::exists(cache_fn)) {
GetConnectedNode()->video_frame_cache()->SetHash(hash_watchers_.value(watcher),
watcher->result());
}
hash_watchers_.remove(watcher);
}
watcher->deleteLater();
}
void ViewerWidget::UpdateRendererParameters()
{
renderer_->SetVideoParams(VideoRenderingParams(GetConnectedNode()->video_params(),
@@ -1071,6 +1089,14 @@ void ViewerWidget::ViewerInvalidatedRange(const TimeRange &range)
if (GetTime() >= range.in() && (GetTime() < range.out() || range.in() == range.out())) {
ForceUpdate();
}
QList<rational> invalidated_frames = GetConnectedNode()->video_frame_cache()->GetFrameListFromTimeRange({range});
foreach (const rational& r, invalidated_frames) {
QFutureWatcher<QByteArray>* watcher = new QFutureWatcher<QByteArray>();
connect(watcher, &QFutureWatcher<QByteArray>::finished, this, &ViewerWidget::HashGenerated);
hash_watchers_.insert(watcher, r);
watcher->setFuture(renderer_->Hash(r, true));
}
}
OLIVE_NAMESPACE_EXIT
+4
View File
@@ -233,6 +233,8 @@ private:
QList< QFutureWatcher<FramePtr>* > nonqueue_watchers_;
QHash<QFutureWatcher<QByteArray>*, rational> hash_watchers_;
private slots:
void PlaybackTimerUpdate();
@@ -268,6 +270,8 @@ private slots:
void RendererGeneratedFrameForQueue();
void HashGenerated();
};
OLIVE_NAMESPACE_EXIT