From 78d96ecd281942740de7c5812a5089d14599a477 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 20 Aug 2019 18:13:34 +1000 Subject: [PATCH] implemented splicing into the timeline --- app/node/block/block.cpp | 15 ++++++++++ app/node/block/block.h | 5 ++++ app/node/block/clip/clip.cpp | 2 +- app/node/block/clip/clip.h | 2 -- app/node/output/track/track.cpp | 51 +++++++++++++++++---------------- app/node/output/track/track.h | 12 ++++---- 6 files changed, 53 insertions(+), 34 deletions(-) diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 17b1fae34..7b17dff5b 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -156,3 +156,18 @@ void Block::DisconnectBlocks(Block *previous, Block *next) NodeParam::DisconnectEdge(previous->block_output(), next->previous_input()); NodeParam::DisconnectEdge(next->block_output(), previous->next_input()); } + +const rational &Block::media_in() +{ + return media_in_; +} + +void Block::set_media_in(const rational &media_in) +{ + if (media_in_ != media_in) { + media_in_ = media_in; + + // Signal that this clips contents have changed + //InvalidateCache(in(), out()); + } +} diff --git a/app/node/block/block.h b/app/node/block/block.h index 33b386c0d..5deacd0d3 100644 --- a/app/node/block/block.h +++ b/app/node/block/block.h @@ -65,6 +65,9 @@ public: static void ConnectBlocks(Block* previous, Block* next); static void DisconnectBlocks(Block* previous, Block* next); + const rational& media_in(); + void set_media_in(const rational& media_in); + public slots: virtual void Process(const rational &time) override; @@ -110,6 +113,8 @@ private: rational length_; + rational media_in_; + private slots: void BlockOrderChanged(NodeEdgePtr edge); diff --git a/app/node/block/clip/clip.cpp b/app/node/block/clip/clip.cpp index f3e37ecd4..60d8e0039 100644 --- a/app/node/block/clip/clip.cpp +++ b/app/node/block/clip/clip.cpp @@ -75,7 +75,7 @@ void ClipBlock::Process(const rational &time) // If the time retrieved is within this block, get texture information if (time >= in() && time < out()) { // We convert the time given (timeline time) to media time - rational media_time = time - in() + media_in_; + rational media_time = time - in() + media_in(); // Retrieve texture texture_output()->set_value(texture_input_->get_value(media_time)); diff --git a/app/node/block/clip/clip.h b/app/node/block/clip/clip.h index 6a459082b..ed6cf5ed6 100644 --- a/app/node/block/clip/clip.h +++ b/app/node/block/clip/clip.h @@ -48,8 +48,6 @@ public slots: private: NodeInput* texture_input_; - rational media_in_; - }; #endif // TIMELINEBLOCK_H diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 7aed6e478..48eb0864f 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -310,10 +310,10 @@ void TrackOutput::RippleRemoveBlock(Block *block) // FIXME: Should there be removing the Blocks from the graph? } -void TrackOutput::SplitBlock(Block *block, rational time) +Block* TrackOutput::SplitBlock(Block *block, rational time) { - if (time < block->in() || time >= block->out()) { - return; + if (time <= block->in() || time >= block->out()) { + return nullptr; } rational original_length = block->length(); @@ -323,29 +323,15 @@ void TrackOutput::SplitBlock(Block *block, rational time) Block* copy = block->copy(); copy->set_length(original_length - block->length()); InsertBlockAfter(copy, block); -} -void TrackOutput::SpliceBlock(Block *inner, Block *outer, rational inner_in) -{ - Q_ASSERT(inner_in >= outer->in() && inner_in < outer->out()); - - // Cache original length - rational original_length = outer->length(); - - // Set outer clip to the clip that PRECEDES the inner clip - outer->set_length(inner_in - outer->in()); - - // Insert inner clip between BEFORE clip and its next clip - InsertBlockAfter(inner, outer); - - // Create the AFTER clip - Block* copy = outer->copy(); - copy->set_length(original_length - outer->length() - inner->length()); - InsertBlockAfter(copy, inner); + return copy; } void TrackOutput::RippleRemoveArea(rational in, rational out, Block *insert) { + // Block that needs to be split to remove this area + Block* splice = nullptr; + // Block whose out point exceeds `in` and needs to be trimmed Block* trim_out_to_in = nullptr; @@ -359,7 +345,7 @@ void TrackOutput::RippleRemoveArea(rational in, rational out, Block *insert) foreach (Block* block, block_cache_) { if (block->in() < in && block->out() > out) { // The area entirely within this Block - // FIXME: Implement splitting a block in half when necessary + splice = block; // We don't need to do anything else here break; @@ -375,10 +361,27 @@ void TrackOutput::RippleRemoveArea(rational in, rational out, Block *insert) } } + // If we picked up a block to splice + if (splice != nullptr) { + + // Split the block here + Block* copy = SplitBlock(splice, in); + + // Perform all further actions as if we were just trimming these clips + trim_out_to_in = splice; + trim_in_to_out = copy; + + } + // If we picked up a block to trim the in point of if (trim_in_to_out != nullptr && trim_in_to_out->in() < out) { - // FIXME: Set media_in point - trim_in_to_out->set_length(trim_in_to_out->out() - out); + rational new_length = trim_in_to_out->out() - out; + + // Push media_in forward to compensate + rational length_diff = trim_in_to_out->length() - new_length; + trim_in_to_out->set_media_in(trim_in_to_out->media_in() - length_diff); + + trim_in_to_out->set_length(new_length); } // Remove all blocks that are flagged for removal diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index ef71b575d..5abedbb92 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -109,14 +109,12 @@ public: /** * @brief Splits `block` into two Blocks at the Sequence point `time` + * + * @return + * + * The second block created as a result of this split */ - void SplitBlock(Block* block, rational time); - - /** - * @brief Inserts Block `inner` between Block `outer`, splitting and shortening it to fit without changing the overall - * length - */ - void SpliceBlock(Block* inner, Block* outer, rational inner_in); + Block *SplitBlock(Block* block, rational time); /** * @brief Clears the area between in and out