diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini
index b787aa823..d38835e1c 100644
--- a/UI/data/locale/en-US.ini
+++ b/UI/data/locale/en-US.ini
@@ -1034,12 +1034,20 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Above Normal"
Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal"
Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Below 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.FormatWarning="Warning: Color formats other than NV12/P010 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.FormatWarningI010="Warning: I010 only works with Rec. 2020 for now."
+Basic.Settings.Advanced.FormatWarningP010="Warning: P010 only works with Rec. 2020 for now."
+Basic.Settings.Advanced.FormatWarning2020="Warning: Rec. 2020 only works with I010/P010 for now."
Basic.Settings.Advanced.Audio.BufferingTime="Audio Buffering Time"
Basic.Settings.Advanced.Video.ColorFormat="Color Format"
Basic.Settings.Advanced.Video.ColorSpace="Color Space"
+Basic.Settings.Advanced.Video.ColorSpace.sRGB="sRGB"
+Basic.Settings.Advanced.Video.ColorSpace.601="Rec. 601"
+Basic.Settings.Advanced.Video.ColorSpace.709="Rec. 709"
+Basic.Settings.Advanced.Video.ColorSpace.2020PQ="Rec. 2020 (PQ)"
+Basic.Settings.Advanced.Video.ColorSpace.2020HLG="Rec. 2020 (HLG)"
Basic.Settings.Advanced.Video.ColorRange="Color Range"
-Basic.Settings.Advanced.Video.ColorRange.Partial="Partial"
+Basic.Settings.Advanced.Video.ColorRange.Partial="Limited"
Basic.Settings.Advanced.Video.ColorRange.Full="Full"
Basic.Settings.Advanced.Video.SdrWhiteLevel="SDR White Level (nits)"
Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring Device"
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index b7b9712f6..a19167f9d 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -4979,7 +4979,17 @@
-
- I444
+ I444
+
+
+ -
+
+ P010
+
+
+ -
+
+ I010
-
@@ -5014,23 +5024,7 @@
0
-
-
-
-
-
- sRGB
-
-
- -
-
- 709
-
-
- -
-
- 601
-
-
-
+
-
diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp
index de668bb24..2437fc533 100644
--- a/UI/window-basic-main.cpp
+++ b/UI/window-basic-main.cpp
@@ -4279,6 +4279,10 @@ static inline enum video_format GetVideoFormatFromName(const char *name)
return VIDEO_FORMAT_NV12;
else if (astrcmpi(name, "I444") == 0)
return VIDEO_FORMAT_I444;
+ else if (astrcmpi(name, "I010") == 0)
+ return VIDEO_FORMAT_I010;
+ else if (astrcmpi(name, "P010") == 0)
+ return VIDEO_FORMAT_P010;
#if 0 //currently unsupported
else if (astrcmpi(name, "YVYU") == 0)
return VIDEO_FORMAT_YVYU;
@@ -4291,6 +4295,21 @@ static inline enum video_format GetVideoFormatFromName(const char *name)
return VIDEO_FORMAT_RGBA;
}
+static inline enum video_colorspace GetVideoColorSpaceFromName(const char *name)
+{
+ enum video_colorspace colorspace = VIDEO_CS_SRGB;
+ if (strcmp(name, "601") == 0)
+ colorspace = VIDEO_CS_601;
+ else if (strcmp(name, "709") == 0)
+ colorspace = VIDEO_CS_709;
+ else if (strcmp(name, "2020PQ") == 0)
+ colorspace = VIDEO_CS_2020_PQ;
+ else if (strcmp(name, "2020HLG") == 0)
+ colorspace = VIDEO_CS_2020_HLG;
+
+ return colorspace;
+}
+
void OBSBasic::ResetUI()
{
bool studioPortraitLayout = config_get_bool(
@@ -4340,11 +4359,7 @@ int OBSBasic::ResetVideo()
ovi.output_height =
(uint32_t)config_get_uint(basicConfig, "Video", "OutputCY");
ovi.output_format = GetVideoFormatFromName(colorFormat);
- ovi.colorspace = astrcmpi(colorSpace, "601") == 0
- ? VIDEO_CS_601
- : (astrcmpi(colorSpace, "709") == 0
- ? VIDEO_CS_709
- : VIDEO_CS_SRGB);
+ ovi.colorspace = GetVideoColorSpaceFromName(colorSpace);
ovi.range = astrcmpi(colorRange, "Full") == 0 ? VIDEO_RANGE_FULL
: VIDEO_RANGE_PARTIAL;
ovi.adapter =
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index c6d99d74b..5679ebf67 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -700,6 +700,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
LoadEncoderTypes();
LoadColorRanges();
+ LoadColorSpaces();
LoadFormats();
auto ReloadAudioSources = [](void *data, calldata_t *param) {
@@ -1029,6 +1030,21 @@ void OBSBasicSettings::LoadColorRanges()
ui->colorRange->addItem(CS_FULL_STR, "Full");
}
+#define CS_SRGB_STR QTStr("Basic.Settings.Advanced.Video.ColorSpace.sRGB")
+#define CS_709_STR QTStr("Basic.Settings.Advanced.Video.ColorSpace.709")
+#define CS_601_STR QTStr("Basic.Settings.Advanced.Video.ColorSpace.601")
+#define CS_2020PQ_STR QTStr("Basic.Settings.Advanced.Video.ColorSpace.2020PQ")
+#define CS_2020HLG_STR QTStr("Basic.Settings.Advanced.Video.ColorSpace.2020HLG")
+
+void OBSBasicSettings::LoadColorSpaces()
+{
+ ui->colorSpace->addItem(CS_SRGB_STR, "sRGB");
+ ui->colorSpace->addItem(CS_709_STR, "709");
+ ui->colorSpace->addItem(CS_601_STR, "601");
+ ui->colorSpace->addItem(CS_2020PQ_STR, "2020PQ");
+ ui->colorSpace->addItem(CS_2020HLG_STR, "2020HLG");
+}
+
#define AV_FORMAT_DEFAULT_STR \
QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatDefault")
#define AUDIO_STR QTStr("Basic.Settings.Output.Adv.FFmpeg.FormatAudio")
@@ -2514,6 +2530,35 @@ void OBSBasicSettings::LoadAudioSettings()
loading = false;
}
+void OBSBasicSettings::UpdateColorFormatSpaceWarning()
+{
+ const QString text = ui->colorFormat->currentText();
+ if (ui->colorSpace->currentIndex() >= 3) {
+ if (text == "P010") {
+ ui->advancedMsg2->clear();
+ } else if (text == "I010") {
+ ui->advancedMsg2->setText(
+ QTStr("Basic.Settings.Advanced.FormatWarning"));
+ } else {
+ ui->advancedMsg2->setText(QTStr(
+ "Basic.Settings.Advanced.FormatWarning2020"));
+ }
+ } else {
+ if (text == "NV12") {
+ ui->advancedMsg2->clear();
+ } else if (text == "I010") {
+ ui->advancedMsg2->setText(QTStr(
+ "Basic.Settings.Advanced.FormatWarningI010"));
+ } else if (text == "P010") {
+ ui->advancedMsg2->setText(QTStr(
+ "Basic.Settings.Advanced.FormatWarningP010"));
+ } else {
+ ui->advancedMsg2->setText(
+ QTStr("Basic.Settings.Advanced.FormatWarning"));
+ }
+ }
+}
+
void OBSBasicSettings::LoadAdvancedSettings()
{
const char *videoColorFormat =
@@ -2592,8 +2637,10 @@ void OBSBasicSettings::LoadAdvancedSettings()
ui->autoRemux->setChecked(autoRemux);
ui->dynBitrate->setChecked(dynBitrate);
+ UpdateColorFormatSpaceWarning();
+
SetComboByName(ui->colorFormat, videoColorFormat);
- SetComboByName(ui->colorSpace, videoColorSpace);
+ SetComboByValue(ui->colorSpace, videoColorSpace);
SetComboByValue(ui->colorRange, videoColorRange);
ui->sdrWhiteLevel->setValue(sdrWhiteLevel);
@@ -3299,7 +3346,7 @@ void OBSBasicSettings::SaveAdvancedSettings()
#endif
SaveCombo(ui->colorFormat, "Video", "ColorFormat");
- SaveCombo(ui->colorSpace, "Video", "ColorSpace");
+ SaveComboData(ui->colorSpace, "Video", "ColorSpace");
SaveComboData(ui->colorRange, "Video", "ColorRange");
SaveSpinBox(ui->sdrWhiteLevel, "Video", "SdrWhiteLevel");
if (obs_audio_monitoring_available()) {
@@ -4026,15 +4073,14 @@ void OBSBasicSettings::on_advOutFFType_currentIndexChanged(int idx)
ui->advOutFFNoSpace->setHidden(idx != 0);
}
-void OBSBasicSettings::on_colorFormat_currentIndexChanged(const QString &text)
+void OBSBasicSettings::on_colorFormat_currentIndexChanged(const QString &)
{
- bool usingNV12 = text == "NV12";
+ UpdateColorFormatSpaceWarning();
+}
- if (usingNV12)
- ui->advancedMsg2->setText(QString());
- else
- ui->advancedMsg2->setText(
- QTStr("Basic.Settings.Advanced.FormatWarning"));
+void OBSBasicSettings::on_colorSpace_currentIndexChanged(const QString &)
+{
+ UpdateColorFormatSpaceWarning();
}
#define INVALID_RES_STR "Basic.Settings.Video.InvalidResolution"
diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp
index 4c66bc210..1ced9f5bb 100644
--- a/UI/window-basic-settings.hpp
+++ b/UI/window-basic-settings.hpp
@@ -222,9 +222,12 @@ private:
void LoadEncoderTypes();
void LoadColorRanges();
+ void LoadColorSpaces();
void LoadFormats();
void ReloadCodecs(const ff_format_desc *formatDesc);
+ void UpdateColorFormatSpaceWarning();
+
void LoadGeneralSettings();
void LoadStream1Settings();
void LoadOutputSettings();
@@ -360,6 +363,7 @@ private slots:
void on_advOutFFType_currentIndexChanged(int idx);
void on_colorFormat_currentIndexChanged(const QString &text);
+ void on_colorSpace_currentIndexChanged(const QString &text);
void on_filenameFormatting_textEdited(const QString &text);
void on_outputResolution_editTextChanged(const QString &text);