Workaround HDR being captured as SDR issue
This commit is contained in:
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
#include <dxgi.h>
|
#include <dxgi.h>
|
||||||
|
#include <highlevelmonitorconfigurationapi.h>
|
||||||
|
#include <physicalmonitorenumerationapi.h>
|
||||||
|
|
||||||
#include "virtual_display.h"
|
#include "virtual_display.h"
|
||||||
|
|
||||||
@@ -106,6 +108,83 @@ bool setPrimaryDisplay(const wchar_t* primaryDeviceName) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ensureDisplayHDR(const wchar_t* displayName) {
|
||||||
|
UINT32 pathCount = 0, modeCount = 0;
|
||||||
|
|
||||||
|
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount) != ERROR_SUCCESS) {
|
||||||
|
printf("Failed to query display configuration.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DISPLAYCONFIG_PATH_INFO> pathArray(pathCount);
|
||||||
|
std::vector<DISPLAYCONFIG_MODE_INFO> modeArray(modeCount);
|
||||||
|
|
||||||
|
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, pathArray.data(), &modeCount, modeArray.data(), NULL) != ERROR_SUCCESS) {
|
||||||
|
printf("Failed to query display paths.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& path : pathArray) {
|
||||||
|
DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo = path.sourceInfo;
|
||||||
|
|
||||||
|
DISPLAYCONFIG_SOURCE_DEVICE_NAME deviceName = {};
|
||||||
|
deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
|
||||||
|
deviceName.header.size = sizeof(deviceName);
|
||||||
|
deviceName.header.adapterId = sourceInfo.adapterId;
|
||||||
|
deviceName.header.id = sourceInfo.id;
|
||||||
|
|
||||||
|
if (DisplayConfigGetDeviceInfo(&deviceName.header) != ERROR_SUCCESS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::wstring_view(displayName) == deviceName.viewGdiDeviceName) {
|
||||||
|
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO hdrInfo = {};
|
||||||
|
hdrInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
|
||||||
|
hdrInfo.header.size = sizeof(hdrInfo);
|
||||||
|
hdrInfo.header.adapterId = path.targetInfo.adapterId;
|
||||||
|
hdrInfo.header.id = path.targetInfo.id;
|
||||||
|
|
||||||
|
if (DisplayConfigGetDeviceInfo(&hdrInfo.header) != ERROR_SUCCESS) {
|
||||||
|
wprintf(L"Failed to get HDR info for display: %ls\n", std::wstring(deviceName.viewGdiDeviceName));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdrInfo.advancedColorSupported) {
|
||||||
|
if (hdrInfo.advancedColorEnabled) {
|
||||||
|
DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE setHdrInfo = {};
|
||||||
|
setHdrInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE;
|
||||||
|
setHdrInfo.header.size = sizeof(setHdrInfo);
|
||||||
|
setHdrInfo.header.adapterId = path.targetInfo.adapterId;
|
||||||
|
setHdrInfo.header.id = path.targetInfo.id;
|
||||||
|
setHdrInfo.enableAdvancedColor = FALSE; // Disable HDR
|
||||||
|
|
||||||
|
if (DisplayConfigSetDeviceInfo(&setHdrInfo.header) == ERROR_SUCCESS) {
|
||||||
|
wprintf(L"HDR toggled off for display: %ls\n", displayName);
|
||||||
|
} else {
|
||||||
|
wprintf(L"Failed to toggle HDR off for display: %ls\n", std::wstring(deviceName.viewGdiDeviceName));
|
||||||
|
}
|
||||||
|
|
||||||
|
setHdrInfo.enableAdvancedColor = TRUE; // Enable HDR back on
|
||||||
|
|
||||||
|
if (DisplayConfigSetDeviceInfo(&setHdrInfo.header) == ERROR_SUCCESS) {
|
||||||
|
wprintf(L"HDR toggled on for display: %ls\n", displayName);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
wprintf(L"Failed to toggle HDR on for display: %ls\n", std::wstring(deviceName.viewGdiDeviceName));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wprintf(L"HDR is not enabled on display: %ls\n", displayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wprintf(L"Display not found or HDR not supported: %ls\n", displayName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void closeVDisplayDevice() {
|
void closeVDisplayDevice() {
|
||||||
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
|
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace VDISPLAY {
|
|||||||
LONG changeDisplaySettings(const wchar_t* deviceName, int width, int height, int refresh_rate);
|
LONG changeDisplaySettings(const wchar_t* deviceName, int width, int height, int refresh_rate);
|
||||||
std::wstring getPrimaryDisplay();
|
std::wstring getPrimaryDisplay();
|
||||||
bool setPrimaryDisplay(const wchar_t* primaryDeviceName);
|
bool setPrimaryDisplay(const wchar_t* primaryDeviceName);
|
||||||
|
bool ensureDisplayHDR(const wchar_t* displayName);
|
||||||
|
|
||||||
void closeVDisplayDevice();
|
void closeVDisplayDevice();
|
||||||
DRIVER_STATUS openVDisplayDevice();
|
DRIVER_STATUS openVDisplayDevice();
|
||||||
|
|||||||
@@ -368,6 +368,24 @@ namespace proc {
|
|||||||
|
|
||||||
_app_launch_time = std::chrono::steady_clock::now();
|
_app_launch_time = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
auto resetHDRThread = std::thread([this]{
|
||||||
|
std::this_thread::sleep_for(200ms);
|
||||||
|
// Windows doesn't seem to be able to set HDR correctly when a display is just connected,
|
||||||
|
// so we have tooggle HDR for the virtual display manually.
|
||||||
|
std::string currentDisplay = this->display_name;
|
||||||
|
if (!currentDisplay.empty()) {
|
||||||
|
if (VDISPLAY::ensureDisplayHDR(platf::from_utf8(currentDisplay).c_str())) {
|
||||||
|
BOOST_LOG(info) << "HDR rsestted for display " << currentDisplay;
|
||||||
|
} else {
|
||||||
|
BOOST_LOG(info) << "HDR not applied for display " << currentDisplay;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resetHDRThread.detach();
|
||||||
|
#endif
|
||||||
|
|
||||||
fg.disable();
|
fg.disable();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace video {
|
|||||||
|
|
||||||
/* See video::config_t declaration for details */
|
/* See video::config_t declaration for details */
|
||||||
|
|
||||||
|
BOOST_LOG(info) << "Client dynamicRange: " << config.dynamicRange << ", Display is HDR: " << hdr_display;
|
||||||
|
|
||||||
if (config.dynamicRange > 0 && hdr_display) {
|
if (config.dynamicRange > 0 && hdr_display) {
|
||||||
// Rec. 2020 with ST 2084 perceptual quantizer
|
// Rec. 2020 with ST 2084 perceptual quantizer
|
||||||
colorspace.colorspace = colorspace_e::bt2020;
|
colorspace.colorspace = colorspace_e::bt2020;
|
||||||
|
|||||||
Reference in New Issue
Block a user