From d25dda52756dfbc2fc71f048359ecd729689dab2 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 6 Dec 2019 00:23:26 +1100 Subject: [PATCH] removed all dependence on NodeOutputs If Nodes only have the one output, we don't need to do so much differentiation between them. Previous iteration used outputs as like a distinct function within a Node (e.g. length output would return one result, buffer output would produce a different result - each run different code to produce their results). Now in this iteration, it's more accurate to say a Node is just one function (which seems more appropriate for a node system anyway). --- app/node/blend/alphaover/alphaover.cpp | 32 ++++--- app/node/blend/alphaover/alphaover.h | 2 +- app/node/blend/blend.cpp | 8 +- app/node/blend/blend.h | 3 +- app/node/block/block.cpp | 15 ---- app/node/block/block.h | 6 -- app/node/color/opacity/opacity.cpp | 34 +++----- app/node/color/opacity/opacity.h | 6 +- app/node/dependency.cpp | 8 +- app/node/dependency.h | 11 +-- app/node/distort/transform/transform.cpp | 8 -- app/node/distort/transform/transform.h | 4 - app/node/generator/solid/solid.cpp | 30 ++----- app/node/generator/solid/solid.h | 6 +- app/node/input.cpp | 2 +- app/node/input/media/audio/audio.cpp | 7 -- app/node/input/media/audio/audio.h | 3 - app/node/input/media/video/video.cpp | 34 +++----- app/node/input/media/video/video.h | 6 +- app/node/node.cpp | 46 ++++------ app/node/node.h | 29 ++----- app/node/output.cpp | 9 ++ app/node/output.h | 2 + app/node/output/timeline/tracklist.cpp | 8 +- app/node/output/track/track.cpp | 38 +++++++-- app/node/output/track/track.h | 3 + app/node/value.cpp | 34 ++++---- app/node/value.h | 4 +- app/project/item/sequence/sequence.cpp | 10 +-- app/render/backend/audio/audioworker.cpp | 12 --- app/render/backend/audio/audioworker.h | 4 - app/render/backend/audiorenderworker.cpp | 6 +- app/render/backend/audiorenderworker.h | 2 +- app/render/backend/opengl/openglbackend.cpp | 6 +- .../backend/opengl/openglshadercache.cpp | 22 ++--- app/render/backend/opengl/openglshadercache.h | 10 +-- app/render/backend/opengl/openglworker.cpp | 41 +++++---- app/render/backend/opengl/openglworker.h | 4 +- app/render/backend/renderbackend.cpp | 2 +- app/render/backend/renderworker.cpp | 84 ++++++------------- app/render/backend/renderworker.h | 33 +------- app/render/backend/videorenderworker.cpp | 16 ++-- app/render/backend/videorenderworker.h | 2 +- app/widget/timelinewidget/timelinewidget.cpp | 2 +- app/widget/timelinewidget/tool/import.cpp | 6 +- 45 files changed, 253 insertions(+), 407 deletions(-) diff --git a/app/node/blend/alphaover/alphaover.cpp b/app/node/blend/alphaover/alphaover.cpp index 4956cd189..0bd2f5592 100644 --- a/app/node/blend/alphaover/alphaover.cpp +++ b/app/node/blend/alphaover/alphaover.cpp @@ -45,23 +45,19 @@ QString AlphaOverBlend::Description() const return tr("A blending node that composites one texture over another using its alpha channel."); } -QString AlphaOverBlend::Code(NodeOutput *output) const +QString AlphaOverBlend::Code() const { - if (output == texture_output()) { - return "#version 110" - "\n" - "varying vec2 v_texcoord;\n" - "\n" - "uniform sampler2D base_in;\n" - "uniform sampler2D blend_in;\n" - "\n" - "void main(void) {\n" - " vec4 base_col = texture2D(base_in, v_texcoord);\n" - " vec4 blend_col = texture2D(blend_in, v_texcoord);\n" - " \n" - " gl_FragColor = base_col - blend_col.a + blend_col;\n" - "}\n"; - } - - return Node::Code(output); + return "#version 110" + "\n" + "varying vec2 v_texcoord;\n" + "\n" + "uniform sampler2D base_in;\n" + "uniform sampler2D blend_in;\n" + "\n" + "void main(void) {\n" + " vec4 base_col = texture2D(base_in, v_texcoord);\n" + " vec4 blend_col = texture2D(blend_in, v_texcoord);\n" + " \n" + " gl_FragColor = base_col - blend_col.a + blend_col;\n" + "}\n"; } diff --git a/app/node/blend/alphaover/alphaover.h b/app/node/blend/alphaover/alphaover.h index a6fb0af27..7289260c5 100644 --- a/app/node/blend/alphaover/alphaover.h +++ b/app/node/blend/alphaover/alphaover.h @@ -34,7 +34,7 @@ public: virtual QString id() const override; virtual QString Description() const override; - virtual QString Code(NodeOutput* output) const override; + virtual QString Code() const override; protected: diff --git a/app/node/blend/blend.cpp b/app/node/blend/blend.cpp index 7f06eb196..d5b790328 100644 --- a/app/node/blend/blend.cpp +++ b/app/node/blend/blend.cpp @@ -29,9 +29,6 @@ BlendNode::BlendNode() blend_input_ = new NodeInput("blend_in"); blend_input_->set_data_type(NodeParam::kTexture); AddParameter(blend_input_); - - texture_output_ = new NodeOutput("tex_out"); - AddParameter(texture_output_); } QString BlendNode::Category() const @@ -49,7 +46,8 @@ NodeInput *BlendNode::blend_input() const return blend_input_; } -NodeOutput *BlendNode::texture_output() const +void BlendNode::Retranslate() { - return texture_output_; + base_input_->set_name(tr("Base")); + blend_input_->set_name(tr("Blend")); } diff --git a/app/node/blend/blend.h b/app/node/blend/blend.h index bd65f9310..5dc84b834 100644 --- a/app/node/blend/blend.h +++ b/app/node/blend/blend.h @@ -34,14 +34,13 @@ public: NodeInput* blend_input() const; - NodeOutput* texture_output() const; + virtual void Retranslate() override; private: NodeInput* base_input_; NodeInput* blend_input_; - NodeOutput* texture_output_; }; #endif // BLEND_H diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 90718dd8b..d5936dc7b 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -26,11 +26,6 @@ Block::Block() : previous_(nullptr), next_(nullptr) { - block_output_ = new NodeOutput("this_out"); - AddParameter(block_output_); - - buffer_output_ = new NodeOutput("buffer_out"); - AddParameter(buffer_output_); } QString Block::Category() const @@ -109,16 +104,6 @@ void Block::set_next(Block *next) next_ = next; } -NodeOutput *Block::buffer_output() const -{ - return buffer_output_; -} - -NodeOutput *Block::block_output() const -{ - return block_output_; -} - const rational &Block::media_in() const { return media_in_; diff --git a/app/node/block/block.h b/app/node/block/block.h index c52ff5cc7..c8c71db0f 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -63,9 +63,6 @@ public: void set_previous(Block* previous); void set_next(Block* next); - NodeOutput* buffer_output() const; - NodeOutput* block_output() const; - const rational& media_in() const; void set_media_in(const rational& media_in); @@ -104,9 +101,6 @@ protected: Block* next_; private: - NodeOutput* block_output_; - NodeOutput* buffer_output_; - rational length_; rational media_in_; diff --git a/app/node/color/opacity/opacity.cpp b/app/node/color/opacity/opacity.cpp index 33400fd3b..af206c98e 100644 --- a/app/node/color/opacity/opacity.cpp +++ b/app/node/color/opacity/opacity.cpp @@ -32,9 +32,6 @@ OpacityNode::OpacityNode() texture_input_ = new NodeInput("tex_in"); texture_input_->set_data_type(NodeParam::kTexture); AddParameter(texture_input_); - - texture_output_ = new NodeOutput("tex_out"); - AddParameter(texture_output_); } Node *OpacityNode::copy() const @@ -67,30 +64,21 @@ void OpacityNode::Retranslate() opacity_input_->set_name(tr("Opacity")); } -QString OpacityNode::Code(NodeOutput *output) const +QString OpacityNode::Code() const { - if (output == texture_output()) { - return "#version 110" - "\n" - "varying vec2 olive_tex_coord;\n" - "\n" - "uniform sampler2D tex_in;\n" - "uniform float opacity_in;\n" - "\n" - "void main(void) {\n" - " gl_FragColor = texture2D(tex_in, olive_tex_coord) * (opacity_in * 0.01);\n" - "}\n"; - } - - return Node::Code(output); + return "#version 110" + "\n" + "varying vec2 olive_tex_coord;\n" + "\n" + "uniform sampler2D tex_in;\n" + "uniform float opacity_in;\n" + "\n" + "void main(void) {\n" + " gl_FragColor = texture2D(tex_in, olive_tex_coord) * (opacity_in * 0.01);\n" + "}\n"; } NodeInput *OpacityNode::texture_input() const { return texture_input_; } - -NodeOutput *OpacityNode::texture_output() const -{ - return texture_output_; -} diff --git a/app/node/color/opacity/opacity.h b/app/node/color/opacity/opacity.h index 12587e629..2eae10ff4 100644 --- a/app/node/color/opacity/opacity.h +++ b/app/node/color/opacity/opacity.h @@ -39,19 +39,15 @@ public: virtual void Retranslate() override; - virtual QString Code(NodeOutput* output) const override; + virtual QString Code() const override; NodeInput* texture_input() const; - NodeOutput* texture_output() const; - private: NodeInput* opacity_input_; NodeInput* texture_input_; - NodeOutput* texture_output_; - }; #endif // OPACITYNODE_H diff --git a/app/node/dependency.cpp b/app/node/dependency.cpp index c86e1e829..a8e98fa31 100644 --- a/app/node/dependency.cpp +++ b/app/node/dependency.cpp @@ -20,24 +20,26 @@ #include "dependency.h" +#include "node.h" + NodeDependency::NodeDependency() : node_(nullptr) { } -NodeDependency::NodeDependency(NodeOutput *node, const TimeRange &range) : +NodeDependency::NodeDependency(Node *node, const TimeRange &range) : node_(node), range_(range) { } -NodeDependency::NodeDependency(NodeOutput *node, const rational &in, const rational &out) : +NodeDependency::NodeDependency(Node *node, const rational &in, const rational &out) : node_(node), range_(in, out) { } -NodeOutput *NodeDependency::node() const +Node *NodeDependency::node() const { return node_; } diff --git a/app/node/dependency.h b/app/node/dependency.h index 718c5f6a2..eccce1d1f 100644 --- a/app/node/dependency.h +++ b/app/node/dependency.h @@ -24,21 +24,22 @@ #include #include "common/timerange.h" -#include "node/output.h" + +class Node; class NodeDependency { public: NodeDependency(); - NodeDependency(NodeOutput* node, const TimeRange& range); - NodeDependency(NodeOutput* node, const rational& in, const rational &out); + NodeDependency(Node* node, const TimeRange& range); + NodeDependency(Node* node, const rational& in, const rational &out); - NodeOutput* node() const; + Node* node() const; const rational& in() const; const rational& out() const; const TimeRange& range() const; private: - NodeOutput* node_; + Node* node_; TimeRange range_; }; diff --git a/app/node/distort/transform/transform.cpp b/app/node/distort/transform/transform.cpp index 7af53fc2e..a75d3c306 100644 --- a/app/node/distort/transform/transform.cpp +++ b/app/node/distort/transform/transform.cpp @@ -41,9 +41,6 @@ TransformDistort::TransformDistort() anchor_input_ = new NodeInput("anchor_in"); anchor_input_->set_data_type(NodeParam::kVec2); AddParameter(anchor_input_); - - matrix_output_ = new NodeOutput("matrix_out"); - AddParameter(matrix_output_); } Node *TransformDistort::copy() const @@ -71,11 +68,6 @@ QString TransformDistort::Description() const return tr("Apply transformations to position, rotation, and scale."); } -NodeOutput *TransformDistort::matrix_output() -{ - return matrix_output_; -} - void TransformDistort::Retranslate() { position_input_->set_name(tr("Position")); diff --git a/app/node/distort/transform/transform.h b/app/node/distort/transform/transform.h index ea9e30cd2..9683e233b 100644 --- a/app/node/distort/transform/transform.h +++ b/app/node/distort/transform/transform.h @@ -36,8 +36,6 @@ public: virtual QString Category() const override; virtual QString Description() const override; - NodeOutput* matrix_output(); - virtual void Retranslate() override; virtual NodeValueTable Value(const NodeValueDatabase& value) const override; @@ -51,8 +49,6 @@ private: NodeInput* anchor_input_; - NodeOutput* matrix_output_; - }; #endif // TRANSFORMDISTORT_H diff --git a/app/node/generator/solid/solid.cpp b/app/node/generator/solid/solid.cpp index 8352cc7b6..ad931b33d 100644 --- a/app/node/generator/solid/solid.cpp +++ b/app/node/generator/solid/solid.cpp @@ -26,9 +26,6 @@ SolidGenerator::SolidGenerator() : color_input_ = new NodeInput("color_in"); color_input_->set_data_type(NodeParam::kColor); AddParameter(color_input_); - - texture_output_ = new NodeOutput("tex_out"); - AddParameter(texture_output_); } Node *SolidGenerator::copy() const @@ -56,23 +53,14 @@ QString SolidGenerator::Description() const return tr("Generate a solid color."); } -NodeOutput *SolidGenerator::texture_output() const +QString SolidGenerator::Code() const { - return texture_output_; -} - -QString SolidGenerator::Code(NodeOutput *output) const -{ - if (output == texture_output()) { - // FIXME: Not color managed - return "#version 110\n" - "\n" - "uniform vec4 color_in;\n" - "\n" - "void main(void) {\n" - " gl_FragColor = color_in;\n" - "}\n"; - } - - return Node::Code(output); + // FIXME: Not color managed + return "#version 110\n" + "\n" + "uniform vec4 color_in;\n" + "\n" + "void main(void) {\n" + " gl_FragColor = color_in;\n" + "}\n"; } diff --git a/app/node/generator/solid/solid.h b/app/node/generator/solid/solid.h index bc31cad2d..8830dd5a5 100644 --- a/app/node/generator/solid/solid.h +++ b/app/node/generator/solid/solid.h @@ -41,15 +41,11 @@ public: virtual QString Category() const override; virtual QString Description() const override; - NodeOutput* texture_output() const; - - virtual QString Code(NodeOutput* output) const override; + virtual QString Code() const override; private: NodeInput* color_input_; - NodeOutput* texture_output_; - QOpenGLTexture* texture_; }; diff --git a/app/node/input.cpp b/app/node/input.cpp index 52dd14002..569af1dde 100644 --- a/app/node/input.cpp +++ b/app/node/input.cpp @@ -43,7 +43,7 @@ NodeParam::Type NodeInput::type() QString NodeInput::name() { if (name_.isEmpty()) { - return GetDefaultDataTypeName(data_type()); + return tr("Input"); } return NodeParam::name(); diff --git a/app/node/input/media/audio/audio.cpp b/app/node/input/media/audio/audio.cpp index 5b9b5e4f0..ccfb52f56 100644 --- a/app/node/input/media/audio/audio.cpp +++ b/app/node/input/media/audio/audio.cpp @@ -2,8 +2,6 @@ AudioInput::AudioInput() { - samples_output_ = new NodeOutput("samples_out"); - AddParameter(samples_output_); } Node *AudioInput::copy() const @@ -31,11 +29,6 @@ QString AudioInput::Description() const return tr("Import an audio footage stream."); } -NodeOutput *AudioInput::samples_output() -{ - return samples_output_; -} - NodeValueTable AudioInput::Value(const NodeValueDatabase &value) const { return value[footage_input_]; diff --git a/app/node/input/media/audio/audio.h b/app/node/input/media/audio/audio.h index 646dc2b48..641b4f8de 100644 --- a/app/node/input/media/audio/audio.h +++ b/app/node/input/media/audio/audio.h @@ -15,13 +15,10 @@ public: virtual QString Category() const override; virtual QString Description() const override; - NodeOutput* samples_output(); - protected: virtual NodeValueTable Value(const NodeValueDatabase& value) const override; private: - NodeOutput* samples_output_; }; #endif // AUDIOINPUT_H diff --git a/app/node/input/media/video/video.cpp b/app/node/input/media/video/video.cpp index 5e2483a71..015ab8c40 100644 --- a/app/node/input/media/video/video.cpp +++ b/app/node/input/media/video/video.cpp @@ -13,9 +13,6 @@ VideoInput::VideoInput() matrix_input_ = new NodeInput("matrix_in"); matrix_input_->set_data_type(NodeInput::kMatrix); AddParameter(matrix_input_); - - texture_output_ = new NodeOutput("tex_out"); - AddParameter(texture_output_); } Node *VideoInput::copy() const @@ -53,27 +50,18 @@ NodeInput *VideoInput::matrix_input() const return matrix_input_; } -NodeOutput *VideoInput::texture_output() const +QString VideoInput::Code() const { - return texture_output_; -} - -QString VideoInput::Code(NodeOutput *output) const -{ - if (output == texture_output()) { - return "#version 110\n" - "\n" - "varying vec2 v_texcoord;\n" - "\n" - "uniform sampler2D footage_in;\n" - "uniform mat4 matrix_in;\n" - "\n" - "void main(void) {\n" - " gl_FragColor = texture2D(footage_in, vec2(vec4(v_texcoord, 0.0, 1.0) * matrix_in));\n" - "}\n"; - } - - return Node::Code(output); + return "#version 110\n" + "\n" + "varying vec2 v_texcoord;\n" + "\n" + "uniform sampler2D footage_in;\n" + "uniform mat4 matrix_in;\n" + "\n" + "void main(void) {\n" + " gl_FragColor = texture2D(footage_in, vec2(vec4(v_texcoord, 0.0, 1.0) * matrix_in));\n" + "}\n"; } /* diff --git a/app/node/input/media/video/video.h b/app/node/input/media/video/video.h index 0a5589feb..c5d434b64 100644 --- a/app/node/input/media/video/video.h +++ b/app/node/input/media/video/video.h @@ -22,9 +22,7 @@ public: NodeInput* matrix_input() const; - NodeOutput* texture_output() const; - - virtual QString Code(NodeOutput* output) const override; + virtual QString Code() const override; //virtual void Hash(QCryptographicHash *hash, NodeOutput* from, const rational &time) override; @@ -33,8 +31,6 @@ protected: private: NodeInput* matrix_input_; - NodeOutput* texture_output_; - }; #endif // VIDEOINPUT_H diff --git a/app/node/node.cpp b/app/node/node.cpp index 13d9a7ebe..cfc21f0b3 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -23,9 +23,10 @@ #include Node::Node() : - last_processed_time_(-1), can_be_deleted_(true) { + output_ = new NodeOutput("node_out"); + AddParameter(output_); } Node::~Node() @@ -75,7 +76,13 @@ void Node::AddParameter(NodeParam *param) } param->setParent(this); - params_.append(param); + + // Keep main output as the last parameter, assume if there are no parameters that this is the output parameter + if (params_.isEmpty()) { + params_.append(param); + } else { + params_.insert(params_.size()-1, param); + } connect(param, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SIGNAL(EdgeAdded(NodeEdgePtr))); connect(param, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SIGNAL(EdgeRemoved(NodeEdgePtr))); @@ -232,32 +239,6 @@ bool Node::IsTrack() const return false; } -rational Node::LastProcessedTime() -{ - rational t; - - LockUserInput(); - - t = last_processed_time_; - - UnlockUserInput(); - - return t; -} - -NodeOutput *Node::LastProcessedOutput() -{ - NodeOutput* o; - - LockUserInput(); - - o = last_processed_parameter_; - - UnlockUserInput(); - - return o; -} - const QList& Node::parameters() const { return params_; @@ -345,10 +326,8 @@ QList Node::GetImmediateDependencies() const return node_list; } -QString Node::Code(NodeOutput *output) const +QString Node::Code() const { - Q_UNUSED(output) - return QString(); } @@ -425,6 +404,11 @@ bool Node::HasParamWithID(const QString &id) const return false; } +NodeOutput *Node::output() const +{ + return output_; +} + bool Node::HasParamOfType(NodeParam::Type type, bool must_be_connected) const { foreach (NodeParam* p, params_) { diff --git a/app/node/node.h b/app/node/node.h index 1f4593307..50db300e1 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -139,7 +139,7 @@ public: /** * @brief Generate OpenCL hardware accelerated code for this Node */ - virtual QString Code(NodeOutput* output) const; + virtual QString Code() const; /** * @brief Returns the parameter with the specified ID (or nullptr if it doesn't exist) @@ -264,6 +264,8 @@ public: */ bool HasParamWithID(const QString& id) const; + NodeOutput* output() const; + protected: /** * @brief Add a parameter to this node @@ -274,16 +276,6 @@ protected: */ void AddParameter(NodeParam* param); - /** - * @brief Retrieve the last timecode Process() was called with - */ - rational LastProcessedTime(); - - /** - * @brief Retrieve the last parameter Process() was called from - */ - NodeOutput* LastProcessedOutput(); - void ClearCachedValuesInParameters(const rational& start_range, const rational& end_range); void SendInvalidateCache(const rational& start_range, const rational& end_range); @@ -320,16 +312,6 @@ private: QList params_; - /** - * @brief The last timecode Process() was called with - */ - rational last_processed_time_; - - /** - * @brief The last parameter Process() was called from - */ - NodeOutput* last_processed_parameter_; - /** * @brief Used for thread safety from main thread */ @@ -340,6 +322,11 @@ private: */ bool can_be_deleted_; + /** + * @brief Primary node output + */ + NodeOutput* output_; + private slots: void InputChanged(rational start, rational end); diff --git a/app/node/output.cpp b/app/node/output.cpp index 81886b496..c70fae381 100644 --- a/app/node/output.cpp +++ b/app/node/output.cpp @@ -31,3 +31,12 @@ NodeParam::Type NodeOutput::type() { return kOutput; } + +QString NodeOutput::name() +{ + if (name_.isEmpty()) { + return tr("Output"); + } + + return NodeParam::name(); +} diff --git a/app/node/output.h b/app/node/output.h index 0fef86775..f7d86989f 100644 --- a/app/node/output.h +++ b/app/node/output.h @@ -40,6 +40,8 @@ public: */ virtual Type type() override; + virtual QString name() override; + private: }; diff --git a/app/node/output/timeline/tracklist.cpp b/app/node/output/timeline/tracklist.cpp index 066a733a0..80ab6f449 100644 --- a/app/node/output/timeline/tracklist.cpp +++ b/app/node/output/timeline/tracklist.cpp @@ -140,13 +140,13 @@ void TrackList::AddTrack() NodeParam::ConnectEdge(track->track_output(), current_last_track->track_input()); // FIXME: Test code only - if (current_last_track->buffer_output()->IsConnected()) { + if (current_last_track->output()->IsConnected()) { AlphaOverBlend* blend = new AlphaOverBlend(); GetParentGraph()->AddNode(blend); - NodeParam::ConnectEdge(track->buffer_output(), blend->blend_input()); - NodeParam::ConnectEdge(current_last_track->buffer_output(), blend->base_input()); - NodeParam::ConnectEdge(blend->texture_output(), current_last_track->buffer_output()->edges().first()->input()); + NodeParam::ConnectEdge(track->output(), blend->blend_input()); + NodeParam::ConnectEdge(current_last_track->output(), blend->base_input()); + NodeParam::ConnectEdge(blend->output(), current_last_track->output()->edges().first()->input()); } // End test code } diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index fd742fe5a..3e58671fd 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -148,6 +148,34 @@ Block *TrackOutput::NearestBlockAfter(const rational &time) const return nullptr; } +Block *TrackOutput::BlockAtTime(const rational &time) const +{ + foreach (Block* block, block_cache_) { + if (block + && block->in() <= time + && block->out() > time) { + return block; + } + } + + return nullptr; +} + +QList TrackOutput::BlocksAtTimeRange(const TimeRange &range) const +{ + QList list; + + foreach (Block* block, block_cache_) { + if (block + && block->out() > range.in() + && block->in() < range.out()) { + list.append(block); + } + } + + return list; +} + const QVector &TrackOutput::Blocks() const { return block_cache_; @@ -191,7 +219,7 @@ void TrackOutput::InsertBlockAtIndex(Block *block, int index) AddBlockToGraph(block); block_input_->InsertAt(index); - NodeParam::ConnectEdge(block->block_output(), + NodeParam::ConnectEdge(block->output(), block_input_->ParamAt(index)); } @@ -203,7 +231,7 @@ void TrackOutput::AppendBlock(Block *block) int last_index = block_input_->GetSize(); block_input_->Append(); - NodeParam::ConnectEdge(block->block_output(), + NodeParam::ConnectEdge(block->output(), block_input_->ParamAt(last_index)); UnblockInvalidateCache(); @@ -264,10 +292,10 @@ void TrackOutput::ReplaceBlock(Block *old, Block *replace) int index_of_old_block = block_cache_.indexOf(old); - NodeParam::DisconnectEdge(old->block_output(), + NodeParam::DisconnectEdge(old->output(), block_input_->ParamAt(index_of_old_block)); - NodeParam::ConnectEdge(replace->block_output(), + NodeParam::ConnectEdge(replace->output(), block_input_->ParamAt(index_of_old_block)); UnblockInvalidateCache(); @@ -277,7 +305,7 @@ void TrackOutput::ReplaceBlock(Block *old, Block *replace) TrackOutput *TrackOutput::TrackFromBlock(Block *block) { - NodeOutput* output = block->block_output(); + NodeOutput* output = block->output(); foreach (NodeEdgePtr edge, output->edges()) { Node* n = edge->input()->parentNode(); diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index 798c3ef35..84cbf9f58 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -60,6 +60,9 @@ public: Block* NearestBlockAfter(const rational& time) const; + Block* BlockAtTime(const rational& time) const; + QList BlocksAtTimeRange(const TimeRange& range) const; + const QVector& Blocks() const; virtual void InvalidateCache(const rational& start_range, const rational& end_range, NodeInput* from = nullptr) override; diff --git a/app/node/value.cpp b/app/node/value.cpp index 1388f860b..e3dd9de85 100644 --- a/app/node/value.cpp +++ b/app/node/value.cpp @@ -56,14 +56,28 @@ NodeValueTable::NodeValueTable() { } -QVariant NodeValueTable::Get(const NodeParam::DataType &type, const QString &tag) +QVariant NodeValueTable::Get(const NodeParam::DataType &type, const QString &tag) const { - return GetInternal(type, tag, false); + int value_index = GetInternal(type, tag); + + if (value_index >= 0) { + return values_.at(value_index).data(); + } + + return QVariant(); } QVariant NodeValueTable::Take(const NodeParam::DataType &type, const QString &tag) { - return GetInternal(type, tag, true); + int value_index = GetInternal(type, tag); + + if (value_index >= 0) { + QVariant val = values_.at(value_index).data(); + values_.removeAt(value_index); + return val; + } + + return QVariant(); } void NodeValueTable::Push(const NodeValue &value) @@ -113,8 +127,6 @@ NodeValueTable NodeValueTable::Merge(QList tables) NodeValueTable merged_table; - QHash::const_iterator iterator; - // Slipstreams all tables together // FIXME: I don't actually know if this is the right approach... foreach (const NodeValueTable& t, tables) { @@ -130,7 +142,7 @@ NodeValueTable NodeValueTable::Merge(QList tables) return merged_table; } -QVariant NodeValueTable::GetInternal(const NodeParam::DataType &type, const QString &tag, bool remove) +int NodeValueTable::GetInternal(const NodeParam::DataType &type, const QString &tag) const { int index = -1; @@ -146,13 +158,5 @@ QVariant NodeValueTable::GetInternal(const NodeParam::DataType &type, const QStr } } - if (index >= 0) { - if (remove) { - values_.removeAt(index); - } - - return values_.at(index).data(); - } - - return QVariant(); + return index; } diff --git a/app/node/value.h b/app/node/value.h index a4d6d876e..3c8d69f51 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -26,7 +26,7 @@ class NodeValueTable public: NodeValueTable(); - QVariant Get(const NodeParam::DataType& type, const QString& tag = QString()); + QVariant Get(const NodeParam::DataType& type, const QString& tag = QString()) const; QVariant Take(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()); @@ -40,7 +40,7 @@ public: static NodeValueTable Merge(QList tables); private: - QVariant GetInternal(const NodeParam::DataType& type, const QString& tag, bool remove); + int GetInternal(const NodeParam::DataType& type, const QString& tag) const; QList values_; diff --git a/app/project/item/sequence/sequence.cpp b/app/project/item/sequence/sequence.cpp index dd112f6b4..5048a4df0 100644 --- a/app/project/item/sequence/sequence.cpp +++ b/app/project/item/sequence/sequence.cpp @@ -73,15 +73,15 @@ void Sequence::add_default_nodes() AddNode(audio_track_output_); // Connect tracks to viewer - NodeParam::ConnectEdge(video_track_output_->buffer_output(), viewer_output_->texture_input()); - NodeParam::ConnectEdge(audio_track_output_->buffer_output(), viewer_output_->samples_input()); + NodeParam::ConnectEdge(video_track_output_->output(), viewer_output_->texture_input()); + NodeParam::ConnectEdge(audio_track_output_->output(), viewer_output_->samples_input()); // Connect timeline length to viewer - NodeParam::ConnectEdge(timeline_output_->length_output(), viewer_output_->length_input()); + NodeParam::ConnectEdge(timeline_output_->output(), viewer_output_->length_input()); // Connect track to timeline - NodeParam::ConnectEdge(video_track_output_->track_output(), timeline_output_->track_input(kTrackTypeVideo)); - NodeParam::ConnectEdge(audio_track_output_->track_output(), timeline_output_->track_input(kTrackTypeAudio)); + NodeParam::ConnectEdge(video_track_output_->output(), timeline_output_->track_input(kTrackTypeVideo)); + NodeParam::ConnectEdge(audio_track_output_->output(), timeline_output_->track_input(kTrackTypeAudio)); // Update the timebase on these nodes set_video_params(video_params_); diff --git a/app/render/backend/audio/audioworker.cpp b/app/render/backend/audio/audioworker.cpp index 333f8c03c..5b2567e32 100644 --- a/app/render/backend/audio/audioworker.cpp +++ b/app/render/backend/audio/audioworker.cpp @@ -9,15 +9,3 @@ QVariant AudioWorker::FrameToValue(FramePtr frame) { return frame->ToByteArray(); } - -bool AudioWorker::OutputIsAccelerated(NodeOutput *output) -{ - Q_UNUSED(output) - return false; -} - -NodeValueTable AudioWorker::RunNodeAccelerated(NodeOutput *output) -{ - Q_UNUSED(output) - return NodeValueTable(); -} diff --git a/app/render/backend/audio/audioworker.h b/app/render/backend/audio/audioworker.h index af3e9747b..ef27c5f93 100644 --- a/app/render/backend/audio/audioworker.h +++ b/app/render/backend/audio/audioworker.h @@ -11,10 +11,6 @@ public: protected: virtual QVariant FrameToValue(FramePtr frame) override; - virtual bool OutputIsAccelerated(NodeOutput *output) override; - - virtual NodeValueTable RunNodeAccelerated(NodeOutput *output) override; - private: }; diff --git a/app/render/backend/audiorenderworker.cpp b/app/render/backend/audiorenderworker.cpp index 0927cf153..61196027b 100644 --- a/app/render/backend/audiorenderworker.cpp +++ b/app/render/backend/audiorenderworker.cpp @@ -28,9 +28,9 @@ FramePtr AudioRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRa return decoder->RetrieveAudio(range.in(), range.out() - range.in(), audio_params_); } -NodeValueTable AudioRenderWorker::RenderBlock(NodeOutput* output, const TimeRange &range) +NodeValueTable AudioRenderWorker::RenderBlock(TrackOutput *track, const TimeRange &range) { - QList active_blocks = ValidateBlockRange(static_cast(output->parentNode()), range); + QList active_blocks = track->BlocksAtTimeRange(range); // All these blocks will need to output to a buffer so we create one here QByteArray block_range_buffer(audio_params_.time_to_bytes(range.length()), 0); @@ -42,7 +42,7 @@ NodeValueTable AudioRenderWorker::RenderBlock(NodeOutput* output, const TimeRang TimeRange range_for_block(qMax(b->in(), range.in()), qMin(b->out(), range.out())); - NodeValueTable table = RenderAsSibling(NodeDependency(b->block_output(), + NodeValueTable table = RenderAsSibling(NodeDependency(b, range_for_block)); QByteArray samples_from_this_block = table.Take(NodeParam::kSamples).toByteArray(); diff --git a/app/render/backend/audiorenderworker.h b/app/render/backend/audiorenderworker.h index cc7df4494..9aea9c154 100644 --- a/app/render/backend/audiorenderworker.h +++ b/app/render/backend/audiorenderworker.h @@ -18,7 +18,7 @@ protected: virtual FramePtr RetrieveFromDecoder(DecoderPtr decoder, const TimeRange& range) override; - virtual NodeValueTable RenderBlock(NodeOutput *output, const TimeRange& range) override; + virtual NodeValueTable RenderBlock(TrackOutput *track, const TimeRange& range) override; private: AudioRenderingParams audio_params_; diff --git a/app/render/backend/opengl/openglbackend.cpp b/app/render/backend/opengl/openglbackend.cpp index 73e37a750..5538cc4f3 100644 --- a/app/render/backend/opengl/openglbackend.cpp +++ b/app/render/backend/opengl/openglbackend.cpp @@ -83,12 +83,12 @@ bool OpenGLBackend::TraverseCompiling(Node *n) { foreach (NodeParam* param, n->parameters()) { if (param->type() == NodeParam::kInput && param->IsConnected()) { - NodeOutput* connected_output = static_cast(param)->get_connected_output(); + Node* connected_output = static_cast(param)->get_connected_node(); // Check if we have a shader or not if (shader_cache_.GetShader(connected_output) == nullptr) { // Since we don't have a shader, compile one now - QString node_code = connected_output->parentNode()->Code(connected_output); + QString node_code = connected_output->Code(); // If the node has no code, it mustn't be GPU accelerated if (!node_code.isEmpty()) { @@ -126,7 +126,7 @@ bool OpenGLBackend::TraverseCompiling(Node *n) } } - if (!TraverseCompiling(connected_output->parentNode())) { + if (!TraverseCompiling(connected_output)) { return false; } } diff --git a/app/render/backend/opengl/openglshadercache.cpp b/app/render/backend/opengl/openglshadercache.cpp index d02d7f7a1..e2f3d5cf9 100644 --- a/app/render/backend/opengl/openglshadercache.cpp +++ b/app/render/backend/opengl/openglshadercache.cpp @@ -2,33 +2,27 @@ #include "node/node.h" -OpenGLShaderCache::OpenGLShaderCache() -{ - -} - -QString OpenGLShaderCache::GenerateShaderID(NodeOutput *output) -{ - // Creates a unique identifier for this specific node and this specific output - return QString("%1:%2").arg(output->parentNode()->id(), output->id()); -} - void OpenGLShaderCache::Clear() { compiled_nodes_.clear(); } -void OpenGLShaderCache::AddShader(NodeOutput *output, OpenGLShaderPtr shader) +void OpenGLShaderCache::AddShader(Node *output, OpenGLShaderPtr shader) { compiled_nodes_.insert(GenerateShaderID(output), shader); } -OpenGLShaderPtr OpenGLShaderCache::GetShader(NodeOutput *output) +OpenGLShaderPtr OpenGLShaderCache::GetShader(Node *output) { return compiled_nodes_.value(GenerateShaderID(output)); } -bool OpenGLShaderCache::HasShader(NodeOutput *output) +QString OpenGLShaderCache::GenerateShaderID(Node *output) +{ + return output->id(); +} + +bool OpenGLShaderCache::HasShader(Node *output) { return compiled_nodes_.contains(GenerateShaderID(output)); } diff --git a/app/render/backend/opengl/openglshadercache.h b/app/render/backend/opengl/openglshadercache.h index c4bcd18fc..8626f31b2 100644 --- a/app/render/backend/opengl/openglshadercache.h +++ b/app/render/backend/opengl/openglshadercache.h @@ -12,18 +12,18 @@ class OpenGLShaderCache { public: - OpenGLShaderCache(); + OpenGLShaderCache() = default; void Clear(); - void AddShader(NodeOutput* output, OpenGLShaderPtr shader); + void AddShader(Node* output, OpenGLShaderPtr shader); - OpenGLShaderPtr GetShader(NodeOutput* output); + OpenGLShaderPtr GetShader(Node* output); - bool HasShader(NodeOutput* output); + bool HasShader(Node* output); private: - QString GenerateShaderID(NodeOutput* output); + QString GenerateShaderID(Node *output); QMap compiled_nodes_; diff --git a/app/render/backend/opengl/openglworker.cpp b/app/render/backend/opengl/openglworker.cpp index f2af33cac..ea805d7c1 100644 --- a/app/render/backend/opengl/openglworker.cpp +++ b/app/render/backend/opengl/openglworker.cpp @@ -63,11 +63,6 @@ QVariant OpenGLWorker::FrameToValue(FramePtr frame) return QVariant::fromValue(footage_tex); } -bool OpenGLWorker::OutputIsAccelerated(NodeOutput* output) -{ - return shader_cache_->HasShader(output); -} - void OpenGLWorker::CloseInternal() { buffer_.Destroy(); @@ -83,10 +78,13 @@ void OpenGLWorker::ParametersChangedEvent() } } -NodeValueTable OpenGLWorker::RunNodeAccelerated(NodeOutput *out) +void OpenGLWorker::RunNodeAccelerated(Node *node, const NodeValueDatabase *input_params, NodeValueTable *output_params) { - OpenGLShaderPtr shader = shader_cache_->GetShader(out); - Node* node = out->parentNode(); + OpenGLShaderPtr shader = shader_cache_->GetShader(node); + + if (shader == nullptr) { + return; + } // Create the output texture OpenGLTexturePtr output = std::make_shared(); @@ -109,35 +107,42 @@ NodeValueTable OpenGLWorker::RunNodeAccelerated(NodeOutput *out) // This variable is used in the shader, let's set it to our value NodeInput* input = static_cast(param); + + // Get value from database at this input + const NodeValueTable& input_data = (*input_params)[input]; + + // Try to get a value from it + QVariant value = input_data.Get(input->data_type()); + switch (input->data_type()) { case NodeInput::kInt: - shader->setUniformValue(variable_location, input->value().toInt()); + shader->setUniformValue(variable_location, value.toInt()); break; case NodeInput::kFloat: - shader->setUniformValue(variable_location, input->value().toFloat()); + shader->setUniformValue(variable_location, value.toFloat()); break; case NodeInput::kVec2: - shader->setUniformValue(variable_location, input->value().value()); + shader->setUniformValue(variable_location, value.value()); break; case NodeInput::kVec3: - shader->setUniformValue(variable_location, input->value().value()); + shader->setUniformValue(variable_location, value.value()); break; case NodeInput::kVec4: - shader->setUniformValue(variable_location, input->value().value()); + shader->setUniformValue(variable_location, value.value()); break; case NodeInput::kMatrix: - shader->setUniformValue(variable_location, input->value().value()); + shader->setUniformValue(variable_location, value.value()); break; case NodeInput::kColor: - shader->setUniformValue(variable_location, input->value().value()); + shader->setUniformValue(variable_location, value.value()); break; case NodeInput::kBoolean: - shader->setUniformValue(variable_location, input->value().toBool()); + shader->setUniformValue(variable_location, value.toBool()); break; case NodeInput::kTexture: case NodeInput::kFootage: { - OpenGLTexturePtr texture = input->value().value(); + OpenGLTexturePtr texture = value.value(); functions_->glActiveTexture(GL_TEXTURE0 + input_texture_count); @@ -192,7 +197,7 @@ NodeValueTable OpenGLWorker::RunNodeAccelerated(NodeOutput *out) functions_->glFinish(); - return QVariant::fromValue(output); + output_params->Push(NodeParam::kTexture, QVariant::fromValue(output)); } void OpenGLWorker::TextureToBuffer(const QVariant &tex_in, QByteArray &buffer) diff --git a/app/render/backend/opengl/openglworker.h b/app/render/backend/opengl/openglworker.h index 4ee18f766..99bba9f32 100644 --- a/app/render/backend/opengl/openglworker.h +++ b/app/render/backend/opengl/openglworker.h @@ -47,9 +47,7 @@ protected: virtual QVariant FrameToValue(FramePtr frame) override; - virtual bool OutputIsAccelerated(NodeOutput *output) override; - - virtual NodeValueTable RunNodeAccelerated(NodeOutput *output) override; + virtual void RunNodeAccelerated(Node *node, const NodeValueDatabase *input_params, NodeValueTable* output_params) override; virtual void TextureToBuffer(const QVariant& texture, QByteArray& buffer) override; diff --git a/app/render/backend/renderbackend.cpp b/app/render/backend/renderbackend.cpp index 8675946af..276ca666c 100644 --- a/app/render/backend/renderbackend.cpp +++ b/app/render/backend/renderbackend.cpp @@ -217,7 +217,7 @@ bool RenderBackend::GenerateData(const TimeRange &range) return false; } - NodeDependency dep = NodeDependency(GetDependentInput()->get_connected_output(), range.in(), range.out()); + NodeDependency dep = NodeDependency(GetDependentInput()->get_connected_node(), range.in(), range.out()); foreach (RenderWorker* worker, processors_) { if (worker->IsAvailable() || worker == processors_.last()) { diff --git a/app/render/backend/renderworker.cpp b/app/render/backend/renderworker.cpp index 2187ed71e..77dcb122b 100644 --- a/app/render/backend/renderworker.cpp +++ b/app/render/backend/renderworker.cpp @@ -44,8 +44,7 @@ void RenderWorker::Render(NodeDependency path) NodeValueTable RenderWorker::RenderAsSibling(NodeDependency dep) { - NodeOutput* output = dep.node(); - Node* node = output->parentNode(); + Node* node = dep.node(); QList connected_inputs; NodeValueTable value; @@ -54,13 +53,11 @@ NodeValueTable RenderWorker::RenderAsSibling(NodeDependency dep) // Firstly we check if this node is a "Block", if it is that means it's part of a linked list of mutually exclusive // nodes based on time and we might need to locate which Block to attach to - if (node->IsBlock() - && (dep.range().in() < static_cast(node)->in() - || dep.range().out() > static_cast(node)->out())) { + if (node->IsTrack()) { // If the range is not wholly contained in this Block, we'll need to do some extra processing - value = RenderBlock(output, dep.range()); + value = RenderBlock(static_cast(node), dep.range()); } else { - value = ProcessNodeNormally(NodeDependency(output, dep.range())); + value = ProcessNodeNormally(NodeDependency(node, dep.range())); } // We're done! @@ -76,54 +73,24 @@ DecoderCache *RenderWorker::decoder_cache() return decoder_cache_; } -Block *RenderWorker::ValidateBlock(Block *block, const rational& time) -{ - Q_ASSERT(block != nullptr && time >= 0); - - while (block->in() > time) { - // This Block is too late, find an earlier one - block = block->previous(); - } - - while (block->out() <= time) { - // This block is too early, find a later one - if (block->next() == nullptr) { - break; - } - - block = block->next(); - } - - // By this point, we should have the correct Block or nullptr if there's no Block here - return block; -} - -QList RenderWorker::ValidateBlockRange(Block *n, const TimeRange &range) -{ - QList list; - Block* block_at_start = ValidateBlock(n, range.in()); - Block* block_at_end = ValidateBlock(n, range.out()); - - list.append(block_at_start); - - // If more than one block is active for this range - if (block_at_start != block_at_end) { - - // Collect all blocks between the start and the end - do { - block_at_start = block_at_start->next(); - list.append(block_at_start); - } while (block_at_start != block_at_end); - } - - return list; -} - NodeValueTable RenderWorker::RenderInternal(const NodeDependency &path) { return RenderAsSibling(path); } +bool RenderWorker::OutputIsAccelerated(Node *output) +{ + Q_UNUSED(output) + return false; +} + +void RenderWorker::RunNodeAccelerated(Node *node, const NodeValueDatabase *input_params, NodeValueTable* output_params) +{ + Q_UNUSED(node) + Q_UNUSED(input_params) + Q_UNUSED(output_params) +} + StreamPtr RenderWorker::ResolveStreamFromInput(NodeInput *input) { return input->get_value_at_time(0).value(); @@ -152,8 +119,7 @@ bool RenderWorker::IsStarted() NodeValueTable RenderWorker::ProcessNodeNormally(const NodeDependency& dep) { - NodeOutput* output = dep.node(); - Node* node = dep.node()->parentNode(); + Node* node = dep.node(); //qDebug() << "Processing" << node->id(); @@ -170,7 +136,7 @@ NodeValueTable RenderWorker::ProcessNodeNormally(const NodeDependency& dep) if (input->IsConnected()) { // Value will equal something from the connected node, follow it - table = ProcessNodeNormally(NodeDependency(input->get_connected_output(), + table = ProcessNodeNormally(NodeDependency(input->get_connected_node(), input_time)); } else { // Push onto the table the value at this time from the input @@ -184,12 +150,10 @@ NodeValueTable RenderWorker::ProcessNodeNormally(const NodeDependency& dep) // By this point, the node should have all the inputs it needs to render correctly + NodeValueTable table = node->Value(database); + // Check if we have a shader for this output - if (OutputIsAccelerated(output)) { - // Run code - return RunNodeAccelerated(output); - } else { - // Generate the value as expected - return node->Value(database); - } + RunNodeAccelerated(node, &database, &table); + + return table; } diff --git a/app/render/backend/renderworker.h b/app/render/backend/renderworker.h index 83ff2bb84..6f14d72ae 100644 --- a/app/render/backend/renderworker.h +++ b/app/render/backend/renderworker.h @@ -4,7 +4,7 @@ #include #include "common/constructors.h" -#include "node/block/block.h" +#include "node/output/track/track.h" #include "node/node.h" #include "decodercache.h" @@ -35,40 +35,15 @@ signals: void CompletedCache(NodeDependency dep, NodeValueTable data); protected: - /** - * @brief Returns the block in a sequence that is active at a given time - * - * Blocks are connected to each other previous/next to create a BlockList or a sequence of blocks. The block that - * is currently "active" depends on the time and only one block in a track can be active at any given time. - * - * Calling this function with a block and a time will traverse the provided block's track to find the block that will - * be active at that time. The block must be valid (non-null) and the time must be valid (>= 0). - * - * This function may return the same block that it was called with. It will never return nullptr. - */ - Block *ValidateBlock(Block* block, const rational& time); - - /** - * @brief Returns all the blocks that could be active within a range of time - * - * Similar to ValidateBlock() but rather than returning one block for a single time, this function returns a list of - * blocks that could be active within a range of time. - * - * The block must be valid (non-null) and the time must be valid (>= 0). - * - * The list will always contain at least one entry. - */ - QList ValidateBlockRange(Block* n, const TimeRange& range); - virtual bool InitInternal() = 0; virtual void CloseInternal() = 0; virtual NodeValueTable RenderInternal(const NodeDependency& path); - virtual bool OutputIsAccelerated(NodeOutput *output) = 0; + virtual bool OutputIsAccelerated(Node *output); - virtual NodeValueTable RunNodeAccelerated(NodeOutput *output) = 0; + virtual void RunNodeAccelerated(Node *node, const NodeValueDatabase *input_params, NodeValueTable* output_params); StreamPtr ResolveStreamFromInput(NodeInput* input); DecoderPtr ResolveDecoderFromInput(NodeInput* input); @@ -79,7 +54,7 @@ protected: NodeValueTable ProcessNodeNormally(const NodeDependency &dep); - virtual NodeValueTable RenderBlock(NodeOutput *output, const TimeRange& range) = 0; + virtual NodeValueTable RenderBlock(TrackOutput *track, const TimeRange& range) = 0; DecoderCache* decoder_cache(); diff --git a/app/render/backend/videorenderworker.cpp b/app/render/backend/videorenderworker.cpp index 67dfffb0b..d5b6a399c 100644 --- a/app/render/backend/videorenderworker.cpp +++ b/app/render/backend/videorenderworker.cpp @@ -21,7 +21,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path) // Get hash of node graph // We use SHA-1 for speed (benchmarks show it's the fastest hash available to us) QCryptographicHash hasher(QCryptographicHash::Sha1); - HashNodeRecursively(&hasher, path.node()->parentNode(), path.in()); + HashNodeRecursively(&hasher, path.node(), path.in()); QByteArray hash = hasher.result(); NodeValueTable value; @@ -50,8 +50,12 @@ FramePtr VideoRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRa void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, Node* n, const rational& time) { // Resolve BlockList - if (n->IsBlock()) { - n = ValidateBlock(static_cast(n), time); + if (n->IsTrack()) { + n = static_cast(n)->BlockAtTime(time); + + if (!n) { + return; + } } // Add this Node's ID @@ -153,15 +157,15 @@ void VideoRenderWorker::Download(NodeDependency dep, QByteArray hash, QVariant t working_--; } -NodeValueTable VideoRenderWorker::RenderBlock(NodeOutput* output, const TimeRange &range) +NodeValueTable VideoRenderWorker::RenderBlock(TrackOutput *track, const TimeRange &range) { // A frame can only have one active block so we just validate the in point of the range - Block* active_block = ValidateBlock(static_cast(output->parentNode()), range.in()); + Block* active_block = track->BlockAtTime(range.in()); NodeValueTable table; if (active_block) { - table = RenderAsSibling(NodeDependency(active_block->block_output(), + table = RenderAsSibling(NodeDependency(active_block, range)); } diff --git a/app/render/backend/videorenderworker.h b/app/render/backend/videorenderworker.h index 7efe595fb..7ed95ec5b 100644 --- a/app/render/backend/videorenderworker.h +++ b/app/render/backend/videorenderworker.h @@ -42,7 +42,7 @@ protected: virtual FramePtr RetrieveFromDecoder(DecoderPtr decoder, const TimeRange& range) override; - virtual NodeValueTable RenderBlock(NodeOutput *output, const TimeRange& range) override; + virtual NodeValueTable RenderBlock(TrackOutput *track, const TimeRange& range) override; private: void ProcessNode(); diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 0bb0971e1..ecf24e6e8 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -315,7 +315,7 @@ void TimelineWidget::SplitAtPlayhead() foreach (TrackOutput* track, timeline_node_->Tracks()) { Block* b = track->BlockContainingTime(playhead_time); - if (b != nullptr) { + if (b) { bool selected = false; // See if this block is selected diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index d085778c6..1a4b4ad53 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -225,10 +225,10 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) { VideoInput* video_input = new VideoInput(); video_input->SetFootage(footage_stream); - NodeParam::ConnectEdge(video_input->texture_output(), clip->texture_input()); + NodeParam::ConnectEdge(video_input->output(), clip->texture_input()); TransformDistort* transform = new TransformDistort(); - NodeParam::ConnectEdge(transform->matrix_output(), video_input->matrix_input()); + NodeParam::ConnectEdge(transform->output(), video_input->matrix_input()); //OpacityNode* opacity = new OpacityNode(); //NodeParam::ConnectEdge(opacity->texture_output(), clip->texture_input()); @@ -239,7 +239,7 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) { AudioInput* audio_input = new AudioInput(); audio_input->SetFootage(footage_stream); - NodeParam::ConnectEdge(audio_input->samples_output(), clip->texture_input()); + NodeParam::ConnectEdge(audio_input->output(), clip->texture_input()); break; } default: