diff --git a/app/config/config.cpp b/app/config/config.cpp index 2efa2f4ad..d96619dd8 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -110,7 +110,6 @@ void Config::SetDefaults() config_map_["DefaultSequenceAudioFrequency"] = 48000; config_map_["DefaultSequenceAudioLayout"] = QVariant::fromValue(static_cast(AV_CH_LAYOUT_STEREO)); config_map_["DefaultSequencePreviewFormat"] = PixelFormat::PIX_FMT_RGBA16F; - config_map_["DefaultSequencePreviewDivider"] = 3; // Online/offline settings config_map_["OnlinePixelFormat"] = PixelFormat::PIX_FMT_RGBA32F; diff --git a/app/core.cpp b/app/core.cpp index 2ee00d74d..fe560b3dd 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -809,6 +809,11 @@ QList Core::SupportedChannelLayouts() return channel_layouts; } +QList Core::SupportedDividers() +{ + return {1, 2, 3, 4, 6, 8, 12, 16}; +} + QString Core::FrameRateToString(const rational &frame_rate) { return tr("%1 FPS").arg(frame_rate.toDouble()); diff --git a/app/core.h b/app/core.h index 2ef4a0566..958fdf28c 100644 --- a/app/core.h +++ b/app/core.h @@ -178,6 +178,11 @@ public: */ static QList SupportedChannelLayouts(); + /** + * @brief Return a list of supported dividers + */ + static QList SupportedDividers(); + /** * @brief Convert rational frame rate (i.e. flipped timebase) to a user-friendly string */ diff --git a/app/dialog/sequence/sequencedialogparametertab.cpp b/app/dialog/sequence/sequencedialogparametertab.cpp index 224ddc98a..83c5fda9b 100644 --- a/app/dialog/sequence/sequencedialogparametertab.cpp +++ b/app/dialog/sequence/sequencedialogparametertab.cpp @@ -90,7 +90,7 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg } // Set up preview dividers - divider_list_ = {1, 2, 3, 4, 6, 8, 12, 16}; + divider_list_ = Core::SupportedDividers(); foreach (int d, divider_list_) { QString name; diff --git a/app/project/item/sequence/sequence.cpp b/app/project/item/sequence/sequence.cpp index a85d8deb8..310a96d87 100644 --- a/app/project/item/sequence/sequence.cpp +++ b/app/project/item/sequence/sequence.cpp @@ -238,14 +238,17 @@ void Sequence::set_audio_params(const AudioParams ¶ms) void Sequence::set_default_parameters() { - set_video_params(VideoParams(Config::Current()["DefaultSequenceWidth"].toInt(), - Config::Current()["DefaultSequenceHeight"].toInt(), - Config::Current()["DefaultSequenceFrameRate"].value(), - static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), - Config::Current()["DefaultSequencePreviewDivider"].toInt())); + int width = Config::Current()["DefaultSequenceWidth"].toInt(); + int height = Config::Current()["DefaultSequenceHeight"].toInt(); + + set_video_params(VideoParams(width, + height, + Config::Current()["DefaultSequenceFrameRate"].value(), + static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), + VideoParams::generate_auto_divider(width, height))); set_audio_params(AudioParams(Config::Current()["DefaultSequenceAudioFrequency"].toInt(), - Config::Current()["DefaultSequenceAudioLayout"].toULongLong(), - SampleFormat::kInternalFormat)); + Config::Current()["DefaultSequenceAudioLayout"].toULongLong(), + SampleFormat::kInternalFormat)); } void Sequence::set_parameters_from_footage(const QList footage) @@ -263,10 +266,10 @@ void Sequence::set_parameters_from_footage(const QList footage) // If this is a video stream, use these parameters if (!found_video_params && !vs->frame_rate().isNull()) { set_video_params(VideoParams(vs->width(), - vs->height(), - vs->frame_rate().flipped(), - static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), - Config::Current()["DefaultSequencePreviewDivider"].toInt())); + vs->height(), + vs->frame_rate().flipped(), + static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), + VideoParams::generate_auto_divider(vs->width(), vs->height()))); found_video_params = true; } break; @@ -278,10 +281,10 @@ void Sequence::set_parameters_from_footage(const QList footage) ImageStream* is = static_cast(s.get()); set_video_params(VideoParams(is->width(), - is->height(), - video_params().time_base(), - static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), - Config::Current()["DefaultSequencePreviewDivider"].toInt())); + is->height(), + video_params().time_base(), + static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), + VideoParams::generate_auto_divider(is->width(), is->height()))); } break; case Stream::kAudio: diff --git a/app/render/videoparams.cpp b/app/render/videoparams.cpp index 360490e55..8f59f41bd 100644 --- a/app/render/videoparams.cpp +++ b/app/render/videoparams.cpp @@ -22,6 +22,8 @@ #include +#include "core.h" + OLIVE_NAMESPACE_ENTER VideoParams::VideoParams() : @@ -48,6 +50,44 @@ VideoParams::VideoParams(const int &width, const int &height, const rational &ti calculate_effective_size(); } +int VideoParams::generate_auto_divider(qint64 width, qint64 height) +{ + // Arbitrary pixel count (from 640x360) + const int target_res = 230400; + + qint64 megapixels = width * height; + + double squared_divider = double(megapixels) / double(target_res); + double divider = qSqrt(squared_divider); + + QList supported_dividers = Core::SupportedDividers(); + + if (divider <= supported_dividers.first()) { + return supported_dividers.first(); + } else if (divider >= supported_dividers.last()) { + return supported_dividers.last(); + } else { + for (int i=1; i= prev_divider && divider <= next_divider) { + double prev_diff = qAbs(prev_divider - divider); + double next_diff = qAbs(next_divider - divider); + + if (prev_diff < next_diff) { + return prev_divider; + } else { + return next_divider; + } + } + } + + // "Safe" fallback + return 2; + } +} + bool VideoParams::operator==(const VideoParams &rhs) const { return width() == rhs.width() diff --git a/app/render/videoparams.h b/app/render/videoparams.h index 7d8207a4a..b108874d5 100644 --- a/app/render/videoparams.h +++ b/app/render/videoparams.h @@ -68,6 +68,8 @@ public: return format_; } + static int generate_auto_divider(qint64 width, qint64 height); + bool is_valid() const; bool operator==(const VideoParams& rhs) const; diff --git a/app/widget/viewer/footageviewer.cpp b/app/widget/viewer/footageviewer.cpp index 17424c5fd..4cfab0008 100644 --- a/app/widget/viewer/footageviewer.cpp +++ b/app/widget/viewer/footageviewer.cpp @@ -85,17 +85,20 @@ void FootageViewerWidget::SetFootage(Footage *footage) if (video_stream) { video_node_->SetFootage(video_stream); viewer_node_->set_video_params(VideoParams(video_stream->width(), - video_stream->height(), - video_stream->frame_rate().flipped(), - static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), - Config::Current()["DefaultSequencePreviewDivider"].toInt())); + video_stream->height(), + video_stream->frame_rate().flipped(), + static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), + VideoParams::generate_auto_divider(video_stream->width(), video_stream->height()))); NodeParam::ConnectEdge(video_node_->output(), viewer_node_->texture_input()); } else { - viewer_node_->set_video_params(VideoParams(Config::Current()["DefaultSequenceWidth"].toInt(), - Config::Current()["DefaultSequenceHeight"].toInt(), - Config::Current()["DefaultSequenceFrameRate"].value(), - static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), - Config::Current()["DefaultSequencePreviewDivider"].toInt())); + int width = Config::Current()["DefaultSequenceWidth"].toInt(); + int height = Config::Current()["DefaultSequenceHeight"].toInt(); + + viewer_node_->set_video_params(VideoParams(width, + height, + Config::Current()["DefaultSequenceFrameRate"].value(), + static_cast(Config::Current()["DefaultSequencePreviewFormat"].toInt()), + VideoParams::generate_auto_divider(width, height))); } if (audio_stream) { @@ -104,8 +107,8 @@ void FootageViewerWidget::SetFootage(Footage *footage) NodeParam::ConnectEdge(audio_node_->output(), viewer_node_->samples_input()); } else { viewer_node_->set_audio_params(AudioParams(Config::Current()["DefaultSequenceAudioFrequency"].toInt(), - Config::Current()["DefaultSequenceAudioLayout"].toULongLong(), - SampleFormat::kInternalFormat)); + Config::Current()["DefaultSequenceAudioLayout"].toULongLong(), + SampleFormat::kInternalFormat)); } ConnectViewerNode(viewer_node_, footage_->project()->color_manager());