nodes: revert to single output

This commit is contained in:
itsmattkc
2021-09-07 22:01:36 -07:00
parent 9843fd47f0
commit b07bccb7dc
89 changed files with 511 additions and 616 deletions
+1 -2
View File
@@ -62,9 +62,8 @@ QString PanNode::Description() const
return tr("Adjust the stereo panning of an audio source.");
}
void PanNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void PanNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
Q_UNUSED(globals)
// Create a sample job
+1 -1
View File
@@ -40,7 +40,7 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override;
+1 -3
View File
@@ -61,10 +61,8 @@ QString VolumeNode::Description() const
return tr("Adjusts the volume of an audio source.");
}
void VolumeNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void VolumeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
return ValueInternal(kOpMultiply,
kPairSampleNumber,
kSamplesInput,
+1 -1
View File
@@ -40,7 +40,7 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override;
+4 -4
View File
@@ -100,7 +100,7 @@ void Block::InputValueChangedEvent(const QString &input, int element)
}
}
bool Block::HashPassthrough(const QString &input, const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
bool Block::HashPassthrough(const QString &input, const Node::ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
if (IsInputConnected(input)) {
TimeRange t = InputTimeAdjustment(input, -1, globals.time());
@@ -108,8 +108,8 @@ bool Block::HashPassthrough(const QString &input, const QString &output, QCrypto
NodeGlobals new_globals = globals;
new_globals.set_time(t);
NodeOutput out = GetConnectedOutput(input);
out.node()->Hash(out.output(), hash, new_globals, video_params);
Node *out = GetConnectedOutput(input);
out->Hash(GetValueHintForInput(input, -1), hash, new_globals, video_params);
return true;
}
@@ -130,7 +130,7 @@ void Block::Retranslate()
SetInputName(kEnabledInput, tr("Enabled"));
}
void Block::Hash(const QString &, QCryptographicHash &, const NodeGlobals &, const VideoParams &) const
void Block::Hash(const ValueHint &hint, QCryptographicHash &, const NodeGlobals &, const VideoParams &) const
{
// A block does nothing by default, so we hash nothing
}
+2 -2
View File
@@ -115,7 +115,7 @@ public:
index_ = i;
}
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const Node::ValueHint &hint, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element = -1, InvalidateCacheOptions options = InvalidateCacheOptions()) override;
@@ -134,7 +134,7 @@ signals:
protected:
virtual void InputValueChangedEvent(const QString& input, int element) override;
bool HashPassthrough(const QString &input, const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const;
bool HashPassthrough(const QString &input, const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const;
Block* previous_;
Block* next_;
+13 -5
View File
@@ -20,6 +20,7 @@
#include "clip.h"
#include "node/output/track/track.h"
#include "widget/slider/floatslider.h"
#include "widget/slider/rationalslider.h"
@@ -50,7 +51,7 @@ ClipBlock::ClipBlock() :
IgnoreHashingFrom(kReverseInput);
PrependInput(kBufferIn, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable));
SetValueHintForInput(kBufferIn, {NodeValue::kBuffer, -1, QString()});
SetValueHintForInput(kBufferIn, -1, {NodeValue::kBuffer, -1, QString()});
}
Node *ClipBlock::copy() const
@@ -60,6 +61,14 @@ Node *ClipBlock::copy() const
QString ClipBlock::Name() const
{
if (track()) {
if (track()->type() == Track::kVideo) {
return tr("Video Clip");
} else if (track()->type() == Track::kAudio) {
return tr("Audio Clip");
}
}
return tr("Clip");
}
@@ -232,9 +241,8 @@ TimeRange ClipBlock::OutputTimeAdjustment(const QString& input, int element, con
return super::OutputTimeAdjustment(input, element, input_time);
}
void ClipBlock::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void ClipBlock::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
Q_UNUSED(globals)
// We discard most values here except for the buffer we received
@@ -256,9 +264,9 @@ void ClipBlock::Retranslate()
SetInputName(kReverseInput, tr("Reverse"));
}
void ClipBlock::Hash(const QString &out, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void ClipBlock::Hash(const ValueHint &out, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
HashPassthrough(kBufferIn, out, hash, globals, video_params);
HashPassthrough(kBufferIn, GetValueHintForInput(kBufferIn, -1), hash, globals, video_params);
}
}
+2 -2
View File
@@ -55,11 +55,11 @@ public:
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Retranslate() override;
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const Node::ValueHint& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
double speed() const
{
+10 -12
View File
@@ -137,10 +137,10 @@ double TransitionBlock::GetInProgress(const double &time) const
return clamp((GetInternalTransitionTime(time) - out_offset().toDouble()) / in_offset().toDouble(), 0.0, 1.0);
}
void TransitionBlock::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TransitionBlock::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
if (HashPassthrough(kInBlockInput, output, hash, globals, video_params) || HashPassthrough(kOutBlockInput, output, hash, globals, video_params)) {
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
double time_dbl = globals.time().in().toDouble();
double all_prog = GetTotalProgress(time_dbl);
@@ -173,10 +173,8 @@ void TransitionBlock::InsertTransitionTimes(AcceleratedJob *job, const double &t
NodeValue(NodeValue::kFloat, GetInProgress(time), this));
}
void TransitionBlock::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TransitionBlock::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
NodeValue out_buffer = value[kOutBlockInput];
NodeValue in_buffer = value[kInBlockInput];
NodeValue::Type data_type = (out_buffer.type() != NodeValue::kNone) ? out_buffer.type() : in_buffer.type();
@@ -236,7 +234,7 @@ void TransitionBlock::InvalidateCache(const TimeRange &range, const QString &fro
TimeRange r = range;
if (from == kOutBlockInput || from == kInBlockInput) {
Block *n = dynamic_cast<Block*>(GetConnectedNode(from));
Block *n = dynamic_cast<Block*>(GetConnectedOutput(from));
if (n) {
r = Track::TransformRangeFromBlock(n, r);
}
@@ -275,24 +273,24 @@ double TransitionBlock::TransformCurve(double linear) const
return linear;
}
void TransitionBlock::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void TransitionBlock::InputConnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(element)
if (input == kOutBlockInput) {
// If node is not a block, this will just be null
if ((connected_out_block_ = dynamic_cast<ClipBlock*>(output.node()))) {
if ((connected_out_block_ = dynamic_cast<ClipBlock*>(output))) {
connected_out_block_->set_out_transition(this);
}
} else if (input == kInBlockInput) {
// If node is not a block, this will just be null
if ((connected_in_block_ = dynamic_cast<ClipBlock*>(output.node()))) {
if ((connected_in_block_ = dynamic_cast<ClipBlock*>(output))) {
connected_in_block_->set_in_transition(this);
}
}
}
void TransitionBlock::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void TransitionBlock::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(element)
Q_UNUSED(output)
@@ -313,7 +311,7 @@ void TransitionBlock::InputDisconnectedEvent(const QString &input, int element,
TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
{
if (input == kInBlockInput || input == kOutBlockInput) {
Block* block = dynamic_cast<Block*>(GetConnectedNode(input));
Block* block = dynamic_cast<Block*>(GetConnectedOutput(input));
if (block) {
return input_time + in() - block->in();
}
@@ -325,7 +323,7 @@ TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element
TimeRange TransitionBlock::OutputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
{
if (input == kInBlockInput || input == kOutBlockInput) {
Block* block = dynamic_cast<Block*>(GetConnectedNode(input));
Block* block = dynamic_cast<Block*>(GetConnectedOutput(input));
if (block) {
return input_time + block->in() - in();
}
+4 -4
View File
@@ -65,9 +65,9 @@ public:
double GetOutProgress(const double &time) const;
double GetInProgress(const double &time) const;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element = -1, InvalidateCacheOptions options = InvalidateCacheOptions()) override;
@@ -83,9 +83,9 @@ protected:
double TransformCurve(double linear) const;
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputConnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
+1 -3
View File
@@ -55,10 +55,8 @@ void CropDistortNode::Retranslate()
SetInputName(kFeatherInput, tr("Feather"));
}
void CropDistortNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void CropDistortNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
job.InsertValue(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this));
+1 -1
View File
@@ -63,7 +63,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
@@ -39,7 +39,7 @@ TransformDistortNode::TransformDistortNode()
AddInput(kInterpolationInput, NodeValue::kCombo, 2);
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
PrependInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
}
void TransformDistortNode::Retranslate()
@@ -54,10 +54,8 @@ void TransformDistortNode::Retranslate()
SetComboBoxStrings(kInterpolationInput, {tr("Nearest Neighbor"), tr("Bilinear"), tr("Mipmapped Bilinear")});
}
void TransformDistortNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TransformDistortNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
// Generate matrix
QMatrix4x4 generated_matrix = GenerateMatrix(value, true, false, false, false);
@@ -309,11 +307,11 @@ void TransformDistortNode::GizmoRelease()
gizmo_drag_ = nullptr;
}
void TransformDistortNode::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TransformDistortNode::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
// If not connected to output, this will produce nothing
NodeOutput out = GetConnectedOutput(kTextureInput);
if (!out.IsValid()) {
Node *out = GetConnectedOutput(kTextureInput);
if (!out) {
return;
}
@@ -321,7 +319,7 @@ void TransformDistortNode::Hash(const QString &output, QCryptographicHash &hash,
NodeTraverser traverser;
traverser.SetCacheVideoParams(video_params);
NodeValueRow db = traverser.GenerateRow(this, output, globals.time());
NodeValueRow db = traverser.GenerateRow(this, globals.time());
TexturePtr tex = db[kTextureInput].data().value<TexturePtr>();
if (tex) {
VideoParams tex_params = tex->params();
@@ -330,12 +328,12 @@ void TransformDistortNode::Hash(const QString &output, QCryptographicHash &hash,
if (!matrix.isIdentity()) {
// Add fingerprint
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
hash.addData(reinterpret_cast<const char*>(&matrix), sizeof(matrix));
}
}
out.node()->Hash(out.output(), hash, globals, video_params);
out->Hash(GetValueHintForInput(kTextureInput, -1), hash, globals, video_params);
}
QMatrix4x4 TransformDistortNode::AdjustMatrixByResolutions(const QMatrix4x4 &mat, const QVector2D &sequence_res, const QVector2D &texture_res, AutoScaleType autoscale_type)
@@ -65,7 +65,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
@@ -80,7 +80,7 @@ public:
virtual void GizmoMove(const QPointF &p, const rational &time) override;
virtual void GizmoRelease() override;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
enum AutoScaleType {
kAutoScaleNone,
-4
View File
@@ -63,10 +63,6 @@ void NodeFactory::Initialize()
Node* created_node = CreateFromFactoryIndex(static_cast<InternalID>(i));
library_.append(created_node);
if (created_node->outputs().isEmpty()) {
qWarning() << "Node" << created_node->id() << "has no outputs";
}
}
}
+1 -3
View File
@@ -87,10 +87,8 @@ ShaderCode BlurFilterNode::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/blur.frag"));
}
void BlurFilterNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void BlurFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -43,7 +43,7 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kTextureInput;
static const QString kMethodInput;
+1 -3
View File
@@ -44,10 +44,8 @@ void MosaicFilterNode::Retranslate()
SetInputName(kVertInput, tr("Vertical"));
}
void MosaicFilterNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MosaicFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -60,7 +60,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
static const QString kTextureInput;
+1 -3
View File
@@ -82,10 +82,8 @@ void StrokeFilterNode::Retranslate()
SetInputName(kInnerInput, tr("Inner"));
}
void StrokeFilterNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void StrokeFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
static const QString kTextureInput;
+1 -3
View File
@@ -88,10 +88,8 @@ void MatrixGenerator::Retranslate()
SetInputName(kAnchorInput, tr("Anchor Point"));
}
void MatrixGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MatrixGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
// Push matrix output
QMatrix4x4 mat = GenerateMatrix(value, true, false, false, false);
table->Push(NodeValue::kMatrix, mat, this);
+1 -1
View File
@@ -46,7 +46,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kPositionInput;
static const QString kRotationInput;
+1 -3
View File
@@ -86,10 +86,8 @@ ShaderCode PolygonGenerator::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/polygon.frag")));
}
void PolygonGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void PolygonGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -44,7 +44,7 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual bool HasGizmos() const override;
//virtual void DrawGizmos(NodeValueDatabase& db, QPainter *p) const override;
+1 -3
View File
@@ -68,10 +68,8 @@ ShaderCode ShapeNode::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/shape.frag")));
}
void ShapeNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -47,7 +47,7 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static QString kTypeInput;
+1 -3
View File
@@ -62,10 +62,8 @@ void SolidGenerator::Retranslate()
SetInputName(kColorInput, tr("Color"));
}
void SolidGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void SolidGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
static const QString kColorInput;
+1 -3
View File
@@ -89,10 +89,8 @@ void TextGenerator::Retranslate()
SetComboBoxStrings(kVAlignInput, {tr("Top"), tr("Center"), tr("Bottom")});
}
void TextGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TextGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
GenerateJob job;
job.InsertValue(value);
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void GenerateFrame(FramePtr frame, const GenerateJob &job) const override;
+2 -2
View File
@@ -123,9 +123,9 @@ signals:
*/
void NodeRemoved(Node* node);
void InputConnected(const NodeOutput& output, const NodeInput& input);
void InputConnected(Node *output, const NodeInput& input);
void InputDisconnected(const NodeOutput& output, const NodeInput& input);
void InputDisconnected(Node *output, const NodeInput& input);
void ValueChanged(const NodeInput& input);
+2 -4
View File
@@ -51,10 +51,8 @@ QString TimeInput::Description() const
return tr("Generates the time (in seconds) at this frame.");
}
void TimeInput::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TimeInput::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
table->Push(NodeValue::kFloat,
globals.time().in().toDouble(),
this,
@@ -62,7 +60,7 @@ void TimeInput::Value(const QString &output, const NodeValueRow &value, const No
QStringLiteral("time"));
}
void TimeInput::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TimeInput::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
Node::Hash(output, hash, globals, video_params);
+2 -2
View File
@@ -40,9 +40,9 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
};
+1 -2
View File
@@ -59,10 +59,9 @@ void ValueNode::Retranslate()
SetComboBoxStrings(kTypeInput, type_names);
}
void ValueNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void ValueNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(globals)
Q_UNUSED(output)
// Ensure value is pushed onto the table
table->Push(value[kValueInput]);
+1 -1
View File
@@ -63,7 +63,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString &output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
protected:
virtual void InputValueChangedEvent(const QString &input, int element) override;
+1 -3
View File
@@ -88,10 +88,8 @@ ShaderCode MathNode::GetShaderCode(const QString &shader_id) const
return GetShaderCodeInternal(shader_id, kParamAIn, kParamBIn);
}
void MathNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MathNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
// Auto-detect what values to operate with
// FIXME: Very inefficient
NodeValueTable at, bt;
+1 -1
View File
@@ -54,7 +54,7 @@ public:
SetStandardValue(kMethodIn, o);
}
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override;
+8 -10
View File
@@ -73,10 +73,8 @@ ShaderCode MergeNode::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/alphaover.frag"));
}
void MergeNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MergeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
@@ -102,12 +100,12 @@ void MergeNode::Value(const QString &output, const NodeValueRow &value, const No
}
}
void MergeNode::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void MergeNode::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
NodeTraverser traverser;
traverser.SetCacheVideoParams(video_params);
NodeValueDatabase db = traverser.GenerateDatabase(this, output, globals.time());
NodeValueDatabase db = traverser.GenerateDatabase(this, globals.time());
TexturePtr base_tex = db[kBaseIn].Get(NodeValue::kTexture).value<TexturePtr>();
TexturePtr blend_tex = db[kBlendIn].Get(NodeValue::kTexture).value<TexturePtr>();
@@ -118,17 +116,17 @@ void MergeNode::Hash(const QString &output, QCryptographicHash &hash, const Node
if (!passthrough_base && !passthrough_blend) {
// This merge will actually do something so we add a fingerprint
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
}
if (!passthrough_base) {
NodeOutput blend_output = GetConnectedOutput(kBlendIn);
blend_output.node()->Hash(blend_output.output(), hash, globals, video_params);
Node *blend_output = GetConnectedOutput(kBlendIn);
blend_output->Hash(GetValueHintForInput(kBlendIn, -1), hash, globals, video_params);
}
if (!passthrough_blend) {
NodeOutput base_output = GetConnectedOutput(kBaseIn);
base_output.node()->Hash(base_output.output(), hash, globals, video_params);
Node *base_output = GetConnectedOutput(kBaseIn);
base_output->Hash(GetValueHintForInput(kBaseIn, -1), hash, globals, video_params);
}
Q_ASSERT(!passthrough_base || !passthrough_blend);
+2 -2
View File
@@ -43,12 +43,12 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kBaseIn;
static const QString kBlendIn;
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
private:
NodeInput* base_in_;
+1 -3
View File
@@ -76,10 +76,8 @@ void TrigonometryNode::Retranslate()
SetInputName(kMethodIn, tr("Method"));
}
void TrigonometryNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TrigonometryNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
double x = value[kXIn].data().toFloat();
switch (static_cast<Operation>(GetStandardValue(kMethodIn).toInt())) {
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kMethodIn;
static const QString kXIn;
+66 -83
View File
@@ -35,6 +35,7 @@
#include "project/project.h"
#include "ui/colorcoding.h"
#include "ui/icons/icons.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
#include "widget/nodeview/nodeviewundo.h"
namespace olive {
@@ -50,7 +51,6 @@ Node::Node() :
operation_stack_(0),
cache_result_(false)
{
AddOutput();
}
Node::~Node()
@@ -122,19 +122,18 @@ void Node::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, uint versi
}
QString output_node_id;
QString output_param_id;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
if ((version >= 210907 && reader->name() == QStringLiteral("output")) || reader->name() == QStringLiteral("node")) {
output_node_id = reader->readElementText();
} else if (reader->name() == QStringLiteral("output")) {
output_param_id = reader->readElementText();
} else if (version < 210907 && reader->name() == QStringLiteral("output")) {
qDebug() << "FIXME: Convert output string to ValueHint";
} else {
reader->skipCurrentElement();
}
}
xml_node_data.desired_connections.append({NodeInput(this, param_id, ele), output_node_id.toULongLong(), output_param_id});
xml_node_data.desired_connections.append({NodeInput(this, param_id, ele), output_node_id.toULongLong()});
} else {
reader->skipCurrentElement();
}
@@ -173,8 +172,7 @@ void Node::Save(QXmlStreamWriter *writer) const
writer->writeAttribute(QStringLiteral("input"), it->first.input());
writer->writeAttribute(QStringLiteral("element"), QString::number(it->first.element()));
writer->writeTextElement(QStringLiteral("node"), QString::number(reinterpret_cast<quintptr>(it->second.node())));
writer->writeTextElement(QStringLiteral("output"), it->second.output());
writer->writeTextElement(QStringLiteral("output"), QString::number(reinterpret_cast<quintptr>(it->second)));
writer->writeEndElement(); // connection
}
@@ -248,25 +246,25 @@ QBrush Node::brush(qreal top, qreal bottom) const
}
}
void Node::ConnectEdge(const NodeOutput &output, const NodeInput &input)
void Node::ConnectEdge(Node *output, const NodeInput &input)
{
// Ensure graph is the same
Q_ASSERT(input.node()->parent() == output.node()->parent());
Q_ASSERT(input.node()->parent() == output->parent());
// Ensure a connection isn't getting overwritten
Q_ASSERT(input.node()->input_connections().find(input) == input.node()->input_connections().end());
// Insert connection on both sides
input.node()->input_connections_[input] = output;
output.node()->output_connections_.push_back(std::pair<NodeOutput, NodeInput>({output, input}));
output->output_connections_.push_back(std::pair<Node*, NodeInput>({output, input}));
// Call internal events
input.node()->InputConnectedEvent(input.input(), input.element(), output);
output.node()->OutputConnectedEvent(output.output(), input);
output->OutputConnectedEvent(input);
// Emit signals
emit input.node()->InputConnected(output, input);
emit output.node()->OutputConnected(output, input);
emit output->OutputConnected(output, input);
// Invalidate all if this node isn't ignoring this input
if (!input.node()->ignore_connections_.contains(input.input())) {
@@ -274,10 +272,10 @@ void Node::ConnectEdge(const NodeOutput &output, const NodeInput &input)
}
}
void Node::DisconnectEdge(const NodeOutput &output, const NodeInput &input)
void Node::DisconnectEdge(Node *output, const NodeInput &input)
{
// Ensure graph is the same
Q_ASSERT(input.node()->parent() == output.node()->parent());
Q_ASSERT(input.node()->parent() == output->parent());
// Ensure connection exists
Q_ASSERT(input.node()->input_connections().at(input) == output);
@@ -286,15 +284,15 @@ void Node::DisconnectEdge(const NodeOutput &output, const NodeInput &input)
InputConnections& inputs = input.node()->input_connections_;
inputs.erase(inputs.find(input));
OutputConnections& outputs = output.node()->output_connections_;
outputs.erase(std::find(outputs.begin(), outputs.end(), std::pair<NodeOutput, NodeInput>({output, input})));
OutputConnections& outputs = output->output_connections_;
outputs.erase(std::find(outputs.begin(), outputs.end(), std::pair<Node*, NodeInput>({output, input})));
// Call internal events
input.node()->InputDisconnectedEvent(input.input(), input.element(), output);
output.node()->OutputDisconnectedEvent(output.output(), input);
output->OutputDisconnectedEvent(input);
emit input.node()->InputDisconnected(output, input);
emit output.node()->OutputDisconnected(output, input);
emit output->OutputDisconnected(output, input);
if (!input.node()->ignore_connections_.contains(input.input())) {
input.node()->InvalidateAll(input.input(), input.element());
@@ -437,10 +435,10 @@ void Node::SetInputIsKeyframing(const QString &input, bool e, int element)
bool Node::IsInputConnected(const QString &input, int element) const
{
return GetConnectedOutput(input, element).IsValid();
return GetConnectedOutput(input, element);
}
NodeOutput Node::GetConnectedOutput(const QString &input, int element) const
Node *Node::GetConnectedOutput(const QString &input, int element) const
{
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
if (it->first.input() == input && it->first.element() == element) {
@@ -448,7 +446,7 @@ NodeOutput Node::GetConnectedOutput(const QString &input, int element) const
}
}
return NodeOutput();
return nullptr;
}
bool Node::IsUsingStandardValue(const QString &input, int track, int element) const
@@ -1013,10 +1011,9 @@ Node::InputFlags Node::GetInputFlags(const QString &input) const
}
}
void Node::Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const
void Node::Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const
{
// Do nothing
Q_UNUSED(output)
Q_UNUSED(value)
Q_UNUSED(globals)
Q_UNUSED(table)
@@ -1092,19 +1089,19 @@ void Node::CopyDependencyGraph(const QVector<Node *> &src, const QVector<Node *>
for (auto it=src_node->input_connections_.cbegin(); it!=src_node->input_connections_.cend(); it++) {
// Determine if the connected node is in our src list
int connection_index = src.indexOf(it->second.node());
int connection_index = src.indexOf(it->second);
if (connection_index > -1) {
// Find the equivalent node in the dst list
Node* dst_connection = dst.at(connection_index);
NodeOutput copied_output = NodeOutput(dst_connection, it->second.output());
Node *copied_output = dst.at(connection_index);
NodeInput copied_input = NodeInput(dst_node, it->first.input(), it->first.element());
if (command) {
command->add_child(new NodeEdgeAddCommand(copied_output, copied_input));
command->add_child(new NodeSetValueHintCommand(copied_input, src_node->GetValueHintForInput(copied_input.input(), copied_input.element())));
} else {
ConnectEdge(copied_output, copied_input);
copied_input.node()->SetValueHintForInput(copied_input.input(), copied_input.element(), src_node->GetValueHintForInput(copied_input.input(), copied_input.element()));
}
}
}
@@ -1128,8 +1125,7 @@ Node *Node::CopyNodeAndDependencyGraphMinusItemsInternal(QMap<Node*, Node*>& cre
// Go through input connections and copy if non-item and connect if item
for (auto it=node->input_connections_.cbegin(); it!=node->input_connections_.cend(); it++) {
NodeInput input = it->first;
NodeOutput output = it->second;
Node* connected = output.node();
Node* connected = it->second;
Node* connected_copy;
if (connected->IsItem()) {
@@ -1144,8 +1140,9 @@ Node *Node::CopyNodeAndDependencyGraphMinusItemsInternal(QMap<Node*, Node*>& cre
}
}
command->add_child(new NodeEdgeAddCommand(NodeOutput(connected_copy, output.output()),
NodeInput(copy, input.input(), input.element())));
NodeInput copied_input(copy, input.input(), input.element());
command->add_child(new NodeEdgeAddCommand(connected_copy, copied_input));
command->add_child(new NodeSetValueHintCommand(copied_input, node->GetValueHintForInput(input.input(), input.element())));
}
if (node->parent()->GetPositionMap().contains(node)) {
@@ -1256,10 +1253,9 @@ bool Node::AreLinked(Node *a, Node *b)
return a->links_.contains(b);
}
void Node::HashAddNodeSignature(QCryptographicHash &hash, const QString &output) const
void Node::HashAddNodeSignature(QCryptographicHash &hash) const
{
hash.addData(id().toUtf8());
hash.addData(output.toUtf8());
}
void Node::InsertInput(const QString &id, NodeValue::Type type, const QVariant &default_value, Node::InputFlags flags, int index)
@@ -1306,32 +1302,6 @@ void Node::RemoveInput(const QString &id)
emit InputRemoved(id);
}
void Node::AddOutput(const QString &id)
{
if (id.isEmpty()) {
qWarning() << "Rejected adding output with an empty ID on node" << this->id();
return;
}
if (HasParamWithID(id)) {
qWarning() << "Failed to add output to node" << this->id() << "- param with ID" << id << "already exists";
return;
}
outputs_.append(id);
emit OutputAdded(id);
}
void Node::RemoveOutput(const QString &id)
{
if (outputs_.removeOne(id)) {
emit OutputRemoved(id);
} else {
ReportInvalidInput("remove", id);
}
}
void Node::ReportInvalidInput(const char *attempted_action, const QString& id) const
{
qWarning() << "Failed to" << attempted_action << "parameter" << id
@@ -1453,13 +1423,29 @@ void Node::SetLabel(const QString &s)
}
}
void Node::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
QString Node::GetLabelAndName() const
{
if (GetLabel().isEmpty()) {
return Name();
} else {
return tr("%1 (%2)").arg(GetLabel(), Name());
}
}
QString Node::GetLabelOrName() const
{
if (GetLabel().isEmpty()) {
return Name();
}
return GetLabel();
}
void Node::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
// Add this Node's ID and output being used
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
auto inputs = inputs_for_output(output);
foreach (const QString& input, inputs) {
foreach (const QString& input, inputs()) {
// For each input, try to hash its value
if (ignore_when_hashing_.contains(input)) {
continue;
@@ -1557,10 +1543,9 @@ void Node::SetCanBeDeleted(bool s)
void GetDependenciesRecursively(QVector<Node*>& list, const Node* node, bool traverse, bool exclusive_only)
{
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
Node* connected_node = it->second.node();
Node* connected_node = it->second;
if (!exclusive_only
|| (connected_node->outputs().size() == 1 && !connected_node->IsItem())) {
if (!exclusive_only || !connected_node->IsItem()) {
if (!list.contains(connected_node)) {
list.append(connected_node);
@@ -1597,11 +1582,11 @@ void Node::HashInputElement(QCryptographicHash &hash, const QString& input, int
if (IsInputConnected(input, element)) {
// Traverse down this edge
NodeOutput output = GetConnectedOutput(input, element);
Node *output = GetConnectedOutput(input, element);
NodeGlobals new_globals = globals;
new_globals.set_time(input_time);
output.node()->Hash(output.output(), hash, new_globals, video_params);
output->Hash(GetValueHintForInput(input, element), hash, new_globals, video_params);
} else {
// Grab the value at this time
QVariant value = GetValueAtTime(input, input_time.in(), element);
@@ -1655,7 +1640,7 @@ bool Node::OutputsTo(Node *n, bool recursively, const OutputConnections &ignore_
return true;
} else if (recursively && connected->OutputsTo(n, recursively, ignore_edges, added_edge)) {
return true;
} else if (added_edge.first.node() == this) {
} else if (added_edge.first == this) {
Node *proposed_connected = added_edge.second.node();
if (proposed_connected == n) {
@@ -1702,11 +1687,11 @@ bool Node::OutputsTo(const NodeInput &input, bool recursively) const
bool Node::InputsFrom(Node *n, bool recursively) const
{
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
const NodeOutput& connected = it->second;
Node *connected = it->second;
if (connected.node() == n) {
if (connected == n) {
return true;
} else if (recursively && connected.node()->InputsFrom(n, recursively)) {
} else if (recursively && connected->InputsFrom(n, recursively)) {
return true;
}
}
@@ -1717,11 +1702,11 @@ bool Node::InputsFrom(Node *n, bool recursively) const
bool Node::InputsFrom(const QString &id, bool recursively) const
{
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
const NodeOutput& connected = it->second;
Node *connected = it->second;
if (connected.node()->id() == id) {
if (connected->id() == id) {
return true;
} else if (recursively && connected.node()->InputsFrom(id, recursively)) {
} else if (recursively && connected->InputsFrom(id, recursively)) {
return true;
}
}
@@ -1808,7 +1793,7 @@ QVector<TimeRange> Node::TransformTimeTo(const TimeRange &time, Node *target, bo
// If this input is connected, traverse it to see if we stumble across the specified `node`
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
TimeRange input_adjustment = InputTimeAdjustment(it->first.input(), it->first.element(), time);
Node* connected = it->second.node();
Node* connected = it->second;
if (connected == target) {
// We found the target, no need to keep traversing
@@ -2121,29 +2106,27 @@ void Node::InputValueChangedEvent(const QString &input, int element)
Q_UNUSED(element)
}
void Node::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Node::InputConnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(input)
Q_UNUSED(element)
Q_UNUSED(output)
}
void Node::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Node::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(input)
Q_UNUSED(element)
Q_UNUSED(output)
}
void Node::OutputConnectedEvent(const QString &output, const NodeInput &input)
void Node::OutputConnectedEvent(const NodeInput &input)
{
Q_UNUSED(output)
Q_UNUSED(input)
}
void Node::OutputDisconnectedEvent(const QString &output, const NodeInput &input)
void Node::OutputDisconnectedEvent(const NodeInput &input)
{
Q_UNUSED(output)
Q_UNUSED(input)
}
+28 -61
View File
@@ -198,30 +198,14 @@ public:
return input_ids_;
}
virtual QVector<QString> inputs_for_output(const QString& output) const
{
Q_UNUSED(output)
return inputs();
}
const QVector<QString>& outputs() const
{
return outputs_;
}
bool HasInputWithID(const QString& id) const
{
return input_ids_.contains(id);
}
bool HasOutputWithID(const QString& id) const
{
return outputs_.contains(id);
}
bool HasParamWithID(const QString& id) const
{
return HasInputWithID(id) || HasOutputWithID(id);
return HasInputWithID(id);
}
/**
@@ -255,9 +239,9 @@ public:
}
}
static void ConnectEdge(const NodeOutput& output, const NodeInput& input);
static void ConnectEdge(Node *output, const NodeInput& input);
static void DisconnectEdge(const NodeOutput& output, const NodeInput& input);
static void DisconnectEdge(Node *output, const NodeInput& input);
QString GetInputName(const QString& id) const;
@@ -295,23 +279,13 @@ public:
return IsInputStatic(input.input(), input.element());
}
NodeOutput GetConnectedOutput(const QString& input, int element = -1) const;
Node *GetConnectedOutput(const QString& input, int element = -1) const;
NodeOutput GetConnectedOutput(const NodeInput& input) const
Node *GetConnectedOutput(const NodeInput& input) const
{
return GetConnectedOutput(input.input(), input.element());
}
Node* GetConnectedNode(const QString& input, int element = -1) const
{
return GetConnectedOutput(input, element).node();
}
Node* GetConnectedNode(const NodeInput& input) const
{
return GetConnectedNode(input.input(), input.element());
}
bool IsUsingStandardValue(const QString& input, int track, int element = -1) const;
NodeValue::Type GetInputDataType(const QString& id) const;
@@ -494,19 +468,19 @@ public:
QString tag;
};
ValueHint GetValueHintForInput(const QString &input) const
ValueHint GetValueHintForInput(const QString &input, int element) const
{
return value_hints_.value(input);
return value_hints_.value({input, element});
}
void SetValueHintForInput(const QString &input, const ValueHint &hint)
void SetValueHintForInput(const QString &input, int element, const ValueHint &hint)
{
value_hints_.insert(input, hint);
value_hints_.insert({input, element}, hint);
}
const NodeKeyframeTrack& GetTrackFromKeyframe(NodeKeyframe* key) const;
using InputConnections = std::map<NodeInput, NodeOutput>;
using InputConnections = std::map<NodeInput, Node*>;
/**
* @brief Return map of input connections
@@ -519,7 +493,7 @@ public:
return input_connections_;
}
using OutputConnection = std::pair<NodeOutput, NodeInput>;
using OutputConnection = std::pair<Node*, NodeInput>;
using OutputConnections = std::vector<OutputConnection>;
/**
@@ -739,7 +713,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 void Value(const QString &output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const;
virtual bool HasGizmos() const;
@@ -752,7 +726,10 @@ public:
const QString& GetLabel() const;
void SetLabel(const QString& s);
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const;
QString GetLabelAndName() const;
QString GetLabelOrName() const;
virtual void Hash(const ValueHint &output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const;
void InvalidateAll(const QString& input, int element = -1);
@@ -873,7 +850,7 @@ protected:
};
void HashAddNodeSignature(QCryptographicHash &hash, const QString &output) const;
void HashAddNodeSignature(QCryptographicHash &hash) const;
void InsertInput(const QString& id, NodeValue::Type type, const QVariant& default_value, InputFlags flags, int index);
@@ -899,10 +876,6 @@ protected:
void RemoveInput(const QString& id);
void AddOutput(const QString& id = kDefaultOutput);
void RemoveOutput(const QString& id);
void SetInputName(const QString& id, const QString& name);
void SetComboBoxStrings(const QString& id, const QStringList& strings)
@@ -954,13 +927,13 @@ protected:
virtual void InputValueChangedEvent(const QString& input, int element);
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output);
virtual void InputConnectedEvent(const QString& input, int element, Node *output);
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output);
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output);
virtual void OutputConnectedEvent(const QString& output, const NodeInput& input);
virtual void OutputConnectedEvent(const NodeInput& input);
virtual void OutputDisconnectedEvent(const QString& output, const NodeInput& input);
virtual void OutputDisconnectedEvent(const NodeInput& input);
virtual void childEvent(QChildEvent *event) override;
@@ -984,13 +957,13 @@ signals:
void ValueChanged(const NodeInput& input, const TimeRange& range);
void InputConnected(const NodeOutput& output, const NodeInput& input);
void InputConnected(Node *output, const NodeInput& input);
void InputDisconnected(const NodeOutput& output, const NodeInput& input);
void InputDisconnected(Node *output, const NodeInput& input);
void OutputConnected(const NodeOutput& output, const NodeInput& input);
void OutputConnected(Node *output, const NodeInput& input);
void OutputDisconnected(const NodeOutput& output, const NodeInput& input);
void OutputDisconnected(Node *output, const NodeInput& input);
void InputPropertyChanged(const QString& input, const QString& key, const QVariant& value);
@@ -1010,10 +983,6 @@ signals:
void InputRemoved(const QString& id);
void OutputAdded(const QString& id);
void OutputRemoved(const QString& id);
void InputNameChanged(const QString& id, const QString& name);
void InputDataTypeChanged(const QString& id, NodeValue::Type type);
@@ -1075,7 +1044,7 @@ private:
try {
NodeInput input(node_, input_, i);
NodeOutput output = node_->input_connections().at(input);
Node *output = node_->input_connections().at(input);
removed_connections_[input] = output;
@@ -1219,8 +1188,6 @@ private:
QVector<QString> input_ids_;
QVector<Input> input_data_;
QVector<QString> outputs_;
QMap<QString, NodeInputImmediate*> standard_immediates_;
QMap<QString, QVector<NodeInputImmediate*> > array_immediates_;
@@ -1237,7 +1204,7 @@ private:
bool cache_result_;
QMap<QString, ValueHint> value_hints_;
QMap<InputElementPair, ValueHint> value_hints_;
private slots:
/**
@@ -1271,7 +1238,7 @@ template<class T>
void Node::FindInputNodeInternal(const Node* n, QVector<T *> &list)
{
for (auto it=n->input_connections_.cbegin(); it!=n->input_connections_.cend(); it++) {
Node* edge = it->second.node();
Node* edge = it->second;
T* cast_test = dynamic_cast<T*>(edge);
if (cast_test) {
+15 -24
View File
@@ -72,6 +72,14 @@ Node *Track::copy() const
QString Track::Name() const
{
if (track_type_ == Track::kVideo) {
return tr("Video Track %1").arg(index_);
} else if (track_type_ == Track::kAudio) {
return tr("Audio Track %1").arg(index_);
} else if (track_type_ == Track::kSubtitle) {
return tr("Subtitle Track %1").arg(index_);
}
return tr("Track");
}
@@ -145,7 +153,7 @@ void Track::SaveCustom(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("height"), QString::number(GetTrackHeight()));
}
void Track::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Track::InputConnectedEvent(const QString &input, int element, Node *output)
{
if (input == kBlockInput) {
if (element == -1) {
@@ -155,7 +163,7 @@ void Track::InputConnectedEvent(const QString &input, int element, const NodeOut
}
// Check if a block was connected, if not, ignore
Block* block = dynamic_cast<Block*>(output.node());
Block* block = dynamic_cast<Block*>(output);
if (!block) {
return;
@@ -220,7 +228,7 @@ void Track::InputConnectedEvent(const QString &input, int element, const NodeOut
}
}
void Track::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Track::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
if (input == kBlockInput) {
if (element == -1) {
@@ -229,7 +237,7 @@ void Track::InputDisconnectedEvent(const QString &input, int element, const Node
return;
}
Block* b = dynamic_cast<Block*>(output.node());
Block* b = dynamic_cast<Block*>(output);
if (!b) {
return;
@@ -425,7 +433,7 @@ void Track::InvalidateCache(const TimeRange& range, const QString& from, int ele
if (from == kBlockInput
&& element >= 0
&& (b = dynamic_cast<const Block*>(GetConnectedOutput(from, element).node()))
&& (b = dynamic_cast<const Block*>(GetConnectedOutput(from, element)))
&& !options.value(QStringLiteral("lengthevent")).toBool()) {
// Limit the range signal to the corresponding block
TimeRange transformed = TransformRangeFromBlock(b, range);
@@ -553,23 +561,6 @@ rational Track::track_length() const
}
}
QString Track::GetDefaultTrackName(Track::Type type, int index)
{
// Starts tracks at 1 rather than 0
int user_friendly_index = index+1;
switch (type) {
case Track::kVideo: return tr("Video %1").arg(user_friendly_index);
case Track::kAudio: return tr("Audio %1").arg(user_friendly_index);
case Track::kSubtitle: return tr("Subtitle %1").arg(user_friendly_index);
case Track::kNone:
case Track::kCount:
break;
}
return tr("Track %1").arg(user_friendly_index);
}
bool Track::IsMuted() const
{
return GetStandardValue(kMutedInput).toBool();
@@ -580,7 +571,7 @@ bool Track::IsLocked() const
return locked_;
}
void Track::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void Track::Hash(const Node::ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
Q_UNUSED(output)
@@ -590,7 +581,7 @@ void Track::Hash(const QString &output, QCryptographicHash &hash, const NodeGlob
if (b) {
NodeGlobals new_globals = globals;
new_globals.set_time(TransformRangeForBlock(b, globals.time()));
b->Hash(kDefaultOutput, hash, new_globals, video_params);
b->Hash(GetValueHintForInput(kBlockInput, GetArrayIndexFromBlock(b)), hash, new_globals, video_params);
}
}
+5 -7
View File
@@ -355,13 +355,13 @@ public:
rational track_length() const;
static QString GetDefaultTrackName(Track::Type type, int index);
bool IsMuted() const;
bool IsLocked() const;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const Node::ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
int GetArrayIndexFromBlock(Block* block) const;
static const double kTrackHeightDefault;
static const double kTrackHeightMinimum;
@@ -416,17 +416,15 @@ protected:
virtual void SaveCustom(QXmlStreamWriter* writer) const override;
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputConnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputValueChangedEvent(const QString& input, int element) override;
private:
void UpdateInOutFrom(int index);
int GetArrayIndexFromBlock(Block* block) const;
int GetArrayIndexFromCacheIndex(int index) const;
int GetCacheIndexFromArrayIndex(int index) const;
+6 -20
View File
@@ -252,20 +252,6 @@ void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from,
super::InvalidateCache(range, from, element, options);
}
QVector<QString> ViewerOutput::inputs_for_output(const QString &output) const
{
QVector<QString> inputs;
Track::Type type = Track::Reference::TypeFromString(output);
if (type == Track::kVideo) {
inputs.append(kTextureInput);
} else if (type == Track::kAudio) {
inputs.append(kSamplesInput);
}
return inputs;
}
QVector<Track::Reference> ViewerOutput::GetEnabledStreamsAsReferences() const
{
QVector<Track::Reference> refs;
@@ -329,7 +315,7 @@ void ViewerOutput::VerifyLength()
}
}
void ViewerOutput::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void ViewerOutput::InputConnectedEvent(const QString &input, int element, Node *output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
@@ -338,7 +324,7 @@ void ViewerOutput::InputConnectedEvent(const QString &input, int element, const
super::InputConnectedEvent(input, element, output);
}
void ViewerOutput::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void ViewerOutput::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
@@ -354,7 +340,7 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
switch (type) {
case Track::kVideo:
if (IsInputConnected(kTextureInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), GetValueHintForInput(kTextureInput, -1), TimeRange(0, 0));
rational r = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
if (!r.isNaN()) {
return r;
@@ -363,7 +349,7 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
break;
case Track::kAudio:
if (IsInputConnected(kSamplesInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), GetValueHintForInput(kSamplesInput, -1), TimeRange(0, 0));
rational r = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();;
if (!r.isNaN()) {
return r;
@@ -379,12 +365,12 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
return 0;
}
NodeOutput ViewerOutput::GetConnectedTextureOutput()
Node *ViewerOutput::GetConnectedTextureOutput()
{
return GetConnectedOutput(kTextureInput);
}
NodeOutput ViewerOutput::GetConnectedSampleOutput()
Node *ViewerOutput::GetConnectedSampleOutput()
{
return GetConnectedOutput(kSamplesInput);
}
+4 -6
View File
@@ -68,8 +68,6 @@ public:
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) override;
virtual QVector<QString> inputs_for_output(const QString& output) const override;
VideoParams GetVideoParams(int index = 0) const
{
// This check isn't strictly necessary (GetStandardValue will return a null VideoParams anyway),
@@ -150,9 +148,9 @@ public:
virtual void Retranslate() override;
virtual NodeOutput GetConnectedTextureOutput();
virtual Node *GetConnectedTextureOutput();
virtual NodeOutput GetConnectedSampleOutput();
virtual Node *GetConnectedSampleOutput();
void SetViewerVideoCacheEnabled(bool e) { video_cache_enabled_ = e; }
void SetViewerAudioCacheEnabled(bool e) { audio_cache_enabled_ = e; }
@@ -207,9 +205,9 @@ public slots:
void VerifyLength();
protected:
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputConnectedEvent(const QString &input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, Node *output) override;
virtual rational VerifyLengthInternal(Track::Type type) const;
+2 -8
View File
@@ -60,12 +60,12 @@ bool NodeInput::IsArray() const
}
}
NodeOutput NodeInput::GetConnectedOutput() const
Node *NodeInput::GetConnectedOutput() const
{
if (IsValid()) {
return node_->GetConnectedOutput(*this);
} else {
return NodeOutput();
return nullptr;
}
}
@@ -128,12 +128,6 @@ uint qHash(const NodeInput &i)
return qHash(i.node()) ^ qHash(i.input()) ^ qHash(i.element());
}
NodeOutput::NodeOutput(Node *n)
{
node_ = n;
output_ = Node::kDefaultOutput;
}
uint qHash(const NodeKeyframeTrackReference &i)
{
return qHash(i.input()) & qHash(i.track());
+25 -46
View File
@@ -41,51 +41,6 @@ struct NodeInputPair {
QString input;
};
/**
* @brief Defines a node output
*/
class NodeOutput
{
public:
NodeOutput(Node* n, const QString& o)
{
node_ = n;
output_ = o;
}
NodeOutput(Node* n);
NodeOutput()
{
node_ = nullptr;
}
bool operator==(const NodeOutput& rhs) const
{
return node_ == rhs.node_ && output_ == rhs.output_;
}
Node* node() const
{
return node_;
}
const QString& output() const
{
return output_;
}
bool IsValid() const
{
return node_;
}
private:
Node* node_;
QString output_;
};
/**
* @brief Defines a Node input
*/
@@ -166,7 +121,7 @@ public:
bool IsArray() const;
NodeOutput GetConnectedOutput() const;
Node *GetConnectedOutput() const;
NodeValue::Type GetDataType() const;
@@ -192,6 +147,30 @@ private:
};
struct InputElementPair {
QString input;
int element;
bool operator<(const InputElementPair &rhs) const
{
if (input != rhs.input) {
return input < rhs.input;
}
return element < rhs.element;
}
bool operator==(const InputElementPair &rhs) const
{
return input == rhs.input && element == rhs.element;
}
bool operator!=(const InputElementPair &rhs) const
{
return !(*this == rhs);
}
};
class NodeKeyframeTrackReference {
public:
NodeKeyframeTrackReference()
+4 -4
View File
@@ -84,10 +84,10 @@ int Folder::index_of_child_in_array(Node *item) const
return item_element_index_.at(index_of_item);
}
void Folder::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Folder::InputConnectedEvent(const QString &input, int element, Node *output)
{
if (input == kChildInput && element != -1) {
Node* item = output.node();
Node* item = output;
// The insert index is always our "count" because we only support appending in our internal
// model. For sorting/organizing, a QSortFilterProxyModel is used instead.
@@ -99,10 +99,10 @@ void Folder::InputConnectedEvent(const QString &input, int element, const NodeOu
}
}
void Folder::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Folder::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
if (input == kChildInput && element != -1) {
Node* item = output.node();
Node* item = output;
int child_index = item_children_.indexOf(item);
emit BeginRemoveItem(item, child_index);
+2 -2
View File
@@ -170,9 +170,9 @@ signals:
void EndRemoveItem();
protected:
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputConnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
private:
template<typename T>
+70 -69
View File
@@ -73,12 +73,6 @@ void Footage::Retranslate()
SetComboBoxStrings(kLoopModeInput, {tr("None"), tr("Loop"), tr("Clamp")});
}
QVector<QString> Footage::inputs_for_output(const QString &output) const
{
Q_UNUSED(output)
return {kFilenameInput, kLoopModeInput};
}
bool Footage::LoadCustom(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled)
{
if (reader->name() == QStringLiteral("timestamp")) {
@@ -280,6 +274,24 @@ int Footage::GetStreamIndex(Track::Type type, int index) const
}
}
Track::Reference Footage::GetReferenceFromRealIndex(int real_index) const
{
// Check video streams
for (int i=0; i<GetVideoStreamCount(); i++) {
if (GetVideoParams(i).stream_index() == real_index) {
return Track::Reference(Track::kVideo, i);
}
}
for (int i=0; i<GetAudioStreamCount(); i++) {
if (GetAudioParams(i).stream_index() == real_index) {
return Track::Reference(Track::kAudio, i);
}
}
return Track::Reference();
}
const QString &Footage::decoder() const
{
return decoder_;
@@ -323,63 +335,48 @@ QString Footage::DescribeAudioStream(const AudioParams &params)
QString::number(params.sample_rate()));
}
void Footage::Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void Footage::Hash(const Node::ValueHint& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
super::Hash(output, hash, globals, video_params);
// Footage last modified date
hash.addData(QString::number(timestamp()).toUtf8());
// Translate output ID to stream
Track::Reference ref = Track::Reference::FromString(output);
for (int i=0; i<GetVideoStreamCount(); i++) {
VideoParams params = GetVideoParams(i);
if (ref.type() == Track::kVideo) {
VideoParams params = GetVideoParams(ref.index());
// Current color config and space
hash.addData(project()->color_manager()->GetConfigFilename().toUtf8());
hash.addData(GetColorspaceToUse(params).toUtf8());
if (params.is_valid()) {
// Add footage details to hash
QString fn = filename();
// Alpha associated setting
hash.addData(QString::number(params.premultiplied_alpha()).toUtf8());
// Footage stream
hash.addData(QString::number(ref.index()).toUtf8());
// Pixel aspect ratio
hash.addData(reinterpret_cast<const char*>(&params.pixel_aspect_ratio()), sizeof(params.pixel_aspect_ratio()));
if (!fn.isEmpty()) {
// Current color config and space
hash.addData(project()->color_manager()->GetConfigFilename().toUtf8());
hash.addData(GetColorspaceToUse(params).toUtf8());
// Footage timestamp
if (params.video_type() != VideoParams::kVideoTypeStill) {
rational adjusted_time = AdjustTimeByLoopMode(globals.time().in(), loop_mode(), GetLength(), params.video_type(), params.frame_rate_as_time_base());
// Alpha associated setting
hash.addData(QString::number(params.premultiplied_alpha()).toUtf8());
if (!adjusted_time.isNaN()) {
int64_t video_ts = Timecode::time_to_timestamp(adjusted_time, params.time_base());
// Pixel aspect ratio
hash.addData(reinterpret_cast<const char*>(&params.pixel_aspect_ratio()), sizeof(params.pixel_aspect_ratio()));
// Footage timestamp
if (params.video_type() != VideoParams::kVideoTypeStill) {
rational adjusted_time = AdjustTimeByLoopMode(globals.time().in(), loop_mode(), GetLength(), params.video_type(), params.frame_rate_as_time_base());
if (!adjusted_time.isNaN()) {
int64_t video_ts = Timecode::time_to_timestamp(adjusted_time, params.time_base());
// Add timestamp in units of the video stream's timebase
hash.addData(reinterpret_cast<const char*>(&video_ts), sizeof(video_ts));
}
// Add start time - used for both image sequences and video streams
auto start_time = params.start_time();
hash.addData(reinterpret_cast<const char*>(&start_time), sizeof(start_time));
}
// Add timestamp in units of the video stream's timebase
hash.addData(reinterpret_cast<const char*>(&video_ts), sizeof(video_ts));
}
// Add start time - used for both image sequences and video streams
auto start_time = params.start_time();
hash.addData(reinterpret_cast<const char*>(&start_time), sizeof(start_time));
}
}
}
void Footage::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void Footage::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(globals)
Track::Reference ref = Track::Reference::FromString(output);
// Pop filename from table
QString file = value[kFilenameInput].data().toString();
@@ -387,23 +384,29 @@ void Footage::Value(const QString &output, const NodeValueRow &value, const Node
// If the file exists and the reference is valid, push a footage job to the renderer
if (QFileInfo(file).exists()) {
FootageJob job(decoder_, filename(), ref.type(), GetLength(), loop_mode);
if (ref.type() == Track::kVideo) {
VideoParams vp = GetVideoParams(ref.index());
// Ensure the colorspace is valid and not empty
vp.set_colorspace(GetColorspaceToUse(vp));
job.set_video_params(vp);
} else {
AudioParams ap = GetAudioParams(ref.index());
job.set_audio_params(ap);
job.set_cache_path(project()->cache_path());
}
// Push length
table->Push(NodeValue::kRational, QVariant::fromValue(GetLength()), this, false, QStringLiteral("length"));
table->Push(NodeValue::kFootageJob, QVariant::fromValue(job), this);
// Push each stream as a footage job
for (int i=0; i<GetTotalStreamCount(); i++) {
Track::Reference ref = GetReferenceFromRealIndex(i);
FootageJob job(decoder_, filename(), ref.type(), GetLength(), loop_mode);
if (ref.type() == Track::kVideo) {
VideoParams vp = GetVideoParams(ref.index());
// Ensure the colorspace is valid and not empty
vp.set_colorspace(GetColorspaceToUse(vp));
job.set_video_params(vp);
} else {
AudioParams ap = GetAudioParams(ref.index());
job.set_audio_params(ap);
job.set_cache_path(project()->cache_path());
}
table->Push(NodeValue::kFootageJob, QVariant::fromValue(job), this, false, ref.ToString());
}
}
}
@@ -424,23 +427,21 @@ QString Footage::GetStreamTypeName(Track::Type type)
return tr("Unknown");
}
NodeOutput Footage::GetConnectedTextureOutput()
Node *Footage::GetConnectedTextureOutput()
{
QString output = Track::Reference(Track::kVideo, 0).ToString();
if (HasOutputWithID(output)) {
return NodeOutput(this, output);
if (GetVideoStreamCount() > 0) {
return this;
} else {
return NodeOutput();
return nullptr;
}
}
NodeOutput Footage::GetConnectedSampleOutput()
Node *Footage::GetConnectedSampleOutput()
{
QString output = Track::Reference(Track::kAudio, 0).ToString();
if (HasOutputWithID(output)) {
return NodeOutput(this, output);
if (GetAudioStreamCount() > 0) {
return this;
} else {
return NodeOutput();
return nullptr;
}
}
+4 -6
View File
@@ -84,8 +84,6 @@ public:
virtual void Retranslate() override;
virtual QVector<QString> inputs_for_output(const QString &output) const override;
/**
* @brief Reset Footage state ready for running through Probe() again
*
@@ -181,15 +179,15 @@ public:
static QString DescribeVideoStream(const VideoParams& params);
static QString DescribeAudioStream(const AudioParams& params);
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Value(const QString &output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static QString GetStreamTypeName(Track::Type type);
virtual NodeOutput GetConnectedTextureOutput() override;
virtual Node *GetConnectedTextureOutput() override;
virtual NodeOutput GetConnectedSampleOutput() override;
virtual Node *GetConnectedSampleOutput() override;
static rational AdjustTimeByLoopMode(rational time, LoopMode loop_mode, const rational& length, VideoParams::Type type, const rational &timebase);
+4 -4
View File
@@ -137,12 +137,12 @@ rational Sequence::VerifyLengthInternal(Track::Type type) const
return 0;
}
void Sequence::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Sequence::InputConnectedEvent(const QString &input, int element, Node *output)
{
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackConnected(output.node(), element);
list->TrackConnected(output, element);
return;
}
}
@@ -150,12 +150,12 @@ void Sequence::InputConnectedEvent(const QString &input, int element, const Node
super::InputConnectedEvent(input, element, output);
}
void Sequence::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Sequence::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackDisconnected(output.node(), element);
list->TrackDisconnected(output, element);
return;
}
}
+2 -2
View File
@@ -97,9 +97,9 @@ public:
}
protected:
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputConnectedEvent(const QString &input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, Node *output) override;
virtual rational VerifyLengthInternal(Track::Type type) const override;
+4 -9
View File
@@ -34,6 +34,7 @@ TimeRemapNode::TimeRemapNode()
AddInput(kTimeInput, NodeValue::kRational, QVariant::fromValue(rational(0)), InputFlags(kInputFlagNotConnectable));
SetInputProperty(kTimeInput, QStringLiteral("view"), RationalSlider::kTime);
SetInputProperty(kTimeInput, QStringLiteral("viewlock"), true);
IgnoreHashingFrom(kTimeInput);
AddInput(kInputInput, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable));
}
@@ -92,22 +93,16 @@ void TimeRemapNode::Retranslate()
SetInputName(kInputInput, QStringLiteral("Input"));
}
QVector<QString> TimeRemapNode::inputs_for_output(const QString &output) const
{
Q_UNUSED(output)
return {kInputInput};
}
void TimeRemapNode::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TimeRemapNode::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
// Don't hash anything of our own, just pass-through to the connected node at the remapped tmie
Q_UNUSED(output)
if (IsInputConnected(kInputInput)) {
NodeOutput out = GetConnectedOutput(kInputInput);
Node *out = GetConnectedOutput(kInputInput);
NodeGlobals new_globals = globals;
new_globals.set_time(TimeRange(GetRemappedTime(globals.time().in()), GetRemappedTime(globals.time().out())));
out.node()->Hash(out.output(), hash, new_globals, video_params);
out->Hash(GetValueHintForInput(kInputInput, -1), hash, new_globals, video_params);
}
}
+1 -3
View File
@@ -45,9 +45,7 @@ public:
virtual void Retranslate() override;
virtual QVector<QString> inputs_for_output(const QString &output) const override;
virtual void Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
static const QString kTimeInput;
static const QString kInputInput;
+37 -19
View File
@@ -26,13 +26,12 @@
namespace olive {
NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const QString& output, const TimeRange &range)
NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const TimeRange &range)
{
NodeValueDatabase database;
// We need to insert tables into the database for each input
auto inputs = node->inputs_for_output(output);
foreach (const QString& input, inputs) {
foreach (const QString& input, node->inputs()) {
if (IsCancelled()) {
return NodeValueDatabase();
}
@@ -43,7 +42,7 @@ NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const QStrin
return database;
}
NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node *node, const QString &output, const TimeRange &range)
NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node *node, const TimeRange &range)
{
// Generate row
NodeValueRow row;
@@ -55,17 +54,36 @@ NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node
return row;
}
NodeValueRow NodeTraverser::GenerateRow(const Node *node, const QString &output, const TimeRange &range)
NodeValueRow NodeTraverser::GenerateRow(const Node *node, const TimeRange &range)
{
// Generate database of input values of node
NodeValueDatabase database = GenerateDatabase(node, output, range);
NodeValueDatabase database = GenerateDatabase(node, range);
return GenerateRow(&database, node, output, range);
return GenerateRow(&database, node, range);
}
NodeValue NodeTraverser::GenerateRowValue(const Node *node, const QString &input, NodeValueTable *table)
{
Node::ValueHint hint = node->GetValueHintForInput(input);
NodeValue value = GenerateRowValueElement(node, input, -1, table);
if (value.array()) {
// Resolve each element of array
QVector<NodeValueTable> tables = value.data().value<QVector<NodeValueTable> >();
QVector<NodeValue> output(tables.size());
for (int i=0; i<tables.size(); i++) {
output[i] = GenerateRowValueElement(node, input, i, &tables[i]);
}
value = NodeValue(value.type(), QVariant::fromValue(output), value.source(), value.array(), value.tag());
}
return value;
}
NodeValue NodeTraverser::GenerateRowValueElement(const Node *node, const QString &input, int element, NodeValueTable *table)
{
Node::ValueHint hint = node->GetValueHintForInput(input, element);
QVector<NodeValue::Type> types = hint.type;
if (types.isEmpty()) {
@@ -133,7 +151,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range);
// Value will equal something from the connected node, follow it
return GenerateTable(node->GetConnectedOutput(input), adjusted_range);
return GenerateTable(node->GetConnectedOutput(input), node->GetValueHintForInput(input, -1), adjusted_range);
} else {
@@ -151,7 +169,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
TimeRange adjusted_range = node->InputTimeAdjustment(input, i, range);
if (node->IsInputConnected(input, i)) {
sub_tbl = GenerateTable(node->GetConnectedOutput(input, i), adjusted_range);
sub_tbl = GenerateTable(node->GetConnectedOutput(input, i), node->GetValueHintForInput(input, i), adjusted_range);
} else {
QVariant input_value = node->GetValueAtTime(input, adjusted_range.in(), i);
sub_tbl.Push(node->GetInputDataType(input), input_value, node);
@@ -176,7 +194,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
}
}
NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output, const TimeRange& range)
NodeValueTable NodeTraverser::GenerateTable(const Node *n, const Node::ValueHint &hint, const TimeRange& range)
{
const Track* track = dynamic_cast<const Track*>(n);
if (track) {
@@ -187,8 +205,8 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output
// FIXME: Cache certain values here if we've already processed them before
// Generate row for node
NodeValueDatabase database = GenerateDatabase(n, output, range);
NodeValueRow row = GenerateRow(&database, n, output, range);
NodeValueDatabase database = GenerateDatabase(n, range);
NodeValueRow row = GenerateRow(&database, n, range);
//qDebug() << "FIXME: Implement pre-process of row";
@@ -196,10 +214,10 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output
NodeValueTable table = database.Merge();
// By this point, the node should have all the inputs it needs to render correctly
n->Value(output, row, GenerateGlobals(video_params_, range), &table);
n->Value(row, GenerateGlobals(video_params_, range), &table);
// Post-process table
PostProcessTable(n, output, range, table);
PostProcessTable(n, hint, range, table);
return table;
}
@@ -212,7 +230,7 @@ NodeValueTable NodeTraverser::GenerateBlockTable(const Track *track, const TimeR
NodeValueTable table;
if (active_block) {
table = GenerateTable(active_block, Track::TransformRangeForBlock(active_block, range));
table = GenerateTable(active_block, track->GetValueHintForInput(Track::kBlockInput, track->GetArrayIndexFromBlock(active_block)), Track::TransformRangeForBlock(active_block, range));
}
return table;
@@ -231,7 +249,7 @@ QVariant NodeTraverser::ProcessAudioFootage(const FootageJob& stream, const Time
Q_UNUSED(stream)
Q_UNUSED(input_time)
return QVariant();
return QVariant::fromValue(SampleBuffer::Create());
}
QVariant NodeTraverser::ProcessShader(const Node *node, const TimeRange &range, const ShaderJob &job)
@@ -284,7 +302,7 @@ QVector2D NodeTraverser::GenerateResolution() const
return QVector2D(video_params_.square_pixel_width(), video_params_.height());
}
void NodeTraverser::PostProcessTable(const Node *node, const QString& output, const TimeRange &range, NodeValueTable &output_params)
void NodeTraverser::PostProcessTable(const Node *node, const Node::ValueHint &hint, const TimeRange &range, NodeValueTable &output_params)
{
bool got_cached_frame = false;
QByteArray cached_node_hash;
@@ -292,7 +310,7 @@ void NodeTraverser::PostProcessTable(const Node *node, const QString& output, co
// Convert footage to image/sample buffers
if (CanCacheFrames() && node->GetCacheTextures()) {
// This node is set to cache the result, see if we can retrieved a previously cached version
cached_node_hash = RenderManager::Hash(node, output, GetCacheVideoParams(), range.in());
cached_node_hash = RenderManager::Hash(node, hint, GetCacheVideoParams(), range.in());
QVariant cached_frame = GetCachedTexture(cached_node_hash);
if (!cached_frame.isNull()) {
+6 -9
View File
@@ -36,18 +36,15 @@ class NodeTraverser : public CancelableObject
public:
NodeTraverser() = default;
NodeValueTable GenerateTable(const Node *n, const QString &output, const TimeRange &range);
NodeValueTable GenerateTable(const NodeOutput& output, const TimeRange &range)
{
return GenerateTable(output.node(), output.output(), range);
}
NodeValueTable GenerateTable(const Node *n, const Node::ValueHint &hint, const TimeRange &range);
NodeValueDatabase GenerateDatabase(const Node *node, const QString &output, const TimeRange &range);
NodeValueDatabase GenerateDatabase(const Node *node, const TimeRange &range);
NodeValueRow GenerateRow(NodeValueDatabase *database, const Node *node, const QString &output, const TimeRange &range);
NodeValueRow GenerateRow(const Node *node, const QString &output, const TimeRange &range);
NodeValueRow GenerateRow(NodeValueDatabase *database, const Node *node, const TimeRange &range);
NodeValueRow GenerateRow(const Node *node, const TimeRange &range);
NodeValue GenerateRowValue(const Node *node, const QString &input, NodeValueTable *table);
NodeValue GenerateRowValueElement(const Node *node, const QString &input, int element, NodeValueTable *table);
static NodeGlobals GenerateGlobals(const VideoParams &params, const TimeRange &time);
static NodeGlobals GenerateGlobals(const VideoParams &params, const rational &time)
@@ -94,7 +91,7 @@ protected:
QVector2D GenerateResolution() const;
private:
void PostProcessTable(const Node *node, const QString &output, const TimeRange &range, NodeValueTable &output_params);
void PostProcessTable(const Node *node, const Node::ValueHint &hint, const TimeRange &range, NodeValueTable &output_params);
VideoParams video_params_;