diff --git a/app/node/node.cpp b/app/node/node.cpp index 5b1944888..2350025d5 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -48,11 +48,13 @@ Node::Node() : can_be_deleted_(true), override_color_(-1), folder_(nullptr), - operation_stack_(0), cache_result_(false), flags_(kNone) { AddInput(kEnabledInput, NodeValue::kBoolean, true); + + video_cache_ = new FrameHashCache(this); + audio_cache_ = new AudioPlaybackCache(this); } Node::~Node() @@ -933,18 +935,6 @@ void Node::InvalidateCache(const TimeRange &range, const QString &from, int elem SendInvalidateCache(range, options); } -void Node::BeginOperation() -{ - // Increase operation stack - operation_stack_++; -} - -void Node::EndOperation() -{ - // Decrease operation stack - operation_stack_--; -} - TimeRange Node::InputTimeAdjustment(const QString &, int, const TimeRange &input_time) const { // Default behavior is no time adjustment at all @@ -1118,13 +1108,11 @@ Node *Node::CopyNodeInGraph(Node *node, MultiUndoCommand *command) void Node::SendInvalidateCache(const TimeRange &range, const InvalidateCacheOptions &options) { - if (GetOperationStack() == 0) { - for (const OutputConnection& conn : output_connections_) { - // Send clear cache signal to the Node - const NodeInput& in = conn.second; + for (const OutputConnection& conn : output_connections_) { + // Send clear cache signal to the Node + const NodeInput& in = conn.second; - in.node()->InvalidateCache(range, in.input(), in.element(), options); - } + in.node()->InvalidateCache(range, in.input(), in.element(), options); } } diff --git a/app/node/node.h b/app/node/node.h index b9bd33c7d..d123c0e72 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -39,6 +39,8 @@ #include "node/inputimmediate.h" #include "node/param.h" #include "render/audioparams.h" +#include "render/audioplaybackcache.h" +#include "render/framehashcache.h" #include "render/job/generatejob.h" #include "render/job/samplejob.h" #include "render/job/shaderjob.h" @@ -219,6 +221,16 @@ public: return HasInputWithID(id); } + FrameHashCache* video_frame_cache() const + { + return video_cache_; + } + + AudioPlaybackCache* audio_playback_cache() const + { + return audio_cache_; + } + struct Position { Position(const QPointF &p = QPointF(0, 0), bool e = false) @@ -798,19 +810,6 @@ public: InvalidateCache(range, from.input(), from.element(), options); } - /** - * @brief Limits cache invalidation temporarily - * - * If you intend to do a number of operations in quick succession, you can optimize it by running - * this function with EndOperation(). - */ - virtual void BeginOperation(); - - /** - * @brief Stops limiting cache invalidation and flushes changes - */ - virtual void EndOperation(); - /** * @brief Adjusts time that should be sent to nodes connected to certain inputs. * @@ -1030,11 +1029,6 @@ protected: */ void IgnoreInvalidationsFrom(const QString &input_id); - int GetOperationStack() const - { - return operation_stack_; - } - enum GizmoScaleHandles { kGizmoScaleTopLeft, kGizmoScaleTopCenter, @@ -1392,8 +1386,6 @@ private: Folder* folder_; - int operation_stack_; - bool cache_result_; QMap value_hints_; @@ -1406,6 +1398,10 @@ private: QString effect_input_; + FrameHashCache *video_cache_; + + AudioPlaybackCache *audio_cache_; + private slots: /** * @brief Slot when a keyframe's time changes to keep the keyframes correctly sorted by time diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index facf4ad92..b2d3775f0 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -406,10 +406,6 @@ QVector Track::BlocksAtTimeRange(const TimeRange &range) const void Track::InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) { - if (GetOperationStack() != 0) { - return; - } - TimeRange limited; const Block* b; @@ -465,69 +461,49 @@ void Track::InsertBlockAfter(Block *block, Block *before) void Track::PrependBlock(Block *block) { - BeginOperation(); - InputArrayPrepend(kBlockInput); Node::ConnectEdge(block, NodeInput(this, kBlockInput, 0)); - EndOperation(); - // Everything has shifted at this point Node::InvalidateCache(TimeRange(0, track_length()), kBlockInput); } void Track::InsertBlockAtIndex(Block *block, int index) { - BeginOperation(); - int insert_index = GetArrayIndexFromCacheIndex(index); InputArrayInsert(kBlockInput, insert_index); Node::ConnectEdge(block, NodeInput(this, kBlockInput, insert_index)); - EndOperation(); - Node::InvalidateCache(TimeRange(block->in(), track_length()), kBlockInput); } void Track::AppendBlock(Block *block) { - BeginOperation(); - InputArrayAppend(kBlockInput); Node::ConnectEdge(block, NodeInput(this, kBlockInput, InputArraySize(kBlockInput) - 1)); - EndOperation(); - // Invalidate area that block was added to Node::InvalidateCache(TimeRange(block->in(), block->out()), kBlockInput); } void Track::RippleRemoveBlock(Block *block) { - BeginOperation(); - rational remove_in = block->in(); rational remove_out = block->out(); InputArrayRemove(kBlockInput, GetArrayIndexFromBlock(block)); - EndOperation(); - Node::InvalidateCache(TimeRange(remove_in, qMax(track_length(), remove_out)), kBlockInput); } void Track::ReplaceBlock(Block *old, Block *replace) { - BeginOperation(); - int index_of_old_block = GetArrayIndexFromBlock(old); DisconnectEdge(old, NodeInput(this, kBlockInput, index_of_old_block)); ConnectEdge(replace, NodeInput(this, kBlockInput, index_of_old_block)); - EndOperation(); - if (old->length() == replace->length()) { Node::InvalidateCache(TimeRange(replace->in(), replace->out()), kBlockInput); } else { diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index d7aa0e4ae..f90b50298 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -40,8 +40,6 @@ ViewerOutput::ViewerOutput(bool create_buffer_inputs, bool create_default_stream last_length_(0), video_length_(0), audio_length_(0), - video_frame_cache_(this), - audio_playback_cache_(this), video_cache_enabled_(true), audio_cache_enabled_(true) { @@ -229,30 +227,6 @@ void ViewerOutput::set_default_parameters() SetVideoAutoCacheEnabled(OLIVE_CONFIG("DefaultSequenceAutoCache").toBool()); } -void ViewerOutput::ShiftVideoCache(const rational &from, const rational &to) -{ - if (video_cache_enabled_) { - video_frame_cache_.Shift(from, to); - } - - ShiftVideoEvent(from, to); -} - -void ViewerOutput::ShiftAudioCache(const rational &from, const rational &to) -{ - if (audio_cache_enabled_) { - audio_playback_cache_.Shift(from, to); - } - - ShiftAudioEvent(from, to); -} - -void ViewerOutput::ShiftCache(const rational &from, const rational &to) -{ - ShiftVideoCache(from, to); - ShiftAudioCache(from, to); -} - void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) { Q_UNUSED(element) @@ -264,9 +238,9 @@ void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from, if (invalidated_range.in() != invalidated_range.out()) { if (from == kTextureInput || from == kVideoParamsInput) { - video_frame_cache_.Invalidate(invalidated_range); + video_frame_cache()->Invalidate(invalidated_range); } else { - audio_playback_cache_.Invalidate(invalidated_range); + audio_playback_cache()->Invalidate(invalidated_range); } } } @@ -454,7 +428,7 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element) if (frame_rate_changed) { if (video_cache_enabled_) { - video_frame_cache_.SetTimebase(new_video_params.frame_rate_as_time_base()); + video_frame_cache()->SetTimebase(new_video_params.frame_rate_as_time_base()); } emit FrameRateChanged(new_video_params.frame_rate()); } @@ -476,7 +450,7 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element) emit AudioParamsChanged(); if (audio_cache_enabled_) { - audio_playback_cache_.SetParameters(GetAudioParams()); + audio_playback_cache()->SetParameters(GetAudioParams()); } cached_audio_params_ = new_audio_params; @@ -487,18 +461,6 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element) super::InputValueChangedEvent(input, element); } -void ViewerOutput::ShiftVideoEvent(const rational &from, const rational &to) -{ - Q_UNUSED(from) - Q_UNUSED(to) -} - -void ViewerOutput::ShiftAudioEvent(const rational &from, const rational &to) -{ - Q_UNUSED(from) - Q_UNUSED(to) -} - void ViewerOutput::set_parameters_from_footage(const QVector footage) { foreach (ViewerOutput* f, footage) { diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index a689d005b..43b4decc4 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -60,10 +60,6 @@ public: void set_parameters_from_footage(const QVector footage); - void ShiftVideoCache(const rational& from, const rational& to); - void ShiftAudioCache(const rational& from, const rational& to); - void ShiftCache(const rational& from, const rational& to); - virtual void InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) override; VideoParams GetVideoParams(int index = 0) const @@ -146,16 +142,6 @@ public: const rational &GetVideoLength() const { return video_length_; } const rational &GetAudioLength() const { return audio_length_; } - FrameHashCache* video_frame_cache() - { - return &video_frame_cache_; - } - - AudioPlaybackCache* audio_playback_cache() - { - return &audio_playback_cache_; - } - TimelinePoints* GetTimelinePoints() { return timeline_points_; @@ -253,10 +239,6 @@ protected: virtual rational VerifyLengthInternal(Track::Type type) const; - virtual void ShiftVideoEvent(const rational &from, const rational &to); - - virtual void ShiftAudioEvent(const rational &from, const rational &to); - virtual void InputValueChangedEvent(const QString& input, int element) override; int AddStream(Track::Type type, const QVariant &value); @@ -266,10 +248,6 @@ private: rational video_length_; rational audio_length_; - FrameHashCache video_frame_cache_; - - AudioPlaybackCache audio_playback_cache_; - VideoParams cached_video_params_; AudioParams cached_audio_params_; diff --git a/app/render/audioplaybackcache.cpp b/app/render/audioplaybackcache.cpp index 8e4804696..859ce454e 100644 --- a/app/render/audioplaybackcache.cpp +++ b/app/render/audioplaybackcache.cpp @@ -170,108 +170,6 @@ void AudioPlaybackCache::WriteSilence(const TimeRange &range) WritePCM(range, {range}, SampleBuffer()); } -void AudioPlaybackCache::ShiftEvent(const rational &from_in_time, const rational &to_in_time) -{ - visual_.Shift(from_in_time, to_in_time); - - qint64 to = params_.time_to_bytes_per_channel(to_in_time); - qint64 from = params_.time_to_bytes_per_channel(from_in_time); - - if (from >= playlist_.GetLength()) { - return; - } - - int to_seg_index = playlist_.GetIndexOfPosition(to); - int from_seg_index = playlist_.GetIndexOfPosition(from); - - qint64 from_seg_start = playlist_.at(from_seg_index).offset(); - qint64 from_seg_end = playlist_.at(from_seg_index).end(); - - if (from < to) { - // Shifting forwards, we must insert a new region and split a segment in half if necessary - int insert_index; - - // Determine at what part of the array we'll be insert into - if (from == from_seg_start) { - insert_index = from_seg_index; - } else { - insert_index = from_seg_index + 1; - - if (from < from_seg_end) { - // Split from segment into two - Segment second = CloneSegment(playlist_.at(from_seg_index)); - - TrimSegmentOut(&playlist_[from_seg_index], from - from_seg_start); - TrimSegmentIn(&second, from_seg_end - from); - - playlist_.insert(insert_index, second); - } - } - - // Insert silent segments - qint64 time_to_insert = to - from; - - while (time_to_insert) { - qint64 new_seg_sz = qMin(kDefaultSegmentSizePerChannel, time_to_insert); - - // Set offset to 0 for now and fill it in later - playlist_.insert(insert_index, CreateSegment(new_seg_sz, 0)); - - time_to_insert -= new_seg_sz; - } - - UpdateOffsetsFrom(insert_index); - - } else { - // Shifting backwards, we'll be removing segments and truncating them if necessary - qint64 to_seg_start = playlist_.at(to_seg_index).offset(); - qint64 to_seg_end = playlist_.at(to_seg_index).end(); - - if (to_seg_index == from_seg_index) { - if (to > to_seg_start && from < from_seg_end) { - // Duplicate segment into two segments and trim each side to move the space in between - Segment second = CloneSegment(playlist_.at(to_seg_index)); - from_seg_index++; - playlist_.insert(from_seg_index, second); - - TrimSegmentOut(&playlist_[to_seg_index], to - to_seg_start); - TrimSegmentIn(&playlist_[from_seg_index], to_seg_end - from); - } else if (to == to_seg_start && from == from_seg_end) { - // Segment contains entire shift area, just remove it - RemoveSegmentFromArray(to_seg_index); - } else if (to == to_seg_start) { - // Trim segment in - TrimSegmentIn(&playlist_[to_seg_index], to_seg_end - from); - } else { - // Assume from == to_seg_end - TrimSegmentOut(&playlist_[to_seg_index], to_seg_end - to); - } - } else { - // Remove any segments between if there are any - while (from_seg_index != to_seg_index+1) { - RemoveSegmentFromArray(to_seg_index+1); - from_seg_index--; - } - - if (from == from_seg_end) { - RemoveSegmentFromArray(from_seg_index); - } else { - // Assume from > from_seg_start and trim its in point - TrimSegmentIn(&playlist_[from_seg_index], from_seg_end - from); - } - - if (to == to_seg_start) { - // Assume from >= to_seg_end, remove "to" segment - RemoveSegmentFromArray(to_seg_index); - } else { - TrimSegmentOut(&playlist_[to_seg_index], to_seg_end - to); - } - } - - UpdateOffsetsFrom(to_seg_index); - } -} - AudioPlaybackCache::Segment AudioPlaybackCache::CloneSegment(const AudioPlaybackCache::Segment &s) const { Segment new_seg = s; @@ -318,9 +216,11 @@ QString AudioPlaybackCache::GenerateSegmentFilename() const { QString new_seg_filename; + QDir cache_dir(QDir(GetCacheDirectory()).filePath(GetUuid().toString())); + do { uint32_t r = QRandomGenerator::global()->generate(); - new_seg_filename = QDir(GetCacheDirectory()).filePath(QStringLiteral("%1.pcm").arg(r)); + new_seg_filename = cache_dir.filePath(QStringLiteral("%1.pcm").arg(r)); } while (QFileInfo::exists(new_seg_filename)); return new_seg_filename; @@ -402,7 +302,7 @@ AudioPlaybackCache::PlaybackDevice *AudioPlaybackCache::CreatePlaybackDevice(QOb PlaybackDevice *d = new PlaybackDevice(playlist_, params_.bytes_per_sample_per_channel(), parent); // If we're child of a viewer, set the data limit so audio doesn't play beyond the length - if (ViewerOutput *viewer = viewer_parent()) { + if (ViewerOutput *viewer = dynamic_cast(this->parent())) { d->SetDataLimit(params_.time_to_bytes_per_channel(viewer->GetAudioLength())); } diff --git a/app/render/audioplaybackcache.h b/app/render/audioplaybackcache.h index 739a38cb0..164953418 100644 --- a/app/render/audioplaybackcache.h +++ b/app/render/audioplaybackcache.h @@ -208,9 +208,6 @@ public: signals: void ParametersChanged(); -protected: - virtual void ShiftEvent(const rational& from, const rational& to) override; - private: static const qint64 kDefaultSegmentSizePerChannel; diff --git a/app/render/framehashcache.cpp b/app/render/framehashcache.cpp index d9b4fd986..cd96cd076 100644 --- a/app/render/framehashcache.cpp +++ b/app/render/framehashcache.cpp @@ -67,7 +67,7 @@ void FrameHashCache::ValidateTime(const rational &time) bool FrameHashCache::SaveCacheFrame(const int64_t &time, FramePtr frame) const { - return SaveCacheFrame(GetCacheDirectory(), uuid_, time, frame); + return SaveCacheFrame(GetCacheDirectory(), GetUuid(), time, frame); } bool FrameHashCache::SaveCacheFrame(const QString &cache_path, const QUuid &uuid, const int64_t &time, FramePtr frame) @@ -125,7 +125,7 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &cache_path, const QUuid & FramePtr FrameHashCache::LoadCacheFrame(const int64_t &hash) const { - return LoadCacheFrame(GetCacheDirectory(), uuid_, hash); + return LoadCacheFrame(GetCacheDirectory(), GetUuid(), hash); } FramePtr FrameHashCache::LoadCacheFrame(const QString &fn) @@ -212,7 +212,7 @@ void FrameHashCache::HashDeleted(const QString& path, const QString &filename) } QFileInfo info(filename); - if (uuid_.toString() != info.dir().dirName()) { + if (GetUuid().toString() != info.dir().dirName()) { return; } @@ -229,12 +229,12 @@ void FrameHashCache::ProjectInvalidated(Project *p) QString FrameHashCache::CachePathName(const int64_t &time) const { - return CachePathName(GetCacheDirectory(), uuid_, time); + return CachePathName(GetCacheDirectory(), GetUuid(), time); } QString FrameHashCache::CachePathName(const rational &time) const { - return CachePathName(GetCacheDirectory(), uuid_, time, timebase_); + return CachePathName(GetCacheDirectory(), GetUuid(), time, timebase_); } QString FrameHashCache::CachePathName(const QString &cache_path, const QUuid &cache_id, const int64_t &time) diff --git a/app/render/framehashcache.h b/app/render/framehashcache.h index 5db391015..a98432ac5 100644 --- a/app/render/framehashcache.h +++ b/app/render/framehashcache.h @@ -21,9 +21,6 @@ #ifndef VIDEORENDERFRAMECACHE_H #define VIDEORENDERFRAMECACHE_H -#include -#include - #include "common/rational.h" #include "common/timecodefunctions.h" #include "common/timerange.h" @@ -39,9 +36,6 @@ class FrameHashCache : public PlaybackCache public: FrameHashCache(QObject* parent = nullptr); - const QUuid &GetUuid() const { return uuid_; } - void SetUuid(const QUuid &u) { uuid_ = u; } - const rational &GetTimebase() const { return timebase_; } void SetTimebase(const rational& tb); @@ -86,8 +80,6 @@ private: rational timebase_; - QUuid uuid_; - static const QString kCacheFormatExtension; private slots: diff --git a/app/render/playbackcache.cpp b/app/render/playbackcache.cpp index e88e65510..0aec6bcf5 100644 --- a/app/render/playbackcache.cpp +++ b/app/render/playbackcache.cpp @@ -43,40 +43,16 @@ void PlaybackCache::Invalidate(const TimeRange &r, bool signal) } } +Node *PlaybackCache::parent() const +{ + return dynamic_cast(QObject::parent()); +} + void PlaybackCache::InvalidateAll() { Invalidate(TimeRange(0, RATIONAL_MAX)); } -void PlaybackCache::Shift(rational from, rational to) -{ - if (from == to) { - return; - } - - // An region between `from` and `to` will be inserted or spliced out - TimeRangeList ranges_to_shift = validated_.Intersects(TimeRange(from, RATIONAL_MAX)); - - // Remove all ranges starting at to - validated_.remove(TimeRange(qMin(from, to), RATIONAL_MAX)); - - // Restore ranges shifted - rational diff = to - from; - foreach (const TimeRange& r, ranges_to_shift) { - validated_.insert(r + diff); - } - - // Tell derivatives that a shift has occurred - ShiftEvent(from, to); - - // Emit signals - emit Shifted(from, to); - - if (diff > 0) { - //emit Invalidated(TimeRange(from, to)); - } -} - void PlaybackCache::Validate(const TimeRange &r, bool signal) { validated_.insert(r); @@ -90,15 +66,17 @@ void PlaybackCache::InvalidateEvent(const TimeRange &) { } -void PlaybackCache::ShiftEvent(const rational &, const rational &) -{ -} - Project *PlaybackCache::GetProject() const { return Project::GetProjectFromObject(this); } +PlaybackCache::PlaybackCache(QObject *parent) : + QObject(parent) +{ + uuid_ = QUuid::createUuid(); +} + TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting) { TimeRangeList invalidated; @@ -133,9 +111,4 @@ QString PlaybackCache::GetCacheDirectory() const } } -ViewerOutput *PlaybackCache::viewer_parent() const -{ - return dynamic_cast(parent()); -} - } diff --git a/app/render/playbackcache.h b/app/render/playbackcache.h index fa67f8866..26f18a5e4 100644 --- a/app/render/playbackcache.h +++ b/app/render/playbackcache.h @@ -21,14 +21,15 @@ #ifndef PLAYBACKCACHE_H #define PLAYBACKCACHE_H -#include #include +#include #include "common/jobtime.h" #include "common/timerange.h" namespace olive { +class Node; class Project; class ViewerOutput; @@ -36,10 +37,10 @@ class PlaybackCache : public QObject { Q_OBJECT public: - PlaybackCache(QObject* parent = nullptr) : - QObject(parent) - { - } + PlaybackCache(QObject* parent = nullptr); + + const QUuid &GetUuid() const { return uuid_; } + void SetUuid(const QUuid &u) { uuid_ = u; } TimeRangeList GetInvalidatedRanges(TimeRange intersecting); TimeRangeList GetInvalidatedRanges(const rational &length) @@ -55,36 +56,32 @@ public: QString GetCacheDirectory() const; - ViewerOutput *viewer_parent() const; - void Invalidate(const TimeRange& r, bool signal = true); const TimeRangeList &GetValidatedRanges() const { return validated_; } + Node *parent() const; + public slots: void InvalidateAll(); - void Shift(rational from, rational to); - signals: void Invalidated(const olive::TimeRange& r); void Validated(const olive::TimeRange& r); - void Shifted(const olive::rational& from, const olive::rational& to); - protected: void Validate(const TimeRange& r, bool signal = true); virtual void InvalidateEvent(const TimeRange& range); - virtual void ShiftEvent(const rational& from, const rational& to); - Project* GetProject() const; private: TimeRangeList validated_; + QUuid uuid_; + }; } diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index ba2550963..ebacd5e43 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -557,7 +557,9 @@ RenderTicketWatcher* PreviewAutoCacher::RenderFrame(const rational& time, Render watcher->setProperty("job", QVariant::fromValue(last_update_time_)); connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoRendered); video_tasks_.insert(watcher, time); - watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_, + watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_->GetConnectedTextureOutput(), + copied_viewer_node_->GetVideoParams(), + copied_viewer_node_->GetAudioParams(), copied_color_manager_, time, RenderMode::kOffline, @@ -574,7 +576,7 @@ RenderTicketPtr PreviewAutoCacher::RenderAudio(const TimeRange &r, bool generate connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::AudioRendered); audio_tasks_.insert(watcher, r); - RenderTicketPtr ticket = RenderManager::instance()->RenderAudio(copied_viewer_node_, r, RenderMode::kOffline, generate_waveforms, priority); + RenderTicketPtr ticket = RenderManager::instance()->RenderAudio(copied_viewer_node_->GetConnectedSampleOutput(), r, copied_viewer_node_->GetAudioParams(), RenderMode::kOffline, generate_waveforms, priority); watcher->SetTicket(ticket); return ticket; } diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp index 3db71aa76..c34b050d8 100644 --- a/app/render/rendermanager.cpp +++ b/app/render/rendermanager.cpp @@ -76,16 +76,16 @@ RenderManager::~RenderManager() } } -RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* color_manager, - const rational& time, RenderMode::Mode mode, +RenderTicketPtr RenderManager::RenderFrame(Node *node, const VideoParams &vparam, const AudioParams ¶m, + ColorManager* color_manager, const rational& time, RenderMode::Mode mode, FrameHashCache* cache, RenderTicketPriority priority, ReturnType return_type) { - return RenderFrame(viewer, + return RenderFrame(node, color_manager, time, mode, - viewer->GetVideoParams(), - viewer->GetAudioParams(), + vparam, + param, QSize(0, 0), QMatrix4x4(), VideoParams::kFormatInvalid, @@ -95,7 +95,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* c return_type); } -RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* color_manager, +RenderTicketPtr RenderManager::RenderFrame(Node *node, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, const VideoParams &video_params, const AudioParams &audio_params, const QSize& force_size, @@ -106,7 +106,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* c // Create ticket RenderTicketPtr ticket = std::make_shared(); - ticket->setProperty("viewer", Node::PtrToValue(viewer)); + ticket->setProperty("node", Node::PtrToValue(node)); ticket->setProperty("time", QVariant::fromValue(time)); ticket->setProperty("size", force_size); ticket->setProperty("matrix", force_matrix); @@ -130,17 +130,12 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* c return ticket; } -RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange& r, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority) -{ - return RenderAudio(viewer, r, viewer->GetAudioParams(), mode, generate_waveforms, priority); -} - -RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange &r, const AudioParams ¶ms, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority) +RenderTicketPtr RenderManager::RenderAudio(Node *node, const TimeRange &r, const AudioParams ¶ms, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority) { // Create ticket RenderTicketPtr ticket = std::make_shared(); - ticket->setProperty("viewer", Node::PtrToValue(viewer)); + ticket->setProperty("node", Node::PtrToValue(node)); ticket->setProperty("time", QVariant::fromValue(r)); ticket->setProperty("type", kTypeAudio); ticket->setProperty("mode", mode); diff --git a/app/render/rendermanager.h b/app/render/rendermanager.h index 543bcbd19..8753f7c90 100644 --- a/app/render/rendermanager.h +++ b/app/render/rendermanager.h @@ -76,10 +76,10 @@ public: * * This function is thread-safe. */ - RenderTicketPtr RenderFrame(ViewerOutput *viewer, ColorManager* color_manager, + RenderTicketPtr RenderFrame(Node *node, const VideoParams &vparam, const AudioParams ¶m, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, FrameHashCache* cache = nullptr, RenderTicketPriority priority = RenderTicketPriority::kNormal, ReturnType return_type = kFrame); - RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, + RenderTicketPtr RenderFrame(Node *node, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, const VideoParams& video_params, const AudioParams& audio_params, const QSize& force_size, @@ -94,8 +94,7 @@ public: * * This function is thread-safe. */ - RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal); - RenderTicketPtr RenderAudio(ViewerOutput *viewer, const TimeRange& r, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal); + RenderTicketPtr RenderAudio(Node *viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal); virtual void RunTicket(RenderTicketPtr ticket) const override; diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 705e626d2..e9ef9be61 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -46,13 +46,12 @@ RenderProcessor::RenderProcessor(RenderTicketPtr ticket, Renderer *render_ctx, D TexturePtr RenderProcessor::GenerateTexture(const rational &time, const rational &frame_length) { - ViewerOutput* viewer = Node::ValueToPtr(ticket_->property("viewer")); TimeRange range = TimeRange(time, time + frame_length); NodeValueTable table; - if (Node *texture_output = viewer->GetConnectedTextureOutput()) { - table = GenerateTable(texture_output, range); + if (Node* node = Node::ValueToPtr(ticket_->property("node"))) { + table = GenerateTable(node, range); } NodeValue tex_val = table.Get(NodeValue::kTexture); @@ -205,12 +204,11 @@ void RenderProcessor::Run() } case RenderManager::kTypeAudio: { - ViewerOutput* viewer = Node::ValueToPtr(ticket_->property("viewer")); TimeRange time = ticket_->property("time").value(); NodeValueTable table; - if (Node *texture_output = viewer->GetConnectedSampleOutput()) { - table = GenerateTable(texture_output, time); + if (Node* node = Node::ValueToPtr(ticket_->property("node"))) { + table = GenerateTable(node, time); } NodeValue sample_val = table.Get(NodeValue::kSamples); diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 47c704a76..aeb1a0678 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -416,8 +416,7 @@ void TimelineWidget::SplitAtPlayhead() void TimelineWidget::ReplaceBlocksWithGaps(const QVector &blocks, bool remove_from_graph, MultiUndoCommand *command, - bool handle_transitions, - bool handle_invalidations) + bool handle_transitions) { foreach (Block* b, blocks) { if (dynamic_cast(b)) { @@ -428,7 +427,7 @@ void TimelineWidget::ReplaceBlocksWithGaps(const QVector &blocks, Track* original_track = b->track(); - command->add_child(new TrackReplaceBlockWithGapCommand(original_track, b, handle_transitions, handle_invalidations)); + command->add_child(new TrackReplaceBlockWithGapCommand(original_track, b, handle_transitions)); if (remove_from_graph) { command->add_child(new NodeRemoveWithExclusiveDependenciesAndDisconnect(b)); @@ -482,7 +481,7 @@ void TimelineWidget::DeleteSelected(bool ripple) } // Replace clips with gaps (effectively deleting them) - ReplaceBlocksWithGaps(clips_to_delete, true, command, false, !ripple); + ReplaceBlocksWithGaps(clips_to_delete, true, command, false); // Insert ripple command now that it's all cleaned up gaps TimelineRippleDeleteGapsAtRegionsCommand *ripple_command = nullptr; diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index e2f9d6b35..c7a38dfaa 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -126,7 +126,7 @@ public: void RestoreSplitterState(const QByteArray& state); - static void ReplaceBlocksWithGaps(const QVector &blocks, bool remove_from_graph, MultiUndoCommand *command, bool handle_transitions = true, bool handle_invalidations = true); + static void ReplaceBlocksWithGaps(const QVector &blocks, bool remove_from_graph, MultiUndoCommand *command, bool handle_transitions = true); /** * @brief Retrieve the QGraphicsItem at a particular scene position diff --git a/app/widget/timelinewidget/undo/timelineundogeneral.cpp b/app/widget/timelinewidget/undo/timelineundogeneral.cpp index a3d470241..c90d8b078 100644 --- a/app/widget/timelinewidget/undo/timelineundogeneral.cpp +++ b/app/widget/timelinewidget/undo/timelineundogeneral.cpp @@ -208,8 +208,6 @@ void TransitionRemoveCommand::redo() Q_ASSERT(out_block_ || in_block_); - track_->BeginOperation(); - TimeRange invalidate_range(block_->in(), block_->out()); if (in_block_) { @@ -230,10 +228,6 @@ void TransitionRemoveCommand::redo() track_->RippleRemoveBlock(block_); - track_->EndOperation(); - - track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput); - if (remove_from_graph_) { if (!remove_command_) { remove_command_ = CreateRemoveCommand(block_); @@ -249,8 +243,6 @@ void TransitionRemoveCommand::undo() remove_command_->undo_now(); } - track_->BeginOperation(); - if (in_block_) { track_->InsertBlockBefore(block_, in_block_); } else { @@ -275,10 +267,6 @@ void TransitionRemoveCommand::undo() if (out_block_) { out_block_->set_length_and_media_out(out_block_->length() - block_->out_offset()); } - - track_->EndOperation(); - - track_->Node::InvalidateCache(TimeRange(block_->in(), block_->out()), Track::kBlockInput); } // @@ -287,11 +275,8 @@ void TransitionRemoveCommand::undo() void TrackListInsertGaps::prepare() { // Determine if all tracks will be affected, which will allow us to make some optimizations - all_tracks_unlocked_ = true; - foreach (Track* track, track_list_->GetTracks()) { if (track->IsLocked()) { - all_tracks_unlocked_ = false; continue; } @@ -346,19 +331,6 @@ void TrackListInsertGaps::prepare() void TrackListInsertGaps::redo() { - if (all_tracks_unlocked_) { - // Optimize by shifting over since we have a constant amount of time being inserted - if (track_list_->type() == Track::kVideo) { - track_list_->parent()->ShiftVideoCache(point_, point_ + length_); - } else if (track_list_->type() == Track::kAudio) { - track_list_->parent()->ShiftAudioCache(point_, point_ + length_); - } - } - - foreach (Track* track, working_tracks_) { - track->BeginOperation(); - } - foreach (Block* gap, gaps_to_extend_) { gap->set_length_and_media_out(gap->length() + length_); } @@ -371,33 +343,10 @@ void TrackListInsertGaps::redo() add_gap.gap->setParent(add_gap.track->parent()); add_gap.track->InsertBlockAfter(add_gap.gap, add_gap.before); } - - foreach (Track* track, working_tracks_) { - track->EndOperation(); - } - - if (!all_tracks_unlocked_) { - foreach (Track* track, working_tracks_) { - track->Node::InvalidateCache(TimeRange(point_, RATIONAL_MAX), Track::kBlockInput); - } - } } void TrackListInsertGaps::undo() { - if (all_tracks_unlocked_) { - // Optimize by shifting over since we have a constant amount of time being inserted - if (track_list_->type() == Track::kVideo) { - track_list_->parent()->ShiftVideoCache(point_ + length_, point_); - } else if (track_list_->type() == Track::kAudio) { - track_list_->parent()->ShiftAudioCache(point_ + length_, point_); - } - } - - foreach (Track* track, working_tracks_) { - track->BeginOperation(); - } - // Remove added gaps foreach (auto add_gap, gaps_added_) { add_gap.gap->track()->RippleRemoveBlock(add_gap.gap); @@ -413,16 +362,6 @@ void TrackListInsertGaps::undo() foreach (Block* gap, gaps_to_extend_) { gap->set_length_and_media_out(gap->length() - length_); } - - foreach (Track* track, working_tracks_) { - track->EndOperation(); - } - - if (!all_tracks_unlocked_) { - foreach (Track* track, working_tracks_) { - track->Node::InvalidateCache(TimeRange(point_, RATIONAL_MAX), Track::kBlockInput); - } - } } // @@ -440,8 +379,6 @@ void TrackReplaceBlockWithGapCommand::redo() } if (block_->next()) { - track_->BeginOperation(); - // Invalidate the range inhabited by this block TimeRange invalidate_range(block_->in(), block_->out()); @@ -488,12 +425,6 @@ void TrackReplaceBlockWithGapCommand::redo() track_->ReplaceBlock(block_, our_gap_); } - track_->EndOperation(); - - if (handle_invalidations_) { - track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput); - } - } else { // Block is at the end of the track, simply remove it Block* preceding = block_->previous(); @@ -512,8 +443,6 @@ void TrackReplaceBlockWithGapCommand::redo() void TrackReplaceBlockWithGapCommand::undo() { if (our_gap_ || existing_gap_) { - track_->BeginOperation(); - if (our_gap_) { // We made this gap, simply swap our gap back @@ -547,11 +476,6 @@ void TrackReplaceBlockWithGapCommand::undo() } - track_->EndOperation(); - - if (handle_invalidations_) { - track_->Node::InvalidateCache(TimeRange(block_->in(), block_->out()), Track::kBlockInput); - } } else { // Our gap and existing gap were both null, our block must have been at the end and thus diff --git a/app/widget/timelinewidget/undo/timelineundogeneral.h b/app/widget/timelinewidget/undo/timelineundogeneral.h index 136af2eea..55f36b7b9 100644 --- a/app/widget/timelinewidget/undo/timelineundogeneral.h +++ b/app/widget/timelinewidget/undo/timelineundogeneral.h @@ -233,14 +233,13 @@ private: class TrackReplaceBlockWithGapCommand : public UndoCommand { public: - TrackReplaceBlockWithGapCommand(Track* track, Block* block, bool handle_transitions = true, bool handle_invalidations = true) : + TrackReplaceBlockWithGapCommand(Track* track, Block* block, bool handle_transitions = true) : track_(track), block_(block), existing_gap_(nullptr), existing_merged_gap_(nullptr), our_gap_(nullptr), - handle_transitions_(handle_transitions), - handle_invalidations_(handle_invalidations) + handle_transitions_(handle_transitions) { } @@ -266,7 +265,6 @@ private: GapBlock* our_gap_; bool handle_transitions_; - bool handle_invalidations_; QObject memory_manager_; @@ -344,8 +342,6 @@ private: QVector working_tracks_; - bool all_tracks_unlocked_; - QVector gaps_to_extend_; struct AddGap { @@ -362,62 +358,6 @@ private: }; -class NodeBeginOperationCommand : public UndoCommand -{ -public: - NodeBeginOperationCommand(Node *node) : - node_(node) - {} - - virtual Project* GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void redo() override - { - node_->BeginOperation(); - } - - virtual void undo() override - { - node_->EndOperation(); - } - -private: - Node *node_; - -}; - -class NodeEndOperationCommand : public UndoCommand -{ -public: - NodeEndOperationCommand(Node *node) : - node_(node) - {} - - virtual Project* GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void redo() override - { - node_->EndOperation(); - } - - virtual void undo() override - { - node_->BeginOperation(); - } - -private: - Node *node_; - -}; - } #endif // TIMELINEUNDOGENERAL_H diff --git a/app/widget/timelinewidget/undo/timelineundopointer.cpp b/app/widget/timelinewidget/undo/timelineundopointer.cpp index a5560f317..f8b51ca4c 100644 --- a/app/widget/timelinewidget/undo/timelineundopointer.cpp +++ b/app/widget/timelinewidget/undo/timelineundopointer.cpp @@ -36,9 +36,6 @@ void BlockTrimCommand::redo() return; } - // Begin an operation since we'll be doing a lot - track_->BeginOperation(); - // Determine how much time to invalidate TimeRange invalidate_range; @@ -82,14 +79,10 @@ void BlockTrimCommand::redo() } } - track_->EndOperation(); - if (dynamic_cast(block_)) { // Whole transition needs to be invalidated invalidate_range = block_->range(); } - - track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput); } void BlockTrimCommand::undo() @@ -98,8 +91,6 @@ void BlockTrimCommand::undo() return; } - track_->BeginOperation(); - // Will be POSITIVE if trimming shorter and NEGATIVE if trimming longer if (needs_adjacent_) { if (we_created_adjacent_) { @@ -146,10 +137,6 @@ void BlockTrimCommand::undo() // Whole transition needs to be invalidated invalidate_range = block_->range(); } - - track_->EndOperation(); - - track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput); } void BlockTrimCommand::prepare() @@ -200,8 +187,6 @@ void TrackSlideCommand::redo() // Make sure all movement blocks' old positions are invalidated TimeRange invalidate_range(blocks_.first()->in(), blocks_.last()->out()); - track_->BeginOperation(); - // We will always have an in adjacent if there was a valid slide if (we_created_in_adjacent_) { // We created in adjacent, so all we have to do is insert it @@ -246,13 +231,9 @@ void TrackSlideCommand::redo() } } - track_->EndOperation(); - // Make sure all movement blocks' new positions are invalidated invalidate_range.set_range(qMin(invalidate_range.in(), blocks_.first()->in()), qMax(invalidate_range.out(), blocks_.last()->out())); - - track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput); } @@ -261,8 +242,6 @@ void TrackSlideCommand::undo() // Make sure all movement blocks' old positions are invalidated TimeRange invalidate_range(blocks_.first()->in(), blocks_.last()->out()); - track_->BeginOperation(); - if (we_created_in_adjacent_) { // We created this, so we can remove it now track_->RippleRemoveBlock(in_adjacent_); @@ -287,13 +266,9 @@ void TrackSlideCommand::undo() } } - track_->EndOperation(); - // Make sure all movement blocks' new positions are invalidated invalidate_range.set_range(qMin(invalidate_range.in(), blocks_.first()->in()), qMax(invalidate_range.out(), blocks_.last()->out())); - - track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput); } void TrackSlideCommand::prepare() @@ -328,8 +303,6 @@ TrackPlaceBlockCommand::~TrackPlaceBlockCommand() void TrackPlaceBlockCommand::redo() { - TimeRangeList ranges_to_invalidate; - // Determine if we need to add tracks if (track_index_ >= timeline_->GetTracks().size()) { if (add_track_commands_.isEmpty()) { @@ -348,8 +321,6 @@ void TrackPlaceBlockCommand::redo() Track* track = timeline_->GetTrackAt(track_index_); - track->BeginOperation(); - bool append = (in_ >= track->track_length()); // Check if the placement location is past the end of the timeline @@ -362,7 +333,6 @@ void TrackPlaceBlockCommand::redo() } gap_->setParent(track->parent()); track->AppendBlock(gap_); - ranges_to_invalidate.insert(gap_->range()); } track->AppendBlock(insert_); @@ -376,14 +346,6 @@ void TrackPlaceBlockCommand::redo() ripple_remove_command_->redo_now(); track->InsertBlockAfter(insert_, ripple_remove_command_->GetInsertionIndex()); } - - track->EndOperation(); - - ranges_to_invalidate.insert(insert_->range()); - - foreach (const TimeRange &r, ranges_to_invalidate) { - track->Node::InvalidateCache(r, Track::kBlockInput); - } } void TrackPlaceBlockCommand::undo() @@ -393,7 +355,6 @@ void TrackPlaceBlockCommand::undo() TimeRange insert_range(insert_->in(), insert_->out()); // Firstly, remove our insert - t->BeginOperation(); t->RippleRemoveBlock(insert_); if (ripple_remove_command_) { @@ -403,9 +364,6 @@ void TrackPlaceBlockCommand::undo() t->RippleRemoveBlock(gap_); gap_->setParent(&memory_manager_); } - t->EndOperation(); - - t->Node::InvalidateCache(insert_range, Track::kBlockInput); // Remove tracks if we added them for (int i=add_track_commands_.size()-1; i>=0; i--) { diff --git a/app/widget/timelinewidget/undo/timelineundoripple.cpp b/app/widget/timelinewidget/undo/timelineundoripple.cpp index 6b4e96098..3b7bdcac9 100644 --- a/app/widget/timelinewidget/undo/timelineundoripple.cpp +++ b/app/widget/timelinewidget/undo/timelineundoripple.cpp @@ -106,8 +106,6 @@ void TrackRippleRemoveAreaCommand::prepare() void TrackRippleRemoveAreaCommand::redo() { - track_->BeginOperation(); - if (splice_split_command_) { // We're just splicing splice_split_command_->redo_now(); @@ -145,17 +143,10 @@ void TrackRippleRemoveAreaCommand::redo() } } } - - track_->EndOperation(); - - track_->Node::InvalidateCache(TimeRange(range_.in(), RATIONAL_MAX), Track::kBlockInput); } void TrackRippleRemoveAreaCommand::undo() { - // Begin operations - track_->BeginOperation(); - if (splice_split_command_) { splice_split_command_->undo_now(); } else { @@ -176,85 +167,36 @@ void TrackRippleRemoveAreaCommand::undo() track_->InsertBlockAfter(op.block, op.before); } } - - // End operations and invalidate - track_->EndOperation(); - - track_->Node::InvalidateCache(TimeRange(range_.in(), RATIONAL_MAX), Track::kBlockInput); } // // TrackListRippleRemoveAreaCommand // +void TrackListRippleRemoveAreaCommand::prepare() +{ + foreach (Track* track, list_->GetTracks()) { + if (track->IsLocked()) { + continue; + } + + TrackRippleRemoveAreaCommand* c = new TrackRippleRemoveAreaCommand(track, range_); + commands_.append(c); + working_tracks_.append(track); + } +} + void TrackListRippleRemoveAreaCommand::redo() { - // Code that's only run on the first redo - if (commands_.isEmpty()) { - all_tracks_unlocked_ = true; - - foreach (Track* track, list_->GetTracks()) { - if (track->IsLocked()) { - all_tracks_unlocked_ = false; - continue; - } - - TrackRippleRemoveAreaCommand* c = new TrackRippleRemoveAreaCommand(track, range_); - commands_.append(c); - working_tracks_.append(track); - } - } - - if (all_tracks_unlocked_) { - // We can optimize here by simply shifting the whole cache forward instead of re-caching - // everything following this time - if (list_->type() == Track::kVideo) { - list_->parent()->ShiftVideoCache(range_.out(), range_.in()); - } else if (list_->type() == Track::kAudio) { - list_->parent()->ShiftAudioCache(range_.out(), range_.in()); - } - - foreach (Track* track, working_tracks_) { - track->BeginOperation(); - } - } - foreach (TrackRippleRemoveAreaCommand* c, commands_) { c->redo_now(); } - - if (all_tracks_unlocked_) { - foreach (Track* track, working_tracks_) { - track->EndOperation(); - } - } } void TrackListRippleRemoveAreaCommand::undo() { - if (all_tracks_unlocked_) { - // We can optimize here by simply shifting the whole cache forward instead of re-caching - // everything following this time - if (list_->type() == Track::kVideo) { - list_->parent()->ShiftVideoCache(range_.in(), range_.out()); - } else if (list_->type() == Track::kAudio) { - list_->parent()->ShiftAudioCache(range_.in(), range_.out()); - } - - foreach (Track* track, working_tracks_) { - track->BeginOperation(); - } - } - foreach (TrackRippleRemoveAreaCommand* c, commands_) { c->undo_now(); } - - if (all_tracks_unlocked_) { - foreach (Track* track, working_tracks_) { - track->EndOperation(); - track->Node::InvalidateCache(range_, Track::kBlockInput); - } - } } // @@ -282,7 +224,6 @@ TrackListRippleToolCommand::TrackListRippleToolCommand(TrackList* track_list, ripple_movement_(ripple_movement), movement_mode_(movement_mode) { - all_tracks_unlocked_ = (info_.size() == track_list_->GetTrackCount()); } void TrackListRippleToolCommand::ripple(bool redo) @@ -324,9 +265,6 @@ void TrackListRippleToolCommand::ripple(bool redo) rational pre_shift; rational post_shift; - // Begin operation so we can invalidate better later - track->BeginOperation(); - if (info.append_gap) { // Rather than rippling the referenced block, we'll insert a gap and ripple with that @@ -429,29 +367,6 @@ void TrackListRippleToolCommand::ripple(bool redo) pre_latest_out = qMax(pre_latest_out, pre_shift); post_latest_out = qMax(post_latest_out, post_shift); } - - if (all_tracks_unlocked_) { - // We rippled all the tracks, so we can shift the whole cache - if (track_list_->type() == Track::kVideo) { - track_list_->parent()->ShiftVideoCache(pre_latest_out, post_latest_out); - } else if (track_list_->type() == Track::kAudio) { - track_list_->parent()->ShiftAudioCache(pre_latest_out, post_latest_out); - } - } - - for (auto it=working_data_.cbegin(); it!=working_data_.cend(); it++) { - Track* track = it.key(); - - track->EndOperation(); - - if (!all_tracks_unlocked_) { - // If we're not shifting, the whole track must get invalidated - track->Node::InvalidateCache(TimeRange(it.value().earliest_point_of_change, RATIONAL_MAX), Track::kBlockInput); - } else if (pre_latest_out < post_latest_out) { - // If we're here, then a new section has been rippled in that needs to be rendered - track->Node::InvalidateCache(TimeRange(pre_latest_out, post_latest_out), Track::kBlockInput); - } - } } // @@ -513,11 +428,8 @@ void TimelineRippleDeleteGapsAtRegionsCommand::prepare() // Determine which gaps will be involved in this operation QVector gaps; - bool all_tracks_unlocked = true; - foreach (Track* track, timeline_->GetTracks()) { if (track->IsLocked()) { - all_tracks_unlocked = false; continue; } @@ -573,24 +485,12 @@ void TimelineRippleDeleteGapsAtRegionsCommand::prepare() if (ripple_length > 0) { foreach (GapBlock *gap, gaps) { - if (all_tracks_unlocked) { - commands_.append(new NodeBeginOperationCommand(gap->track())); - } - if (gap_lengths.value(gap) == ripple_length) { commands_.append(new TrackRippleRemoveBlockCommand(gap->track(), gap)); } else { gap_lengths[gap] -= ripple_length; commands_.append(new BlockResizeCommand(gap, gap_lengths.value(gap))); } - - if (all_tracks_unlocked) { - commands_.append(new NodeEndOperationCommand(gap->track())); - } - } - - if (all_tracks_unlocked) { - commands_.append(new TimelineShiftCacheCommand(timeline_, latest_point, latest_point - ripple_length)); } } } @@ -610,14 +510,4 @@ void TimelineRippleDeleteGapsAtRegionsCommand::undo() } } -void TimelineShiftCacheCommand::redo() -{ - timeline_->ShiftCache(from_, to_); -} - -void TimelineShiftCacheCommand::undo() -{ - timeline_->ShiftCache(to_, from_); -} - } diff --git a/app/widget/timelinewidget/undo/timelineundoripple.h b/app/widget/timelinewidget/undo/timelineundoripple.h index 6a8c1191a..11e211575 100644 --- a/app/widget/timelinewidget/undo/timelineundoripple.h +++ b/app/widget/timelinewidget/undo/timelineundoripple.h @@ -119,6 +119,8 @@ public: } protected: + virtual void prepare() override; + virtual void redo() override; virtual void undo() override; @@ -130,8 +132,6 @@ private: TimeRange range_; - bool all_tracks_unlocked_; - QVector commands_; }; @@ -200,8 +200,6 @@ private: QObject memory_manager_; - bool all_tracks_unlocked_; - }; class TimelineRippleDeleteGapsAtRegionsCommand : public UndoCommand @@ -250,34 +248,6 @@ private: }; -class TimelineShiftCacheCommand : public UndoCommand -{ -public: - TimelineShiftCacheCommand(Sequence* timeline, const rational &from, const rational &to) : - timeline_(timeline), - from_(from), - to_(to) - {} - - virtual Project* GetRelevantProject() const override - { - return timeline_->project(); - } - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - Sequence* timeline_; - - rational from_; - - rational to_; - -}; - } #endif // TIMELINEUNDORIPPLE_H diff --git a/app/widget/timelinewidget/undo/timelineundosplit.cpp b/app/widget/timelinewidget/undo/timelineundosplit.cpp index 3bf70d355..9d1ea40ce 100644 --- a/app/widget/timelinewidget/undo/timelineundosplit.cpp +++ b/app/widget/timelinewidget/undo/timelineundosplit.cpp @@ -53,7 +53,6 @@ void BlockSplitCommand::redo() // Begin an operation Track* track = block_->track(); - track->BeginOperation(); // Set lengths block_->set_length_and_media_out(new_length); @@ -76,16 +75,12 @@ void BlockSplitCommand::redo() } } } - - track->EndOperation(); } void BlockSplitCommand::undo() { Track* track = block_->track(); - track->BeginOperation(); - if (moved_transition_.IsValid()) { Node::DisconnectEdge(new_block(), moved_transition_); Node::ConnectEdge(block_, moved_transition_); @@ -96,8 +91,6 @@ void BlockSplitCommand::undo() // If we ran a reconnect command, disconnect now reconnect_tree_command_->undo_now(); - - track->EndOperation(); } // diff --git a/app/widget/timeruler/timeruler.cpp b/app/widget/timeruler/timeruler.cpp index 1b60a077c..642e160df 100644 --- a/app/widget/timeruler/timeruler.cpp +++ b/app/widget/timeruler/timeruler.cpp @@ -82,7 +82,6 @@ void TimeRuler::SetPlaybackCache(PlaybackCache *cache) if (playback_cache_) { disconnect(playback_cache_, &PlaybackCache::Invalidated, viewport(), static_cast(&QWidget::update)); disconnect(playback_cache_, &PlaybackCache::Validated, viewport(), static_cast(&QWidget::update)); - disconnect(playback_cache_, &PlaybackCache::Shifted, viewport(), static_cast(&QWidget::update)); } playback_cache_ = cache; @@ -90,7 +89,6 @@ void TimeRuler::SetPlaybackCache(PlaybackCache *cache) if (playback_cache_) { connect(playback_cache_, &PlaybackCache::Invalidated, viewport(), static_cast(&QWidget::update)); connect(playback_cache_, &PlaybackCache::Validated, viewport(), static_cast(&QWidget::update)); - connect(playback_cache_, &PlaybackCache::Shifted, viewport(), static_cast(&QWidget::update)); } update(); @@ -257,35 +255,37 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect) // If cache status is enabled if (show_cache_status_ && playback_cache_) { // FIXME: Hardcoded to get video length, if we ever need audio length, this will have to change - rational len = playback_cache_->viewer_parent()->GetVideoLength(); - int lim_left = GetScroll(); - int lim_right = lim_left + width(); + if (ViewerOutput *viewer = dynamic_cast(playback_cache_->parent())) { + rational len = viewer->GetVideoLength(); + int lim_left = GetScroll(); + int lim_right = lim_left + width(); - int cache_screen_length = TimeToScene(len); + int cache_screen_length = TimeToScene(len); - if (cache_screen_length > 0) { - int cache_y = height() - cache_status_height_; + if (cache_screen_length > 0) { + int cache_y = height() - cache_status_height_; - p->fillRect(0, cache_y, cache_screen_length, cache_status_height_, Qt::green); + p->fillRect(0, cache_y, cache_screen_length, cache_status_height_, Qt::green); - foreach (const TimeRange& range, playback_cache_->GetInvalidatedRanges(len)) { - int range_left = TimeToScene(range.in()); - if (range_left >= width()) { - continue; + foreach (const TimeRange& range, playback_cache_->GetInvalidatedRanges(len)) { + int range_left = TimeToScene(range.in()); + if (range_left >= width()) { + continue; + } + + int range_right = TimeToScene(range.out()); + if (range_right < 0) { + continue; + } + + int adjusted_left = qMax(lim_left, range_left); + + p->fillRect(adjusted_left, + cache_y, + qMin(lim_right, range_right) - adjusted_left, + cache_status_height_, + Qt::red); } - - int range_right = TimeToScene(range.out()); - if (range_right < 0) { - continue; - } - - int adjusted_left = qMax(lim_left, range_left); - - p->fillRect(adjusted_left, - cache_y, - qMin(lim_right, range_right) - adjusted_left, - cache_status_height_, - Qt::red); } } } diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 452fb49c2..ad37fb118 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -205,7 +205,6 @@ void ViewerWidget::ConnectNodeEvent(ViewerOutput *n) connect(n, &ViewerOutput::VideoParamsChanged, this, &ViewerWidget::UpdateRendererVideoParameters); connect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters); connect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange); - connect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange); connect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateStack); VideoParams vp = n->GetVideoParams(); @@ -250,7 +249,6 @@ void ViewerWidget::DisconnectNodeEvent(ViewerOutput *n) disconnect(n, &ViewerOutput::VideoParamsChanged, this, &ViewerWidget::UpdateRendererVideoParameters); disconnect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters); disconnect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange); - disconnect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange); disconnect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateStack); CloseAudioProcessor(); @@ -1556,13 +1554,6 @@ void ViewerWidget::ManualSwitchToWaveform(bool e) } } -void ViewerWidget::ViewerShiftedRange(const rational &from, const rational &to) -{ - if (GetTime() >= qMin(from, to)) { - QMetaObject::invokeMethod(this, &ViewerWidget::UpdateTextureFromNode, Qt::QueuedConnection); - } -} - void ViewerWidget::DragEntered(QDragEnterEvent* event) { if (event->mimeData()->formats().contains(Project::kItemMimeType)) { diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 0eef98bbe..bc998748c 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -291,8 +291,6 @@ private slots: void SetZoomFromMenu(QAction* action); - void ViewerShiftedRange(const olive::rational& from, const olive::rational& to); - void UpdateStack(); void ContextMenuSetFullScreen(QAction* action);