diff --git a/obs/data/locale/en-US.ini b/obs/data/locale/en-US.ini
index e08bda0d6..e8f045ae5 100644
--- a/obs/data/locale/en-US.ini
+++ b/obs/data/locale/en-US.ini
@@ -509,6 +509,11 @@ Basic.Settings.Audio.UnknownAudioDevice="[Device not connected or not available]
# basic mode 'advanced' settings
Basic.Settings.Advanced="Advanced"
+Basic.Settings.Advanced.General.ProcessPriority="Process Priority"
+Basic.Settings.Advanced.General.ProcessPriority.High="High"
+Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Above Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
+Basic.Settings.Advanced.General.ProcessPriority.Idle="Idle"
Basic.Settings.Advanced.FormatWarning="Warning: Color formats other than NV12 are primarily intended for recording, and are not recommended when streaming. Streaming may incur increased CPU usage due to color format conversion."
Basic.Settings.Advanced.Audio.BufferingTime="Audio Buffering Time"
Basic.Settings.Advanced.Video.ColorFormat="Color Format"
diff --git a/obs/forms/OBSBasicSettings.ui b/obs/forms/OBSBasicSettings.ui
index cfd5e14e5..4d32dca14 100644
--- a/obs/forms/OBSBasicSettings.ui
+++ b/obs/forms/OBSBasicSettings.ui
@@ -2887,8 +2887,8 @@
0
0
- 559
- 563
+ 718
+ 622
@@ -2907,6 +2907,28 @@
-
+
-
+
+
+ Basic.Settings.General
+
+
+
-
+
+
+ Basic.Settings.Advanced.General.ProcessPriority
+
+
+ processPriority
+
+
+
+ -
+
+
+
+
+
-
diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp
index 5a9831248..7df4b151d 100644
--- a/obs/obs-app.cpp
+++ b/obs/obs-app.cpp
@@ -328,6 +328,8 @@ bool OBSApp::InitGlobalConfigDefaults()
config_set_default_string(globalConfig, "General", "Language",
DEFAULT_LANG);
config_set_default_uint(globalConfig, "General", "MaxLogs", 10);
+ config_set_default_string(globalConfig, "General", "ProcessPriority",
+ "Normal");
#if _WIN32
config_set_default_string(globalConfig, "Video", "Renderer",
diff --git a/obs/platform-windows.cpp b/obs/platform-windows.cpp
index c34bbd565..fb4c99759 100644
--- a/obs/platform-windows.cpp
+++ b/obs/platform-windows.cpp
@@ -215,3 +215,18 @@ void SetAlwaysOnTop(QMainWindow *window, bool enable)
SetWindowPos(hwnd, enable ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
+
+void SetProcessPriority(const char *priority)
+{
+ if (!priority)
+ return;
+
+ if (strcmp(priority, "High") == 0)
+ SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+ else if (strcmp(priority, "AboveNormal") == 0)
+ SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
+ else if (strcmp(priority, "Normal") == 0)
+ SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
+ else if (strcmp(priority, "Idle") == 0)
+ SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
+}
diff --git a/obs/platform.hpp b/obs/platform.hpp
index de9d1c660..a25e4a8d8 100644
--- a/obs/platform.hpp
+++ b/obs/platform.hpp
@@ -51,6 +51,7 @@ void SetAlwaysOnTop(QMainWindow *window, bool enable);
#ifdef _WIN32
uint32_t GetWindowsVersion();
void SetAeroEnabled(bool enable);
+void SetProcessPriority(const char *priority);
#endif
#ifdef __APPLE__
diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp
index dcd34dda0..30878deba 100644
--- a/obs/window-basic-main.cpp
+++ b/obs/window-basic-main.cpp
@@ -2267,13 +2267,20 @@ void OBSBasic::SetService(obs_service_t *newService)
service = newService;
}
-bool OBSBasic::StreamingActive()
+bool OBSBasic::StreamingActive() const
{
if (!outputHandler)
return false;
return outputHandler->StreamingActive();
}
+bool OBSBasic::Active() const
+{
+ if (!outputHandler)
+ return false;
+ return outputHandler->Active();
+}
+
#ifdef _WIN32
#define IS_WIN32 1
#else
@@ -3397,6 +3404,27 @@ void OBSBasic::StartStreaming()
StartRecording();
}
+#ifdef _WIN32
+static inline void UpdateProcessPriority()
+{
+ const char *priority = config_get_string(App()->GlobalConfig(),
+ "General", "ProcessPriority");
+ if (priority && strcmp(priority, "Normal") != 0)
+ SetProcessPriority(priority);
+}
+
+static inline void ClearProcessPriority()
+{
+ const char *priority = config_get_string(App()->GlobalConfig(),
+ "General", "ProcessPriority");
+ if (priority && strcmp(priority, "Normal") != 0)
+ SetProcessPriority("Normal");
+}
+#else
+#define UpdateProcessPriority() do {} while(false)
+#define ClearProcessPriority() do {} while(false)
+#endif
+
void OBSBasic::StopStreaming()
{
SaveProject();
@@ -3407,6 +3435,7 @@ void OBSBasic::StopStreaming()
if (!outputHandler->Active() && !ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(true);
App()->DecrementSleepInhibition();
+ ClearProcessPriority();
}
bool recordWhenStreaming = config_get_bool(GetGlobalConfig(),
@@ -3427,6 +3456,7 @@ void OBSBasic::ForceStopStreaming()
if (!outputHandler->Active() && !ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(true);
App()->DecrementSleepInhibition();
+ ClearProcessPriority();
}
bool recordWhenStreaming = config_get_bool(GetGlobalConfig(),
@@ -3457,6 +3487,7 @@ void OBSBasic::StreamDelayStarting(int sec)
if (ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(false);
App()->IncrementSleepInhibition();
+ UpdateProcessPriority();
}
}
@@ -3487,6 +3518,7 @@ void OBSBasic::StreamingStart()
if (ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(false);
App()->IncrementSleepInhibition();
+ UpdateProcessPriority();
}
blog(LOG_INFO, STREAMING_START);
@@ -3533,6 +3565,7 @@ void OBSBasic::StreamingStop(int code)
if (!outputHandler->Active() && !ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(true);
App()->DecrementSleepInhibition();
+ ClearProcessPriority();
}
blog(LOG_INFO, STREAMING_STOP);
@@ -3573,6 +3606,7 @@ void OBSBasic::StopRecording()
if (!outputHandler->Active() && !ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(true);
App()->DecrementSleepInhibition();
+ ClearProcessPriority();
}
}
@@ -3584,6 +3618,7 @@ void OBSBasic::RecordingStart()
if (ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(false);
App()->IncrementSleepInhibition();
+ UpdateProcessPriority();
}
blog(LOG_INFO, RECORDING_START);
@@ -3614,6 +3649,7 @@ void OBSBasic::RecordingStop(int code)
if (!outputHandler->Active() && !ui->profileMenu->isEnabled()) {
ui->profileMenu->setEnabled(true);
App()->DecrementSleepInhibition();
+ ClearProcessPriority();
}
}
diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp
index c82b4c1c6..581164212 100644
--- a/obs/window-basic-main.hpp
+++ b/obs/window-basic-main.hpp
@@ -370,7 +370,8 @@ public:
obs_service_t *GetService();
void SetService(obs_service_t *service);
- bool StreamingActive();
+ bool StreamingActive() const;
+ bool Active() const;
int ResetVideo();
bool ResetAudio();
diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp
index 24b6c731e..28c595d25 100644
--- a/obs/window-basic-settings.cpp
+++ b/obs/window-basic-settings.cpp
@@ -371,6 +371,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->reconnectEnable, CHECK_CHANGED, ADV_CHANGED);
HookWidget(ui->reconnectRetryDelay, SCROLL_CHANGED, ADV_CHANGED);
HookWidget(ui->reconnectMaxRetries, SCROLL_CHANGED, ADV_CHANGED);
+ HookWidget(ui->processPriority, COMBO_CHANGED, ADV_CHANGED);
#ifdef _WIN32
uint32_t winVer = GetWindowsVersion();
@@ -386,15 +387,39 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
connect(toggleAero, &QAbstractButton::toggled,
this, &OBSBasicSettings::ToggleDisableAero);
}
+
+#define PROCESS_PRIORITY(val) \
+ {"Basic.Settings.Advanced.General.ProcessPriority." ## val , val}
+
+ static struct ProcessPriority {
+ const char *name;
+ const char *val;
+ } processPriorities[] = {
+ PROCESS_PRIORITY("High"),
+ PROCESS_PRIORITY("AboveNormal"),
+ PROCESS_PRIORITY("Normal"),
+ PROCESS_PRIORITY("Idle")
+ };
+#undef PROCESS_PRIORITY
+
+ for (ProcessPriority pri : processPriorities)
+ ui->processPriority->addItem(QTStr(pri.name), pri.val);
+
#else
delete ui->rendererLabel;
delete ui->renderer;
delete ui->adapterLabel;
delete ui->adapter;
+ delete ui->processPriorityLabel;
+ delete ui->processPriority;
+ delete ui->advancedGeneralGroupBox;
ui->rendererLabel = nullptr;
ui->renderer = nullptr;
ui->adapterLabel = nullptr;
ui->adapter = nullptr;
+ ui->processPriorityLabel = nullptr;
+ ui->processPriority = nullptr;
+ ui->advancedGeneralGroupBox = nullptr;
#endif
#ifndef __APPLE__
@@ -1817,6 +1842,13 @@ void OBSBasicSettings::LoadAdvancedSettings()
ui->disableOSXVSync->setChecked(disableOSXVSync);
ui->resetOSXVSync->setChecked(resetOSXVSync);
ui->resetOSXVSync->setEnabled(disableOSXVSync);
+#elif _WIN32
+ const char *processPriority = config_get_string(App()->GlobalConfig(),
+ "General", "ProcessPriority");
+ int idx = ui->processPriority->findData(processPriority);
+ if (idx == -1)
+ idx = ui->processPriority->findData("Normal");
+ ui->processPriority->setCurrentIndex(idx);
#endif
loading = false;
@@ -2250,6 +2282,13 @@ void OBSBasicSettings::SaveAdvancedSettings()
if (WidgetChanged(ui->renderer))
config_set_string(App()->GlobalConfig(), "Video", "Renderer",
QT_TO_UTF8(ui->renderer->currentText()));
+
+ std::string priority =
+ QT_TO_UTF8(ui->processPriority->currentData().toString());
+ config_set_string(App()->GlobalConfig(), "General", "ProcessPriority",
+ priority.c_str());
+ if (main->Active())
+ SetProcessPriority(priority.c_str());
#endif
#ifdef __APPLE__