renderer: copy cache path before render to avoid race conditions
This commit is contained in:
@@ -430,7 +430,7 @@ void RenderBackend::RunNextJob()
|
|||||||
worker->SetRenderMode(render_mode_);
|
worker->SetRenderMode(render_mode_);
|
||||||
worker->SetPreviewGenerationEnabled(generate_audio_previews_);
|
worker->SetPreviewGenerationEnabled(generate_audio_previews_);
|
||||||
worker->SetCopyMap(©_map_);
|
worker->SetCopyMap(©_map_);
|
||||||
worker->SetViewerNode(viewer_node_);
|
worker->SetCachePath(viewer_node_->video_frame_cache()->GetCacheDirectory());
|
||||||
|
|
||||||
// Move ticket from queue to running list
|
// Move ticket from queue to running list
|
||||||
RenderTicketPtr ticket = render_queue_.front();
|
RenderTicketPtr ticket = render_queue_.front();
|
||||||
|
|||||||
@@ -318,10 +318,11 @@ QVariant RenderWorker::ProcessFrameGeneration(const Node* node, const GenerateJo
|
|||||||
QVariant RenderWorker::GetCachedFrame(const Node* node, const rational& time)
|
QVariant RenderWorker::GetCachedFrame(const Node* node, const rational& time)
|
||||||
{
|
{
|
||||||
if (render_mode_ == RenderMode::kOffline
|
if (render_mode_ == RenderMode::kOffline
|
||||||
|
&& !cache_path_.isEmpty()
|
||||||
&& node->id() == QStringLiteral("org.olivevideoeditor.Olive.videoinput")) {
|
&& node->id() == QStringLiteral("org.olivevideoeditor.Olive.videoinput")) {
|
||||||
QByteArray hash = HashNode(node, video_params(), time);
|
QByteArray hash = HashNode(node, video_params(), time);
|
||||||
|
|
||||||
FramePtr f = viewer_->video_frame_cache()->LoadCacheFrame(hash);
|
FramePtr f = FrameHashCache::LoadCacheFrame(cache_path_, hash);
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
// The cached frame won't load with the correct divider by default, so we enforce it here
|
// The cached frame won't load with the correct divider by default, so we enforce it here
|
||||||
|
|||||||
@@ -50,11 +50,6 @@ public:
|
|||||||
available_ = a;
|
available_ = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetViewerNode(ViewerOutput* viewer)
|
|
||||||
{
|
|
||||||
viewer_ = viewer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetVideoParams(const VideoParams& params)
|
void SetVideoParams(const VideoParams& params)
|
||||||
{
|
{
|
||||||
video_params_ = params;
|
video_params_ = params;
|
||||||
@@ -90,6 +85,11 @@ public:
|
|||||||
generate_audio_previews_ = e;
|
generate_audio_previews_ = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetCachePath(const QString& s)
|
||||||
|
{
|
||||||
|
cache_path_ = s;
|
||||||
|
}
|
||||||
|
|
||||||
void Hash(RenderTicketPtr ticket, ViewerOutput* viewer, const QVector<rational>& times);
|
void Hash(RenderTicketPtr ticket, ViewerOutput* viewer, const QVector<rational>& times);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,14 +186,14 @@ private:
|
|||||||
|
|
||||||
bool generate_audio_previews_;
|
bool generate_audio_previews_;
|
||||||
|
|
||||||
ViewerOutput* viewer_;
|
|
||||||
|
|
||||||
QHash<Node*, Node*>* copy_map_;
|
QHash<Node*, Node*>* copy_map_;
|
||||||
|
|
||||||
RenderMode::Mode render_mode_;
|
RenderMode::Mode render_mode_;
|
||||||
|
|
||||||
QTimer* cleanup_timer_;
|
QTimer* cleanup_timer_;
|
||||||
|
|
||||||
|
QString cache_path_;
|
||||||
|
|
||||||
static const int kMaxDecoderLife;
|
static const int kMaxDecoderLife;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|||||||
@@ -220,12 +220,17 @@ bool FrameHashCache::SaveCacheFrame(const QByteArray &hash, FramePtr frame) cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FramePtr FrameHashCache::LoadCacheFrame(const QString &cache_path, const QByteArray &hash)
|
||||||
|
{
|
||||||
|
return LoadCacheFrame(CachePathName(cache_path, hash));
|
||||||
|
}
|
||||||
|
|
||||||
FramePtr FrameHashCache::LoadCacheFrame(const QByteArray &hash) const
|
FramePtr FrameHashCache::LoadCacheFrame(const QByteArray &hash) const
|
||||||
{
|
{
|
||||||
return LoadCacheFrame(CachePathName(hash));
|
return LoadCacheFrame(CachePathName(hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
FramePtr FrameHashCache::LoadCacheFrame(const QString &fn) const
|
FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
|
||||||
{
|
{
|
||||||
FramePtr frame = nullptr;
|
FramePtr frame = nullptr;
|
||||||
|
|
||||||
@@ -371,10 +376,15 @@ void FrameHashCache::ProjectInvalidated(Project *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString FrameHashCache::CachePathName(const QByteArray& hash) const
|
QString FrameHashCache::CachePathName(const QByteArray& hash) const
|
||||||
|
{
|
||||||
|
return CachePathName(GetCacheDirectory(), hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FrameHashCache::CachePathName(const QString &cache_path, const QByteArray &hash)
|
||||||
{
|
{
|
||||||
QString ext = GetFormatExtension();
|
QString ext = GetFormatExtension();
|
||||||
|
|
||||||
QDir cache_dir(QDir(GetCacheDirectory()).filePath(QString(hash.left(1).toHex())));
|
QDir cache_dir(QDir(cache_path).filePath(QString(hash.left(1).toHex())));
|
||||||
cache_dir.mkpath(".");
|
cache_dir.mkpath(".");
|
||||||
|
|
||||||
QString filename = QStringLiteral("%1%2").arg(QString(hash.mid(1).toHex()), ext);
|
QString filename = QStringLiteral("%1%2").arg(QString(hash.mid(1).toHex()), ext);
|
||||||
@@ -383,7 +393,7 @@ QString FrameHashCache::CachePathName(const QByteArray& hash) const
|
|||||||
QMetaObject::invokeMethod(DiskManager::instance(),
|
QMetaObject::invokeMethod(DiskManager::instance(),
|
||||||
"Accessed",
|
"Accessed",
|
||||||
Qt::QueuedConnection,
|
Qt::QueuedConnection,
|
||||||
Q_ARG(QString, GetCacheDirectory()),
|
Q_ARG(QString, cache_path),
|
||||||
Q_ARG(QByteArray, hash));
|
Q_ARG(QByteArray, hash));
|
||||||
|
|
||||||
return cache_dir.filePath(filename);
|
return cache_dir.filePath(filename);
|
||||||
|
|||||||
@@ -59,12 +59,14 @@ public:
|
|||||||
* @brief Return the path of the cached image at this time
|
* @brief Return the path of the cached image at this time
|
||||||
*/
|
*/
|
||||||
QString CachePathName(const QByteArray &hash) const;
|
QString CachePathName(const QByteArray &hash) const;
|
||||||
|
static QString CachePathName(const QString& cache_path, const QByteArray &hash);
|
||||||
|
|
||||||
bool SaveCacheFrame(const QString& filename, char *data, const VideoParams &vparam, int linesize_bytes) const;
|
bool SaveCacheFrame(const QString& filename, char *data, const VideoParams &vparam, int linesize_bytes) const;
|
||||||
bool SaveCacheFrame(const QByteArray& hash, char *data, const VideoParams &vparam, int linesize_bytes) const;
|
bool SaveCacheFrame(const QByteArray& hash, char *data, const VideoParams &vparam, int linesize_bytes) const;
|
||||||
bool SaveCacheFrame(const QByteArray& hash, FramePtr frame) const;
|
bool SaveCacheFrame(const QByteArray& hash, FramePtr frame) const;
|
||||||
|
static FramePtr LoadCacheFrame(const QString& cache_path, const QByteArray& hash);
|
||||||
FramePtr LoadCacheFrame(const QByteArray& hash) const;
|
FramePtr LoadCacheFrame(const QByteArray& hash) const;
|
||||||
FramePtr LoadCacheFrame(const QString& fn) const;
|
static FramePtr LoadCacheFrame(const QString& fn);
|
||||||
|
|
||||||
static QString GetFormatExtension();
|
static QString GetFormatExtension();
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ public:
|
|||||||
return !invalidated_.isEmpty();
|
return !invalidated_.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GetCacheDirectory() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Invalidated(const OLIVE_NAMESPACE::TimeRange& r);
|
void Invalidated(const OLIVE_NAMESPACE::TimeRange& r);
|
||||||
|
|
||||||
@@ -87,8 +89,6 @@ protected:
|
|||||||
|
|
||||||
Project* GetProject() const;
|
Project* GetProject() const;
|
||||||
|
|
||||||
QString GetCacheDirectory() const;
|
|
||||||
|
|
||||||
struct JobIdentifier {
|
struct JobIdentifier {
|
||||||
TimeRange range;
|
TimeRange range;
|
||||||
qint64 job_time;
|
qint64 job_time;
|
||||||
|
|||||||
Reference in New Issue
Block a user