From fdbaa75dffb7b398ec051c56f4ea8c9890b0b550 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 22 Jan 2020 14:05:37 +1100 Subject: [PATCH] renderer: allow parameters to be changed mid-session --- app/core.cpp | 6 ++++ app/dialog/export/export.cpp | 2 +- .../tabs/preferencesqualitytab.cpp | 8 ++--- app/render/backend/opengl/openglbackend.cpp | 14 ++++++-- app/render/backend/opengl/openglbackend.h | 2 ++ app/render/backend/renderbackend.cpp | 2 +- app/render/backend/videorenderbackend.cpp | 17 +++++++++- app/render/backend/videorenderbackend.h | 4 +++ app/render/backend/videorenderframecache.cpp | 4 +-- app/render/backend/videorenderworker.cpp | 11 +++++- app/render/backend/videorenderworker.h | 2 ++ app/render/pixelservice.cpp | 21 ++++++++++-- app/render/pixelservice.h | 21 +++++++++--- app/widget/viewer/viewer.cpp | 34 ++++++++++++------- app/widget/viewer/viewer.h | 2 ++ 15 files changed, 118 insertions(+), 32 deletions(-) diff --git a/app/core.cpp b/app/core.cpp index 827b59014..d15741d82 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -48,6 +48,7 @@ #include "project/item/sequence/sequence.h" #include "render/colormanager.h" #include "render/diskmanager.h" +#include "render/pixelservice.h" #include "task/taskmanager.h" #include "ui/style/style.h" #include "undo/undostack.h" @@ -141,6 +142,8 @@ void Core::Stop() DiskManager::DestroyInstance(); + PixelService::DestroyInstance(); + NodeFactory::Destroy(); delete main_window_; @@ -388,6 +391,9 @@ void Core::StartGUI(bool full_screen) // Initialize task manager TaskManager::CreateInstance(); + // Initialize pixel service + PixelService::CreateInstance(); + // Connect the PanelFocusManager to the application's focus change signal connect(qApp, &QApplication::focusChanged, diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index cf908c4d6..d906980e0 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -211,7 +211,7 @@ void ExportDialog::accept() VideoRenderingParams video_render_params(dest_width, dest_height, video_tab_->frame_rate().flipped(), - PixelService::GetConfiguredFormatForMode(render_mode), + PixelService::instance()->GetConfiguredFormatForMode(render_mode), render_mode); AudioRenderingParams audio_render_params(audio_tab_->sample_rate_combobox()->currentData().toInt(), diff --git a/app/dialog/preferences/tabs/preferencesqualitytab.cpp b/app/dialog/preferences/tabs/preferencesqualitytab.cpp index 33314c1c1..1f0432f3c 100644 --- a/app/dialog/preferences/tabs/preferencesqualitytab.cpp +++ b/app/dialog/preferences/tabs/preferencesqualitytab.cpp @@ -26,13 +26,13 @@ PreferencesQualityTab::PreferencesQualityTab() quality_stack_ = new QStackedWidget(); offline_group_ = new PreferencesQualityGroup(tr("Offline Quality")); - offline_group_->bit_depth_combobox()->setCurrentIndex(PixelService::GetConfiguredFormatForMode(RenderMode::kOffline)); + offline_group_->bit_depth_combobox()->setCurrentIndex(PixelService::instance()->GetConfiguredFormatForMode(RenderMode::kOffline)); offline_group_->sample_fmt_combobox()->setCurrentIndex(SampleFormat::GetConfiguredFormatForMode(RenderMode::kOffline)); offline_group_->ocio_method()->setCurrentIndex(ColorManager::GetOCIOMethodForMode(RenderMode::kOffline)); quality_stack_->addWidget(offline_group_); online_group_ = new PreferencesQualityGroup(tr("Online Quality")); - online_group_->bit_depth_combobox()->setCurrentIndex(PixelService::GetConfiguredFormatForMode(RenderMode::kOnline)); + online_group_->bit_depth_combobox()->setCurrentIndex(PixelService::instance()->GetConfiguredFormatForMode(RenderMode::kOnline)); online_group_->sample_fmt_combobox()->setCurrentIndex(SampleFormat::GetConfiguredFormatForMode(RenderMode::kOnline)); online_group_->ocio_method()->setCurrentIndex(ColorManager::GetOCIOMethodForMode(RenderMode::kOnline)); quality_stack_->addWidget(online_group_); @@ -46,8 +46,8 @@ void PreferencesQualityTab::Accept() { ColorManager::SetOCIOMethodForMode(RenderMode::kOffline, static_cast(offline_group_->ocio_method()->currentIndex())); ColorManager::SetOCIOMethodForMode(RenderMode::kOnline, static_cast(online_group_->ocio_method()->currentIndex())); - PixelService::SetConfiguredFormatForMode(RenderMode::kOffline, static_cast(offline_group_->bit_depth_combobox()->currentData().toInt())); - PixelService::SetConfiguredFormatForMode(RenderMode::kOnline, static_cast(online_group_->bit_depth_combobox()->currentData().toInt())); + PixelService::instance()->SetConfiguredFormatForMode(RenderMode::kOffline, static_cast(offline_group_->bit_depth_combobox()->currentData().toInt())); + PixelService::instance()->SetConfiguredFormatForMode(RenderMode::kOnline, static_cast(online_group_->bit_depth_combobox()->currentData().toInt())); SampleFormat::SetConfiguredFormatForMode(RenderMode::kOffline, static_cast(offline_group_->sample_fmt_combobox()->currentData().toInt())); SampleFormat::SetConfiguredFormatForMode(RenderMode::kOnline, static_cast(online_group_->sample_fmt_combobox()->currentData().toInt())); } diff --git a/app/render/backend/opengl/openglbackend.cpp b/app/render/backend/opengl/openglbackend.cpp index aa49df222..4a529b0ec 100644 --- a/app/render/backend/opengl/openglbackend.cpp +++ b/app/render/backend/opengl/openglbackend.cpp @@ -59,7 +59,7 @@ OpenGLTexturePtr OpenGLBackend::GetCachedFrameAsTexture(const rational &time) { const char* cached_frame = GetCachedFrame(time); - if (cached_frame != nullptr) { + if (cached_frame) { master_texture_->Upload(cached_frame); return master_texture_; } @@ -69,7 +69,7 @@ OpenGLTexturePtr OpenGLBackend::GetCachedFrameAsTexture(const rational &time) bool OpenGLBackend::CompileInternal() { - if (viewer_node() == nullptr || !viewer_node()->texture_input()->IsConnected()) { + if (!viewer_node() || !viewer_node()->texture_input()->IsConnected()) { // Nothing to be done, nothing to compile return true; } @@ -154,6 +154,16 @@ void OpenGLBackend::EmitCachedFrameReady(const rational &time, const QVariant &v emit CachedFrameReady(time, QVariant::fromValue(tex), job_time); } +void OpenGLBackend::ParamsChangedEvent() +{ + // Assume if the texture is allocated, it needs to be changed. Otherwise the texture should be created through + // InitInternal() with the correct parameters + if (master_texture_) { + master_texture_->Destroy(); + master_texture_->Create(QOpenGLContext::currentContext(), params().effective_width(), params().effective_height(), params().format()); + } +} + OpenGLTexturePtr OpenGLBackend::CopyTexture(OpenGLTexturePtr input) { input->Lock(); diff --git a/app/render/backend/opengl/openglbackend.h b/app/render/backend/opengl/openglbackend.h index 243a97371..2959cd993 100644 --- a/app/render/backend/opengl/openglbackend.h +++ b/app/render/backend/opengl/openglbackend.h @@ -30,6 +30,8 @@ protected: virtual void EmitCachedFrameReady(const rational &time, const QVariant& value, qint64 job_time) override; + virtual void ParamsChangedEvent() override; + private: OpenGLTexturePtr CopyTexture(OpenGLTexturePtr input); diff --git a/app/render/backend/renderbackend.cpp b/app/render/backend/renderbackend.cpp index d6e5f2b04..9c140444f 100644 --- a/app/render/backend/renderbackend.cpp +++ b/app/render/backend/renderbackend.cpp @@ -20,7 +20,7 @@ bool RenderBackend::Init() return true; } - threads_.resize(qMax(1, QThread::idealThreadCount() / 2)); + threads_.resize(qMax(1, QThread::idealThreadCount() - 1)); for (int i=0;i(worker)->SetParameters(params_); @@ -162,6 +168,10 @@ void VideoRenderBackend::InvalidateCacheInternal(const rational &start_range, co Requeue(); } +void VideoRenderBackend::ParamsChangedEvent() +{ +} + VideoRenderFrameCache *VideoRenderBackend::frame_cache() { return &frame_cache_; @@ -406,3 +416,8 @@ void VideoRenderBackend::Requeue() CacheNext(); } + +void VideoRenderBackend::ResizeCacheLoadBuffer() +{ + cache_frame_load_buffer_.resize(PixelService::GetBufferSize(params_.format(), params_.effective_width(), params_.effective_height())); +} diff --git a/app/render/backend/videorenderbackend.h b/app/render/backend/videorenderbackend.h index 394ce72d7..30e949f84 100644 --- a/app/render/backend/videorenderbackend.h +++ b/app/render/backend/videorenderbackend.h @@ -105,6 +105,8 @@ protected: virtual void InvalidateCacheInternal(const rational &start_range, const rational &end_range) override; + virtual void ParamsChangedEvent(); + VideoRenderWorker::OperatingMode operating_mode_; signals: @@ -122,6 +124,8 @@ private: void Requeue(); + void ResizeCacheLoadBuffer(); + VideoRenderingParams params_; QByteArray cache_frame_load_buffer_; diff --git a/app/render/backend/videorenderframecache.cpp b/app/render/backend/videorenderframecache.cpp index 3e3a8ccda..36eb9109a 100644 --- a/app/render/backend/videorenderframecache.cpp +++ b/app/render/backend/videorenderframecache.cpp @@ -116,8 +116,8 @@ QString VideoRenderFrameCache::CachePathName(const QByteArray &hash, const Pixel QString ext; - if (pix_fmt == PixelFormat::PIX_FMT_RGBA8) { - // For some reason, 8-bit EXRs are extremely slow to load, so we use TIFF instead. + if (pix_fmt == PixelFormat::PIX_FMT_RGBA8 || pix_fmt == PixelFormat::PIX_FMT_RGBA16U) { + // For some reason, integer EXRs are extremely slow to load, so we use TIFF instead. ext = QStringLiteral("tiff"); } else { ext = QStringLiteral("exr"); diff --git a/app/render/backend/videorenderworker.cpp b/app/render/backend/videorenderworker.cpp index 5e0751ece..b4f6fadb9 100644 --- a/app/render/backend/videorenderworker.cpp +++ b/app/render/backend/videorenderworker.cpp @@ -187,6 +187,10 @@ void VideoRenderWorker::SetParameters(const VideoRenderingParams &video_params) { video_params_ = video_params; + if (IsStarted()) { + ResizeDownloadBuffer(); + } + ParametersChangedEvent(); } @@ -197,7 +201,7 @@ void VideoRenderWorker::SetOperatingMode(const VideoRenderWorker::OperatingMode bool VideoRenderWorker::InitInternal() { - download_buffer_.resize(PixelService::GetBufferSize(video_params().format(), video_params().effective_width(), video_params().effective_height())); + ResizeDownloadBuffer(); return true; } @@ -233,6 +237,11 @@ void VideoRenderWorker::Download(QVariant texture, QString filename) } } +void VideoRenderWorker::ResizeDownloadBuffer() +{ + download_buffer_.resize(PixelService::GetBufferSize(video_params_.format(), video_params_.effective_width(), video_params_.effective_height())); +} + NodeValueTable VideoRenderWorker::RenderBlock(const TrackOutput *track, const TimeRange &range) { // A frame can only have one active block so we just validate the in point of the range diff --git a/app/render/backend/videorenderworker.h b/app/render/backend/videorenderworker.h index 7d73e8281..28042a89f 100644 --- a/app/render/backend/videorenderworker.h +++ b/app/render/backend/videorenderworker.h @@ -80,6 +80,8 @@ private: void Download(QVariant texture, QString filename); + void ResizeDownloadBuffer(); + VideoRenderingParams video_params_; VideoRenderFrameCache* frame_cache_; diff --git a/app/render/pixelservice.cpp b/app/render/pixelservice.cpp index 3fed169d7..033e79a33 100644 --- a/app/render/pixelservice.cpp +++ b/app/render/pixelservice.cpp @@ -27,8 +27,21 @@ #include "common/define.h" #include "core.h" -PixelService::PixelService() +PixelService* PixelService::instance_ = nullptr; + +void PixelService::CreateInstance() { + instance_ = new PixelService(); +} + +void PixelService::DestroyInstance() +{ + delete instance_; +} + +PixelService *PixelService::instance() +{ + return instance_; } PixelFormat::Format PixelService::GetConfiguredFormatForMode(RenderMode::Mode mode) @@ -38,7 +51,11 @@ PixelFormat::Format PixelService::GetConfiguredFormatForMode(RenderMode::Mode mo void PixelService::SetConfiguredFormatForMode(RenderMode::Mode mode, PixelFormat::Format format) { - Core::SetPreferenceForRenderMode(mode, QStringLiteral("PixelFormat"), format); + if (format != GetConfiguredFormatForMode(mode)) { + Core::SetPreferenceForRenderMode(mode, QStringLiteral("PixelFormat"), format); + + emit FormatChanged(); + } } PixelFormat::Info PixelService::GetPixelFormatInfo(const PixelFormat::Format &format) diff --git a/app/render/pixelservice.h b/app/render/pixelservice.h index 3a52ff21f..ee84ed317 100644 --- a/app/render/pixelservice.h +++ b/app/render/pixelservice.h @@ -27,16 +27,19 @@ #include "pixelformat.h" #include "render/rendermodes.h" -class PixelService : public QObject { +class PixelService : public QObject +{ + Q_OBJECT public: - - PixelService(); + static void CreateInstance(); + static void DestroyInstance(); + static PixelService* instance(); /** * @brief Returns the configured pixel format for a given mode */ - static PixelFormat::Format GetConfiguredFormatForMode(RenderMode::Mode mode); - static void SetConfiguredFormatForMode(RenderMode::Mode mode, PixelFormat::Format format); + PixelFormat::Format GetConfiguredFormatForMode(RenderMode::Mode mode); + void SetConfiguredFormatForMode(RenderMode::Mode mode, PixelFormat::Format format); /** * @brief Return a PixelFormatInfo containing information for a certain format @@ -88,6 +91,14 @@ public: */ static void ConvertRGBtoRGBA(FramePtr frame); +signals: + void FormatChanged(); + +private: + PixelService() = default; + + static PixelService* instance_; + }; #endif // PIXELSERVICE_H diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 45f6253ff..52d868005 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -85,6 +85,8 @@ ViewerWidget::ViewerWidget(QWidget *parent) : connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler_, &TimeRuler::CacheTimeReady); connect(video_renderer_, &VideoRenderBackend::RangeInvalidated, ruler_, &TimeRuler::CacheInvalidatedRange); audio_renderer_ = new AudioBackend(this); + + connect(PixelService::instance(), &PixelService::FormatChanged, this, &ViewerWidget::UpdateRendererParameters); } void ViewerWidget::SetTimebase(const rational &r) @@ -177,19 +179,7 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man qWarning() << "Failed to find a suitable color manager for the connected viewer node"; } - RenderMode::Mode render_mode = RenderMode::kOffline; - - video_renderer_->SetParameters(VideoRenderingParams(viewer_node_->video_params(), - PixelService::GetConfiguredFormatForMode(render_mode), - render_mode, - 2)); - audio_renderer_->SetParameters(AudioRenderingParams(viewer_node_->audio_params(), - SampleFormat::GetConfiguredFormatForMode(render_mode))); - - // Reload cache into these renderers - // FIXME: Slow, rather than invalidate, we should probably serialize the cache into and out of files - video_renderer_->InvalidateCache(0, viewer_node_->Length()); - //audio_renderer_->InvalidateCache(0, viewer_node_->Length()); + UpdateRendererParameters(); } } @@ -296,6 +286,24 @@ void ViewerWidget::PushScrubbedAudio() } } +void ViewerWidget::UpdateRendererParameters() +{ + if (!viewer_node_) { + return; + } + + RenderMode::Mode render_mode = RenderMode::kOffline; + + video_renderer_->SetParameters(VideoRenderingParams(viewer_node_->video_params(), + PixelService::instance()->GetConfiguredFormatForMode(render_mode), + render_mode, + 2)); + audio_renderer_->SetParameters(AudioRenderingParams(viewer_node_->audio_params(), + SampleFormat::GetConfiguredFormatForMode(render_mode))); + + video_renderer_->InvalidateCache(0, viewer_node_->Length()); +} + void ViewerWidget::RulerTimeChange(int64_t i) { Pause(); diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 208b8cce6..f514950b3 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -185,6 +185,8 @@ private slots: void LengthChangedSlot(const rational& length); + void UpdateRendererParameters(); + }; #endif // VIEWER_WIDGET_H