From 2f80be437a4e1ed181d90f63726622e2c2e6cb40 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 16 Apr 2020 23:12:05 +1000 Subject: [PATCH] node: fixed issue with "taking" values from input tables As opposed to simply leaving all values in the table, nodes can now "take" values that they use to free up memory (e.g. "taking" input buffers if they're used to produce an output buffer). This is a fairly large change, expect regressions. --- app/common/tohex.h | 4 + app/core.cpp | 1 + app/node/audio/volume/volume.cpp | 2 +- app/node/block/clip/clip.cpp | 5 +- app/node/block/clip/clip.h | 2 +- app/node/distort/transform/transform.cpp | 2 +- app/node/distort/transform/transform.h | 2 +- app/node/input.cpp | 3 +- app/node/input/media/media.cpp | 11 +- app/node/input/media/media.h | 2 +- app/node/input/time/timeinput.cpp | 2 +- app/node/input/time/timeinput.h | 2 +- app/node/math/math/math.cpp | 106 ++++++++++++-------- app/node/math/math/math.h | 18 ++-- app/node/math/trigonometry/trigonometry.cpp | 2 +- app/node/math/trigonometry/trigonometry.h | 2 +- app/node/node.cpp | 10 +- app/node/node.h | 4 +- app/node/traverser.cpp | 2 +- app/node/traverser.h | 2 +- app/node/value.cpp | 55 ++++++++-- app/node/value.h | 13 ++- app/render/backend/audio/audioworker.cpp | 4 +- app/render/backend/audio/audioworker.h | 2 +- app/render/backend/opengl/openglproxy.cpp | 6 +- app/render/backend/opengl/openglproxy.h | 2 +- app/render/backend/opengl/openglworker.cpp | 2 +- app/render/backend/opengl/openglworker.h | 4 +- app/render/backend/renderworker.cpp | 4 +- app/render/backend/renderworker.h | 4 +- 30 files changed, 179 insertions(+), 101 deletions(-) create mode 100644 app/common/tohex.h diff --git a/app/common/tohex.h b/app/common/tohex.h new file mode 100644 index 000000000..56c590ae1 --- /dev/null +++ b/app/common/tohex.h @@ -0,0 +1,4 @@ +#ifndef TOHEX_H +#define TOHEX_H + +#endif // TOHEX_H diff --git a/app/core.cpp b/app/core.cpp index 37471e1f8..6bd866cc3 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -390,6 +390,7 @@ void Core::DeclareTypesForQt() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); diff --git a/app/node/audio/volume/volume.cpp b/app/node/audio/volume/volume.cpp index a6478ac27..5d1c90b4f 100644 --- a/app/node/audio/volume/volume.cpp +++ b/app/node/audio/volume/volume.cpp @@ -63,7 +63,7 @@ Node::Capabilities VolumeNode::GetCapabilities(const NodeValueDatabase &) const return kSampleProcessor; } -NodeInput *VolumeNode::ProcessesSamplesFrom(const NodeValueDatabase &value) const +NodeInput *VolumeNode::ProcessesSamplesFrom(const NodeValueDatabase &) const { return samples_input_; } diff --git a/app/node/block/clip/clip.cpp b/app/node/block/clip/clip.cpp index dc968ae08..ebd286171 100644 --- a/app/node/block/clip/clip.cpp +++ b/app/node/block/clip/clip.cpp @@ -100,16 +100,15 @@ TimeRange ClipBlock::OutputTimeAdjustment(NodeInput *input, const TimeRange &inp return Block::InputTimeAdjustment(input, input_time); } -NodeValueTable ClipBlock::Value(const NodeValueDatabase &value) const +NodeValueTable ClipBlock::Value(NodeValueDatabase &value) const { // We discard most values here except for the buffer we received - NodeValueTable table; NodeValue data = value[texture_input()].GetWithMeta(NodeParam::kBuffer); + NodeValueTable table; if (data.type() != NodeParam::kNone) { table.Push(data); } - return table; } diff --git a/app/node/block/clip/clip.h b/app/node/block/clip/clip.h index b2abac8e2..6dc996b08 100644 --- a/app/node/block/clip/clip.h +++ b/app/node/block/clip/clip.h @@ -50,7 +50,7 @@ public: virtual TimeRange OutputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const override; - virtual NodeValueTable Value(const NodeValueDatabase& value) const override; + virtual NodeValueTable Value(NodeValueDatabase& value) const override; virtual void Retranslate() override; diff --git a/app/node/distort/transform/transform.cpp b/app/node/distort/transform/transform.cpp index 5b4e70e80..649aa065e 100644 --- a/app/node/distort/transform/transform.cpp +++ b/app/node/distort/transform/transform.cpp @@ -83,7 +83,7 @@ void TransformDistort::Retranslate() anchor_input_->set_name(tr("Anchor Point")); } -NodeValueTable TransformDistort::Value(const NodeValueDatabase &value) const +NodeValueTable TransformDistort::Value(NodeValueDatabase &value) const { QMatrix4x4 mat; diff --git a/app/node/distort/transform/transform.h b/app/node/distort/transform/transform.h index fb4beb17a..6e3acd6a4 100644 --- a/app/node/distort/transform/transform.h +++ b/app/node/distort/transform/transform.h @@ -40,7 +40,7 @@ public: virtual void Retranslate() override; - virtual NodeValueTable Value(const NodeValueDatabase& value) const override; + virtual NodeValueTable Value(NodeValueDatabase& value) const override; private: NodeInput* position_input_; diff --git a/app/node/input.cpp b/app/node/input.cpp index c0f301688..9025b6415 100644 --- a/app/node/input.cpp +++ b/app/node/input.cpp @@ -27,6 +27,7 @@ #include "common/bezier.h" #include "common/lerp.h" +#include "common/tohex.h" #include "common/xmlutils.h" #include "node.h" #include "output.h" @@ -306,7 +307,7 @@ QString NodeInput::ValueToString(const DataType& data_type, const QVariant &valu } if (!value.isNull()) { - qWarning() << "Failed to convert type" << QStringLiteral("%1").arg(data_type, 0, 16) << "to string"; + qWarning() << "Failed to convert type" << ToHex(data_type) << "to string"; } /* fall through */ diff --git a/app/node/input/media/media.cpp b/app/node/input/media/media.cpp index b3058d112..a69207ab6 100644 --- a/app/node/input/media/media.cpp +++ b/app/node/input/media/media.cpp @@ -21,6 +21,7 @@ #include "media.h" #include "common/timecodefunctions.h" +#include "common/tohex.h" OLIVE_NAMESPACE_ENTER @@ -54,9 +55,9 @@ void MediaInput::Retranslate() footage_input_->set_name(tr("Footage")); } -NodeValueTable MediaInput::Value(const NodeValueDatabase &value) const +NodeValueTable MediaInput::Value(NodeValueDatabase &value) const { - NodeValueTable table = value.Merge(); + NodeValueTable table; if (connected_footage_) { rational media_duration = Timecode::timestamp_to_time(connected_footage_->duration(), @@ -65,6 +66,12 @@ NodeValueTable MediaInput::Value(const NodeValueDatabase &value) const table.Push(NodeInput::kRational, QVariant::fromValue(media_duration), "length"); } + // Push buffer to the top of the stack + NodeValue buffer = value[footage_input_].GetWithMeta(NodeParam::kSamples); + if (buffer.type() != NodeParam::kNone) { + table.Push(buffer); + } + return table; } diff --git a/app/node/input/media/media.h b/app/node/input/media/media.h index 405edf7c2..a7c15e37b 100644 --- a/app/node/input/media/media.h +++ b/app/node/input/media/media.h @@ -42,7 +42,7 @@ public: virtual void Retranslate() override; - virtual NodeValueTable Value(const NodeValueDatabase& value) const override; + virtual NodeValueTable Value(NodeValueDatabase& value) const override; protected: NodeInput* footage_input_; diff --git a/app/node/input/time/timeinput.cpp b/app/node/input/time/timeinput.cpp index 48eefb662..1a8791460 100644 --- a/app/node/input/time/timeinput.cpp +++ b/app/node/input/time/timeinput.cpp @@ -51,7 +51,7 @@ QString TimeInput::Description() const return tr("Generates the time (in seconds) at this frame"); } -NodeValueTable TimeInput::Value(const NodeValueDatabase &value) const +NodeValueTable TimeInput::Value(NodeValueDatabase &value) const { NodeValueTable table = value.Merge(); diff --git a/app/node/input/time/timeinput.h b/app/node/input/time/timeinput.h index de3016a3e..284faba4a 100644 --- a/app/node/input/time/timeinput.h +++ b/app/node/input/time/timeinput.h @@ -38,7 +38,7 @@ public: virtual QString Category() const override; virtual QString Description() const override; - virtual NodeValueTable Value(const NodeValueDatabase& value) const override; + virtual NodeValueTable Value(NodeValueDatabase& value) const override; }; diff --git a/app/node/math/math/math.cpp b/app/node/math/math/math.cpp index 86769f967..4a2d6f14a 100644 --- a/app/node/math/math/math.cpp +++ b/app/node/math/math/math.cpp @@ -23,6 +23,7 @@ #include #include +#include "common/tohex.h" #include "render/color.h" OLIVE_NAMESPACE_ENTER @@ -169,35 +170,47 @@ QString MathNode::ShaderFragmentCode(const NodeValueDatabase &input) const operation); } -NodeValue MathNode::InputValueFromTable(NodeInput *input, const NodeValueDatabase &db) const +NodeValue MathNode::InputValueFromTable(NodeInput *input, NodeValueDatabase &db, bool take) const { if (input == param_a_in_ || input == param_b_in_) { PairingCalculator calc(db[param_a_in_], db[param_b_in_]); - if (input == param_a_in_) { - return calc.GetMostLikelyValueA(); - } else { - return calc.GetMostLikelyValueB(); + NodeValue v = (input == param_a_in_) + ? calc.GetMostLikelyValueA() + : calc.GetMostLikelyValueB(); + + if (take) { + db[input].Remove(v); } + + return v; } - return Node::InputValueFromTable(input, db); + return Node::InputValueFromTable(input, db, take); } -NodeValueTable MathNode::Value(const NodeValueDatabase &value) const +NodeValueTable MathNode::Value(NodeValueDatabase &value) const { - NodeValueTable output = value.Merge(); - // Auto-detect what values to operate with // FIXME: Add manual override for this PairingCalculator calc(value[param_a_in_], value[param_b_in_]); - if (!calc.FoundMostLikelyPairing()) { - return output; + if (!calc.FoundMostLikelyPairing() + || calc.GetMostLikelyPairing() == kPairSampleNumber + || calc.GetMostLikelyPairing() == kPairTextureTexture + || calc.GetMostLikelyPairing() == kPairTextureNumber + || calc.GetMostLikelyPairing() == kPairTextureColor + || calc.GetMostLikelyPairing() == kPairTextureMatrix) { + return value.Merge(); } NodeValue val_a = calc.GetMostLikelyValueA(); + value[param_a_in_].Remove(val_a); + NodeValue val_b = calc.GetMostLikelyValueB(); + value[param_b_in_].Remove(val_b); + + NodeValueTable output = value.Merge(); switch (calc.GetMostLikelyPairing()) { @@ -395,39 +408,44 @@ QVector MathNode::PairingCalculator::GetPairLikelihood(const NodeValueTable for (int i=0;i &a, const QVector &b) +MathNode::Pairing MathNode::PairingCalculator::GetMostLikelyPairingInternal(const QVector &a, + const QVector &b, + const int& weight_a, + const int& weight_b) { QVector likelihoods(kPairCount); @@ -435,15 +453,13 @@ MathNode::Pairing MathNode::PairingCalculator::GetMostLikelyPairingInternal(cons if (a.at(i) == -1 || b.at(i) == -1) { likelihoods.replace(i, -1); } else { - likelihoods.replace(i, a.at(i) + b.at(i)); + likelihoods.replace(i, a.at(i) + weight_a + b.at(i) + weight_b); } } Pairing pairing = kPairNone; for (int i=0;i -1) { if (pairing == kPairNone || likelihoods.at(i) > likelihoods.at(pairing)) { @@ -495,18 +511,22 @@ float MathNode::RetrieveNumber(const NodeValue &val) } } -MathNode::PairingCalculator::PairingCalculator(const NodeValueTable &table_a, const NodeValueTable &table_b) +MathNode::PairingCalculator::PairingCalculator(const NodeValueTable &table_a, const NodeValueTable &table_b) : + table_a_(table_a), + table_b_(table_b) { - table_a_ = table_a; - table_b_ = table_b; pair_likelihood_a_ = GetPairLikelihood(table_a_); pair_likelihood_b_ = GetPairLikelihood(table_b_); - most_likely_pairing_ = GetMostLikelyPairingInternal(pair_likelihood_a_, pair_likelihood_b_); + + most_likely_pairing_ = GetMostLikelyPairingInternal(pair_likelihood_a_, + pair_likelihood_b_, + qMax(0, table_b_.Count() - table_a_.Count()), + qMax(0, table_a_.Count() - table_b_.Count())); } bool MathNode::PairingCalculator::FoundMostLikelyPairing() const { - return (most_likely_pairing_ >= 0 && most_likely_pairing_ < kPairCount); + return (most_likely_pairing_ > kPairNone && most_likely_pairing_ < kPairCount); } MathNode::Pairing MathNode::PairingCalculator::GetMostLikelyPairing() const @@ -514,17 +534,17 @@ MathNode::Pairing MathNode::PairingCalculator::GetMostLikelyPairing() const return most_likely_pairing_; } -NodeValue MathNode::PairingCalculator::GetMostLikelyValueA() const +const NodeValue &MathNode::PairingCalculator::GetMostLikelyValueA() const { return GetMostLikelyValue(table_a_, pair_likelihood_a_); } -NodeValue MathNode::PairingCalculator::GetMostLikelyValueB() const +const NodeValue &MathNode::PairingCalculator::GetMostLikelyValueB() const { return GetMostLikelyValue(table_b_, pair_likelihood_b_); } -NodeValue MathNode::PairingCalculator::GetMostLikelyValue(const NodeValueTable &table, const QVector &likelihood) const +const NodeValue& MathNode::PairingCalculator::GetMostLikelyValue(const NodeValueTable &table, const QVector &likelihood) const { return table.At(likelihood.at(most_likely_pairing_)); } diff --git a/app/node/math/math/math.h b/app/node/math/math/math.h index 3220a4e48..306dfc487 100644 --- a/app/node/math/math/math.h +++ b/app/node/math/math/math.h @@ -43,9 +43,9 @@ public: virtual QString ShaderID(const NodeValueDatabase&) const override; virtual QString ShaderFragmentCode(const NodeValueDatabase&) const override; - virtual NodeValue InputValueFromTable(NodeInput* input, const NodeValueDatabase &db) const override; + virtual NodeValue InputValueFromTable(NodeInput* input, NodeValueDatabase &db, bool take) const override; - virtual NodeValueTable Value(const NodeValueDatabase& value) const override; + virtual NodeValueTable Value(NodeValueDatabase &value) const override; virtual NodeInput* ProcessesSamplesFrom(const NodeValueDatabase &value) const override; virtual void ProcessSamples(const NodeValueDatabase &values, const AudioRenderingParams& params, const SampleBufferPtr input, SampleBufferPtr output, int index) const override; @@ -87,26 +87,26 @@ private: class PairingCalculator { public: - PairingCalculator(const NodeValueTable& table_a, const NodeValueTable& table_b); + PairingCalculator(const NodeValueTable &table_a, const NodeValueTable &table_b); bool FoundMostLikelyPairing() const; Pairing GetMostLikelyPairing() const; - NodeValue GetMostLikelyValueA() const; - NodeValue GetMostLikelyValueB() const; + const NodeValue& GetMostLikelyValueA() const; + const NodeValue& GetMostLikelyValueB() const; private: - static Pairing GetMostLikelyPairingInternal(const QVector &a, const QVector &b); + static Pairing GetMostLikelyPairingInternal(const QVector &a, const QVector &b, const int &weight_a, const int &weight_b); static QVector GetPairLikelihood(const NodeValueTable& table); - NodeValue GetMostLikelyValue(const NodeValueTable& table, const QVector& likelihood) const; + const NodeValue &GetMostLikelyValue(const NodeValueTable& table, const QVector& likelihood) const; Pairing most_likely_pairing_; - NodeValueTable table_a_; + const NodeValueTable& table_a_; - NodeValueTable table_b_; + const NodeValueTable& table_b_; QVector pair_likelihood_a_; diff --git a/app/node/math/trigonometry/trigonometry.cpp b/app/node/math/trigonometry/trigonometry.cpp index 00c6a693a..af073c3c5 100644 --- a/app/node/math/trigonometry/trigonometry.cpp +++ b/app/node/math/trigonometry/trigonometry.cpp @@ -77,7 +77,7 @@ void TrigonometryNode::Retranslate() method_in_->set_name(tr("Method")); } -NodeValueTable TrigonometryNode::Value(const NodeValueDatabase &value) const +NodeValueTable TrigonometryNode::Value(NodeValueDatabase &value) const { float x = value[x_in_].Take(NodeParam::kFloat).toFloat(); diff --git a/app/node/math/trigonometry/trigonometry.h b/app/node/math/trigonometry/trigonometry.h index 44808ee3c..c999104eb 100644 --- a/app/node/math/trigonometry/trigonometry.h +++ b/app/node/math/trigonometry/trigonometry.h @@ -39,7 +39,7 @@ public: virtual void Retranslate() override; - virtual NodeValueTable Value(const NodeValueDatabase& value) const override; + virtual NodeValueTable Value(NodeValueDatabase &value) const override; private: enum Operation { diff --git a/app/node/node.cpp b/app/node/node.cpp index ba2bf8279..ae681ecf1 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -148,7 +148,7 @@ void Node::AddParameter(NodeParam *param) } } -NodeValueTable Node::Value(const NodeValueDatabase &value) const +NodeValueTable Node::Value(NodeValueDatabase &value) const { return value.Merge(); } @@ -616,7 +616,7 @@ NodeOutput *Node::output() const return output_; } -NodeValue Node::InputValueFromTable(NodeInput *input, const NodeValueDatabase &db) const +NodeValue Node::InputValueFromTable(NodeInput *input, NodeValueDatabase &db, bool take) const { NodeParam::DataType find_data_type = input->data_type(); @@ -626,7 +626,11 @@ NodeValue Node::InputValueFromTable(NodeInput *input, const NodeValueDatabase &d } // Try to get a value from it - return db[input].GetWithMeta(find_data_type); + if (take) { + return db[input].TakeWithMeta(find_data_type); + } else { + return db[input].GetWithMeta(find_data_type); + } } const QPointF &Node::GetPosition() diff --git a/app/node/node.h b/app/node/node.h index efd45d10e..0ec7e06eb 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -332,7 +332,7 @@ public: * corresponding output if it's connected to one. If your node doesn't directly deal with time, the default behavior * of the NodeParam objects will handle everything related to it automatically. */ - virtual NodeValueTable Value(const NodeValueDatabase& value) const; + virtual NodeValueTable Value(NodeValueDatabase& value) const; /** * @brief Return whether a parameter with ID `id` has already been added to this Node @@ -341,7 +341,7 @@ public: NodeOutput* output() const; - virtual NodeValue InputValueFromTable(NodeInput* input, const NodeValueDatabase& db) const; + virtual NodeValue InputValueFromTable(NodeInput* input, NodeValueDatabase &db, bool take) const; const QPointF& GetPosition(); diff --git a/app/node/traverser.cpp b/app/node/traverser.cpp index 9884be33f..c4737cfd1 100644 --- a/app/node/traverser.cpp +++ b/app/node/traverser.cpp @@ -72,7 +72,7 @@ NodeValueTable NodeTraverser::ProcessNode(const NodeDependency& dep) // By this point, the node should have all the inputs it needs to render correctly NodeValueTable table = node->Value(database); - ProcessNodeEvent(node, dep.range(), database, &table); + ProcessNodeEvent(node, dep.range(), database, table); return table; } diff --git a/app/node/traverser.h b/app/node/traverser.h index 2111abf95..7897cd7a1 100644 --- a/app/node/traverser.h +++ b/app/node/traverser.h @@ -46,7 +46,7 @@ protected: virtual void InputProcessingEvent(NodeInput*, const TimeRange&, NodeValueTable*){} - virtual void ProcessNodeEvent(const Node*, const TimeRange&, const NodeValueDatabase&, NodeValueTable*){} + virtual void ProcessNodeEvent(const Node*, const TimeRange&, NodeValueDatabase&, NodeValueTable&){} }; diff --git a/app/node/value.cpp b/app/node/value.cpp index 497a84129..7c0d92d90 100644 --- a/app/node/value.cpp +++ b/app/node/value.cpp @@ -22,14 +22,24 @@ OLIVE_NAMESPACE_ENTER -NodeValueTable NodeValueDatabase::operator[](const QString &input_id) const +NodeValueTable& NodeValueDatabase::operator[](const QString &input_id) { - return tables_.value(input_id); + return tables_[input_id]; } -NodeValueTable NodeValueDatabase::operator[](const NodeInput *input) const +NodeValueTable& NodeValueDatabase::operator[](const NodeInput *input) { - return tables_.value(input->id()); + return tables_[input->id()]; +} + +const NodeValueTable NodeValueDatabase::operator[](const QString &input_id) const +{ + return tables_[input_id]; +} + +const NodeValueTable NodeValueDatabase::operator[](const NodeInput *input) const +{ + return tables_[input->id()]; } void NodeValueDatabase::Insert(const QString &key, const NodeValueTable &value) @@ -64,6 +74,11 @@ const QString &NodeValue::tag() const return tag_; } +bool NodeValue::operator==(const NodeValue &rhs) const +{ + return type_ == rhs.type_ && tag_ == rhs.tag_ && data_ == rhs.data_; +} + const QVariant &NodeValue::data() const { return data_; @@ -71,9 +86,7 @@ const QVariant &NodeValue::data() const QVariant NodeValueTable::Get(const NodeParam::DataType &type, const QString &tag) const { - NodeValue v = GetWithMeta(type, tag); - - return v.data(); + return GetWithMeta(type, tag).data(); } NodeValue NodeValueTable::GetWithMeta(const NodeParam::DataType &type, const QString &tag) const @@ -88,16 +101,19 @@ NodeValue NodeValueTable::GetWithMeta(const NodeParam::DataType &type, const QSt } QVariant NodeValueTable::Take(const NodeParam::DataType &type, const QString &tag) +{ + return TakeWithMeta(type, tag).data(); +} + +NodeValue NodeValueTable::TakeWithMeta(const NodeParam::DataType &type, const QString &tag) { int value_index = GetInternal(type, tag); if (value_index >= 0) { - QVariant val = values_.at(value_index).data(); - values_.removeAt(value_index); - return val; + return values_.takeAt(value_index); } - return QVariant(); + return NodeValue(NodeParam::kNone, QVariant()); } void NodeValueTable::Push(const NodeValue &value) @@ -125,6 +141,11 @@ const NodeValue &NodeValueTable::At(int index) const return values_.at(index); } +NodeValue NodeValueTable::TakeAt(int index) +{ + return values_.takeAt(index); +} + int NodeValueTable::Count() const { return values_.size(); @@ -143,6 +164,18 @@ bool NodeValueTable::Has(const NodeParam::DataType &type) const return false; } +void NodeValueTable::Remove(const NodeValue &v) +{ + for (int i=values_.size() - 1;i>=0;i--) { + const NodeValue& compare = values_.at(i); + + if (compare == v) { + values_.removeAt(i); + return; + } + } +} + bool NodeValueTable::isEmpty() const { return values_.isEmpty(); diff --git a/app/node/value.h b/app/node/value.h index 4bfe949bc..456ba797f 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -37,6 +37,8 @@ public: const QVariant& data() const; const QString& tag() const; + bool operator==(const NodeValue& rhs) const; + private: NodeParam::DataType type_; QVariant data_; @@ -52,13 +54,16 @@ public: QVariant Get(const NodeParam::DataType& type, const QString& tag = QString()) const; NodeValue GetWithMeta(const NodeParam::DataType& type, const QString& tag = QString()) const; QVariant Take(const NodeParam::DataType& type, const QString& tag = QString()); + NodeValue TakeWithMeta(const NodeParam::DataType& type, const QString& tag = QString()); void Push(const NodeValue& value); void Push(const NodeParam::DataType& type, const QVariant& data, const QString& tag = QString()); void Prepend(const NodeValue& value); void Prepend(const NodeParam::DataType& type, const QVariant& data, const QString& tag = QString()); const NodeValue& At(int index) const; + NodeValue TakeAt(int index); int Count() const; bool Has(const NodeParam::DataType& type) const; + void Remove(const NodeValue& v); bool isEmpty() const; @@ -76,8 +81,11 @@ class NodeValueDatabase public: NodeValueDatabase() = default; - NodeValueTable operator[](const QString& input_id) const; - NodeValueTable operator[](const NodeInput* input) const; + NodeValueTable& operator[](const QString& input_id); + NodeValueTable& operator[](const NodeInput* input); + + const NodeValueTable operator[](const QString& input_id) const; + const NodeValueTable operator[](const NodeInput* input) const; void Insert(const QString& key, const NodeValueTable &value); void Insert(const NodeInput* key, const NodeValueTable& value); @@ -92,5 +100,6 @@ private: OLIVE_NAMESPACE_EXIT Q_DECLARE_METATYPE(OLIVE_NAMESPACE::NodeValueTable) +Q_DECLARE_METATYPE(OLIVE_NAMESPACE::NodeValueDatabase) #endif // VALUE_H diff --git a/app/render/backend/audio/audioworker.cpp b/app/render/backend/audio/audioworker.cpp index bdaf4d6b9..5e0e38ee7 100644 --- a/app/render/backend/audio/audioworker.cpp +++ b/app/render/backend/audio/audioworker.cpp @@ -44,7 +44,7 @@ void AudioWorker::FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeR } } -void AudioWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params_in, NodeValueTable *output_params) +void AudioWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params_in, NodeValueTable &output_params) { // Check if node processes samples if (!(node->GetCapabilities(input_params_in) & Node::kSampleProcessor)) { @@ -101,7 +101,7 @@ void AudioWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, c i); } - output_params->Push(NodeParam::kSamples, QVariant::fromValue(output_buffer)); + output_params.Push(NodeParam::kSamples, QVariant::fromValue(output_buffer)); } OLIVE_NAMESPACE_EXIT diff --git a/app/render/backend/audio/audioworker.h b/app/render/backend/audio/audioworker.h index db49a1902..53192706f 100644 --- a/app/render/backend/audio/audioworker.h +++ b/app/render/backend/audio/audioworker.h @@ -33,7 +33,7 @@ public: protected: virtual void FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable* table) override; - virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase& input_params, NodeValueTable* output_params) override; + virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, NodeValueDatabase& input_params, NodeValueTable& output_params) override; private: diff --git a/app/render/backend/opengl/openglproxy.cpp b/app/render/backend/opengl/openglproxy.cpp index 9c1cc6f59..a6f99656a 100644 --- a/app/render/backend/opengl/openglproxy.cpp +++ b/app/render/backend/opengl/openglproxy.cpp @@ -200,7 +200,7 @@ void OpenGLProxy::Close() ctx_ = nullptr; } -void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable *output_params) +void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable &output_params) { if (!(node->GetCapabilities(input_params) & Node::kShader)) { return; @@ -257,7 +257,7 @@ void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, c NodeInput* input = static_cast(param); // Get value from database at this input - NodeValue meta_value = node->InputValueFromTable(input, input_params); + NodeValue meta_value = node->InputValueFromTable(input, input_params, true); const QVariant& value = meta_value.data(); NodeParam::DataType data_type; @@ -423,7 +423,7 @@ void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, c shader->release(); - output_params->Push(NodeParam::kTexture, QVariant::fromValue(output_tex)); + output_params.Push(NodeParam::kTexture, QVariant::fromValue(output_tex)); } void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer) diff --git a/app/render/backend/opengl/openglproxy.h b/app/render/backend/opengl/openglproxy.h index 7c3a873dd..f30943670 100644 --- a/app/render/backend/opengl/openglproxy.h +++ b/app/render/backend/opengl/openglproxy.h @@ -65,7 +65,7 @@ public: void FrameToValue(FramePtr frame, StreamPtr stream, NodeValueTable* table); - void RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params); + void RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params); void TextureToBuffer(const QVariant& texture, void *buffer); diff --git a/app/render/backend/opengl/openglworker.cpp b/app/render/backend/opengl/openglworker.cpp index ff091ba22..be7937e50 100644 --- a/app/render/backend/opengl/openglworker.cpp +++ b/app/render/backend/opengl/openglworker.cpp @@ -45,7 +45,7 @@ void OpenGLWorker::FrameToValue(DecoderPtr decoder, StreamPtr stream, const Time } } -void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable *output_params) +void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable &output_params) { emit RequestRunNodeAccelerated(node, range, input_params, output_params); } diff --git a/app/render/backend/opengl/openglworker.h b/app/render/backend/opengl/openglworker.h index cfaedec80..6bc90b4c2 100644 --- a/app/render/backend/opengl/openglworker.h +++ b/app/render/backend/opengl/openglworker.h @@ -40,14 +40,14 @@ public: signals: void RequestFrameToValue(FramePtr frame, StreamPtr stream, NodeValueTable* table); - void RequestRunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params); + void RequestRunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params); void RequestTextureToBuffer(const QVariant& texture, void *buffer); protected: virtual void FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable* table) override; - virtual void RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params) override; + virtual void RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params) override; virtual void TextureToBuffer(const QVariant& texture, void *buffer) override; diff --git a/app/render/backend/renderworker.cpp b/app/render/backend/renderworker.cpp index 58b14aef2..947cb2f1e 100644 --- a/app/render/backend/renderworker.cpp +++ b/app/render/backend/renderworker.cpp @@ -68,7 +68,7 @@ NodeValueTable RenderWorker::RenderInternal(const NodeDependency &path, const qi return ProcessNode(path); } -void RenderWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params) +void RenderWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable& output_params) { Q_UNUSED(node) Q_UNUSED(range) @@ -136,7 +136,7 @@ void RenderWorker::InputProcessingEvent(NodeInput* input, const TimeRange& input } } -void RenderWorker::ProcessNodeEvent(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params) +void RenderWorker::ProcessNodeEvent(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable &output_params) { // Check if we have a shader for this output RunNodeAccelerated(node, range, input_params, output_params); diff --git a/app/render/backend/renderworker.h b/app/render/backend/renderworker.h index 9e85da223..c0d3d35e3 100644 --- a/app/render/backend/renderworker.h +++ b/app/render/backend/renderworker.h @@ -57,7 +57,7 @@ protected: virtual NodeValueTable RenderInternal(const NodeDependency& CurrentPath, const qint64& job_time); - virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase &input_params, NodeValueTable* output_params); + virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, NodeValueDatabase &input_params, NodeValueTable &output_params); virtual void FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable* table) = 0; @@ -65,7 +65,7 @@ protected: virtual void InputProcessingEvent(NodeInput *input, const TimeRange &input_time, NodeValueTable* table) override; - virtual void ProcessNodeEvent(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params) override; + virtual void ProcessNodeEvent(const Node *node, const TimeRange &range, NodeValueDatabase &input_params, NodeValueTable &output_params) override; StreamPtr ResolveStreamFromInput(NodeInput* input);