allow setting of pixel format/ocio method/sample format in preferences
Implementation isn't perfect yet, viewer/renderer doesn't update yet when the preference is changed so a sequence needs to be re-opened for the change to take effect.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<SampleFormat::Format>(Core::GetPreferenceForRenderMode(mode, QStringLiteral("SampleFormat")).toInt());
|
||||
}
|
||||
|
||||
void SampleFormat::SetConfiguredFormatForMode(RenderMode::Mode mode, SampleFormat::Format format)
|
||||
{
|
||||
Core::SetPreferenceForRenderMode(mode, QStringLiteral("SampleFormat"), format);
|
||||
}
|
||||
|
||||
@@ -21,17 +21,34 @@
|
||||
#ifndef SAMPLEFORMAT_H
|
||||
#define SAMPLEFORMAT_H
|
||||
|
||||
enum SampleFormat {
|
||||
SAMPLE_FMT_INVALID = -1,
|
||||
#include <QObject>
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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<int16_t>(&file_, kWAVIntegerFormat);
|
||||
break;
|
||||
case SAMPLE_FMT_FLT:
|
||||
case SAMPLE_FMT_DBL:
|
||||
case SampleFormat::SAMPLE_FMT_FLT:
|
||||
case SampleFormat::SAMPLE_FMT_DBL:
|
||||
write_int<int16_t>(&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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;i<bool_restart_required.size();i++) {
|
||||
if (bool_restart_required.at(i)
|
||||
&& bool_ui.at(i)->isChecked() != *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<olive::styling::Style>(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;i<bool_ui.size();i++) {
|
||||
*bool_value[i] = bool_ui.at(i)->isChecked();
|
||||
}
|
||||
|
||||
// Set new style
|
||||
olive::config.style = static_cast<olive::styling::Style>(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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "preferencesplaybacktab.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
PreferencesPlaybackTab::PreferencesPlaybackTab()
|
||||
{
|
||||
}
|
||||
|
||||
void PreferencesPlaybackTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef PREFERENCESPLAYBACKTAB_H
|
||||
#define PREFERENCESPLAYBACKTAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
class PreferencesPlaybackTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesPlaybackTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // PREFERENCESPLAYBACKTAB_H
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "preferencesqualitytab.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#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<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()));
|
||||
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()));
|
||||
}
|
||||
|
||||
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;i<PixelFormat::PIX_FMT_COUNT;i++) {
|
||||
bit_depth_combobox_->addItem(PixelService::GetPixelFormatInfo(static_cast<PixelFormat::Format>(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;i<SampleFormat::SAMPLE_FMT_COUNT;i++) {
|
||||
sample_fmt_combobox_->addItem(SampleFormat::GetSampleFormatName(static_cast<SampleFormat::Format>(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_;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef PREFERENCESQUALITYTAB_H
|
||||
#define PREFERENCESQUALITYTAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QGroupBox>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#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
|
||||
+14
-14
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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<rational> hashes_with_time = frame_cache()->FramesWithHash(hash);
|
||||
@@ -322,7 +322,7 @@ void VideoRenderBackend::ThreadSkippedFrame(NodeDependency dep, qint64 job_time,
|
||||
SetWorkerBusyState(static_cast<RenderWorker*>(sender()), false);
|
||||
|
||||
if (SetFrameHash(dep, hash, job_time)
|
||||
&& frame_cache_.HasHash(hash)) {
|
||||
&& frame_cache_.HasHash(hash, params_.format())) {
|
||||
emit CachedTimeReady(dep.in(), job_time);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<rational, QByteArray> &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);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QMutex>
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
@@ -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_);
|
||||
|
||||
|
||||
@@ -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<OCIOMethod>(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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -25,11 +25,22 @@
|
||||
#include <QFloat16>
|
||||
|
||||
#include "common/define.h"
|
||||
#include "core.h"
|
||||
|
||||
PixelService::PixelService()
|
||||
{
|
||||
}
|
||||
|
||||
PixelFormat::Format PixelService::GetConfiguredFormatForMode(RenderMode::Mode mode)
|
||||
{
|
||||
return static_cast<PixelFormat::Format>(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;
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user