cache: improved setting manual cache path on a per project basis

This commit is contained in:
itsmattkc
2020-08-07 13:41:09 +10:00
parent df14c2aaa7
commit d85089f71a
12 changed files with 119 additions and 194 deletions
+7 -18
View File
@@ -37,8 +37,6 @@ AudioPlaybackCache::AudioPlaybackCache(QObject* parent) :
void AudioPlaybackCache::SetParameters(const AudioParams &params)
{
QMutexLocker locker(lock());
if (params_ == params) {
return;
}
@@ -52,22 +50,17 @@ void AudioPlaybackCache::SetParameters(const AudioParams &params)
}
// Our current audio cache is unusable, so we truncate it automatically
TimeRange invalidate_range(0, NoLockGetLength());
TimeRange invalidate_range(0, GetLength());
if (invalidate_range.in() != invalidate_range.out()) {
NoLockInvalidate(invalidate_range);
Invalidate(invalidate_range);
}
locker.unlock();
emit ParametersChanged();
emit Invalidated(invalidate_range);
}
void AudioPlaybackCache::WritePCM(const TimeRange &range, SampleBufferPtr samples, const qint64 &job_time)
{
QMutexLocker locker(lock());
QList<TimeRange> valid_ranges = NoLockGetValidRanges(range, job_time);
QList<TimeRange> valid_ranges = GetValidRanges(range, job_time);
if (valid_ranges.isEmpty()) {
return;
}
@@ -102,11 +95,7 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, SampleBufferPtr sample
f.close();
NoLockValidate(range);
locker.unlock();
emit Validated(range);
Validate(range);
} else {
qWarning() << "Failed to write PCM data to" << filename_;
}
@@ -114,8 +103,6 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, SampleBufferPtr sample
void AudioPlaybackCache::WriteSilence(const TimeRange &range)
{
QMutexLocker locker(lock());
QFile f(filename_);
if (f.open(QFile::ReadWrite)) {
qint64 start_offset = params_.time_to_bytes(range.in());
@@ -132,6 +119,8 @@ void AudioPlaybackCache::WriteSilence(const TimeRange &range)
f.write(a);
f.close();
Validate(range);
} else {
qWarning() << "Failed to write PCM data to" << filename_;
}
@@ -232,7 +221,7 @@ void AudioPlaybackCache::LengthChangedEvent(const rational& old, const rational&
}
}
QList<TimeRange> AudioPlaybackCache::NoLockGetValidRanges(const TimeRange& range, const qint64& job_time)
QList<TimeRange> AudioPlaybackCache::GetValidRanges(const TimeRange& range, const qint64& job_time)
{
QList<TimeRange> valid_ranges;
+3 -10
View File
@@ -33,8 +33,8 @@ class AudioPlaybackCache : public PlaybackCache
public:
AudioPlaybackCache(QObject* parent = nullptr);
AudioParams GetParameters() {
QMutexLocker locker(lock());
AudioParams GetParameters()
{
return params_;
}
@@ -48,12 +48,7 @@ public:
const QString& GetCacheFilename() const;
QList<TimeRange> GetValidRanges(const TimeRange &range, const qint64 &job_time)
{
QMutexLocker locker(lock());
return NoLockGetValidRanges(range, job_time);
}
QList<TimeRange> GetValidRanges(const TimeRange &range, const qint64 &job_time);
signals:
void ParametersChanged();
@@ -64,8 +59,6 @@ protected:
virtual void LengthChangedEvent(const rational& old, const rational& newlen) override;
private:
QList<TimeRange> NoLockGetValidRanges(const TimeRange &range, const qint64 &job_time);
void UpdateFilename(const QString& s);
QString filename_;
+9
View File
@@ -136,6 +136,15 @@ DiskCacheFolder *DiskManager::GetOpenFolder(const QString &path)
return f;
}
bool DiskManager::ShowDiskCacheChangeConfirmationDialog(QWidget *parent)
{
return (QMessageBox::question(parent,
tr("Disk Cache"),
tr("You've chosen to change the default disk cache location. This "
"will invalidate your current cache. Would you like to continue?"),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);
}
DiskCacheFolder::DiskCacheFolder(const QString &path, QObject *parent) :
QObject(parent)
{
+5
View File
@@ -26,6 +26,7 @@
#include <QObject>
#include "common/define.h"
#include "project/project.h"
OLIVE_NAMESPACE_ENTER
@@ -128,6 +129,8 @@ public:
return open_folders_;
}
static bool ShowDiskCacheChangeConfirmationDialog(QWidget* parent);
public slots:
void Accessed(const QString& cache_folder, const QByteArray& hash);
@@ -136,6 +139,8 @@ public slots:
signals:
void DeletedFrame(const QString& path, const QByteArray& hash);
void InvalidateProject(Project* p);
private:
DiskManager();
+14 -57
View File
@@ -39,20 +39,17 @@ FrameHashCache::FrameHashCache(QObject *parent) :
{
if (DiskManager::instance()) {
connect(DiskManager::instance(), &DiskManager::DeletedFrame, this, &FrameHashCache::HashDeleted);
connect(DiskManager::instance(), &DiskManager::InvalidateProject, this, &FrameHashCache::ProjectInvalidated);
}
}
QByteArray FrameHashCache::GetHash(const rational &time)
{
QMutexLocker locker(lock());
return time_hash_map_.value(time);
}
void FrameHashCache::SetHash(const rational &time, const QByteArray &hash, const qint64& job_time, bool frame_exists)
{
QMutexLocker locker(lock());
bool is_current = false;
for (int i=jobs_.size()-1; i>=0; i--) {
@@ -74,54 +71,34 @@ void FrameHashCache::SetHash(const rational &time, const QByteArray &hash, const
TimeRange validated_range;
if (frame_exists) {
validated_range = TimeRange(time, time + timebase_);
NoLockValidate(validated_range);
}
locker.unlock();
if (frame_exists) {
emit Validated(validated_range);
Validate(validated_range);
}
}
void FrameHashCache::SetTimebase(const rational &tb)
{
QMutexLocker locker(lock());
timebase_ = tb;
}
void FrameHashCache::ValidateFramesWithHash(const QByteArray &hash)
{
QMutexLocker locker(lock());
QMap<rational, QByteArray>::const_iterator iterator;
const TimeRangeList& invalidated_ranges = NoLockGetInvalidatedRanges();
TimeRangeList ranges_validated;
const TimeRangeList& invalidated_ranges = GetInvalidatedRanges();
for (iterator=time_hash_map_.begin();iterator!=time_hash_map_.end();iterator++) {
if (iterator.value() == hash) {
TimeRange frame_range(iterator.key(), iterator.key() + timebase_);
if (invalidated_ranges.ContainsTimeRange(frame_range)) {
NoLockValidate(frame_range);
ranges_validated.InsertTimeRange(frame_range);
Validate(frame_range);
}
}
}
locker.unlock();
foreach (const TimeRange& range, ranges_validated) {
emit Validated(range);
}
}
QList<rational> FrameHashCache::GetFramesWithHash(const QByteArray &hash)
{
QMutexLocker locker(lock());
QList<rational> times;
QMap<rational, QByteArray>::const_iterator iterator;
@@ -137,8 +114,6 @@ QList<rational> FrameHashCache::GetFramesWithHash(const QByteArray &hash)
QList<rational> FrameHashCache::TakeFramesWithHash(const QByteArray &hash)
{
QMutexLocker locker(lock());
QList<rational> times;
QMap<rational, QByteArray>::iterator iterator = time_hash_map_.begin();
@@ -154,13 +129,7 @@ QList<rational> FrameHashCache::TakeFramesWithHash(const QByteArray &hash)
}
foreach (const rational& r, times) {
NoLockInvalidate(TimeRange(r, r + timebase_));
}
locker.unlock();
foreach (const rational& r, times) {
emit Invalidated(TimeRange(r, r + timebase_));
Invalidate(TimeRange(r, r + timebase_));
}
return times;
@@ -168,8 +137,6 @@ QList<rational> FrameHashCache::TakeFramesWithHash(const QByteArray &hash)
QMap<rational, QByteArray> FrameHashCache::time_hash_map()
{
QMutexLocker locker(lock());
return time_hash_map_;
}
@@ -205,23 +172,17 @@ QVector<rational> FrameHashCache::GetFrameListFromTimeRange(TimeRangeList range_
QVector<rational> FrameHashCache::GetFrameListFromTimeRange(const TimeRangeList &range)
{
QMutexLocker locker(lock());
return GetFrameListFromTimeRange(range, timebase_);
}
QVector<rational> FrameHashCache::GetInvalidatedFrames()
{
QMutexLocker locker(lock());
return GetFrameListFromTimeRange(NoLockGetInvalidatedRanges(), timebase_);
return GetFrameListFromTimeRange(GetInvalidatedRanges());
}
QVector<rational> FrameHashCache::GetInvalidatedFrames(const TimeRange &intersecting)
{
QMutexLocker locker(lock());
return GetFrameListFromTimeRange(NoLockGetInvalidatedRanges().Intersects(intersecting), timebase_);
return GetFrameListFromTimeRange(GetInvalidatedRanges().Intersects(intersecting));
}
bool FrameHashCache::SaveCacheFrame(const QByteArray& hash,
@@ -379,24 +340,20 @@ void FrameHashCache::HashDeleted(const QString& s, const QByteArray &hash)
return;
}
QMutexLocker locker(lock());
TimeRangeList invalidated;
QMap<rational, QByteArray>::const_iterator i;
for (i=time_hash_map_.constBegin(); i!=time_hash_map_.constEnd(); i++) {
if (i.value() == hash) {
TimeRange r(i.key(), i.key() + timebase_);
NoLockInvalidate(r);
invalidated.InsertTimeRange(r);
Invalidate(TimeRange(i.key(), i.key() + timebase_));
}
}
}
locker.unlock();
void FrameHashCache::ProjectInvalidated(Project *p)
{
if (GetProject() == p) {
time_hash_map_.clear();
foreach (const TimeRange& r, invalidated) {
emit Invalidated(r);
InvalidateAll();
}
}
+2
View File
@@ -89,6 +89,8 @@ private:
private slots:
void HashDeleted(const QString &s, const QByteArray& hash);
void ProjectInvalidated(Project* p);
};
OLIVE_NAMESPACE_EXIT
+35 -59
View File
@@ -30,36 +30,30 @@ OLIVE_NAMESPACE_ENTER
void PlaybackCache::Invalidate(const TimeRange &r)
{
QMutexLocker locker(lock());
Q_ASSERT(r.in() != r.out());
NoLockInvalidate(r);
invalidated_.InsertTimeRange(r);
locker.unlock();
RemoveRangeFromJobs(r);
qint64 job_time = QDateTime::currentMSecsSinceEpoch();
jobs_.append({r, job_time});
InvalidateEvent(r);
emit Invalidated(r);
}
void PlaybackCache::InvalidateAll()
{
QMutexLocker locker(lock());
if (length_.isNull()) {
return;
}
TimeRange invalidate_range(0, length_);
NoLockInvalidate(invalidate_range);
locker.unlock();
emit Invalidated(invalidate_range);
Invalidate(TimeRange(0, length_));
}
void PlaybackCache::SetLength(const rational &r)
{
QMutexLocker locker(lock());
if (length_ == r) {
// Same length - do nothing
return;
@@ -85,8 +79,6 @@ void PlaybackCache::SetLength(const rational &r)
rational old_length = length_;
length_ = r;
locker.unlock();
if (r > old_length) {
emit Invalidated(range_diff);
} else {
@@ -100,21 +92,19 @@ void PlaybackCache::Shift(const rational &from, const rational &to)
return;
}
QMutexLocker locker(lock());
// An region between `from` and `to` will be inserted or spliced out
TimeRangeList ranges_to_shift = invalidated_.Intersects(TimeRange(from, RATIONAL_MAX));
// Remove everything from the minimum point
TimeRange remove_range = TimeRange(qMin(from, to), RATIONAL_MAX);
NoLockValidate(remove_range);
RemoveRangeFromJobs(remove_range);
Validate(remove_range);
// Shift everything in our ranges to shift list
// (`diff` is POSITIVE when moving forward -> and NEGATIVE when moving backward <-)
rational diff = to - from;
foreach (const TimeRange& r, ranges_to_shift) {
NoLockInvalidate(r + diff);
Invalidate(r + diff);
}
ShiftEvent(from, to);
@@ -123,38 +113,18 @@ void PlaybackCache::Shift(const rational &from, const rational &to)
if (diff > rational()) {
// If shifting forward, add this section to the invalidated region
NoLockInvalidate(TimeRange(from, to));
Invalidate(TimeRange(from, to));
}
locker.unlock();
// Emit signals
emit Validated(remove_range);
foreach (const TimeRange& r, ranges_to_shift) {
emit Invalidated(r + diff);
}
if (diff > rational()) {
emit Invalidated(TimeRange(from, to));
}
emit Shifted(from, to);
}
void PlaybackCache::NoLockInvalidate(const TimeRange &r)
{
Q_ASSERT(r.in() != r.out());
invalidated_.InsertTimeRange(r);
RemoveRangeFromJobs(r);
qint64 job_time = QDateTime::currentMSecsSinceEpoch();
jobs_.append({r, job_time});
InvalidateEvent(r);
}
void PlaybackCache::NoLockValidate(const TimeRange &r)
void PlaybackCache::Validate(const TimeRange &r)
{
invalidated_.RemoveTimeRange(r);
emit Validated(r);
}
void PlaybackCache::LengthChangedEvent(const rational &, const rational &)
@@ -169,6 +139,22 @@ void PlaybackCache::ShiftEvent(const rational &, const rational &)
{
}
Project *PlaybackCache::GetProject() const
{
// NOTE: A lot of assumptions in this behavior
ViewerOutput* viewer = static_cast<ViewerOutput*>(parent());
if (!viewer) {
return nullptr;
}
Sequence* sequence = static_cast<Sequence*>(viewer->parent());
if (!sequence) {
return nullptr;
}
return sequence->project();
}
void PlaybackCache::RemoveRangeFromJobs(const TimeRange &remove)
{
// Code shamelessly copied from TimeRangeList::RemoveTimeRange
@@ -196,23 +182,13 @@ void PlaybackCache::RemoveRangeFromJobs(const TimeRange &remove)
QString PlaybackCache::GetCacheDirectory() const
{
// NOTE: A lot of assumptions in this behavior
ViewerOutput* viewer = static_cast<ViewerOutput*>(parent());
if (!viewer) {
Project* project = GetProject();
if (project) {
return project->cache_path();
} else {
return QString();
}
Sequence* sequence = static_cast<Sequence*>(viewer->parent());
if (!sequence) {
return QString();
}
Project* project = sequence->project();
if (!project) {
return QString();
}
return project->cache_path();
}
OLIVE_NAMESPACE_EXIT
+7 -30
View File
@@ -28,6 +28,8 @@
OLIVE_NAMESPACE_ENTER
class Project;
class PlaybackCache : public QObject
{
Q_OBJECT
@@ -43,17 +45,13 @@ public:
const rational& GetLength()
{
QMutexLocker locker(lock());
return NoLockGetLength();
return length_;
}
void SetLength(const rational& r);
bool IsFullyValidated()
{
QMutexLocker locker(lock());
return invalidated_.isEmpty();
}
@@ -61,15 +59,11 @@ public:
const TimeRangeList& GetInvalidatedRanges()
{
QMutexLocker locker(lock());
return NoLockGetInvalidatedRanges();
return invalidated_;
}
bool HasInvalidatedRanges()
{
QMutexLocker locker(lock());
return !invalidated_.isEmpty();
}
@@ -83,19 +77,7 @@ signals:
void LengthChanged(const OLIVE_NAMESPACE::rational& r);
protected:
void NoLockInvalidate(const TimeRange& r);
void NoLockValidate(const TimeRange& r);
const rational& NoLockGetLength() const
{
return length_;
}
const TimeRangeList& NoLockGetInvalidatedRanges()
{
return invalidated_;
}
void Validate(const TimeRange& r);
virtual void LengthChangedEvent(const rational& old, const rational& newlen);
@@ -103,12 +85,9 @@ protected:
virtual void ShiftEvent(const rational& from, const rational& to);
QString GetCacheDirectory() const;
Project* GetProject() const;
QMutex* lock()
{
return &lock_;
}
QString GetCacheDirectory() const;
struct JobIdentifier {
TimeRange range;
@@ -120,8 +99,6 @@ protected:
private:
void RemoveRangeFromJobs(const TimeRange& remove);
QMutex lock_;
TimeRangeList invalidated_;
rational length_;