cache: use render job times to synchronize cache

Ensure old inaccurate jobs are never prioritized over current jobs.
This commit is contained in:
itsmattkc
2020-06-04 16:48:23 +10:00
parent cc34f0e251
commit 9ff9817b95
13 changed files with 106 additions and 40 deletions
+12 -1
View File
@@ -63,10 +63,14 @@ void AudioPlaybackCache::SetParameters(const AudioRenderingParams &params)
emit Invalidated(invalidate_range);
}
void AudioPlaybackCache::WritePCM(const TimeRange &range, SampleBufferPtr samples)
void AudioPlaybackCache::WritePCM(const TimeRange &range, SampleBufferPtr samples, const qint64 &job_time)
{
QMutexLocker locker(lock());
if (!JobIsCurrent(range, job_time)) {
return;
}
QFile f(filename_);
if (f.open(QFile::ReadWrite)) {
qint64 start_offset = params_.time_to_bytes(range.in());
@@ -193,6 +197,13 @@ void AudioPlaybackCache::ShiftEvent(const rational &from, const rational &to)
}
}
void AudioPlaybackCache::LengthChangedEvent(const rational& old, const rational& newlen)
{
if (newlen < old) {
QFile(filename_).resize(params_.time_to_bytes(newlen));
}
}
const QString &AudioPlaybackCache::GetCacheFilename() const
{
return filename_;
+3 -1
View File
@@ -40,7 +40,7 @@ public:
void SetParameters(const AudioRenderingParams& params);
void WritePCM(const TimeRange &range, SampleBufferPtr samples);
void WritePCM(const TimeRange &range, SampleBufferPtr samples, const qint64& job_time);
void WriteSilence(const TimeRange &range);
@@ -52,6 +52,8 @@ signals:
protected:
virtual void ShiftEvent(const rational& from, const rational& to) override;
virtual void LengthChangedEvent(const rational& old, const rational& newlen) override;
private:
QString filename_;
-2
View File
@@ -351,8 +351,6 @@ void RenderBackend::WorkerFinished()
if (viewer_node_) {
RunNextJob();
} else {
qDebug() << "Ignored job finish because no viewer";
}
}
+5 -1
View File
@@ -41,10 +41,14 @@ QByteArray FrameHashCache::GetHash(const rational &time)
return time_hash_map_.value(time);
}
void FrameHashCache::SetHash(const rational &time, const QByteArray &hash)
void FrameHashCache::SetHash(const rational &time, const QByteArray &hash, const qint64& job_time)
{
QMutexLocker locker(lock());
if (!JobIsCurrent(TimeRange(time, time), job_time)) {
return;
}
time_hash_map_.insert(time, hash);
TimeRange validated_range(time, time + timebase_);
+1 -1
View File
@@ -39,7 +39,7 @@ public:
QByteArray GetHash(const rational& time);
void SetHash(const rational& time, const QByteArray& hash);
void SetHash(const rational& time, const QByteArray& hash, const qint64 &job_time);
void SetTimebase(const rational& tb);
+44 -11
View File
@@ -20,6 +20,8 @@
#include "playbackcache.h"
#include <QDateTime>
OLIVE_NAMESPACE_ENTER
void PlaybackCache::Invalidate(const TimeRange &r)
@@ -89,21 +91,13 @@ void PlaybackCache::Shift(const rational &from, const rational &to)
emit Shifted(from, to);
}
void PlaybackCache::Validate(const TimeRange &r)
{
QMutexLocker locker(&lock_);
NoLockValidate(r);
locker.unlock();
emit Validated(r);
}
void PlaybackCache::NoLockInvalidate(const TimeRange &r)
{
invalidated_.InsertTimeRange(r);
RemoveRangeFromJobs(r);
jobs_.append({r, QDateTime::currentMSecsSinceEpoch()});
InvalidateEvent(r);
}
@@ -132,6 +126,20 @@ void PlaybackCache::NoLockSetLength(const rational &r)
length_ = r;
}
bool PlaybackCache::JobIsCurrent(const TimeRange &r, qint64 job_time)
{
for (int i=jobs_.size()-1; i>=0; i--) {
const JobIdentifier& job = jobs_.at(i);
if (job.range.Contains(r, true, r.in() != r.out())
&& job_time >= job.job_time) {
return true;
}
}
return false;
}
void PlaybackCache::LengthChangedEvent(const rational &, const rational &)
{
}
@@ -144,4 +152,29 @@ void PlaybackCache::ShiftEvent(const rational &, const rational &)
{
}
void PlaybackCache::RemoveRangeFromJobs(const TimeRange &remove)
{
// Code shamelessly copied from TimeRangeList::RemoveTimeRange
for (int i=0;i<jobs_.size();i++) {
JobIdentifier& job = jobs_[i];
TimeRange& compare = job.range;
if (remove.Contains(compare)) {
// This element is entirely encompassed in this range, remove it
jobs_.removeAt(i);
i--;
} else if (compare.Contains(remove, false, false)) {
// The remove range is within this element, only choice is to split the element into two
jobs_.append({TimeRange(remove.out(), compare.out()), job.job_time});
compare.set_out(remove.in());
} else if (compare.in() < remove.in() && compare.out() > remove.in()) {
// This element's out point overlaps the range's in, we'll trim it
compare.set_out(remove.in());
} else if (compare.in() < remove.out() && compare.out() > remove.out()) {
// This element's in point overlaps the range's out, we'll trim it
compare.set_in(remove.out());
}
}
}
OLIVE_NAMESPACE_EXIT
+11 -2
View File
@@ -80,14 +80,14 @@ signals:
void LengthChanged(const OLIVE_NAMESPACE::rational& r);
protected:
void Validate(const TimeRange& r);
void NoLockInvalidate(const TimeRange& r);
void NoLockValidate(const TimeRange& r);
void NoLockSetLength(const rational& r);
bool JobIsCurrent(const TimeRange& r, qint64 job_time);
const rational& NoLockGetLength() const
{
return length_;
@@ -110,10 +110,19 @@ protected:
}
private:
void RemoveRangeFromJobs(const TimeRange& remove);
QMutex lock_;
TimeRangeList invalidated_;
struct JobIdentifier {
TimeRange range;
qint64 job_time;
};
QList<JobIdentifier> jobs_;
rational length_;
};