diff --git a/app/audio/audiomanager.cpp b/app/audio/audiomanager.cpp index 57ee51fd0..e3c897606 100644 --- a/app/audio/audiomanager.cpp +++ b/app/audio/audiomanager.cpp @@ -106,32 +106,32 @@ void AudioManager::SetOutputDevice(const QAudioDeviceInfo &info) format.setByteOrder(QAudioFormat::LittleEndian); switch (output_params_.format()) { - case SAMPLE_FMT_U8: + case SampleFormat::SAMPLE_FMT_U8: format.setSampleSize(8); format.setSampleType(QAudioFormat::UnSignedInt); break; - case SAMPLE_FMT_S16: + case SampleFormat::SAMPLE_FMT_S16: format.setSampleSize(16); format.setSampleType(QAudioFormat::SignedInt); break; - case SAMPLE_FMT_S32: + case SampleFormat::SAMPLE_FMT_S32: format.setSampleSize(32); format.setSampleType(QAudioFormat::SignedInt); break; - case SAMPLE_FMT_S64: + case SampleFormat::SAMPLE_FMT_S64: format.setSampleSize(64); format.setSampleType(QAudioFormat::SignedInt); break; - case SAMPLE_FMT_FLT: + case SampleFormat::SAMPLE_FMT_FLT: format.setSampleSize(32); format.setSampleType(QAudioFormat::Float); break; - case SAMPLE_FMT_DBL: + case SampleFormat::SAMPLE_FMT_DBL: format.setSampleSize(64); format.setSampleType(QAudioFormat::Float); break; - case SAMPLE_FMT_COUNT: - case SAMPLE_FMT_INVALID: + case SampleFormat::SAMPLE_FMT_COUNT: + case SampleFormat::SAMPLE_FMT_INVALID: abort(); } diff --git a/app/audio/sampleformat.cpp b/app/audio/sampleformat.cpp index 08fff1777..df1437b67 100644 --- a/app/audio/sampleformat.cpp +++ b/app/audio/sampleformat.cpp @@ -1 +1,36 @@ #include "sampleformat.h" + +#include "core.h" + +QString SampleFormat::GetSampleFormatName(const SampleFormat::Format &f) +{ + switch (f) { + case SAMPLE_FMT_U8: + return tr("Unsigned 8-bit"); + case SAMPLE_FMT_S16: + return tr("Signed 16-bit"); + case SAMPLE_FMT_S32: + return tr("Signed 32-bit"); + case SAMPLE_FMT_S64: + return tr("Signed 64-bit"); + case SAMPLE_FMT_FLT: + return tr("32-bit Float"); + case SAMPLE_FMT_DBL: + return tr("64-bit Float"); + case SAMPLE_FMT_COUNT: + case SAMPLE_FMT_INVALID: + break; + } + + return tr("Invalid"); +} + +SampleFormat::Format SampleFormat::GetConfiguredFormatForMode(RenderMode::Mode mode) +{ + return static_cast(Core::GetPreferenceForRenderMode(mode, QStringLiteral("SampleFormat")).toInt()); +} + +void SampleFormat::SetConfiguredFormatForMode(RenderMode::Mode mode, SampleFormat::Format format) +{ + Core::SetPreferenceForRenderMode(mode, QStringLiteral("SampleFormat"), format); +} diff --git a/app/audio/sampleformat.h b/app/audio/sampleformat.h index c87ca4d39..2c03227ba 100644 --- a/app/audio/sampleformat.h +++ b/app/audio/sampleformat.h @@ -21,17 +21,34 @@ #ifndef SAMPLEFORMAT_H #define SAMPLEFORMAT_H -enum SampleFormat { - SAMPLE_FMT_INVALID = -1, +#include - SAMPLE_FMT_U8, - SAMPLE_FMT_S16, - SAMPLE_FMT_S32, - SAMPLE_FMT_S64, - SAMPLE_FMT_FLT, - SAMPLE_FMT_DBL, +#include "render/rendermodes.h" + +class SampleFormat : public QObject +{ + Q_OBJECT +public: + SampleFormat() = default; + + enum Format { + SAMPLE_FMT_INVALID = -1, + + SAMPLE_FMT_U8, + SAMPLE_FMT_S16, + SAMPLE_FMT_S32, + SAMPLE_FMT_S64, + SAMPLE_FMT_FLT, + SAMPLE_FMT_DBL, + + SAMPLE_FMT_COUNT + }; + + static QString GetSampleFormatName(const Format& f); + + static Format GetConfiguredFormatForMode(RenderMode::Mode mode); + static void SetConfiguredFormatForMode(RenderMode::Mode mode, Format format); - SAMPLE_FMT_COUNT }; #endif // SAMPLEFORMAT_H diff --git a/app/codec/ffmpeg/ffmpegcommon.cpp b/app/codec/ffmpeg/ffmpegcommon.cpp index 2d2063dba..d1236816a 100644 --- a/app/codec/ffmpeg/ffmpegcommon.cpp +++ b/app/codec/ffmpeg/ffmpegcommon.cpp @@ -14,21 +14,21 @@ AVPixelFormat FFmpegCommon::GetCompatiblePixelFormat(const AVPixelFormat &pix_fm nullptr); } -SampleFormat FFmpegCommon::GetNativeSampleFormat(const AVSampleFormat &smp_fmt) +SampleFormat::Format FFmpegCommon::GetNativeSampleFormat(const AVSampleFormat &smp_fmt) { switch (smp_fmt) { case AV_SAMPLE_FMT_U8: - return SAMPLE_FMT_U8; + return SampleFormat::SAMPLE_FMT_U8; case AV_SAMPLE_FMT_S16: - return SAMPLE_FMT_S16; + return SampleFormat::SAMPLE_FMT_S16; case AV_SAMPLE_FMT_S32: - return SAMPLE_FMT_S32; + return SampleFormat::SAMPLE_FMT_S32; case AV_SAMPLE_FMT_S64: - return SAMPLE_FMT_S64; + return SampleFormat::SAMPLE_FMT_S64; case AV_SAMPLE_FMT_FLT: - return SAMPLE_FMT_FLT; + return SampleFormat::SAMPLE_FMT_FLT; case AV_SAMPLE_FMT_DBL: - return SAMPLE_FMT_DBL; + return SampleFormat::SAMPLE_FMT_DBL; case AV_SAMPLE_FMT_U8P : case AV_SAMPLE_FMT_S16P: case AV_SAMPLE_FMT_S32P: @@ -40,26 +40,26 @@ SampleFormat FFmpegCommon::GetNativeSampleFormat(const AVSampleFormat &smp_fmt) break; } - return SAMPLE_FMT_INVALID; + return SampleFormat::SAMPLE_FMT_INVALID; } -AVSampleFormat FFmpegCommon::GetFFmpegSampleFormat(const SampleFormat &smp_fmt) +AVSampleFormat FFmpegCommon::GetFFmpegSampleFormat(const SampleFormat::Format &smp_fmt) { switch (smp_fmt) { - case SAMPLE_FMT_U8: + case SampleFormat::SAMPLE_FMT_U8: return AV_SAMPLE_FMT_U8; - case SAMPLE_FMT_S16: + case SampleFormat::SAMPLE_FMT_S16: return AV_SAMPLE_FMT_S16; - case SAMPLE_FMT_S32: + case SampleFormat::SAMPLE_FMT_S32: return AV_SAMPLE_FMT_S32; - case SAMPLE_FMT_S64: + case SampleFormat::SAMPLE_FMT_S64: return AV_SAMPLE_FMT_S64; - case SAMPLE_FMT_FLT: + case SampleFormat::SAMPLE_FMT_FLT: return AV_SAMPLE_FMT_FLT; - case SAMPLE_FMT_DBL: + case SampleFormat::SAMPLE_FMT_DBL: return AV_SAMPLE_FMT_DBL; - case SAMPLE_FMT_INVALID: - case SAMPLE_FMT_COUNT: + case SampleFormat::SAMPLE_FMT_INVALID: + case SampleFormat::SAMPLE_FMT_COUNT: break; } diff --git a/app/codec/ffmpeg/ffmpegcommon.h b/app/codec/ffmpeg/ffmpegcommon.h index c322e55b9..5383e1e97 100644 --- a/app/codec/ffmpeg/ffmpegcommon.h +++ b/app/codec/ffmpeg/ffmpegcommon.h @@ -28,12 +28,12 @@ public: /** * @brief Returns a native sample format type for a given AVSampleFormat */ - static SampleFormat GetNativeSampleFormat(const AVSampleFormat& smp_fmt); + static SampleFormat::Format GetNativeSampleFormat(const AVSampleFormat& smp_fmt); /** * @brief Returns an FFmpeg sample format type for a given native type */ - static AVSampleFormat GetFFmpegSampleFormat(const SampleFormat& smp_fmt); + static AVSampleFormat GetFFmpegSampleFormat(const SampleFormat::Format &smp_fmt); }; #endif // FFMPEGABSTRACTION_H diff --git a/app/codec/waveinput.cpp b/app/codec/waveinput.cpp index d3650edf2..12edb6135 100644 --- a/app/codec/waveinput.cpp +++ b/app/codec/waveinput.cpp @@ -85,27 +85,27 @@ bool WaveInput::open() uint16_t bits_per_sample; data_stream >> bits_per_sample; - SampleFormat format; + SampleFormat::Format format; switch (bits_per_sample) { case 8: - format = SAMPLE_FMT_U8; + format = SampleFormat::SAMPLE_FMT_U8; break; case 16: - format = SAMPLE_FMT_S16; + format = SampleFormat::SAMPLE_FMT_S16; break; case 32: if (data_is_float) { - format = SAMPLE_FMT_FLT; + format = SampleFormat::SAMPLE_FMT_FLT; } else { - format = SAMPLE_FMT_S32; + format = SampleFormat::SAMPLE_FMT_S32; } break; case 64: if (data_is_float) { - format = SAMPLE_FMT_DBL; + format = SampleFormat::SAMPLE_FMT_DBL; } else { - format = SAMPLE_FMT_S64; + format = SampleFormat::SAMPLE_FMT_S64; } break; default: diff --git a/app/codec/waveoutput.cpp b/app/codec/waveoutput.cpp index 34f73407b..e8ed84882 100644 --- a/app/codec/waveoutput.cpp +++ b/app/codec/waveoutput.cpp @@ -38,18 +38,18 @@ bool WaveOutput::open() // Type of format switch (params_.format()) { - case SAMPLE_FMT_U8: - case SAMPLE_FMT_S16: - case SAMPLE_FMT_S32: - case SAMPLE_FMT_S64: + case SampleFormat::SAMPLE_FMT_U8: + case SampleFormat::SAMPLE_FMT_S16: + case SampleFormat::SAMPLE_FMT_S32: + case SampleFormat::SAMPLE_FMT_S64: write_int(&file_, kWAVIntegerFormat); break; - case SAMPLE_FMT_FLT: - case SAMPLE_FMT_DBL: + case SampleFormat::SAMPLE_FMT_FLT: + case SampleFormat::SAMPLE_FMT_DBL: write_int(&file_, kWAVFloatFormat); break; - case SAMPLE_FMT_INVALID: - case SAMPLE_FMT_COUNT: + case SampleFormat::SAMPLE_FMT_INVALID: + case SampleFormat::SAMPLE_FMT_COUNT: qWarning() << "Invalid sample format for WAVE audio"; file_.close(); return false; diff --git a/app/config/config.cpp b/app/config/config.cpp index b6e11d6ee..cbfaa6767 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -85,6 +85,14 @@ void Config::SetDefaults() config_map_["DefaultSequenceFrameRate"] = QVariant::fromValue(rational(1001, 30000)); config_map_["DefaultSequenceAudioFrequency"] = 48000; config_map_["DefaultSequenceAudioLayout"] = AV_CH_LAYOUT_STEREO; + + // Online/offline settings + config_map_["OnlinePixelFormat"] = PixelFormat::PIX_FMT_RGBA32F; + config_map_["OfflinePixelFormat"] = PixelFormat::PIX_FMT_RGBA16F; + config_map_["OnlineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT; + config_map_["OfflineSampleFormat"] = SampleFormat::SAMPLE_FMT_FLT; + config_map_["OnlineOCIOMethod"] = ColorManager::kOCIOAccurate; + config_map_["OfflineOCIOMethod"] = ColorManager::kOCIOFast; } void Config::Load() diff --git a/app/core.cpp b/app/core.cpp index fe38380c4..827b59014 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -600,6 +600,25 @@ int Core::CountFilesInFileList(const QFileInfoList &filenames) return file_count; } +QString GetRenderModePreferencePrefix(RenderMode::Mode mode, const QString &preference) { + QString key; + + key.append((mode == RenderMode::kOffline) ? QStringLiteral("Offline") : QStringLiteral("Online")); + key.append(preference); + + return key; +} + +QVariant Core::GetPreferenceForRenderMode(RenderMode::Mode mode, const QString &preference) +{ + return Config::Current()[GetRenderModePreferencePrefix(mode, preference)]; +} + +void Core::SetPreferenceForRenderMode(RenderMode::Mode mode, const QString &preference, const QVariant &value) +{ + Config::Current()[GetRenderModePreferencePrefix(mode, preference)] = value; +} + void Core::InitiateOpenSaveProcess(Task *manager, const QString& dialog_text, const QString& dialog_title) { // Create save dialog diff --git a/app/core.h b/app/core.h index d8bc81168..f7b23968a 100644 --- a/app/core.h +++ b/app/core.h @@ -171,6 +171,9 @@ public: */ static int CountFilesInFileList(const QFileInfoList &filenames); + static QVariant GetPreferenceForRenderMode(RenderMode::Mode mode, const QString& preference); + static void SetPreferenceForRenderMode(RenderMode::Mode mode, const QString& preference, const QVariant& value); + public slots: /** * @brief Starts an open file dialog to load a project from file diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index b6d381122..cf908c4d6 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -13,6 +13,7 @@ #include "project/item/sequence/sequence.h" #include "project/project.h" #include "render/backend/opengl/openglexporter.h" +#include "render/pixelservice.h" #include "ui/icons/icons.h" ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) : @@ -205,13 +206,17 @@ void ExportDialog::accept() dest_height); } - // FIXME: Hardcoded pixel format - VideoRenderingParams video_render_params(dest_width, dest_height, video_tab_->frame_rate().flipped(), PixelFormat::PIX_FMT_RGBA32F, RenderMode::kOnline); + RenderMode::Mode render_mode = RenderMode::kOnline; + + VideoRenderingParams video_render_params(dest_width, + dest_height, + video_tab_->frame_rate().flipped(), + PixelService::GetConfiguredFormatForMode(render_mode), + render_mode); - // FIXME: Hardcoded sample format AudioRenderingParams audio_render_params(audio_tab_->sample_rate_combobox()->currentData().toInt(), audio_tab_->channel_layout_combobox()->currentData().toULongLong(), - SAMPLE_FMT_FLT); + SampleFormat::GetConfiguredFormatForMode(render_mode)); ColorProcessorPtr color_processor = ColorProcessor::Create(color_manager_->GetConfig(), OCIO::ROLE_SCENE_LINEAR, diff --git a/app/dialog/preferences/preferences.cpp b/app/dialog/preferences/preferences.cpp index 3197d3eef..d25a2a3ed 100644 --- a/app/dialog/preferences/preferences.cpp +++ b/app/dialog/preferences/preferences.cpp @@ -29,7 +29,7 @@ #include "tabs/preferencesgeneraltab.h" #include "tabs/preferencesbehaviortab.h" #include "tabs/preferencesappearancetab.h" -#include "tabs/preferencesplaybacktab.h" +#include "tabs/preferencesqualitytab.h" #include "tabs/preferencesdisktab.h" #include "tabs/preferencesaudiotab.h" #include "tabs/preferenceskeyboardtab.h" @@ -52,8 +52,8 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, QMenuBar* main_menu_bar) : AddTab(new PreferencesGeneralTab(), tr("General")); AddTab(new PreferencesAppearanceTab(), tr("Appearance")); AddTab(new PreferencesBehaviorTab(), tr("Behavior")); + AddTab(new PreferencesQualityTab(), tr("Quality")); AddTab(new PreferencesDiskTab(), tr("Disk")); - AddTab(new PreferencesPlaybackTab(), tr("Playback")); AddTab(new PreferencesAudioTab(), tr("Audio")); AddTab(new PreferencesKeyboardTab(main_menu_bar), tr("Keyboard")); @@ -70,7 +70,6 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, QMenuBar* main_menu_bar) : connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(list_widget_, SIGNAL(currentRowChanged(int)), preference_pane_stack_, SLOT(setCurrentIndex(int))); - } void PreferencesDialog::accept() @@ -86,247 +85,6 @@ void PreferencesDialog::accept() } QDialog::accept(); - - /* - bool restart_after_saving = false; - bool reinit_audio = false; - bool reload_language = false; - bool reload_effects = false; - bool reset_ocio_shaders = false; - bool reset_render_threads = false; - - // Validate whether the specified CSS file exists - if (!custom_css_fn->text().isEmpty() && !QFileInfo::exists(custom_css_fn->text())) { - QMessageBox::critical( - this, - tr("Invalid CSS File"), - tr("CSS file '%1' does not exist.").arg(custom_css_fn->text()) - ); - return; - } - - // Validate whether the chosen OCIO configuration file - if (enable_color_management->isChecked()) { - - // Check whether the file exists - if (!QFileInfo::exists(ocio_config_file->text())) { - - QString msg_title = tr("Invalid OpenColorIO Configuration File"); - QString msg_body; - - if (ocio_config_file->text().isEmpty()) { - msg_body = tr("You must specify an OpenColorIO configuration file if color management is enabled."); - } else { - msg_body = tr("OpenColorIO configuration file '%1' does not exist.").arg(ocio_config_file->text()); - } - - QMessageBox::critical( - this, - msg_title, - msg_body - ); - return; - - } else if (olive::config.ocio_config_path != ocio_config_file->text()) { - - // Check whether OCIO can load it - OCIO::ConstConfigRcPtr file_config = TestOCIOConfig(ocio_config_file->text().toUtf8()); - - if (!file_config) { - return; - } - - } - } - - // Validate whether one of the bool options requires a restart - bool bool_requires_restart = false; - for (int i=0;iisChecked() != *bool_value.at(i)) { - bool_requires_restart = true; - break; - } - } - - // Check if any settings will require a restart of Olive (including the bool options determined above) - if (bool_requires_restart - || olive::config.thumbnail_resolution != thumbnail_res_spinbox->value() - || olive::config.waveform_resolution != waveform_res_spinbox->value() - || olive::config.css_path != custom_css_fn->text() - || olive::config.style != static_cast(ui_style->currentData().toInt())) { - - // any changes to these settings will require a restart - ask the user if we should do one now or later - - int ret = QMessageBox::question(this, - "Restart Required", - "Some of the changed settings will require a restart of Olive. Would you like " - "to restart now?", - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) { - // Return to Preferences dialog without saving any settings - return; - } else if (ret == QMessageBox::Yes) { - - // Check if we can close the current project. If not, we'll treat it as if the user clicked "Cancel". - if (olive::Global->can_close_project()) { - restart_after_saving = true; - } else { - return; - } - } - // Selecting "No" will save the settings and not restart. They will become active next time Olive opens. - - } - - - // Everything checks out, start saving settings from the UI to the backend - olive::config.css_path = custom_css_fn->text(); - olive::config.recording_mode = recordingComboBox->currentIndex() + 1; - olive::config.img_seq_formats = imgSeqFormatEdit->text(); - olive::config.upcoming_queue_size = upcoming_queue_spinbox->value(); - olive::config.upcoming_queue_type = upcoming_queue_type->currentIndex(); - olive::config.previous_queue_size = previous_queue_spinbox->value(); - olive::config.previous_queue_type = previous_queue_type->currentIndex(); - - // Audio settings may require the audio device to be re-initiated. - if (kUsingAudioOutput != audio_output_devices->currentData().toString() - || olive::config.preferred_audio_input != audio_input_devices->currentData().toString() - || olive::config.audio_rate != audio_sample_rate->currentData().toInt()) { - reinit_audio = true; - } - kUsingAudioOutput = audio_output_devices->currentData().toString(); - olive::config.preferred_audio_input = audio_input_devices->currentData().toString(); - olive::config.audio_rate = audio_sample_rate->currentData().toInt(); - - olive::config.effect_textbox_lines = effect_textbox_lines_field->value(); - - // see if the language file should be reloaded (not necessary if the app is restarting anyway) - if (!restart_after_saving - && olive::config.language_file != language_combobox->currentData().toString()) { - reload_language = true; - } - olive::config.language_file = language_combobox->currentData().toString(); - - // Check whether OCIO settings will require a reset of the render threads - if (olive::config.playback_bit_depth != playback_bit_depth->currentIndex() - || olive::config.export_bit_depth != export_bit_depth->currentIndex()) { - reset_render_threads = true; - } - if (olive::config.ocio_config_path != ocio_config_file->text() - || olive::config.ocio_display != ocio_display->currentText() - || olive::config.ocio_view != ocio_view->currentText() - || olive::config.ocio_look != ocio_look->currentData().toString()) { - reset_ocio_shaders = true; - } - if (olive::config.ocio_config_path != ocio_config_file->text()) { - OCIO::SetCurrentConfig(OCIO::Config::CreateFromFile(ocio_config_file->text().toUtf8())); - olive::config.ocio_config_path = ocio_config_file->text(); - } - olive::config.enable_color_management = enable_color_management->isChecked(); - olive::config.playback_bit_depth = playback_bit_depth->currentIndex(); - olive::config.export_bit_depth = export_bit_depth->currentIndex(); - olive::config.ocio_display = ocio_display->currentText(); - olive::config.ocio_default_input_colorspace = ocio_default_input->currentText(); - olive::config.ocio_view = ocio_view->currentText(); - - // We use data here instead of text because there's a "(None)" option with an empty string - olive::config.ocio_look = ocio_look->currentData().toString(); - - - // Set default sequence options - olive::config.default_sequence_width = default_sequence.width(); - olive::config.default_sequence_height = default_sequence.height(); - olive::config.default_sequence_framerate = default_sequence.frame_rate(); - olive::config.default_sequence_audio_frequency = default_sequence.audio_frequency(); - olive::config.default_sequence_audio_channel_layout = default_sequence.audio_layout(); - - // Set all bool options - for (int i=0;iisChecked(); - } - - // Set new style - olive::config.style = static_cast(ui_style->currentData().toInt()); - - // Check if the thumbnail or waveform icon fields have changed, we may need to recreate the previews if so - if (olive::config.thumbnail_resolution != thumbnail_res_spinbox->value() - || olive::config.waveform_resolution != waveform_res_spinbox->value()) { - // we're changing the size of thumbnails and waveforms, so let's delete them and regenerate them next start - - // delete nothing - PreviewDeleteTypes delete_type = DELETE_NONE; - - if (olive::config.thumbnail_resolution != thumbnail_res_spinbox->value()) { - // delete existing thumbnails - olive::config.thumbnail_resolution = thumbnail_res_spinbox->value(); - - // delete only thumbnails - delete_type = DELETE_THUMBNAILS; - } - - if (olive::config.waveform_resolution != waveform_res_spinbox->value()) { - // delete existing waveforms - olive::config.waveform_resolution = waveform_res_spinbox->value(); - - // if we're already deleting thumbnails - if (delete_type == DELETE_THUMBNAILS) { - // delete all - delete_type = DELETE_BOTH; - } else { - // just delete waveforms - delete_type = DELETE_WAVEFORMS; - } - } - - delete_previews(delete_type); - } - - - - QDialog::accept(); - - if (restart_after_saving) { - - // since we already ran can_close_project(), bypass checking again by running set_modified(false) - olive::Global->set_modified(false); - - olive::MainWindow->close(); - - QProcess::startDetached(QApplication::applicationFilePath(), { olive::ActiveProjectFilename }); - } else { - - // Audio settings may require the audio device to be re-initiated. - if (reinit_audio) { - init_audio(); - } - - if (reload_effects) { - panel_effect_controls->Reload(); - } - - // reload language file if it changed - if (reload_language) { - olive::Global->load_translation_from_config(); - } - - if (reset_render_threads) { - if (panel_footage_viewer->seq != nullptr) { - panel_footage_viewer->seq->Close(); - } - panel_footage_viewer->viewer_widget()->get_renderer()->delete_ctx(); - if (panel_sequence_viewer->seq != nullptr) { - panel_sequence_viewer->seq->Close(); - } - panel_sequence_viewer->viewer_widget()->get_renderer()->delete_ctx(); - } else if (reset_ocio_shaders) { - panel_footage_viewer->viewer_widget()->get_renderer()->destroy_ocio(); - panel_sequence_viewer->viewer_widget()->get_renderer()->destroy_ocio(); - } - - } - */ } void PreferencesDialog::AddTab(PreferencesTab *tab, const QString &title) diff --git a/app/dialog/preferences/tabs/CMakeLists.txt b/app/dialog/preferences/tabs/CMakeLists.txt index e381fb72f..65259cc3b 100644 --- a/app/dialog/preferences/tabs/CMakeLists.txt +++ b/app/dialog/preferences/tabs/CMakeLists.txt @@ -24,8 +24,8 @@ set(OLIVE_SOURCES dialog/preferences/tabs/preferencesdisktab.cpp dialog/preferences/tabs/preferencesappearancetab.h dialog/preferences/tabs/preferencesappearancetab.cpp - dialog/preferences/tabs/preferencesplaybacktab.h - dialog/preferences/tabs/preferencesplaybacktab.cpp + dialog/preferences/tabs/preferencesqualitytab.h + dialog/preferences/tabs/preferencesqualitytab.cpp dialog/preferences/tabs/preferencesaudiotab.h dialog/preferences/tabs/preferencesaudiotab.cpp dialog/preferences/tabs/preferenceskeyboardtab.h diff --git a/app/dialog/preferences/tabs/preferencesplaybacktab.cpp b/app/dialog/preferences/tabs/preferencesplaybacktab.cpp deleted file mode 100644 index 5d21e773e..000000000 --- a/app/dialog/preferences/tabs/preferencesplaybacktab.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "preferencesplaybacktab.h" - -#include -#include -#include - -PreferencesPlaybackTab::PreferencesPlaybackTab() -{ -} - -void PreferencesPlaybackTab::Accept() -{ - -} diff --git a/app/dialog/preferences/tabs/preferencesplaybacktab.h b/app/dialog/preferences/tabs/preferencesplaybacktab.h deleted file mode 100644 index 00321ec0f..000000000 --- a/app/dialog/preferences/tabs/preferencesplaybacktab.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PREFERENCESPLAYBACKTAB_H -#define PREFERENCESPLAYBACKTAB_H - -#include -#include - -#include "preferencestab.h" - -class PreferencesPlaybackTab : public PreferencesTab -{ - Q_OBJECT -public: - PreferencesPlaybackTab(); - - virtual void Accept() override; - -private: -}; - -#endif // PREFERENCESPLAYBACKTAB_H diff --git a/app/dialog/preferences/tabs/preferencesqualitytab.cpp b/app/dialog/preferences/tabs/preferencesqualitytab.cpp new file mode 100644 index 000000000..33314c1c1 --- /dev/null +++ b/app/dialog/preferences/tabs/preferencesqualitytab.cpp @@ -0,0 +1,122 @@ +#include "preferencesqualitytab.h" + +#include +#include +#include + +#include "render/colormanager.h" +#include "render/pixelservice.h" + +PreferencesQualityTab::PreferencesQualityTab() +{ + QVBoxLayout* layout = new QVBoxLayout(this); + + QHBoxLayout* profile_layout = new QHBoxLayout(); + profile_layout->setMargin(0); + + profile_layout->addWidget(new QLabel(tr("Profile:"))); + + QComboBox* profile_combobox = new QComboBox(); + profile_combobox->addItem(tr("Preview (Offline)")); + profile_combobox->addItem(tr("Export (Online)")); + profile_layout->addWidget(profile_combobox); + + layout->addLayout(profile_layout); + + quality_stack_ = new QStackedWidget(); + + offline_group_ = new PreferencesQualityGroup(tr("Offline Quality")); + offline_group_->bit_depth_combobox()->setCurrentIndex(PixelService::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_->sample_fmt_combobox()->setCurrentIndex(SampleFormat::GetConfiguredFormatForMode(RenderMode::kOnline)); + online_group_->ocio_method()->setCurrentIndex(ColorManager::GetOCIOMethodForMode(RenderMode::kOnline)); + quality_stack_->addWidget(online_group_); + + layout->addWidget(quality_stack_); + + connect(profile_combobox, SIGNAL(currentIndexChanged(int)), quality_stack_, SLOT(setCurrentIndex(int))); +} + +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())); + 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())); +} + +PreferencesQualityGroup::PreferencesQualityGroup(const QString &title, QWidget *parent) : + QGroupBox(title, parent) +{ + QVBoxLayout* quality_outer_layout = new QVBoxLayout(this); + + QGroupBox* video_group = new QGroupBox(tr("Video")); + + QGridLayout* video_layout = new QGridLayout(video_group); + quality_outer_layout->addWidget(video_group); + + int row = 0; + + video_layout->addWidget(new QLabel(tr("Pixel Format:")), row, 0); + + bit_depth_combobox_ = new QComboBox(); + + // Populate with bit depths + for (int i=0;iaddItem(PixelService::GetPixelFormatInfo(static_cast(i)).name, + i); + } + + video_layout->addWidget(bit_depth_combobox_, row, 1); + + row++; + + video_layout->addWidget(new QLabel(tr("OpenColorIO Method:")), row, 0); + + ocio_method_ = new QComboBox(); + ocio_method_->addItem(tr("Fast")); + ocio_method_->addItem(tr("Accurate")); + video_layout->addWidget(ocio_method_, row, 1); + + row = 0; + + QGroupBox* audio_group = new QGroupBox(tr("Audio")); + + QGridLayout* audio_layout = new QGridLayout(audio_group); + quality_outer_layout->addWidget(audio_group); + + audio_layout->addWidget(new QLabel(tr("Sample Format:")), row, 0); + + sample_fmt_combobox_ = new QComboBox(); + + for (int i=0;iaddItem(SampleFormat::GetSampleFormatName(static_cast(i)), + i); + } + + audio_layout->addWidget(sample_fmt_combobox_, row, 1); + + quality_outer_layout->addStretch(); +} + +QComboBox *PreferencesQualityGroup::bit_depth_combobox() +{ + return bit_depth_combobox_; +} + +QComboBox *PreferencesQualityGroup::ocio_method() +{ + return ocio_method_; +} + +QComboBox *PreferencesQualityGroup::sample_fmt_combobox() +{ + return sample_fmt_combobox_; +} diff --git a/app/dialog/preferences/tabs/preferencesqualitytab.h b/app/dialog/preferences/tabs/preferencesqualitytab.h new file mode 100644 index 000000000..dbae346f0 --- /dev/null +++ b/app/dialog/preferences/tabs/preferencesqualitytab.h @@ -0,0 +1,49 @@ +#ifndef PREFERENCESQUALITYTAB_H +#define PREFERENCESQUALITYTAB_H + +#include +#include +#include +#include + +#include "preferencestab.h" + +class PreferencesQualityGroup : public QGroupBox +{ + Q_OBJECT +public: + PreferencesQualityGroup(const QString& title, QWidget* parent = nullptr); + + QComboBox* bit_depth_combobox(); + + QComboBox* ocio_method(); + + QComboBox* sample_fmt_combobox(); + +private: + QComboBox* bit_depth_combobox_; + + QComboBox* ocio_method_; + + QComboBox* sample_fmt_combobox_; + +}; + +class PreferencesQualityTab : public PreferencesTab +{ + Q_OBJECT +public: + PreferencesQualityTab(); + + virtual void Accept() override; + +private: + QStackedWidget* quality_stack_; + + PreferencesQualityGroup* offline_group_; + + PreferencesQualityGroup* online_group_; + +}; + +#endif // PREFERENCESQUALITYTAB_H diff --git a/app/render/audioparams.cpp b/app/render/audioparams.cpp index 59496f528..aef3d00de 100644 --- a/app/render/audioparams.cpp +++ b/app/render/audioparams.cpp @@ -27,23 +27,23 @@ const uint64_t &AudioParams::channel_layout() const } AudioRenderingParams::AudioRenderingParams() : - format_(SAMPLE_FMT_INVALID) + format_(SampleFormat::SAMPLE_FMT_INVALID) { } -AudioRenderingParams::AudioRenderingParams(const int &sample_rate, const uint64_t &channel_layout, const SampleFormat &format) : +AudioRenderingParams::AudioRenderingParams(const int &sample_rate, const uint64_t &channel_layout, const SampleFormat::Format &format) : AudioParams(sample_rate, channel_layout), format_(format) { } -AudioRenderingParams::AudioRenderingParams(const AudioParams ¶ms, const SampleFormat &format) : +AudioRenderingParams::AudioRenderingParams(const AudioParams ¶ms, const SampleFormat::Format &format) : AudioParams(params), format_(format) { } -const SampleFormat &AudioRenderingParams::format() const +const SampleFormat::Format &AudioRenderingParams::format() const { return format_; } @@ -98,18 +98,18 @@ int AudioRenderingParams::channel_count() const int AudioRenderingParams::bytes_per_sample_per_channel() const { switch (format_) { - case SAMPLE_FMT_U8: + case SampleFormat::SAMPLE_FMT_U8: return 1; - case SAMPLE_FMT_S16: + case SampleFormat::SAMPLE_FMT_S16: return 2; - case SAMPLE_FMT_S32: - case SAMPLE_FMT_FLT: + case SampleFormat::SAMPLE_FMT_S32: + case SampleFormat::SAMPLE_FMT_FLT: return 4; - case SAMPLE_FMT_DBL: - case SAMPLE_FMT_S64: + case SampleFormat::SAMPLE_FMT_DBL: + case SampleFormat::SAMPLE_FMT_S64: return 8; - case SAMPLE_FMT_INVALID: - case SAMPLE_FMT_COUNT: + case SampleFormat::SAMPLE_FMT_INVALID: + case SampleFormat::SAMPLE_FMT_COUNT: break; } @@ -125,8 +125,8 @@ bool AudioRenderingParams::is_valid() const { bool valid = (sample_rate() > 0 && channel_layout() > 0 - && format_ != SAMPLE_FMT_INVALID - && format_ != SAMPLE_FMT_COUNT); + && format_ != SampleFormat::SAMPLE_FMT_INVALID + && format_ != SampleFormat::SAMPLE_FMT_COUNT); if (!valid) { qWarning() << "Invalid params found:" << sample_rate() << channel_layout() << format(); diff --git a/app/render/audioparams.h b/app/render/audioparams.h index 17dcd6998..179fa60f1 100644 --- a/app/render/audioparams.h +++ b/app/render/audioparams.h @@ -25,8 +25,8 @@ private: class AudioRenderingParams : public AudioParams { public: AudioRenderingParams(); - AudioRenderingParams(const int& sample_rate, const uint64_t& channel_layout, const SampleFormat& format); - AudioRenderingParams(const AudioParams& params, const SampleFormat& format); + AudioRenderingParams(const int& sample_rate, const uint64_t& channel_layout, const SampleFormat::Format& format); + AudioRenderingParams(const AudioParams& params, const SampleFormat::Format& format); int time_to_bytes(const rational& time) const; int time_to_samples(const rational& time) const; @@ -37,13 +37,13 @@ public: int bits_per_sample() const; bool is_valid() const; - const SampleFormat& format() const; + const SampleFormat::Format &format() const; bool operator==(const AudioRenderingParams& other) const; bool operator!=(const AudioRenderingParams& other) const; private: - SampleFormat format_; + SampleFormat::Format format_; }; Q_DECLARE_METATYPE(AudioRenderingParams) diff --git a/app/render/backend/opengl/opengltexture.cpp b/app/render/backend/opengl/opengltexture.cpp index 57ea91edf..03dd4fbe8 100644 --- a/app/render/backend/opengl/opengltexture.cpp +++ b/app/render/backend/opengl/opengltexture.cpp @@ -185,17 +185,15 @@ void OpenGLTexture::CreateInternal(QOpenGLContext* create_ctx, GLuint* tex, cons // Allocate storage for texture const PixelFormat::Info& bit_depth = PixelService::GetPixelFormatInfo(format_); - f->glTexImage2D( - GL_TEXTURE_2D, - 0, - bit_depth.internal_format, - width_, - height_, - 0, - bit_depth.pixel_format, - bit_depth.gl_pixel_type, - data - ); + f->glTexImage2D(GL_TEXTURE_2D, + 0, + bit_depth.internal_format, + width_, + height_, + 0, + bit_depth.pixel_format, + bit_depth.gl_pixel_type, + data); // Set texture filtering to bilinear f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); diff --git a/app/render/backend/opengl/openglworker.cpp b/app/render/backend/opengl/openglworker.cpp index 4e0304786..4df2850f1 100644 --- a/app/render/backend/opengl/openglworker.cpp +++ b/app/render/backend/opengl/openglworker.cpp @@ -71,8 +71,10 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable color_cache()->Add(video_stream->colorspace(), color_processor); } + ColorManager::OCIOMethod ocio_method = ColorManager::GetOCIOMethodForMode(video_params().mode()); + // OCIO's CPU conversion is more accurate, so for online we render on CPU but offline we render GPU - if (video_params().mode() == RenderMode::kOnline) { + if (ocio_method == ColorManager::kOCIOAccurate) { // If alpha is associated, disassociate for the color transform if (video_stream->premultiplied_alpha()) { ColorManager::DisassociateAlpha(frame); @@ -96,7 +98,7 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable OpenGLTextureCache::ReferencePtr footage_tex_ref = texture_cache_->Get(ctx_, footage_params, frame->data()); - if (video_params().mode() == RenderMode::kOffline) { + if (ocio_method == ColorManager::kOCIOFast) { if (!color_processor->IsEnabled()) { color_processor->Enable(ctx_, video_stream->premultiplied_alpha()); } diff --git a/app/render/backend/videorenderbackend.cpp b/app/render/backend/videorenderbackend.cpp index 457f6a3e6..a2ecdecb6 100644 --- a/app/render/backend/videorenderbackend.cpp +++ b/app/render/backend/videorenderbackend.cpp @@ -192,7 +192,7 @@ const char *VideoRenderBackend::GetCachedFrame(const rational &time) QByteArray frame_hash = frame_cache_.TimeToHash(time); if (!frame_hash.isEmpty()) { - QString fn = frame_cache_.CachePathName(frame_hash); + QString fn = frame_cache_.CachePathName(frame_hash, params_.format()); if (QFileInfo::exists(fn)) { auto in = OIIO::ImageInput::open(fn.toStdString()); @@ -304,7 +304,7 @@ void VideoRenderBackend::ThreadCompletedDownload(NodeDependency dep, qint64 job_ // Register frame with the disk manager if (operating_mode_ & VideoRenderWorker::kDownloadOnly) { - DiskManager::instance()->CreatedFile(frame_cache()->CachePathName(hash), hash); + DiskManager::instance()->CreatedFile(frame_cache()->CachePathName(hash, params_.format()), hash); } QList hashes_with_time = frame_cache()->FramesWithHash(hash); @@ -322,7 +322,7 @@ void VideoRenderBackend::ThreadSkippedFrame(NodeDependency dep, qint64 job_time, SetWorkerBusyState(static_cast(sender()), false); if (SetFrameHash(dep, hash, job_time) - && frame_cache_.HasHash(hash)) { + && frame_cache_.HasHash(hash, params_.format())) { emit CachedTimeReady(dep.in(), job_time); } diff --git a/app/render/backend/videorenderframecache.cpp b/app/render/backend/videorenderframecache.cpp index a7d8cad69..e9bde2145 100644 --- a/app/render/backend/videorenderframecache.cpp +++ b/app/render/backend/videorenderframecache.cpp @@ -21,9 +21,9 @@ void VideoRenderFrameCache::Clear() cache_id_.clear(); } -bool VideoRenderFrameCache::HasHash(const QByteArray &hash) +bool VideoRenderFrameCache::HasHash(const QByteArray &hash, const PixelFormat::Format& format) { - return QFileInfo::exists(CachePathName(hash)) && !IsCaching(hash); + return QFileInfo::exists(CachePathName(hash, format)) && !IsCaching(hash); } bool VideoRenderFrameCache::IsCaching(const QByteArray &hash) @@ -114,12 +114,21 @@ const QMap &VideoRenderFrameCache::time_hash_map() const return time_hash_map_; } -QString VideoRenderFrameCache::CachePathName(const QByteArray &hash) const +QString VideoRenderFrameCache::CachePathName(const QByteArray &hash, const PixelFormat::Format& pix_fmt) const { QDir this_cache_dir = QDir(GetMediaCacheLocation()); this_cache_dir.mkpath("."); - QString filename = QStringLiteral("%1.exr").arg(QString(hash.toHex())); + 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. + ext = QStringLiteral("tiff"); + } else { + ext = QStringLiteral("exr"); + } + + QString filename = QStringLiteral("%1.%2").arg(QString(hash.toHex()), ext); return this_cache_dir.filePath(filename); } diff --git a/app/render/backend/videorenderframecache.h b/app/render/backend/videorenderframecache.h index adcdc426c..0829cc3c3 100644 --- a/app/render/backend/videorenderframecache.h +++ b/app/render/backend/videorenderframecache.h @@ -4,6 +4,7 @@ #include #include "common/rational.h" +#include "render/pixelformat.h" class VideoRenderFrameCache { @@ -15,7 +16,7 @@ public: /** * @brief Return whether a frame with this hash already exists */ - bool HasHash(const QByteArray& hash); + bool HasHash(const QByteArray& hash, const PixelFormat::Format &format); /** * @brief Return whether a frame is currently being cached @@ -30,7 +31,7 @@ public: /** * @brief Return the path of the cached image at this time */ - QString CachePathName(const QByteArray &hash) const; + QString CachePathName(const QByteArray &hash, const PixelFormat::Format& pix_fmt) const; void SetCacheID(const QString& id); diff --git a/app/render/backend/videorenderworker.cpp b/app/render/backend/videorenderworker.cpp index 1f6c450d2..04dc9d907 100644 --- a/app/render/backend/videorenderworker.cpp +++ b/app/render/backend/videorenderworker.cpp @@ -49,7 +49,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con // Emit only the hash emit CompletedDownload(path, job_time, hash); - } else if ((operating_mode_ & kHashOnly) && frame_cache_->HasHash(hash)) { + } else if ((operating_mode_ & kHashOnly) && frame_cache_->HasHash(hash, video_params_.format())) { // We've already cached this hash, no need to continue emit HashAlreadyExists(path, job_time, hash); @@ -67,7 +67,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con // If we actually have a texture, download it into the disk cache if ((operating_mode_ & kDownloadOnly) && !texture.isNull()) { - Download(path, hash, texture, frame_cache_->CachePathName(hash)); + Download(path, hash, texture, frame_cache_->CachePathName(hash, video_params_.format())); } frame_cache_->RemoveHashFromCurrentlyCaching(hash); @@ -212,7 +212,11 @@ void VideoRenderWorker::Download(NodeDependency dep, QByteArray hash, QVariant t // Set up OIIO::ImageSpec for compressing cached images on disk OIIO::ImageSpec spec(video_params().effective_width(), video_params().effective_height(), kRGBAChannels, format_info.oiio_desc); - spec.attribute("compression", "dwaa:200"); + + if (video_params_.format() != PixelFormat::PIX_FMT_RGBA8) { + // 8-bit doesn't use EXR because EXR loading is really slow on 8-bit + spec.attribute("compression", "dwaa:200"); + } TextureToBuffer(texture, download_buffer_); diff --git a/app/render/colormanager.cpp b/app/render/colormanager.cpp index 7e1d33e82..1ed688b9c 100644 --- a/app/render/colormanager.cpp +++ b/app/render/colormanager.cpp @@ -4,6 +4,7 @@ #include "common/define.h" #include "config/config.h" +#include "core.h" ColorManager::ColorManager() { @@ -110,6 +111,16 @@ QStringList ColorManager::ListAvailableInputColorspaces(OCIO::ConstConfigRcPtr c return spaces; } +ColorManager::OCIOMethod ColorManager::GetOCIOMethodForMode(RenderMode::Mode mode) +{ + return static_cast(Core::GetPreferenceForRenderMode(mode, QStringLiteral("OCIOMethod")).toInt()); +} + +void ColorManager::SetOCIOMethodForMode(RenderMode::Mode mode, ColorManager::OCIOMethod method) +{ + Core::SetPreferenceForRenderMode(mode, QStringLiteral("OCIOMethod"), method); +} + void ColorManager::AssociateAlphaPixFmtFilter(ColorManager::AlphaAction action, FramePtr f) { int pixel_count = f->width() * f->height() * kRGBAChannels; diff --git a/app/render/colormanager.h b/app/render/colormanager.h index 8c2270026..601c6f432 100644 --- a/app/render/colormanager.h +++ b/app/render/colormanager.h @@ -38,6 +38,15 @@ public: static QStringList ListAvailableInputColorspaces(OCIO::ConstConfigRcPtr config); + enum OCIOMethod { + kOCIOFast, + kOCIOAccurate + }; + + static OCIOMethod GetOCIOMethodForMode(RenderMode::Mode mode); + + static void SetOCIOMethodForMode(RenderMode::Mode mode, OCIOMethod method); + signals: void ConfigChanged(); diff --git a/app/render/pixelservice.cpp b/app/render/pixelservice.cpp index 603f9fd4c..3fed169d7 100644 --- a/app/render/pixelservice.cpp +++ b/app/render/pixelservice.cpp @@ -25,11 +25,22 @@ #include #include "common/define.h" +#include "core.h" PixelService::PixelService() { } +PixelFormat::Format PixelService::GetConfiguredFormatForMode(RenderMode::Mode mode) +{ + return static_cast(Core::GetPreferenceForRenderMode(mode, QStringLiteral("PixelFormat")).toInt()); +} + +void PixelService::SetConfiguredFormatForMode(RenderMode::Mode mode, PixelFormat::Format format) +{ + Core::SetPreferenceForRenderMode(mode, QStringLiteral("PixelFormat"), format); +} + PixelFormat::Info PixelService::GetPixelFormatInfo(const PixelFormat::Format &format) { PixelFormat::Info info; diff --git a/app/render/pixelservice.h b/app/render/pixelservice.h index 921a8e304..3a52ff21f 100644 --- a/app/render/pixelservice.h +++ b/app/render/pixelservice.h @@ -25,12 +25,19 @@ #include "codec/frame.h" #include "pixelformat.h" +#include "render/rendermodes.h" class PixelService : public QObject { public: PixelService(); + /** + * @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); + /** * @brief Return a PixelFormatInfo containing information for a certain format * diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 7e9483f25..45f6253ff 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -31,6 +31,7 @@ #include "config/config.h" #include "project/item/sequence/sequence.h" #include "project/project.h" +#include "render/pixelservice.h" ViewerWidget::ViewerWidget(QWidget *parent) : QWidget(parent), @@ -176,8 +177,14 @@ void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_man qWarning() << "Failed to find a suitable color manager for the connected viewer node"; } - video_renderer_->SetParameters(VideoRenderingParams(viewer_node_->video_params(), PixelFormat::PIX_FMT_RGBA16F, RenderMode::kOffline, 2)); - audio_renderer_->SetParameters(AudioRenderingParams(viewer_node_->audio_params(), SAMPLE_FMT_FLT)); + 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