removed hashes from previewautocacher

This commit is contained in:
itsmattkc
2022-05-09 19:40:58 -07:00
parent 2cf0b24e0f
commit 4bc82ca6df
12 changed files with 75 additions and 102 deletions
+5 -21
View File
@@ -62,6 +62,11 @@ void FrameHashCache::ValidateTimestamp(const int64_t &ts)
Validate(frame_range);
}
void FrameHashCache::ValidateTime(const rational &time)
{
Validate(TimeRange(time, time + timebase_));
}
bool FrameHashCache::SaveCacheFrame(const int64_t &time, FramePtr frame) const
{
return SaveCacheFrame(GetCacheDirectory(), uuid_, time, frame);
@@ -190,27 +195,6 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
return frame;
}
struct HashTimePair {
rational time;
QByteArray hash;
};
void FrameHashCache::ShiftEvent(const rational &from, const rational &to)
{
}
void FrameHashCache::InvalidateEvent(const TimeRange &range)
{
TimeRangeListFrameIterator iterator({range}, timebase_);
rational t;
while (iterator.GetNext(&t)) {
int64_t ts = ToTimestamp(t, Timecode::kCeil);
QFile::remove(CachePathName(ts));
}
}
rational FrameHashCache::ToTime(const int64_t &ts) const
{
return Timecode::timestamp_to_time(ts, timebase_);
+9 -5
View File
@@ -39,16 +39,25 @@ class FrameHashCache : public PlaybackCache
public:
FrameHashCache(QObject* parent = nullptr);
const QUuid &GetUuid() const { return uuid_; }
void SetUuid(const QUuid &u) { uuid_ = u; }
const rational &GetTimebase() const { return timebase_; }
void SetTimebase(const rational& tb);
void ValidateTimestamp(const int64_t &ts);
void ValidateTime(const rational &time);
/**
* @brief Return the path of the cached image at this time
*/
QString CachePathName(const int64_t &time) const;
QString CachePathName(const rational &time) const
{
return CachePathName(ToTimestamp(time, Timecode::kFloor));
}
static QString CachePathName(const QString& cache_path, const QUuid &cache_id, const int64_t &time);
static bool SaveCacheFrame(const QString& filename, FramePtr frame);
@@ -58,11 +67,6 @@ public:
FramePtr LoadCacheFrame(const int64_t &time) const;
static FramePtr LoadCacheFrame(const QString& fn);
protected:
virtual void ShiftEvent(const rational& from, const rational& to) override;
virtual void InvalidateEvent(const TimeRange& range) override;
private:
rational ToTime(const int64_t &ts) const;
int64_t ToTimestamp(const rational &ts, Timecode::Rounding rounding = Timecode::kRound) const;
+31 -42
View File
@@ -67,19 +67,11 @@ RenderTicketPtr PreviewAutoCacher::GetSingleFrame(const rational &t, bool priori
// If we have a single frame render queued (but not yet sent to the RenderManager), cancel it now
CancelQueuedSingleFrameRender();
// See if we have a hash, we may or may not retrieve one depending on the state of the video
// frame cache
QByteArray hash;
if (viewer_node_->GetVideoAutoCacheEnabled()) {
hash = viewer_node_->video_frame_cache()->GetHash(t);
}
// Create a new single frame render ticket
auto sfr = std::make_shared<RenderTicket>();
sfr->Start();
sfr->setProperty("time", QVariant::fromValue(t));
sfr->setProperty("prioritize", prioritize);
sfr->setProperty("hash", hash);
// Queue it and try to render
single_frame_render_ = sfr;
@@ -204,25 +196,27 @@ void PreviewAutoCacher::VideoRendered()
// If the task list doesn't contain this watcher, presumably it was cleared as a result of a
// viewer switch, so we'll completely ignore this watcher
if (video_tasks_.remove(watcher)) {
auto it = video_tasks_.find(watcher);
if (it != video_tasks_.end()) {
// Assume that a "result" is a fully completed image and a non-result is a cancelled ticket
if (watcher->HasResult()) {
qDebug() << "FIXME: oops no frame downloading";
/*
// Download frame in another thread
FramePtr frame = watcher->Get().value<FramePtr>();
RenderTicketWatcher* w = new RenderTicketWatcher();
w->setProperty("job", QVariant::fromValue(last_update_time_));
w->setProperty("frame", QVariant::fromValue(frame));
video_download_tasks_.insert(w, hash);
connect(w, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoDownloaded);
w->SetTicket(RenderManager::instance()->SaveFrameToCache(viewer_node_->video_frame_cache(),
frame,
true));
*/
if (FramePtr frame = watcher->Get().value<FramePtr>()) {
RenderTicketWatcher* w = new RenderTicketWatcher();
w->setProperty("job", QVariant::fromValue(last_update_time_));
w->setProperty("frame", QVariant::fromValue(frame));
video_download_tasks_.insert(w, it.value());
connect(w, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoDownloaded);
w->SetTicket(RenderManager::instance()->SaveFrameToCache(viewer_node_->video_frame_cache(),
frame,
it.value(),
true));
}
}
video_tasks_.erase(it);
// Continue rendering
TryRender();
}
@@ -249,11 +243,11 @@ void PreviewAutoCacher::VideoDownloaded()
// viewer switch, so we'll completely ignore this watcher
if (video_download_tasks_.contains(watcher)) {
// Remove from task list
QByteArray hash = video_download_tasks_.take(watcher);
rational time = video_download_tasks_.take(watcher);
// Assume that `true` is a completely successful frame save
if (watcher->Get().toBool()) {
viewer_node_->video_frame_cache()->ValidateFramesWithHash(hash);
viewer_node_->video_frame_cache()->ValidateTime(time);
} else {
qCritical() << "Failed to download video frame";
}
@@ -535,11 +529,11 @@ void PreviewAutoCacher::TryRender()
// Check for newly invalidated video and hash it
if (!invalidated_video_.isEmpty()) {
if (!copied_viewer_node_->GetConnectedTextureOutput()) {
hash_iterator_.reset();
} else if (hash_iterator_.HasNext()) {
hash_iterator_.insert(invalidated_video_);
queued_frame_iterator_.reset();
} else if (queued_frame_iterator_.HasNext()) {
queued_frame_iterator_.insert(invalidated_video_);
} else {
hash_iterator_ = TimeRangeListFrameIterator(invalidated_video_, viewer_node_->GetVideoParams().frame_rate_as_time_base());
queued_frame_iterator_ = TimeRangeListFrameIterator(invalidated_video_, viewer_node_->GetVideoParams().frame_rate_as_time_base());
}
invalidated_video_.clear();
}
@@ -552,15 +546,14 @@ void PreviewAutoCacher::TryRender()
if (single_frame_render_) {
// Check if already caching this
QByteArray hash = single_frame_render_->property("hash").toByteArray();
rational time = single_frame_render_->property("time").value<rational>();
RenderTicketWatcher* watcher;
if (!hash.isEmpty() && (watcher = video_tasks_.key(hash))) {
if ((watcher = video_tasks_.key(time))) {
video_immediate_passthroughs_[watcher].append(single_frame_render_);
} else if (!hash.isEmpty() && (watcher = video_download_tasks_.key(hash))) {
} else if ((watcher = video_download_tasks_.key(time))) {
single_frame_render_->Finish(watcher->property("frame"));
} else {
watcher = RenderFrame(hash,
single_frame_render_->property("time").value<rational>(),
watcher = RenderFrame(single_frame_render_->property("time").value<rational>(),
single_frame_render_->property("prioritize").toBool(),
!viewer_node_->GetVideoAutoCacheEnabled());
@@ -576,14 +569,12 @@ void PreviewAutoCacher::TryRender()
// Handle video tasks
rational t;
while (video_tasks_.size() < max_tasks && queued_frame_iterator_.GetNext(&t)) {
const QByteArray& hash = viewer_node_->video_frame_cache()->GetHash(t);
RenderTicketWatcher* render_task = video_tasks_.key(hash);
RenderTicketWatcher* render_task = video_tasks_.key(t);
// We want this hash, if we're not already rendering, start render now
if (!render_task && !video_download_tasks_.key(hash)) {
if (!render_task && !video_download_tasks_.key(t)) {
// Don't render any hash more than once
RenderFrame(hash, t, false, false);
RenderFrame(t, false, false);
}
emit SignalCacheProxyTaskProgress(double(queued_frame_iterator_.frame_index()) / double(queued_frame_iterator_.size()));
@@ -609,13 +600,12 @@ void PreviewAutoCacher::TryRender()
}
}
RenderTicketWatcher* PreviewAutoCacher::RenderFrame(const QByteArray &hash, const rational& time, bool prioritize, bool texture_only)
RenderTicketWatcher* PreviewAutoCacher::RenderFrame(const rational& time, bool prioritize, bool texture_only)
{
RenderTicketWatcher* watcher = new RenderTicketWatcher();
watcher->setProperty("hash", hash);
watcher->setProperty("job", QVariant::fromValue(last_update_time_));
connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoRendered);
video_tasks_.insert(watcher, hash);
video_tasks_.insert(watcher, time);
watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_,
copied_color_manager_,
time,
@@ -751,7 +741,6 @@ void PreviewAutoCacher::SetViewerNode(ViewerOutput *viewer_node)
// Clear iterators
queued_frame_iterator_.reset();
audio_iterator_.clear();
hash_iterator_.reset();
// Clear any invalidated ranges
invalidated_video_.clear();
+3 -4
View File
@@ -100,7 +100,7 @@ signals:
private:
void TryRender();
RenderTicketWatcher *RenderFrame(const QByteArray& hash, const rational &time, bool prioritize, bool texture_only);
RenderTicketWatcher *RenderFrame(const rational &time, bool prioritize, bool texture_only);
RenderTicketPtr RenderAudio(const TimeRange &range, bool generate_waveforms, bool prioritize);
/**
@@ -173,8 +173,8 @@ private:
RenderTicketPtr single_frame_render_;
QMap<RenderTicketWatcher*, TimeRange> audio_tasks_;
QMap<RenderTicketWatcher*, QByteArray> video_tasks_;
QMap<RenderTicketWatcher*, QByteArray> video_download_tasks_;
QMap<RenderTicketWatcher*, rational> video_tasks_;
QMap<RenderTicketWatcher*, rational> video_download_tasks_;
QMap<RenderTicketWatcher*, QVector<RenderTicketPtr> > video_immediate_passthroughs_;
JobTime graph_changed_time_;
@@ -190,7 +190,6 @@ private:
RenderJobTracker audio_job_tracker_;
TimeRangeListFrameIterator queued_frame_iterator_;
TimeRangeListFrameIterator hash_iterator_;
TimeRangeList audio_iterator_;
static const bool kRealTimeWaveformsEnabled;
+3 -1
View File
@@ -187,13 +187,15 @@ RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange
return ticket;
}
RenderTicketPtr RenderManager::SaveFrameToCache(FrameHashCache *cache, FramePtr frame, bool prioritize)
RenderTicketPtr RenderManager::SaveFrameToCache(FrameHashCache *cache, FramePtr frame, const rational &time, bool prioritize)
{
// Create ticket
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
ticket->setProperty("cache", cache->GetCacheDirectory());
ticket->setProperty("frame", QVariant::fromValue(frame));
ticket->setProperty("time", QVariant::fromValue(Timecode::time_to_timestamp(time, cache->GetTimebase(), Timecode::kFloor)));
ticket->setProperty("uuid", QVariant::fromValue(cache->GetUuid()));
ticket->setProperty("type", kTypeVideoDownload);
if (ticket->thread() != this->thread()) {
+1 -1
View File
@@ -98,7 +98,7 @@ public:
RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, bool prioritize = false);
RenderTicketPtr RenderAudio(ViewerOutput *viewer, const TimeRange& r, RenderMode::Mode mode, bool generate_waveforms, bool prioritize = false);
RenderTicketPtr SaveFrameToCache(FrameHashCache* cache, FramePtr frame, bool prioritize = false);
RenderTicketPtr SaveFrameToCache(FrameHashCache* cache, FramePtr frame, const rational &time, bool prioritize = false);
virtual void RunTicket(RenderTicketPtr ticket) const override;
+3 -2
View File
@@ -219,9 +219,10 @@ void RenderProcessor::Run()
{
QString cache = ticket_->property("cache").toString();
FramePtr frame = ticket_->property("frame").value<FramePtr>();
QByteArray hash = ticket_->property("hash").toByteArray();
int64_t time = ticket_->property("time").value<int64_t>();
QUuid uuid = ticket_->property("uuid").value<QUuid>();
ticket_->Finish(FrameHashCache::SaveCacheFrame(cache, hash, frame));
ticket_->Finish(FrameHashCache::SaveCacheFrame(cache, uuid, time, frame));
break;
}
default:
+3 -3
View File
@@ -165,7 +165,7 @@ bool RenderTask::Render(ColorManager* manager,
} else if (ticket_type == RenderManager::kTypeVideo && TwoStepFrameRendering()) {
if (!DownloadFrame(&watcher_thread, watcher->Get().value<FramePtr>())) {
if (!DownloadFrame(&watcher_thread, watcher->Get().value<FramePtr>(), watcher->property("time").value<rational>())) {
result = false;
}
@@ -237,14 +237,14 @@ bool RenderTask::Render(ColorManager* manager,
return result;
}
bool RenderTask::DownloadFrame(QThread *thread, FramePtr frame)
bool RenderTask::DownloadFrame(QThread *thread, FramePtr frame, const rational &time)
{
RenderTicketWatcher* watcher = new RenderTicketWatcher();
PrepareWatcher(watcher, thread);
IncrementRunningTickets();
watcher->SetTicket(RenderManager::instance()->SaveFrameToCache(viewer_->video_frame_cache(), frame));
watcher->SetTicket(RenderManager::instance()->SaveFrameToCache(viewer_->video_frame_cache(), frame, time));
// NOTE: Doesn't reflect the actual return result of SaveFrameToCache
return true;
+1 -1
View File
@@ -49,7 +49,7 @@ protected:
VideoParams::Format force_format = VideoParams::kFormatInvalid,
ColorProcessorPtr force_color_output = nullptr);
virtual bool DownloadFrame(QThread* thread, FramePtr frame);
virtual bool DownloadFrame(QThread* thread, FramePtr frame, const rational &time);
virtual bool FrameDownloaded(FramePtr frame, const rational &time) = 0;
+6 -6
View File
@@ -80,17 +80,17 @@ void TimeRuler::SetPlaybackCache(PlaybackCache *cache)
}
if (playback_cache_) {
disconnect(playback_cache_, &PlaybackCache::Invalidated, this, static_cast<void(TimeRuler::*)()>(&TimeRuler::update));
disconnect(playback_cache_, &PlaybackCache::Validated, this, static_cast<void(TimeRuler::*)()>(&TimeRuler::update));
disconnect(playback_cache_, &PlaybackCache::Shifted, this, static_cast<void(TimeRuler::*)()>(&TimeRuler::update));
disconnect(playback_cache_, &PlaybackCache::Invalidated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
disconnect(playback_cache_, &PlaybackCache::Validated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
disconnect(playback_cache_, &PlaybackCache::Shifted, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
}
playback_cache_ = cache;
if (playback_cache_) {
connect(playback_cache_, &PlaybackCache::Invalidated, this, static_cast<void(TimeRuler::*)()>(&TimeRuler::update));
connect(playback_cache_, &PlaybackCache::Validated, this, static_cast<void(TimeRuler::*)()>(&TimeRuler::update));
connect(playback_cache_, &PlaybackCache::Shifted, this, static_cast<void(TimeRuler::*)()>(&TimeRuler::update));
connect(playback_cache_, &PlaybackCache::Invalidated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
connect(playback_cache_, &PlaybackCache::Validated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
connect(playback_cache_, &PlaybackCache::Shifted, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
}
update();
+8 -14
View File
@@ -399,9 +399,9 @@ void ViewerWidget::StartCapture(TimelineWidget *source, const TimeRange &time, c
recording_track_ = track;
}
FramePtr ViewerWidget::DecodeCachedImage(const QString &cache_path, const QByteArray& hash, const rational& time)
FramePtr ViewerWidget::DecodeCachedImage(const QString &cache_path, const QUuid &cache_id, const int64_t& time)
{
FramePtr frame = FrameHashCache::LoadCacheFrame(cache_path, hash);
FramePtr frame = FrameHashCache::LoadCacheFrame(cache_path, cache_id, time);
if (frame) {
frame->set_timestamp(time);
@@ -412,10 +412,10 @@ FramePtr ViewerWidget::DecodeCachedImage(const QString &cache_path, const QByteA
return frame;
}
void ViewerWidget::DecodeCachedImage(RenderTicketPtr ticket, const QString &cache_path, const QByteArray& hash, const rational& time)
void ViewerWidget::DecodeCachedImage(RenderTicketPtr ticket, const QString &cache_path, const QUuid &cache_id, const int64_t& time)
{
ticket->Start();
ticket->Finish(QVariant::fromValue(DecodeCachedImage(cache_path, hash, time)));
ticket->Finish(QVariant::fromValue(DecodeCachedImage(cache_path, cache_id, time)));
}
bool ViewerWidget::ShouldForceWaveform() const
@@ -813,11 +813,7 @@ void ViewerWidget::SetColorTransform(const ColorTransform &transform, ViewerDisp
QString ViewerWidget::GetCachedFilenameFromTime(const rational &time)
{
if (FrameExistsAtTime(time)) {
QByteArray hash = GetConnectedNode()->video_frame_cache()->GetHash(time);
if (!hash.isEmpty()) {
return GetConnectedNode()->video_frame_cache()->CachePathName(hash);
}
return GetConnectedNode()->video_frame_cache()->CachePathName(time);
}
return QString();
@@ -860,18 +856,16 @@ void ViewerWidget::RequestNextFrameForQueue(bool prioritize, bool increment)
RenderTicketPtr ViewerWidget::GetFrame(const rational &t, bool prioritize)
{
QByteArray cached_hash = GetConnectedNode()->video_frame_cache()->GetHash(t);
QString cache_fn = GetConnectedNode()->video_frame_cache()->CachePathName(t);
QString cache_fn = GetConnectedNode()->video_frame_cache()->CachePathName(cached_hash);
if (cached_hash.isEmpty() || !QFileInfo::exists(cache_fn)) {
if (!QFileInfo::exists(cache_fn)) {
// Frame hasn't been cached, start render job
return auto_cacher_.GetSingleFrame(t, prioritize);
} else {
// Frame has been cached, grab the frame
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
ticket->setProperty("time", QVariant::fromValue(t));
QtConcurrent::run(ViewerWidget::DecodeCachedImage, ticket, GetConnectedNode()->video_frame_cache()->GetCacheDirectory(), cached_hash, t);
QtConcurrent::run(ViewerWidget::DecodeCachedImage, ticket, GetConnectedNode()->video_frame_cache()->GetCacheDirectory(), GetConnectedNode()->video_frame_cache()->GetUuid(), Timecode::time_to_timestamp(t, timebase(), Timecode::kFloor));
return ticket;
}
}
+2 -2
View File
@@ -193,9 +193,9 @@ private:
int DeterminePlaybackQueueSize();
static FramePtr DecodeCachedImage(const QString &cache_path, const QByteArray &hash, const rational& time);
static FramePtr DecodeCachedImage(const QString &cache_path, const QUuid &cache_id, const int64_t& time);
static void DecodeCachedImage(RenderTicketPtr ticket, const QString &cache_path, const QByteArray &hash, const rational& time);
static void DecodeCachedImage(RenderTicketPtr ticket, const QString &cache_path, const QUuid &cache_id, const int64_t &time);
bool ShouldForceWaveform() const;