Added Video framerate limiter
Will fix cinematics and videos when readed over their framerate
This commit is contained in:
parent
e9069dfe76
commit
acf0df69b8
7 changed files with 76 additions and 0 deletions
|
@ -54,6 +54,7 @@ void LogSettings() {
|
|||
log_setting("Renderer_AntiAliasing", values.anti_aliasing.GetValue());
|
||||
log_setting("Renderer_UseSpeedLimit", values.use_speed_limit.GetValue());
|
||||
log_setting("Renderer_SpeedLimit", values.speed_limit.GetValue());
|
||||
log_setting("Renderer_VideoFramerate", values.video_framerate.GetValue());
|
||||
log_setting("Renderer_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
|
||||
log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue());
|
||||
log_setting("Renderer_UseAsynchronousGpuEmulation",
|
||||
|
@ -218,6 +219,8 @@ void RestoreGlobalState(bool is_powered_on) {
|
|||
values.max_anisotropy.SetGlobal(true);
|
||||
values.use_speed_limit.SetGlobal(true);
|
||||
values.speed_limit.SetGlobal(true);
|
||||
values.use_video_framerate.SetGlobal(true);
|
||||
values.video_framerate.SetGlobal(true);
|
||||
values.use_disk_shader_cache.SetGlobal(true);
|
||||
values.gpu_accuracy.SetGlobal(true);
|
||||
values.use_asynchronous_gpu_emulation.SetGlobal(true);
|
||||
|
|
|
@ -456,6 +456,8 @@ struct Values {
|
|||
SwitchableSetting<int, true> max_anisotropy{0, 0, 5, "max_anisotropy"};
|
||||
SwitchableSetting<bool> use_speed_limit{true, "use_speed_limit"};
|
||||
SwitchableSetting<u16, true> speed_limit{100, 0, 9999, "speed_limit"};
|
||||
SwitchableSetting<bool> use_video_framerate{false, "use_video_framerate"};
|
||||
SwitchableSetting<u16, true> video_framerate{30, 1, 240, "video_framerate"};
|
||||
SwitchableSetting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
|
||||
SwitchableSetting<GPUAccuracy, true> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal,
|
||||
GPUAccuracy::Extreme, "gpu_accuracy"};
|
||||
|
|
|
@ -278,14 +278,32 @@ void Codec::Decode() {
|
|||
}
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::time_point last_frame_time = std::chrono::steady_clock::now();
|
||||
std::chrono::microseconds min_call_interval = std::chrono::microseconds(1000/Settings::values.video_framerate.GetValue()*1000);
|
||||
AVFramePtr Codec::GetCurrentFrame() {
|
||||
// Sometimes VIC will request more frames than have been decoded.
|
||||
// in this case, return a nullptr and don't overwrite previous frame data
|
||||
if (av_frames.empty()) {
|
||||
return AVFramePtr{nullptr, AVFrameDeleter};
|
||||
}
|
||||
|
||||
AVFramePtr frame = std::move(av_frames.front());
|
||||
av_frames.pop();
|
||||
|
||||
if (Settings::values.use_video_framerate.GetValue()) {
|
||||
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
std::chrono::microseconds elapsed =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(now - last_frame_time);
|
||||
|
||||
if (elapsed < min_call_interval) {
|
||||
std::this_thread::sleep_for(min_call_interval - elapsed);
|
||||
now = std::chrono::steady_clock::now();
|
||||
elapsed = std::chrono::duration_cast<std::chrono::microseconds>(now - last_frame_time);
|
||||
}
|
||||
|
||||
last_frame_time = now;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
|
|
@ -705,6 +705,8 @@ void Config::ReadRendererValues() {
|
|||
ReadGlobalSetting(Settings::values.anti_aliasing);
|
||||
ReadGlobalSetting(Settings::values.max_anisotropy);
|
||||
ReadGlobalSetting(Settings::values.speed_limit);
|
||||
ReadGlobalSetting(Settings::values.use_video_framerate);
|
||||
ReadGlobalSetting(Settings::values.video_framerate);
|
||||
ReadGlobalSetting(Settings::values.use_disk_shader_cache);
|
||||
ReadGlobalSetting(Settings::values.gpu_accuracy);
|
||||
ReadGlobalSetting(Settings::values.use_asynchronous_gpu_emulation);
|
||||
|
@ -1346,6 +1348,8 @@ void Config::SaveRendererValues() {
|
|||
Settings::values.anti_aliasing.UsingGlobal());
|
||||
WriteGlobalSetting(Settings::values.max_anisotropy);
|
||||
WriteGlobalSetting(Settings::values.speed_limit);
|
||||
WriteGlobalSetting(Settings::values.use_video_framerate);
|
||||
WriteGlobalSetting(Settings::values.video_framerate);
|
||||
WriteGlobalSetting(Settings::values.use_disk_shader_cache);
|
||||
WriteSetting(QString::fromStdString(Settings::values.gpu_accuracy.GetLabel()),
|
||||
static_cast<u32>(Settings::values.gpu_accuracy.GetValue(global)),
|
||||
|
|
|
@ -20,6 +20,9 @@ ConfigureGeneral::ConfigureGeneral(const Core::System& system_, QWidget* parent)
|
|||
SetConfiguration();
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
connect(ui->toggle_video_framerate, &QCheckBox::clicked, ui->video_framerate, [this]() {
|
||||
ui->video_framerate->setEnabled(ui->toggle_video_framerate->isChecked());
|
||||
});
|
||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit,
|
||||
[this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); });
|
||||
}
|
||||
|
@ -41,14 +44,19 @@ void ConfigureGeneral::SetConfiguration() {
|
|||
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background.GetValue());
|
||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
|
||||
|
||||
ui->toggle_video_framerate->setChecked(Settings::values.use_video_framerate.GetValue());
|
||||
ui->video_framerate->setValue(Settings::values.video_framerate.GetValue());
|
||||
|
||||
ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
|
||||
ui->speed_limit->setValue(Settings::values.speed_limit.GetValue());
|
||||
|
||||
ui->button_reset_defaults->setEnabled(runtime_lock);
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->video_framerate->setEnabled(Settings::values.use_video_framerate.GetValue());
|
||||
ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue());
|
||||
} else {
|
||||
ui->video_framerate->setEnabled(Settings::values.use_video_framerate.GetValue() && use_video_framerate != ConfigurationShared::CheckState::Global);
|
||||
ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() &&
|
||||
use_speed_limit != ConfigurationShared::CheckState::Global);
|
||||
}
|
||||
|
@ -83,6 +91,12 @@ void ConfigureGeneral::ApplyConfiguration() {
|
|||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||
|
||||
if (Settings::values.use_video_framerate.UsingGlobal()) {
|
||||
Settings::values.use_video_framerate.SetValue(
|
||||
ui->toggle_video_framerate->checkState() ==
|
||||
Qt::Checked);
|
||||
Settings::values.video_framerate.SetValue(ui->video_framerate->value());
|
||||
}
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.use_speed_limit.UsingGlobal()) {
|
||||
Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
|
||||
|
@ -118,6 +132,8 @@ void ConfigureGeneral::SetupPerGameUI() {
|
|||
// Disables each setting if:
|
||||
// - A game is running (thus settings in use), and
|
||||
// - A non-global setting is applied.
|
||||
ui->toggle_video_framerate->setEnabled(Settings::values.use_video_framerate.UsingGlobal());
|
||||
ui->video_framerate->setEnabled(Settings::values.video_framerate.UsingGlobal());
|
||||
ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal());
|
||||
ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal());
|
||||
|
||||
|
@ -131,11 +147,16 @@ void ConfigureGeneral::SetupPerGameUI() {
|
|||
|
||||
ui->button_reset_defaults->setVisible(false);
|
||||
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_video_framerate, Settings::values.use_video_framerate, use_video_framerate);
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit,
|
||||
Settings::values.use_speed_limit, use_speed_limit);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
|
||||
use_multi_core);
|
||||
|
||||
connect(ui->toggle_video_framerate, &QCheckBox::clicked, ui->video_framerate, [this]() {
|
||||
ui->video_framerate->setEnabled(ui->toggle_video_framerate->isChecked() &&
|
||||
(use_video_framerate != ConfigurationShared::CheckState::Global));
|
||||
});
|
||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
|
||||
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
|
||||
(use_speed_limit != ConfigurationShared::CheckState::Global));
|
||||
|
|
|
@ -46,6 +46,7 @@ private:
|
|||
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
||||
|
||||
ConfigurationShared::CheckState use_speed_limit;
|
||||
ConfigurationShared::CheckState use_video_framerate;
|
||||
ConfigurationShared::CheckState use_multi_core;
|
||||
|
||||
const Core::System& system;
|
||||
|
|
|
@ -89,6 +89,33 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_video_framerate">
|
||||
<property name="text">
|
||||
<string>Limit Videos Framerate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="video_framerate">
|
||||
<property name="suffix">
|
||||
<string>fps</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>240</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>30</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
Loading…
Add table
Reference in a new issue