nodes: moved hashing to nodes so they can override behavior if they wish

This commit is contained in:
itsmattkc
2020-04-30 01:56:08 +10:00
parent ba94aa0b22
commit aecfa842c3
13 changed files with 128 additions and 115 deletions
+12
View File
@@ -234,6 +234,18 @@ void Block::SaveInternal(QXmlStreamWriter *writer) const
}
}
QList<NodeInput *> Block::GetInputsToHash() const
{
QList<NodeInput*> inputs = Node::GetInputsToHash();
// Ignore these inputs
inputs.removeOne(media_in_input_);
inputs.removeOne(speed_input_);
inputs.removeOne(length_input_);
return inputs;
}
void Block::LengthInputChanged()
{
emit LengthChanged(length());
+2
View File
@@ -126,6 +126,8 @@ protected:
virtual void SaveInternal(QXmlStreamWriter* writer) const override;
virtual QList<NodeInput*> GetInputsToHash() const override;
Block* previous_;
Block* next_;
+13
View File
@@ -129,6 +129,19 @@ double TransitionBlock::GetInProgress(const rational &time) const
return clamp((GetInternalTransitionTime(time) - out_offset().toDouble()) / in_offset().toDouble(), 0.0, 1.0);
}
void TransitionBlock::Hash(QCryptographicHash &hash, const rational &time) const
{
Block::Hash(hash, time);
double all_prog = GetTotalProgress(time);
double in_prog = GetInProgress(time);
double out_prog = GetOutProgress(time);
hash.addData(reinterpret_cast<const char*>(&all_prog), sizeof(double));
hash.addData(reinterpret_cast<const char*>(&in_prog), sizeof(double));
hash.addData(reinterpret_cast<const char*>(&out_prog), sizeof(double));
}
double TransitionBlock::GetInternalTransitionTime(const rational &time) const
{
return time.toDouble() - in().toDouble();
+2
View File
@@ -47,6 +47,8 @@ public:
double GetOutProgress(const rational& time) const;
double GetInProgress(const rational& time) const;
virtual void Hash(QCryptographicHash& hash, const rational &time) const override;
private:
double GetInternalTransitionTime(const rational& time) const;
+8
View File
@@ -62,4 +62,12 @@ NodeValueTable TimeInput::Value(NodeValueDatabase &value) const
return table;
}
void TimeInput::Hash(QCryptographicHash &hash, const rational &time) const
{
Node::Hash(hash, time);
// Make sure time is hashed
hash.addData(NodeParam::ValueToBytes(NodeParam::kRational, QVariant::fromValue(time)));
}
OLIVE_NAMESPACE_EXIT
+2
View File
@@ -40,6 +40,8 @@ public:
virtual NodeValueTable Value(NodeValueDatabase& value) const override;
virtual void Hash(QCryptographicHash& hash, const rational& time) const override;
};
OLIVE_NAMESPACE_EXIT
+71
View File
@@ -25,6 +25,9 @@
#include <QFile>
#include "common/xmlutils.h"
#include "project/project.h"
#include "project/item/footage/footage.h"
#include "project/item/footage/imagestream.h"
OLIVE_NAMESPACE_ENTER
@@ -232,6 +235,11 @@ void Node::SaveInternal(QXmlStreamWriter *) const
{
}
QList<NodeInput *> Node::GetInputsToHash() const
{
return GetInputsIncludingArrays();
}
QString Node::ReadFileAsString(const QString &filename)
{
QFile f(filename);
@@ -294,6 +302,69 @@ void Node::SetLabel(const QString &s)
}
}
void Node::Hash(QCryptographicHash &hash, const rational& time) const
{
// Add this Node's ID
hash.addData(id().toUtf8());
QList<NodeInput*> inputs = GetInputsToHash();
foreach (NodeInput* input, inputs) {
// For each input, try to hash its value
// Get time adjustment
// For a single frame, we only care about one of the times
rational input_time = InputTimeAdjustment(input, TimeRange(time, time)).in();
if (input->IsConnected()) {
// Traverse down this edge
input->get_connected_node()->Hash(hash, input_time);
} else {
// Grab the value at this time
QVariant value = input->get_value_at_time(input_time);
hash.addData(NodeParam::ValueToBytes(input->data_type(), value));
}
// We have one exception for FOOTAGE types, since we resolve the footage into a frame in the renderer
if (input->data_type() == NodeParam::kFootage) {
StreamPtr stream = input->get_standard_value().value<StreamPtr>();
if (stream) {
// Add footage details to hash
// Footage filename
hash.addData(stream->footage()->filename().toUtf8());
// Footage last modified date
hash.addData(stream->footage()->timestamp().toString().toUtf8());
// Footage stream
hash.addData(QString::number(stream->index()).toUtf8());
if (stream->type() == Stream::kImage || stream->type() == Stream::kVideo) {
ImageStreamPtr image_stream = std::static_pointer_cast<ImageStream>(stream);
// Current color config and space
hash.addData(image_stream->footage()->project()->color_manager()->GetConfigFilename().toUtf8());
hash.addData(image_stream->colorspace().toUtf8());
// Alpha associated setting
hash.addData(QString::number(image_stream->premultiplied_alpha()).toUtf8());
}
// Footage timestamp
if (stream->type() == Stream::kVideo) {
hash.addData(QStringLiteral("%1/%2").arg(QString::number(input_time.numerator()),
QString::number(input_time.denominator())).toUtf8());
hash.addData(QString::number(static_cast<VideoStream*>(stream.get())->start_time()).toUtf8());
}
}
}
}
}
void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
{
Q_ASSERT(source->id() == destination->id());
+4
View File
@@ -362,6 +362,8 @@ public:
const QString& GetLabel() const;
void SetLabel(const QString& s);
virtual void Hash(QCryptographicHash& hash, const rational &time) const;
protected:
void AddInput(NodeInput* input);
@@ -373,6 +375,8 @@ protected:
virtual void SaveInternal(QXmlStreamWriter* writer) const;
virtual QList<NodeInput*> GetInputsToHash() const;
public slots:
signals:
+10
View File
@@ -418,6 +418,16 @@ NodeInputArray *TrackOutput::block_input() const
return block_input_;
}
void TrackOutput::Hash(QCryptographicHash &hash, const rational &time) const
{
// Resolve block list
Block* b = BlockAtTime(time);
if (b) {
return b->Hash(hash, time);
}
}
void TrackOutput::SetTrackName(const QString &name)
{
track_name_ = name;
+2
View File
@@ -152,6 +152,8 @@ public:
NodeInputArray* block_input() const;
virtual void Hash(QCryptographicHash& hash, const rational &time) const override;
public slots:
void SetTrackName(const QString& name);