nodes: fixed hashing issues

This commit is contained in:
itsmattkc
2021-04-11 18:54:22 +10:00
parent f9b60538fc
commit 210eb86cd2
8 changed files with 32 additions and 22 deletions
+5 -2
View File
@@ -114,12 +114,15 @@ void ClipBlock::Retranslate()
SetInputName(kBufferIn, tr("Buffer")); 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)) { if (IsInputConnected(kBufferIn)) {
rational t = InputTimeAdjustment(kBufferIn, -1, TimeRange(time, time)).in(); 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);
} }
} }
+6 -2
View File
@@ -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 // 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. // 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(); QByteArray current_result = hash.result();
bool base_changed_hash = false; bool base_changed_hash = false;
bool blend_changed_hash = false; bool blend_changed_hash = false;
if (IsInputConnected(kBaseIn)) { 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(); QByteArray post_base_hash = hash.result();
base_changed_hash = (post_base_hash != current_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)) { 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); blend_changed_hash = (hash.result() != current_result);
} }
+3 -1
View File
@@ -574,11 +574,13 @@ bool Track::IsLocked() const
void Track::Hash(const QString &output, QCryptographicHash &hash, const rational &time) const void Track::Hash(const QString &output, QCryptographicHash &hash, const rational &time) const
{ {
Q_UNUSED(output)
Block* b = BlockAtTime(time); Block* b = BlockAtTime(time);
// Defer to block at this time, don't add any of our own information to the hash // Defer to block at this time, don't add any of our own information to the hash
if (b) { if (b) {
b->Hash(output, hash, TransformTimeForBlock(b, time)); b->Hash(kDefaultOutput, hash, TransformTimeForBlock(b, time));
} }
} }
+9 -12
View File
@@ -302,27 +302,23 @@ void Footage::Hash(const QString& output, QCryptographicHash &hash, const ration
{ {
super::Hash(output, hash, time); super::Hash(output, hash, time);
// Footage last modified date
hash.addData(QString::number(timestamp()).toUtf8());
// Translate output ID to stream // Translate output ID to stream
Track::Reference ref = Track::Reference::FromString(output); Track::Reference ref = Track::Reference::FromString(output);
QString fn = filename(); if (ref.type() == Track::kVideo) {
if (!fn.isEmpty()) {
VideoParams params = GetVideoParams(ref.index()); VideoParams params = GetVideoParams(ref.index());
if (params.is_valid()) { if (params.is_valid()) {
// Add footage details to hash // Add footage details to hash
QString fn = filename();
// Footage filename
hash.addData(filename().toUtf8());
// Footage last modified date
hash.addData(QString::number(timestamp()).toUtf8());
// Footage stream // Footage stream
hash.addData(QString::number(ref.index()).toUtf8()); hash.addData(QString::number(ref.index()).toUtf8());
if (ref.type() == Track::kVideo) { if (!fn.isEmpty()) {
// Current color config and space // Current color config and space
hash.addData(project()->color_manager()->GetConfigFilename().toUtf8()); hash.addData(project()->color_manager()->GetConfigFilename().toUtf8());
hash.addData(GetColorspaceToUse(params).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()); int64_t video_ts = Timecode::time_to_timestamp(time, params.time_base());
// Add timestamp in units of the video stream's timebase // Add timestamp in units of the video stream's timebase
hash.addData(reinterpret_cast<const char*>(&video_ts), sizeof(int64_t)); hash.addData(reinterpret_cast<const char*>(&video_ts), sizeof(video_ts));
// Add start time - used for both image sequences and video streams // 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<const char*>(&start_time), sizeof(start_time));
} }
} }
} }
+1 -1
View File
@@ -69,7 +69,7 @@ void PreviewAutoCacher::GenerateHashes(ViewerOutput *viewer, FrameHashCache* cac
foreach (const rational& time, times) { foreach (const rational& time, times) {
// See if hash already exists in disk cache // 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 // Check memory list since disk checking is slow
bool hash_exists = (std::find(existing_hashes.begin(), existing_hashes.end(), hash) != existing_hashes.end()); bool hash_exists = (std::find(existing_hashes.begin(), existing_hashes.end(), hash) != existing_hashes.end());
+2 -2
View File
@@ -79,7 +79,7 @@ RenderManager::~RenderManager()
} }
} }
QByteArray RenderManager::Hash(const Node *n, const VideoParams &params, const rational &time) QByteArray RenderManager::Hash(const Node *n, const QString& output, const VideoParams &params, const rational &time)
{ {
QCryptographicHash hasher(QCryptographicHash::Sha1); QCryptographicHash hasher(QCryptographicHash::Sha1);
@@ -93,7 +93,7 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams &params, const r
hasher.addData(reinterpret_cast<const char*>(&format), sizeof(VideoParams::Format)); hasher.addData(reinterpret_cast<const char*>(&format), sizeof(VideoParams::Format));
if (n) { if (n) {
n->Hash(Node::kDefaultOutput, hasher, time); n->Hash(output, hasher, time);
} }
return hasher.result(); return hasher.result();
+5 -1
View File
@@ -67,7 +67,11 @@ public:
/** /**
* @brief Generate a unique identifier for a certain node at a certain time * @brief Generate a unique identifier for a certain node at a certain time
*/ */
static QByteArray Hash(const Node *n, const VideoParams &params, const rational &time); static QByteArray Hash(const Node *n, const QString &output, const VideoParams &params, const rational &time);
static QByteArray Hash(const NodeOutput &output, const VideoParams &params, const rational &time)
{
return Hash(output.node(), output.output(), params, time);
}
/** /**
* @brief Asynchronously generate a frame at a given time * @brief Asynchronously generate a frame at a given time
+1 -1
View File
@@ -85,7 +85,7 @@ bool RenderTask::Render(ColorManager* manager,
return true; 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 // Filter out duplicates