From 210eb86cd2c2ceab868179ebcfac8637419b2a87 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 11 Apr 2021 18:54:22 +1000 Subject: [PATCH] nodes: fixed hashing issues --- app/node/block/clip/clip.cpp | 7 +++++-- app/node/math/merge/merge.cpp | 8 ++++++-- app/node/output/track/track.cpp | 4 +++- app/node/project/footage/footage.cpp | 21 +++++++++------------ app/render/previewautocacher.cpp | 2 +- app/render/rendermanager.cpp | 4 ++-- app/render/rendermanager.h | 6 +++++- app/task/render/render.cpp | 2 +- 8 files changed, 32 insertions(+), 22 deletions(-) diff --git a/app/node/block/clip/clip.cpp b/app/node/block/clip/clip.cpp index e7b7f9799..ba2c93d0c 100644 --- a/app/node/block/clip/clip.cpp +++ b/app/node/block/clip/clip.cpp @@ -114,12 +114,15 @@ void ClipBlock::Retranslate() SetInputName(kBufferIn, tr("Buffer")); } -void ClipBlock::Hash(const QString &output, QCryptographicHash &hash, const rational &time) const +void ClipBlock::Hash(const QString &out, QCryptographicHash &hash, const rational &time) const { + Q_UNUSED(out) + if (IsInputConnected(kBufferIn)) { rational t = InputTimeAdjustment(kBufferIn, -1, TimeRange(time, time)).in(); - GetConnectedNode(kBufferIn)->Hash(output, hash, t); + NodeOutput output = GetConnectedOutput(kBufferIn); + output.node()->Hash(output.output(), hash, t); } } diff --git a/app/node/math/merge/merge.cpp b/app/node/math/merge/merge.cpp index 823a101b2..0051e95d5 100644 --- a/app/node/math/merge/merge.cpp +++ b/app/node/math/merge/merge.cpp @@ -107,13 +107,16 @@ void MergeNode::Hash(const QString &output, QCryptographicHash &hash, const rati // connected node happens to return nothing (a gap for instance). Therefore we only add our // fingerprint if the base AND the blend change the hash. Otherwise, we assume it's a passthrough. + Q_UNUSED(output) + QByteArray current_result = hash.result(); bool base_changed_hash = false; bool blend_changed_hash = false; if (IsInputConnected(kBaseIn)) { - GetConnectedNode(kBaseIn)->Hash(output, hash, time); + NodeOutput base_output = GetConnectedOutput(kBaseIn); + base_output.node()->Hash(base_output.output(), hash, time); QByteArray post_base_hash = hash.result(); base_changed_hash = (post_base_hash != current_result); @@ -121,7 +124,8 @@ void MergeNode::Hash(const QString &output, QCryptographicHash &hash, const rati } if(IsInputConnected(kBlendIn)) { - GetConnectedNode(kBlendIn)->Hash(output, hash, time); + NodeOutput blend_output = GetConnectedOutput(kBlendIn); + blend_output.node()->Hash(blend_output.output(), hash, time); blend_changed_hash = (hash.result() != current_result); } diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 3740d311d..5dd552e58 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -574,11 +574,13 @@ bool Track::IsLocked() const void Track::Hash(const QString &output, QCryptographicHash &hash, const rational &time) const { + Q_UNUSED(output) + Block* b = BlockAtTime(time); // Defer to block at this time, don't add any of our own information to the hash if (b) { - b->Hash(output, hash, TransformTimeForBlock(b, time)); + b->Hash(kDefaultOutput, hash, TransformTimeForBlock(b, time)); } } diff --git a/app/node/project/footage/footage.cpp b/app/node/project/footage/footage.cpp index 83e9e4eb4..96122ad45 100644 --- a/app/node/project/footage/footage.cpp +++ b/app/node/project/footage/footage.cpp @@ -302,27 +302,23 @@ void Footage::Hash(const QString& output, QCryptographicHash &hash, const ration { super::Hash(output, hash, time); + // Footage last modified date + hash.addData(QString::number(timestamp()).toUtf8()); + // Translate output ID to stream Track::Reference ref = Track::Reference::FromString(output); - QString fn = filename(); - - if (!fn.isEmpty()) { + if (ref.type() == Track::kVideo) { VideoParams params = GetVideoParams(ref.index()); if (params.is_valid()) { // Add footage details to hash - - // Footage filename - hash.addData(filename().toUtf8()); - - // Footage last modified date - hash.addData(QString::number(timestamp()).toUtf8()); + QString fn = filename(); // Footage stream hash.addData(QString::number(ref.index()).toUtf8()); - if (ref.type() == Track::kVideo) { + if (!fn.isEmpty()) { // Current color config and space hash.addData(project()->color_manager()->GetConfigFilename().toUtf8()); hash.addData(GetColorspaceToUse(params).toUtf8()); @@ -338,10 +334,11 @@ void Footage::Hash(const QString& output, QCryptographicHash &hash, const ration int64_t video_ts = Timecode::time_to_timestamp(time, params.time_base()); // Add timestamp in units of the video stream's timebase - hash.addData(reinterpret_cast(&video_ts), sizeof(int64_t)); + hash.addData(reinterpret_cast(&video_ts), sizeof(video_ts)); // Add start time - used for both image sequences and video streams - hash.addData(QString::number(params.start_time()).toUtf8()); + auto start_time = params.start_time(); + hash.addData(reinterpret_cast(&start_time), sizeof(start_time)); } } } diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index ed681955b..12eabb035 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -69,7 +69,7 @@ void PreviewAutoCacher::GenerateHashes(ViewerOutput *viewer, FrameHashCache* cac foreach (const rational& time, times) { // See if hash already exists in disk cache - QByteArray hash = RenderManager::Hash(viewer->GetConnectedNode(ViewerOutput::kTextureInput), viewer->GetVideoParams(), time); + QByteArray hash = RenderManager::Hash(viewer->GetConnectedTextureOutput(), viewer->GetVideoParams(), time); // Check memory list since disk checking is slow bool hash_exists = (std::find(existing_hashes.begin(), existing_hashes.end(), hash) != existing_hashes.end()); diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp index 73449d9ea..0eac197fe 100644 --- a/app/render/rendermanager.cpp +++ b/app/render/rendermanager.cpp @@ -79,7 +79,7 @@ RenderManager::~RenderManager() } } -QByteArray RenderManager::Hash(const Node *n, const VideoParams ¶ms, const rational &time) +QByteArray RenderManager::Hash(const Node *n, const QString& output, const VideoParams ¶ms, const rational &time) { QCryptographicHash hasher(QCryptographicHash::Sha1); @@ -93,7 +93,7 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams ¶ms, const r hasher.addData(reinterpret_cast(&format), sizeof(VideoParams::Format)); if (n) { - n->Hash(Node::kDefaultOutput, hasher, time); + n->Hash(output, hasher, time); } return hasher.result(); diff --git a/app/render/rendermanager.h b/app/render/rendermanager.h index 7881894a0..df68fe5ca 100644 --- a/app/render/rendermanager.h +++ b/app/render/rendermanager.h @@ -67,7 +67,11 @@ public: /** * @brief Generate a unique identifier for a certain node at a certain time */ - static QByteArray Hash(const Node *n, const VideoParams ¶ms, const rational &time); + static QByteArray Hash(const Node *n, const QString &output, const VideoParams ¶ms, const rational &time); + static QByteArray Hash(const NodeOutput &output, const VideoParams ¶ms, const rational &time) + { + return Hash(output.node(), output.output(), params, time); + } /** * @brief Asynchronously generate a frame at a given time diff --git a/app/task/render/render.cpp b/app/task/render/render.cpp index 0511f808c..009d5bee1 100644 --- a/app/task/render/render.cpp +++ b/app/task/render/render.cpp @@ -85,7 +85,7 @@ bool RenderTask::Render(ColorManager* manager, return true; } - hashes[i] = RenderManager::instance()->Hash(viewer(), video_params_, times.at(i)); + hashes[i] = RenderManager::instance()->Hash(viewer()->GetConnectedTextureOutput(), video_params_, times.at(i)); } // Filter out duplicates