From 4de0a72786f6b04e4814b9236d3ce73109e4feb1 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 24 May 2021 16:04:46 +1000 Subject: [PATCH 1/6] rational: don't flip if null Fixes issue where flipped rationals would erroneously create a NaN. Fixes #1641 Fixes #1642 --- app/common/rational.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/common/rational.cpp b/app/common/rational.cpp index 8d12a69a1..fd5641047 100644 --- a/app/common/rational.cpp +++ b/app/common/rational.cpp @@ -142,7 +142,9 @@ rational rational::flipped() const void rational::flip() { - std::swap(denom_, numer_); + if (!isNull()) { + std::swap(denom_, numer_); + } } bool rational::isNull() const From a5d3c6f2f5655cc958bdc5961ba1fbe76fe560d6 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 26 May 2021 17:02:57 +1000 Subject: [PATCH 2/6] renderer: this should actually just be less than --- app/render/renderprocessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index e66833713..1ca1a7da8 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -311,8 +311,8 @@ QVariant RenderProcessor::ProcessVideoFootage(const FootageJob &stream, const ra // See if we can make this divider larger (i.e. if the fooage is smaller) int footage_divider = render_params.divider(); while (footage_divider > 1 - && VideoParams::GetScaledDimension(stream_data.width(), footage_divider-1) <= render_params.effective_width() - && VideoParams::GetScaledDimension(stream_data.height(), footage_divider-1) <= render_params.effective_height()) { + && VideoParams::GetScaledDimension(stream_data.width(), footage_divider-1) < render_params.effective_width() + && VideoParams::GetScaledDimension(stream_data.height(), footage_divider-1) < render_params.effective_height()) { footage_divider--; } From 2d53e35e7cdf0bcea03e8486adabf09f2563364a Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 26 May 2021 17:03:11 +1000 Subject: [PATCH 3/6] keyframeviewbase: null check to fix crash --- app/widget/keyframeview/keyframeviewbase.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/widget/keyframeview/keyframeviewbase.cpp b/app/widget/keyframeview/keyframeviewbase.cpp index c4c8e1a84..2832068a8 100644 --- a/app/widget/keyframeview/keyframeviewbase.cpp +++ b/app/widget/keyframeview/keyframeviewbase.cpp @@ -608,7 +608,9 @@ void KeyframeViewBase::AutoSelectKeyTimeNeighbors() // Ensure this key is not already selected KeyframeViewItem* item = item_map_.value(k); - item->setSelected(true); + if (item) { + item->setSelected(true); + } } } From d0bd5e2142c4865d9146fa9acfe8f5491ad5820e Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 26 May 2021 17:03:49 +1000 Subject: [PATCH 4/6] nodeparamview: fix crash when inserting color keyframe --- .../nodeparamview/nodeparamviewwidgetbridge.cpp | 14 ++++++++------ .../nodeparamview/nodeparamviewwidgetbridge.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index dd92f159e..8dfe37d58 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -197,12 +197,12 @@ void NodeParamViewWidgetBridge::SetInputValue(const QVariant &value, int track) { MultiUndoCommand* command = new MultiUndoCommand(); - SetInputValueInternal(value, track, command); + SetInputValueInternal(value, track, command, true); Core::instance()->undo_stack()->pushIfHasChildren(command); } -void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int track, MultiUndoCommand *command) +void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int track, MultiUndoCommand *command, bool insert_on_all_tracks_if_no_key) { rational node_time = GetCurrentTimeAsNodeTime(); @@ -219,6 +219,8 @@ void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int if (i == track) { track_value = value; + } else if (!insert_on_all_tracks_if_no_key) { + continue; } else { track_value = input_.node()->GetSplitValueAtTimeOnTrack(input_.input(), node_time, i, input_.element()); } @@ -339,10 +341,10 @@ void NodeParamViewWidgetBridge::WidgetCallback() MultiUndoCommand* command = new MultiUndoCommand(); - SetInputValueInternal(c.red(), 0, command); - SetInputValueInternal(c.green(), 1, command); - SetInputValueInternal(c.blue(), 2, command); - SetInputValueInternal(c.alpha(), 3, command); + SetInputValueInternal(c.red(), 0, command, false); + SetInputValueInternal(c.green(), 1, command, false); + SetInputValueInternal(c.blue(), 2, command, false); + SetInputValueInternal(c.alpha(), 3, command, false); Node* n = input_.node(); n->blockSignals(true); diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h index b583a2e8b..aff076ffa 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h @@ -62,7 +62,7 @@ private: void SetInputValue(const QVariant& value, int track); - void SetInputValueInternal(const QVariant& value, int track, MultiUndoCommand *command); + void SetInputValueInternal(const QVariant& value, int track, MultiUndoCommand *command, bool insert_on_all_tracks_if_no_key); void ProcessSlider(NumericSliderBase* slider, const QVariant& value); From d13f68593be16a48bd29abb1901b81b8c7d692d1 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 26 May 2021 18:00:12 +1000 Subject: [PATCH 5/6] audiomonitor: fix param sync issue that caused crashes --- app/audio/audiomanager.cpp | 4 ++-- app/panel/audiomonitor/audiomonitor.h | 5 +++++ app/widget/audiomonitor/audiomonitor.cpp | 24 +++++++++++++----------- app/widget/audiomonitor/audiomonitor.h | 5 +++++ app/window/mainwindow/mainwindow.cpp | 4 +++- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/app/audio/audiomanager.cpp b/app/audio/audiomanager.cpp index da2f48387..6a2bee79c 100644 --- a/app/audio/audiomanager.cpp +++ b/app/audio/audiomanager.cpp @@ -164,9 +164,9 @@ void AudioManager::SetOutputParams(const AudioParams ¶ms) // Refresh output device SetOutputDevice(output_device_info_); - - emit AudioParamsChanged(output_params_); } + + emit AudioParamsChanged(output_params_); } void AudioManager::SetInputDevice(const QAudioDeviceInfo &info) diff --git a/app/panel/audiomonitor/audiomonitor.h b/app/panel/audiomonitor/audiomonitor.h index 1c5c06aa8..5d4b49c49 100644 --- a/app/panel/audiomonitor/audiomonitor.h +++ b/app/panel/audiomonitor/audiomonitor.h @@ -35,6 +35,11 @@ class AudioMonitorPanel : public PanelWidget public: AudioMonitorPanel(QWidget* parent = nullptr); + bool IsPlaying() const + { + return audio_monitor_->IsPlaying(); + } + void SetParams(const AudioParams& params) { audio_monitor_->SetParams(params); diff --git a/app/widget/audiomonitor/audiomonitor.cpp b/app/widget/audiomonitor/audiomonitor.cpp index 2e709a143..6363465c5 100644 --- a/app/widget/audiomonitor/audiomonitor.cpp +++ b/app/widget/audiomonitor/audiomonitor.cpp @@ -49,17 +49,19 @@ AudioMonitor::AudioMonitor(QWidget *parent) : void AudioMonitor::SetParams(const AudioParams ¶ms) { - params_ = params; + if (params_ != params) { + params_ = params; - for (int i=0;i v(params_.channel_count(), 0); - if (file_ || waveform_) { + if (IsPlaying()) { // Determines how many milliseconds have passed since last update qint64 current_time = QDateTime::currentMSecsSinceEpoch(); qint64 delta_time = current_time - last_time_; @@ -308,7 +310,7 @@ void AudioMonitor::paintGL() } } - if (all_zeroes && !file_ && !waveform_) { + if (all_zeroes && !IsPlaying()) { // Optimize by disabling the update loop SetUpdateLoop(false); } diff --git a/app/widget/audiomonitor/audiomonitor.h b/app/widget/audiomonitor/audiomonitor.h index 87803b74d..1570618bc 100644 --- a/app/widget/audiomonitor/audiomonitor.h +++ b/app/widget/audiomonitor/audiomonitor.h @@ -38,6 +38,11 @@ class AudioMonitor : public QOpenGLWidget public: AudioMonitor(QWidget* parent = nullptr); + bool IsPlaying() const + { + return file_ || waveform_; + } + public slots: void SetParams(const AudioParams& params); diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 8fb4a2bc7..297de30c7 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -692,7 +692,9 @@ void MainWindow::SaveCustomShortcuts() void MainWindow::UpdateAudioMonitorParams(ViewerOutput *viewer) { - audio_monitor_panel_->SetParams(viewer ? viewer->GetAudioParams() : AudioParams()); + if (!audio_monitor_panel_->IsPlaying()) { + audio_monitor_panel_->SetParams(viewer ? viewer->GetAudioParams() : AudioParams()); + } } void MainWindow::FocusedPanelChanged(PanelWidget *panel) From 91c88b1ccf80955b11bbd20defd5b9524c7b937a Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 26 May 2021 18:07:18 +1000 Subject: [PATCH 6/6] openglrenderer: initialize framebuffer variable as null --- app/render/opengl/openglrenderer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/render/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp index d97a6def3..992c660f7 100644 --- a/app/render/opengl/openglrenderer.cpp +++ b/app/render/opengl/openglrenderer.cpp @@ -79,7 +79,8 @@ private: OpenGLRenderer::OpenGLRenderer(QObject* parent) : Renderer(parent), cache_timer_(this), - context_(nullptr) + context_(nullptr), + framebuffer_(0) { cache_timer_.setInterval(kTextureCacheMaxSize); connect(&cache_timer_, &QTimer::timeout, this, &OpenGLRenderer::GarbageCollectTextureCache); @@ -153,6 +154,7 @@ void OpenGLRenderer::DestroyInternal() if (context_) { // Delete framebuffer functions_->glDeleteFramebuffers(1, &framebuffer_); + framebuffer_ = 0; for (auto it=texture_cache_.cbegin(); it!=texture_cache_.cend(); it++) { functions_->glDeleteTextures(1, &it->texture);