From c32a1c8be26d7c19aed294f8c12567540e18357c Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 6 Dec 2019 04:21:55 +1100 Subject: [PATCH] removed last of the NodeOutput dependencies Since all Nodes have an output that provides all output values now, we now never need to add an output from a Node derivative. These changes remove the last of them and disable the ability to add more outputs from a derivative. --- app/node/blend/blend.cpp | 4 +- app/node/block/clip/clip.cpp | 6 +- app/node/color/opacity/opacity.cpp | 5 +- app/node/distort/transform/transform.cpp | 8 +- app/node/generator/solid/solid.cpp | 8 +- app/node/generator/solid/solid.h | 2 + app/node/input/media/media.cpp | 7 +- app/node/input/media/media.h | 2 + app/node/input/media/video/video.cpp | 189 +---------------------- app/node/input/media/video/video.h | 2 +- app/node/node.cpp | 5 + app/node/node.h | 18 ++- app/node/output/timeline/timeline.cpp | 35 +++-- app/node/output/timeline/timeline.h | 6 +- app/node/output/timeline/tracklist.cpp | 4 +- app/node/output/track/track.cpp | 12 +- app/node/output/track/track.h | 4 - app/node/output/viewer/viewer.cpp | 6 +- 18 files changed, 83 insertions(+), 240 deletions(-) diff --git a/app/node/blend/blend.cpp b/app/node/blend/blend.cpp index d5b790328..1d18439fd 100644 --- a/app/node/blend/blend.cpp +++ b/app/node/blend/blend.cpp @@ -24,11 +24,11 @@ BlendNode::BlendNode() { base_input_ = new NodeInput("base_in"); base_input_->set_data_type(NodeParam::kTexture); - AddParameter(base_input_); + AddInput(base_input_); blend_input_ = new NodeInput("blend_in"); blend_input_->set_data_type(NodeParam::kTexture); - AddParameter(blend_input_); + AddInput(blend_input_); } QString BlendNode::Category() const diff --git a/app/node/block/clip/clip.cpp b/app/node/block/clip/clip.cpp index 7d9541bf8..4a283c8dd 100644 --- a/app/node/block/clip/clip.cpp +++ b/app/node/block/clip/clip.cpp @@ -22,9 +22,9 @@ ClipBlock::ClipBlock() { - texture_input_ = new NodeInput("tex_in"); - texture_input_->set_data_type(NodeInput::kTexture); - AddParameter(texture_input_); + texture_input_ = new NodeInput("buffer_in"); + texture_input_->set_data_type(NodeInput::kBuffer); + AddInput(texture_input_); } Node *ClipBlock::copy() const diff --git a/app/node/color/opacity/opacity.cpp b/app/node/color/opacity/opacity.cpp index af206c98e..da579b53a 100644 --- a/app/node/color/opacity/opacity.cpp +++ b/app/node/color/opacity/opacity.cpp @@ -27,11 +27,11 @@ OpacityNode::OpacityNode() opacity_input_->set_value_at_time(0, 100); opacity_input_->set_minimum(0); opacity_input_->set_maximum(100); - AddParameter(opacity_input_); + AddInput(opacity_input_); texture_input_ = new NodeInput("tex_in"); texture_input_->set_data_type(NodeParam::kTexture); - AddParameter(texture_input_); + AddInput(texture_input_); } Node *OpacityNode::copy() const @@ -62,6 +62,7 @@ QString OpacityNode::id() const void OpacityNode::Retranslate() { opacity_input_->set_name(tr("Opacity")); + texture_input_->set_name(tr("Texture")); } QString OpacityNode::Code() const diff --git a/app/node/distort/transform/transform.cpp b/app/node/distort/transform/transform.cpp index a75d3c306..9ae83e576 100644 --- a/app/node/distort/transform/transform.cpp +++ b/app/node/distort/transform/transform.cpp @@ -27,20 +27,20 @@ TransformDistort::TransformDistort() { position_input_ = new NodeInput("pos_in"); position_input_->set_data_type(NodeParam::kVec2); - AddParameter(position_input_); + AddInput(position_input_); rotation_input_ = new NodeInput("rot_in"); rotation_input_->set_data_type(NodeParam::kFloat); - AddParameter(rotation_input_); + AddInput(rotation_input_); scale_input_ = new NodeInput("scale_in"); scale_input_->set_data_type(NodeParam::kVec2); scale_input_->set_value_at_time(0, QVector2D(100.0f, 100.0f)); - AddParameter(scale_input_); + AddInput(scale_input_); anchor_input_ = new NodeInput("anchor_in"); anchor_input_->set_data_type(NodeParam::kVec2); - AddParameter(anchor_input_); + AddInput(anchor_input_); } Node *TransformDistort::copy() const diff --git a/app/node/generator/solid/solid.cpp b/app/node/generator/solid/solid.cpp index ad931b33d..63c2d4b63 100644 --- a/app/node/generator/solid/solid.cpp +++ b/app/node/generator/solid/solid.cpp @@ -25,7 +25,7 @@ SolidGenerator::SolidGenerator() : { color_input_ = new NodeInput("color_in"); color_input_->set_data_type(NodeParam::kColor); - AddParameter(color_input_); + AddInput(color_input_); } Node *SolidGenerator::copy() const @@ -55,7 +55,6 @@ QString SolidGenerator::Description() const QString SolidGenerator::Code() const { - // FIXME: Not color managed return "#version 110\n" "\n" "uniform vec4 color_in;\n" @@ -64,3 +63,8 @@ QString SolidGenerator::Code() const " gl_FragColor = color_in;\n" "}\n"; } + +void SolidGenerator::Retranslate() +{ + color_input_->set_name(tr("Color")); +} diff --git a/app/node/generator/solid/solid.h b/app/node/generator/solid/solid.h index 8830dd5a5..1c8cc7106 100644 --- a/app/node/generator/solid/solid.h +++ b/app/node/generator/solid/solid.h @@ -43,6 +43,8 @@ public: virtual QString Code() const override; + virtual void Retranslate() override; + private: NodeInput* color_input_; diff --git a/app/node/input/media/media.cpp b/app/node/input/media/media.cpp index c2f85a3ab..7bb66f79f 100644 --- a/app/node/input/media/media.cpp +++ b/app/node/input/media/media.cpp @@ -24,7 +24,7 @@ MediaInput::MediaInput() { footage_input_ = new NodeInput("footage_in"); footage_input_->set_data_type(NodeInput::kFootage); - AddParameter(footage_input_); + AddInput(footage_input_); } StreamPtr MediaInput::footage() @@ -36,3 +36,8 @@ void MediaInput::SetFootage(StreamPtr f) { footage_input_->set_value_at_time(0, QVariant::fromValue(f)); } + +void MediaInput::Retranslate() +{ + footage_input_->set_name(tr("Footage")); +} diff --git a/app/node/input/media/media.h b/app/node/input/media/media.h index 7334de176..be08e14c0 100644 --- a/app/node/input/media/media.h +++ b/app/node/input/media/media.h @@ -36,6 +36,8 @@ public: StreamPtr footage(); void SetFootage(StreamPtr f); + virtual void Retranslate() override; + protected: NodeInput* footage_input_; diff --git a/app/node/input/media/video/video.cpp b/app/node/input/media/video/video.cpp index 015ab8c40..cbd91dfa4 100644 --- a/app/node/input/media/video/video.cpp +++ b/app/node/input/media/video/video.cpp @@ -12,7 +12,7 @@ VideoInput::VideoInput() { matrix_input_ = new NodeInput("matrix_in"); matrix_input_->set_data_type(NodeInput::kMatrix); - AddParameter(matrix_input_); + AddInput(matrix_input_); } Node *VideoInput::copy() const @@ -64,190 +64,9 @@ QString VideoInput::Code() const "}\n"; } -/* -void VideoInput::Hash(QCryptographicHash *hash, NodeOutput *from, const rational &time) +void VideoInput::Retranslate() { - Node::Hash(hash, from, time); + MediaInput::Retranslate(); - // Use frame value from Decoder - if (from == texture_output_) { - if (!SetupDecoder()) { - qDebug() << "Failed to setup decoder for hashing"; - return; - } - - int64_t timestamp = decoder_->GetTimestampFromTime(time); - - QByteArray pts_bytes; - pts_bytes.resize(sizeof(int64_t)); - memcpy(pts_bytes.data(), ×tamp, sizeof(int64_t)); - - hash->addData(pts_bytes); - // FIXME: Add OCIO data - // FIXME: Add alpha association value - } + matrix_input_->set_name(tr("Transform")); } - -QVariant VideoInput::Value(NodeOutput *output, const rational &in, const rational &out) -{ - Q_UNUSED(out) - - if (output == texture_output_) { - if (footage() == nullptr - || (footage()->type() != Stream::kVideo && footage()->type() != Stream::kImage)) { - return 0; - } - - // FIXME: Hardcoded value - bool alpha_is_associated = false; - - // Find the current Renderer instance - RenderInstance* renderer = VideoRendererProcessor::CurrentInstance(); - - // If nothing is available, don't return a texture - if (renderer == nullptr) { - return 0; - } - - // Make sure decoder is set up - if (!SetupDecoder()) { - return 0; - } - - // Check if we need to get a frame or not - if (frame_ == nullptr || frame_->native_timestamp() != decoder_->GetTimestampFromTime(in)) { - // Get frame from Decoder - frame_ = decoder_->Retrieve(in); - - if (frame_ == nullptr) { - qDebug() << "Received a null frame while time was" << in.toDouble(); - return 0; - } - - if (color_processor_ == nullptr) { - QString colorspace = std::static_pointer_cast(footage())->colorspace(); - if (colorspace.isEmpty()) { - // FIXME: Should use Footage() to find the Project* it belongs to instead of this - colorspace = olive::core.GetActiveProject()->default_input_colorspace(); - } - - color_processor_ = ColorProcessor::Create(colorspace, OCIO::ROLE_SCENE_LINEAR); - } - - // OpenColorIO v1's color transforms can be done on GPU, which improves performance but reduces accuracy. When - // online, we prefer accuracy over performance so we use the CPU path instead: - // NOTE: OCIO v2 boasts 1:1 results with the CPU and GPU path so this won't be necessary forever - if (renderer->params().mode() == olive::RenderMode::kOnline) { - // Convert to 32F, which is required for OpenColorIO's color transformation - frame_ = PixelService::ConvertPixelFormat(frame_, olive::PIX_FMT_RGBA32F); - - if (alpha_is_associated) { - // Unassociate alpha here if associated - ColorManager::DisassociateAlpha(frame_); - } - - // Transform color to reference space - color_processor_->ConvertFrame(frame_); - - if (alpha_is_associated) { - // If alpha was associated, reassociate here - ColorManager::ReassociateAlpha(frame_); - } else { - // If alpha was not associated, associate here - ColorManager::AssociateAlpha(frame_); - } - } - - // We use an internal texture to bring the texture into GPU space before performing transformations - - // Ensure the texture is the accurate to the frame - if (internal_tex_.width() != frame_->width() - || internal_tex_.height() != frame_->height() - || internal_tex_.format() != frame_->format()) { - internal_tex_.Destroy(); - } - - // Create or upload the new data to the texture - if (!internal_tex_.IsCreated()) { - internal_tex_.Create(renderer->context(), - frame_->width(), - frame_->height(), - static_cast(frame_->format()), - frame_->data()); - } else { - internal_tex_.Upload(frame_->data()); - } - } - - // Create new texture in reference space to send throughout the rest of the graph - - RenderTexturePtr output_texture = std::make_shared(); - - output_texture->Create(renderer->context(), - renderer->params().effective_width(), - renderer->params().effective_height(), - renderer->params().format(), - RenderTexture::kDoubleBuffer); - - // Using the transformation matrix, blit our internal texture (in frame format) to our output texture (in - // reference format) - - if (renderer->params().mode() == olive::RenderMode::kOffline) { - // For offline rendering, OCIO's GPU path is acceptable: - // NOTE: OCIO v2 boasts 1:1 results with the CPU and GPU path so this won't be necessary forever - - // Use an OCIO pipeline shader (which wraps in a default pipeline and will also handle alpha association) - if (pipeline_ == nullptr) { - pipeline_ = olive::ShaderGenerator::OCIOPipeline(renderer->context(), - ocio_texture_, // FIXME: A raw GLuint texture, should wrap this up - color_processor_->GetProcessor(), - alpha_is_associated); - - // Used for cleanup later - ocio_ctx_ = renderer->context(); - } - } else if (pipeline_ == nullptr) { - // In online, the color transformation was performed on the CPU (see above), so we only need to blit - pipeline_ = olive::ShaderGenerator::DefaultPipeline(); - } - - renderer->context()->functions()->glBlendFunc(GL_ONE, GL_ZERO); - - // Draw onto the output texture using the renderer's framebuffer - renderer->buffer()->Attach(output_texture); - renderer->buffer()->Bind(); - - // Draw with the internal texture - internal_tex_.Bind(); - - QMatrix4x4 transform; - - // Scale texture to a square for incoming matrix transformation - transform.scale(2.0f / static_cast(renderer->params().width()), - 2.0f / static_cast(renderer->params().height())); - - // Multiply by input transformation - transform *= matrix_input_->get_value(in).value(); - - // Scale texture to the media size - transform.scale(static_cast(frame_->width()), static_cast(frame_->height())); - transform.scale(0.5f, 0.5f); - - // Use pipeline to blit using transformation matrix from input - if (renderer->params().mode() == olive::RenderMode::kOffline) { - olive::gl::OCIOBlit(pipeline_, ocio_texture_, false, transform); - } else { - olive::gl::Blit(pipeline_, false, transform); - } - - // Release everything - internal_tex_.Release(); - renderer->buffer()->Detach(); - renderer->buffer()->Release(); - - return QVariant::fromValue(output_texture); - } - - return 0; -} -*/ diff --git a/app/node/input/media/video/video.h b/app/node/input/media/video/video.h index c5d434b64..1f666ae09 100644 --- a/app/node/input/media/video/video.h +++ b/app/node/input/media/video/video.h @@ -24,7 +24,7 @@ public: virtual QString Code() const override; - //virtual void Hash(QCryptographicHash *hash, NodeOutput* from, const rational &time) override; + virtual void Retranslate() override; protected: diff --git a/app/node/node.cpp b/app/node/node.cpp index 2a97df553..527e5f2e1 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -442,6 +442,11 @@ NodeOutput *Node::output() const return output_; } +void Node::AddInput(NodeInput *input) +{ + AddParameter(input); +} + 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 86b86bf1f..3cd1f752f 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -267,14 +267,7 @@ public: NodeOutput* output() const; protected: - /** - * @brief Add a parameter to this node - * - * The Node takes ownership of this parameter. - * - * This can be either an output or an input at any time. Parameters will always appear in the order they're added. - */ - void AddParameter(NodeParam* param); + void AddInput(NodeInput* input); void ClearCachedValuesInParameters(const rational& start_range, const rational& end_range); @@ -304,6 +297,15 @@ signals: void EdgeRemoved(NodeEdgePtr edge); private: + /** + * @brief Add a parameter to this node + * + * The Node takes ownership of this parameter. + * + * This can be either an output or an input at any time. Parameters will always appear in the order they're added. + */ + void AddParameter(NodeParam* param); + bool HasParamOfType(NodeParam::Type type, bool must_be_connected) const; void ConnectInput(NodeInput* input); diff --git a/app/node/output/timeline/timeline.cpp b/app/node/output/timeline/timeline.cpp index d08bf07e6..0d3becb43 100644 --- a/app/node/output/timeline/timeline.cpp +++ b/app/node/output/timeline/timeline.cpp @@ -35,7 +35,7 @@ TimelineOutput::TimelineOutput() for (int i=0;i(i), track_input); @@ -47,9 +47,6 @@ TimelineOutput::TimelineOutput() connect(list, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(TrackListAddedTrack(TrackOutput*))); connect(list, SIGNAL(TrackRemoved(TrackOutput*)), this, SIGNAL(TrackRemoved(TrackOutput*))); } - - length_output_ = new NodeOutput("length_out"); - AddParameter(length_output_); } Node *TimelineOutput::copy() const @@ -87,11 +84,6 @@ const QVector& TimelineOutput::Tracks() const return track_cache_; } -NodeOutput *TimelineOutput::length_output() const -{ - return length_output_; -} - const rational &TimelineOutput::timeline_length() const { return length_; @@ -152,6 +144,31 @@ void TimelineOutput::SetTimebase(const rational &timebase) emit TimebaseChanged(timebase_); } +void TimelineOutput::Retranslate() +{ + for (int i=0;i(i)) { + case kTrackTypeVideo: + input_name = tr("Video Tracks"); + break; + case kTrackTypeAudio: + input_name = tr("Audio Tracks"); + break; + case kTrackTypeSubtitle: + input_name = tr("Subtitle Tracks"); + break; + case kTrackTypeNone: + case kTrackTypeCount: + break; + } + + if (!input_name.isEmpty()) + track_inputs_.at(i)->set_name(input_name); + } +} + NodeInput *TimelineOutput::track_input(TrackType type) const { return track_inputs_.at(type); diff --git a/app/node/output/timeline/timeline.h b/app/node/output/timeline/timeline.h index 35fd00184..4b69397f2 100644 --- a/app/node/output/timeline/timeline.h +++ b/app/node/output/timeline/timeline.h @@ -52,14 +52,14 @@ public: TrackList* track_list(TrackType type) const; - NodeOutput* length_output() const; - const rational& timeline_length() const; const rational& timebase() const; void SetTimebase(const rational &timebase); + virtual void Retranslate() override; + signals: void LengthChanged(const rational& length); void TimebaseChanged(const rational &timebase); @@ -80,8 +80,6 @@ private: QVector track_cache_; - NodeOutput* length_output_; - rational length_; rational timebase_; diff --git a/app/node/output/timeline/tracklist.cpp b/app/node/output/timeline/tracklist.cpp index 80ab6f449..93e4d3f47 100644 --- a/app/node/output/timeline/tracklist.cpp +++ b/app/node/output/timeline/tracklist.cpp @@ -132,12 +132,12 @@ void TrackList::AddTrack() if (track_cache_.isEmpty()) { // Connect this track directly to this output - NodeParam::ConnectEdge(track->track_output(), track_input_); + NodeParam::ConnectEdge(track->output(), track_input_); } else { TrackOutput* current_last_track = track_cache_.last(); // Connect this track to the current last track - NodeParam::ConnectEdge(track->track_output(), current_last_track->track_input()); + NodeParam::ConnectEdge(track->output(), current_last_track->track_input()); // FIXME: Test code only if (current_last_track->output()->IsConnected()) { diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 3e58671fd..a86131491 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -31,17 +31,14 @@ TrackOutput::TrackOutput() : index_(-1) { block_input_ = new NodeInputArray("block_in"); - AddParameter(block_input_); + AddInput(block_input_); connect(block_input_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(BlockConnected(NodeEdgePtr))); connect(block_input_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(BlockDisconnected(NodeEdgePtr))); connect(block_input_, SIGNAL(SizeChanged(int)), this, SLOT(BlockListSizeChanged(int))); track_input_ = new NodeInput("track_in"); track_input_->set_dependent(false); - AddParameter(track_input_); - - track_output_ = new NodeOutput("track_out"); - AddParameter(track_output_); + AddInput(track_input_); } void TrackOutput::set_track_type(const TrackType &track_type) @@ -106,11 +103,6 @@ NodeInput *TrackOutput::track_input() return track_input_; } -NodeOutput* TrackOutput::track_output() -{ - return track_output_; -} - Block *TrackOutput::BlockContainingTime(const rational &time) const { foreach (Block* block, block_cache_) { diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index 84cbf9f58..904574aae 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -52,8 +52,6 @@ public: NodeInput* track_input(); - NodeOutput* track_output(); - Block* BlockContainingTime(const rational& time) const; Block* NearestBlockBefore(const rational& time) const; @@ -160,8 +158,6 @@ private: NodeInput* track_input_; - NodeOutput* track_output_; - TrackType track_type_; rational track_length_; diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 6541534fb..341ecd993 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -24,15 +24,15 @@ ViewerOutput::ViewerOutput() { texture_input_ = new NodeInput("tex_in"); texture_input_->set_data_type(NodeInput::kTexture); - AddParameter(texture_input_); + AddInput(texture_input_); samples_input_ = new NodeInput("samples_in"); samples_input_->set_data_type(NodeInput::kSamples); - AddParameter(samples_input_); + AddInput(samples_input_); length_input_ = new NodeInput("length_in"); length_input_->set_data_type(NodeInput::kRational); - AddParameter(length_input_); + AddInput(length_input_); } Node *ViewerOutput::copy() const