renderer: allow parameters to be changed mid-session
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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<ColorManager::OCIOMethod>(offline_group_->ocio_method()->currentIndex()));
|
||||
ColorManager::SetOCIOMethodForMode(RenderMode::kOnline, static_cast<ColorManager::OCIOMethod>(online_group_->ocio_method()->currentIndex()));
|
||||
PixelService::SetConfiguredFormatForMode(RenderMode::kOffline, static_cast<PixelFormat::Format>(offline_group_->bit_depth_combobox()->currentData().toInt()));
|
||||
PixelService::SetConfiguredFormatForMode(RenderMode::kOnline, static_cast<PixelFormat::Format>(online_group_->bit_depth_combobox()->currentData().toInt()));
|
||||
PixelService::instance()->SetConfiguredFormatForMode(RenderMode::kOffline, static_cast<PixelFormat::Format>(offline_group_->bit_depth_combobox()->currentData().toInt()));
|
||||
PixelService::instance()->SetConfiguredFormatForMode(RenderMode::kOnline, static_cast<PixelFormat::Format>(online_group_->bit_depth_combobox()->currentData().toInt()));
|
||||
SampleFormat::SetConfiguredFormatForMode(RenderMode::kOffline, static_cast<SampleFormat::Format>(offline_group_->sample_fmt_combobox()->currentData().toInt()));
|
||||
SampleFormat::SetConfiguredFormatForMode(RenderMode::kOnline, static_cast<SampleFormat::Format>(online_group_->sample_fmt_combobox()->currentData().toInt()));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<threads_.size();i++) {
|
||||
QThread* thread = new QThread(this);
|
||||
|
||||
@@ -44,7 +44,7 @@ VideoRenderBackend::VideoRenderBackend(QObject *parent) :
|
||||
|
||||
bool VideoRenderBackend::InitInternal()
|
||||
{
|
||||
cache_frame_load_buffer_.resize(PixelService::GetBufferSize(params_.format(), params_.effective_width(), params_.effective_height()));
|
||||
ResizeCacheLoadBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -84,6 +84,12 @@ void VideoRenderBackend::SetParameters(const VideoRenderingParams& params)
|
||||
// Set new parameters
|
||||
params_ = params;
|
||||
|
||||
// Resize frame load buffer
|
||||
ResizeCacheLoadBuffer();
|
||||
|
||||
// Handle custom events from derivatives
|
||||
ParamsChangedEvent();
|
||||
|
||||
// Set params on all processors
|
||||
foreach (RenderWorker* worker, processors_) {
|
||||
static_cast<VideoRenderWorker*>(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()));
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -80,6 +80,8 @@ private:
|
||||
|
||||
void Download(QVariant texture, QString filename);
|
||||
|
||||
void ResizeDownloadBuffer();
|
||||
|
||||
VideoRenderingParams video_params_;
|
||||
|
||||
VideoRenderFrameCache* frame_cache_;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -185,6 +185,8 @@ private slots:
|
||||
|
||||
void LengthChangedSlot(const rational& length);
|
||||
|
||||
void UpdateRendererParameters();
|
||||
|
||||
};
|
||||
|
||||
#endif // VIEWER_WIDGET_H
|
||||
|
||||
Reference in New Issue
Block a user