From 9b36df199ed3893a353fc054248ccc5e64f5785e Mon Sep 17 00:00:00 2001 From: Skajdrovski Date: Fri, 24 Oct 2025 21:56:08 +0200 Subject: [PATCH] libobs-winrt: Prevent hard cap of 60 fps for WGC capture Original commit: https://github.com/ClassicOldSong/Apollo/pull/785 --- libobs-winrt/winrt-capture.cpp | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/libobs-winrt/winrt-capture.cpp b/libobs-winrt/winrt-capture.cpp index a31414f47c9942..30325a2b8735fe 100644 --- a/libobs-winrt/winrt-capture.cpp +++ b/libobs-winrt/winrt-capture.cpp @@ -1,5 +1,9 @@ #include "winrt-capture.h" +#if defined(WDK_NTDDI_VERSION) && (WDK_NTDDI_VERSION >= 0x0A000010) +#define WINRT_MIN_UPDATE_INTERVAL +#endif + extern "C" EXPORT BOOL winrt_capture_supported() try { /* no contract for IGraphicsCaptureItemInterop, verify 10.0.18362.0 */ @@ -27,6 +31,18 @@ try { return false; } +#ifdef WINRT_MIN_UPDATE_INTERVAL +static inline winrt::Windows::Foundation::TimeSpan calculate_min_interval() +{ + obs_video_info ovi{}; + if (!obs_get_video_info(&ovi) || !ovi.fps_num) + return winrt::Windows::Foundation::TimeSpan{0}; + + const uint64_t frame_interval_hns = util_mul_div64(ovi.fps_den, 10000000ULL, ovi.fps_num); + return winrt::Windows::Foundation::TimeSpan{static_cast(frame_interval_hns / 2)}; +} +#endif + template static winrt::com_ptr GetDXGIInterfaceFromObject(winrt::Windows::Foundation::IInspectable const &object) { @@ -306,6 +322,18 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data) capture->last_size); const winrt::Windows::Graphics::Capture::GraphicsCaptureSession session = frame_pool.CreateCaptureSession(item); +#ifdef WINRT_MIN_UPDATE_INTERVAL + if (winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent( + L"Windows.Graphics.Capture.GraphicsCaptureSession", L"MinUpdateInterval")) { + try { + session.MinUpdateInterval(calculate_min_interval()); + } catch (const winrt::hresult_error &err) { + blog(LOG_WARNING, "GraphicsCaptureSession::MinUpdateInterval (0x%08X): %s", err.code().value, + winrt::to_string(err.message()).c_str()); + } + } +#endif + if (winrt_capture_border_toggle_supported()) { winrt::Windows::Graphics::Capture::GraphicsCaptureAccess::RequestAccessAsync( winrt::Windows::Graphics::Capture::GraphicsCaptureAccessKind::Borderless) @@ -370,6 +398,18 @@ try { device, static_cast(format), 2, size); const winrt::Windows::Graphics::Capture::GraphicsCaptureSession session = frame_pool.CreateCaptureSession(item); +#ifdef WINRT_MIN_UPDATE_INTERVAL + if (winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent( + L"Windows.Graphics.Capture.GraphicsCaptureSession", L"MinUpdateInterval")) { + try { + session.MinUpdateInterval(calculate_min_interval()); + } catch (const winrt::hresult_error &err) { + blog(LOG_WARNING, "GraphicsCaptureSession::MinUpdateInterval (0x%08X): %s", err.code().value, + winrt::to_string(err.message()).c_str()); + } + } +#endif + if (winrt_capture_border_toggle_supported()) { winrt::Windows::Graphics::Capture::GraphicsCaptureAccess::RequestAccessAsync( winrt::Windows::Graphics::Capture::GraphicsCaptureAccessKind::Borderless)