From 14c7bd6dbce1a1a5390b022e48dcb5dc604a1998 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Sun, 2 Oct 2022 10:39:35 -0700 Subject: [PATCH] multicam: implemented queuing of future node selections during playback --- app/panel/multicam/multicampanel.h | 8 ------ app/panel/viewer/viewerbase.cpp | 9 ++++--- app/panel/viewer/viewerbase.h | 6 ++--- app/widget/multicam/multicamwidget.cpp | 34 ++++++++++++++++++-------- app/widget/multicam/multicamwidget.h | 17 ++++++++++--- app/widget/viewer/viewer.cpp | 13 ++++++++-- app/widget/viewer/viewer.h | 8 +++--- app/window/mainwindow/mainwindow.cpp | 3 +-- 8 files changed, 60 insertions(+), 38 deletions(-) diff --git a/app/panel/multicam/multicampanel.h b/app/panel/multicam/multicampanel.h index ffa9616d0..1b6dee6fc 100644 --- a/app/panel/multicam/multicampanel.h +++ b/app/panel/multicam/multicampanel.h @@ -14,14 +14,6 @@ public: MulticamWidget *GetMulticamWidget() const { return static_cast(GetTimeBasedWidget()); } -public slots: - void SetMulticamNode(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip) - { - ConnectViewerNode(viewer); - GetMulticamWidget()->SetMulticamNode(n); - GetMulticamWidget()->SetClip(clip); - } - protected: virtual void Retranslate() override; diff --git a/app/panel/viewer/viewerbase.cpp b/app/panel/viewer/viewerbase.cpp index ac575699e..c1aac4d13 100644 --- a/app/panel/viewer/viewerbase.cpp +++ b/app/panel/viewer/viewerbase.cpp @@ -100,16 +100,17 @@ void ViewerPanelBase::SetViewerWidget(ViewerWidget *vw) connect(vw, &ViewerWidget::TextureChanged, this, &ViewerPanelBase::TextureChanged); connect(vw, &ViewerWidget::ColorProcessorChanged, this, &ViewerPanelBase::ColorProcessorChanged); connect(vw, &ViewerWidget::ColorManagerChanged, this, &ViewerPanelBase::ColorManagerChanged); - connect(vw, &ViewerWidget::MulticamNodeDetected, this, &ViewerPanelBase::MulticamNodeDetected); SetTimeBasedWidget(vw); } void ViewerPanelBase::FocusedPanelChanged(PanelWidget *panel) { - auto vw = GetViewerWidget(); - if (vw->IsPlaying() && panel != this) { - vw->Pause(); + if (dynamic_cast(panel)) { + auto vw = GetViewerWidget(); + if (vw->IsPlaying() && panel != this) { + vw->Pause(); + } } } diff --git a/app/panel/viewer/viewerbase.h b/app/panel/viewer/viewerbase.h index 41925a537..60122c262 100644 --- a/app/panel/viewer/viewerbase.h +++ b/app/panel/viewer/viewerbase.h @@ -77,9 +77,9 @@ public: GetViewerWidget()->SetTimelineSelectedBlocks(b); } - void ConnectMulticamPanel(MulticamPanel *p) + void ConnectMulticamWidget(MulticamWidget *p) { - GetViewerWidget()->ConnectMulticamPanel(p); + GetViewerWidget()->ConnectMulticamWidget(p); } public slots: @@ -110,8 +110,6 @@ signals: */ void ColorManagerChanged(ColorManager* color_manager); - void MulticamNodeDetected(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip); - protected: void SetViewerWidget(ViewerWidget *vw); diff --git a/app/widget/multicam/multicamwidget.cpp b/app/widget/multicam/multicamwidget.cpp index 9d77b6a7c..2cc388107 100644 --- a/app/widget/multicam/multicamwidget.cpp +++ b/app/widget/multicam/multicamwidget.cpp @@ -56,15 +56,23 @@ MulticamWidget::MulticamWidget(QWidget *parent) : } } -void MulticamWidget::SetMulticamNode(MultiCamNode *n) +void MulticamWidget::SetMulticamNodeInternal(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip) { + ConnectViewerNode(viewer); node_ = n; display_->SetMulticamNode(n); + clip_ = clip; } -void MulticamWidget::SetClip(ClipBlock *clip) +void MulticamWidget::SetMulticamNode(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip, const rational &time) { - clip_ = clip; + if (time == rational::NaN || time == GetTime()) { + SetMulticamNodeInternal(viewer, n, clip); + play_queue_.clear(); + } else { + MulticamNodeQueue m = {time, viewer, n, clip}; + play_queue_.push_back(m); + } } void MulticamWidget::ConnectNodeEvent(ViewerOutput *n) @@ -83,6 +91,19 @@ void MulticamWidget::DisconnectNodeEvent(ViewerOutput *n) disconnect(n, &ViewerOutput::PixelAspectChanged, sizer_, &ViewerSizer::SetPixelAspectRatio); } +void MulticamWidget::TimeChangedEvent(const rational &t) +{ + super::TimeChangedEvent(t); + + if (!play_queue_.empty()) { + const MulticamNodeQueue &m = play_queue_.front(); + if (m.time >= t) { + SetMulticamNodeInternal(m.viewer, m.node, m.clip); + play_queue_.pop_front(); + } + } +} + void MulticamWidget::Switch(int source, bool split_clip) { if (!node_) { @@ -112,13 +133,6 @@ void MulticamWidget::Switch(int source, bool split_clip) command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(cam, cam->kCurrentInput)), source)); Core::instance()->undo_stack()->push(command); - if (cam != node_) { - SetMulticamNode(cam); - } - if (clip != clip_) { - SetClip(clip); - } - display_->update(); } diff --git a/app/widget/multicam/multicamwidget.h b/app/widget/multicam/multicamwidget.h index c68b1945a..8691c5668 100644 --- a/app/widget/multicam/multicamwidget.h +++ b/app/widget/multicam/multicamwidget.h @@ -35,15 +35,16 @@ public: MulticamDisplay *GetDisplayWidget() const { return display_; } - void SetMulticamNode(MultiCamNode *n); - - void SetClip(ClipBlock *clip); + void SetMulticamNode(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip, const rational &time); protected: virtual void ConnectNodeEvent(ViewerOutput *n) override; virtual void DisconnectNodeEvent(ViewerOutput *n) override; + virtual void TimeChangedEvent(const rational &t) override; private: + void SetMulticamNodeInternal(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip); + void Switch(int source, bool split_clip); ViewerSizer *sizer_; @@ -54,6 +55,16 @@ private: ClipBlock *clip_; + struct MulticamNodeQueue + { + rational time; + ViewerOutput *viewer; + MultiCamNode *node; + ClipBlock *clip; + }; + + std::list play_queue_; + private slots: void DisplayClicked(const QPoint &p); diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index ac741f9da..fa8c2ac52 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -419,6 +419,11 @@ void ViewerWidget::StartCapture(TimelineWidget *source, const TimeRange &time, c recording_track_ = track; } +void ViewerWidget::ConnectMulticamWidget(MulticamWidget *p) +{ + multicam_panel_ = p; +} + FramePtr ViewerWidget::DecodeCachedImage(const QString &cache_path, const QUuid &cache_id, const int64_t& time) { FramePtr frame = FrameHashCache::LoadCacheFrame(cache_path, cache_id, time); @@ -646,11 +651,15 @@ void ViewerWidget::DetectMulticamNode(const rational &time) } if (multicam) { - emit MulticamNodeDetected(GetConnectedNode(), multicam, clip); + if (multicam_panel_) { + multicam_panel_->SetMulticamNode(GetConnectedNode(), multicam, clip, time); + } auto_cacher()->SetMulticamNode(multicam); } else { auto_cacher()->SetMulticamNode(nullptr); - emit MulticamNodeDetected(nullptr, nullptr, nullptr); + if (multicam_panel_) { + multicam_panel_->SetMulticamNode(nullptr, nullptr, nullptr, time); + } } } diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 35ce4147a..a5312eb3b 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -43,7 +43,7 @@ namespace olive { -class MulticamPanel; +class MulticamWidget; /** * @brief An OpenGL-based viewer widget with playback controls (a PlaybackControls widget). @@ -122,7 +122,7 @@ public: } } - void ConnectMulticamPanel(MulticamPanel *p) { multicam_panel_ = p; } + void ConnectMulticamWidget(MulticamWidget *p); public slots: void Play(bool in_to_out_only); @@ -180,8 +180,6 @@ signals: */ void ColorManagerChanged(ColorManager* color_manager); - void MulticamNodeDetected(ViewerOutput *viewer, MultiCamNode *n, ClipBlock *clip); - protected: ViewerWidget(ViewerDisplayWidget *display, QWidget* parent = nullptr); @@ -343,7 +341,7 @@ private: QVector timeline_selected_blocks_; - MulticamPanel *multicam_panel_; + MulticamWidget *multicam_panel_; private slots: void PlaybackTimerUpdate(); diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 813bab9aa..dfb5e11a2 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -118,8 +118,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(PanelManager::instance(), &PanelManager::FocusedPanelChanged, this, &MainWindow::FocusedPanelChanged); sequence_viewer_panel_->AddPlaybackDevice(multicam_panel_->GetMulticamWidget()->GetDisplayWidget()); - sequence_viewer_panel_->ConnectMulticamPanel(multicam_panel_); - connect(sequence_viewer_panel_, &ViewerPanelBase::MulticamNodeDetected, multicam_panel_, &MulticamPanel::SetMulticamNode); + sequence_viewer_panel_->ConnectMulticamWidget(multicam_panel_->GetMulticamWidget()); scope_panel_->SetViewerPanel(sequence_viewer_panel_);