cache: use render job times to synchronize cache
Ensure old inaccurate jobs are never prioritized over current jobs.
This commit is contained in:
@@ -63,10 +63,14 @@ void AudioPlaybackCache::SetParameters(const AudioRenderingParams ¶ms)
|
||||
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_;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -351,8 +351,6 @@ void RenderBackend::WorkerFinished()
|
||||
|
||||
if (viewer_node_) {
|
||||
RunNextJob();
|
||||
} else {
|
||||
qDebug() << "Ignored job finish because no viewer";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user