0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-19 20:32:15 +02:00

libobs-winrt,win-capture: Allow forcing SDR

We don't know if there's a way to get window color space, so we've been
using the monitor color space of the window. This toggle forces OBS to
ignore the monitor color space, and assume the window is SDR.
This commit is contained in:
jpark37 2022-09-04 12:16:44 -07:00 committed by Jim
parent e583e86b35
commit 894e37d0e1
4 changed files with 39 additions and 16 deletions

View File

@ -109,19 +109,26 @@ static bool get_client_box(HWND window, uint32_t width, uint32_t height,
return client_box_available;
}
static DXGI_FORMAT get_pixel_format(HWND window, HMONITOR monitor)
static DXGI_FORMAT get_pixel_format(HWND window, HMONITOR monitor,
BOOL force_sdr)
{
static constexpr DXGI_FORMAT sdr_format = DXGI_FORMAT_B8G8R8A8_UNORM;
if (force_sdr)
return sdr_format;
if (window)
monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
return (monitor && gs_is_monitor_hdr(monitor))
? DXGI_FORMAT_R16G16B16A16_FLOAT
: DXGI_FORMAT_B8G8R8A8_UNORM;
: sdr_format;
}
struct winrt_capture {
HWND window;
bool client_area;
BOOL client_area;
BOOL force_sdr;
HMONITOR monitor;
DXGI_FORMAT format;
@ -177,7 +184,8 @@ struct winrt_capture {
obs_enter_graphics();
if (desc.Format == get_pixel_format(window, monitor)) {
if (desc.Format ==
get_pixel_format(window, monitor, force_sdr)) {
if (!client_area ||
get_client_box(window, desc.Width, desc.Height,
&client_box)) {
@ -425,10 +433,9 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
}
}
static struct winrt_capture *winrt_capture_init_internal(BOOL cursor,
HWND window,
BOOL client_area,
HMONITOR monitor)
static struct winrt_capture *
winrt_capture_init_internal(BOOL cursor, HWND window, BOOL client_area,
BOOL force_sdr, HMONITOR monitor)
try {
ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj();
ComPtr<IDXGIDevice> dxgi_device;
@ -461,7 +468,7 @@ try {
device = inspectable.as<winrt::Windows::Graphics::DirectX::
Direct3D11::IDirect3DDevice>();
const winrt::Windows::Graphics::SizeInt32 size = item.Size();
const DXGI_FORMAT format = get_pixel_format(window, monitor);
const DXGI_FORMAT format = get_pixel_format(window, monitor, force_sdr);
const winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool
frame_pool = winrt::Windows::Graphics::Capture::
Direct3D11CaptureFramePool::Create(
@ -490,6 +497,7 @@ try {
struct winrt_capture *capture = new winrt_capture{};
capture->window = window;
capture->client_area = client_area;
capture->force_sdr = force_sdr;
capture->monitor = monitor;
capture->format = format;
capture->capture_cursor = cursor && cursor_toggle_supported;
@ -530,15 +538,17 @@ try {
}
extern "C" EXPORT struct winrt_capture *
winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area)
winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area,
BOOL force_sdr)
{
return winrt_capture_init_internal(cursor, window, client_area, NULL);
return winrt_capture_init_internal(cursor, window, client_area,
force_sdr, NULL);
}
extern "C" EXPORT struct winrt_capture *
winrt_capture_init_monitor(BOOL cursor, HMONITOR monitor)
{
return winrt_capture_init_internal(cursor, NULL, false, monitor);
return winrt_capture_init_internal(cursor, NULL, false, false, monitor);
}
extern "C" EXPORT void winrt_capture_free(struct winrt_capture *capture)

View File

@ -12,7 +12,8 @@ extern "C" {
EXPORT BOOL winrt_capture_supported();
EXPORT BOOL winrt_capture_cursor_toggle_supported();
EXPORT struct winrt_capture *winrt_capture_init_window(BOOL cursor, HWND window,
BOOL client_area);
BOOL client_area,
BOOL force_sdr);
EXPORT struct winrt_capture *winrt_capture_init_monitor(BOOL cursor,
HMONITOR monitor);
EXPORT void winrt_capture_free(struct winrt_capture *capture);

View File

@ -12,6 +12,7 @@ WindowCapture.Priority.Exe="Match title, otherwise find window of same executabl
CaptureCursor="Capture Cursor"
Compatibility="Multi-adapter Compatibility"
ClientArea="Client Area"
ForceSdr="Force SDR"
SLIFix="SLI/Crossfire Capture Mode (Slow)"
AllowTransparency="Allow Transparency"
Monitor="Display"

View File

@ -21,6 +21,7 @@
#define TEXT_CAPTURE_CURSOR obs_module_text("CaptureCursor")
#define TEXT_COMPATIBILITY obs_module_text("Compatibility")
#define TEXT_CLIENT_AREA obs_module_text("ClientArea")
#define TEXT_FORCE_SDR obs_module_text("ForceSdr")
/* clang-format on */
@ -30,8 +31,10 @@
typedef BOOL (*PFN_winrt_capture_supported)();
typedef BOOL (*PFN_winrt_capture_cursor_toggle_supported)();
typedef struct winrt_capture *(*PFN_winrt_capture_init_window)(
BOOL cursor, HWND window, BOOL client_area);
typedef struct winrt_capture *(*PFN_winrt_capture_init_window)(BOOL cursor,
HWND window,
BOOL client_area,
BOOL force_sdr);
typedef void (*PFN_winrt_capture_free)(struct winrt_capture *capture);
typedef BOOL (*PFN_winrt_capture_active)(const struct winrt_capture *capture);
@ -82,6 +85,7 @@ struct window_capture {
bool cursor;
bool compatibility;
bool client_area;
bool force_sdr;
bool use_wildcards; /* TODO */
struct dc_capture capture;
@ -204,6 +208,7 @@ static void update_settings(struct window_capture *wc, obs_data_t *s)
wc->method = choose_method(method, wgc_supported, wc->class);
wc->priority = (enum window_priority)priority;
wc->cursor = obs_data_get_bool(s, "cursor");
wc->force_sdr = obs_data_get_bool(s, "force_sdr");
wc->use_wildcards = obs_data_get_bool(s, "use_wildcards");
wc->compatibility = obs_data_get_bool(s, "compatibility");
wc->client_area = obs_data_get_bool(s, "client_area");
@ -370,6 +375,7 @@ static void wc_defaults(obs_data_t *defaults)
{
obs_data_set_default_int(defaults, "method", METHOD_AUTO);
obs_data_set_default_bool(defaults, "cursor", true);
obs_data_set_default_bool(defaults, "force_sdr", false);
obs_data_set_default_bool(defaults, "compatibility", false);
obs_data_set_default_bool(defaults, "client_area", true);
}
@ -396,6 +402,9 @@ static void update_settings_visibility(obs_properties_t *props,
p = obs_properties_get(props, "client_area");
obs_property_set_visible(p, wgc_options);
p = obs_properties_get(props, "force_sdr");
obs_property_set_visible(p, wgc_cursor_toggle);
pthread_mutex_unlock(&wc->update_mutex);
}
@ -465,6 +474,8 @@ static obs_properties_t *wc_properties(void *data)
obs_properties_add_bool(ppts, "client_area", TEXT_CLIENT_AREA);
obs_properties_add_bool(ppts, "force_sdr", TEXT_FORCE_SDR);
return ppts;
}
@ -608,7 +619,7 @@ static void wc_tick(void *data, float seconds)
wc->capture_winrt =
wc->exports.winrt_capture_init_window(
wc->cursor, wc->window,
wc->client_area);
wc->client_area, wc->force_sdr);
if (!wc->capture_winrt) {
wc->previously_failed = true;