diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index ee1776c6790..64db6109e0f 100644 --- a/docs/source/about/advanced_usage.rst +++ b/docs/source/about/advanced_usage.rst @@ -357,27 +357,6 @@ resolutions 3840x1600, ] -dwmflush -^^^^^^^^ - -**Description** - Invoke DwmFlush() to sync screen capture to the Windows presentation interval. - - .. Caution:: Applies to Windows only. Alleviates visual stuttering during mouse movement. - If enabled, this feature will automatically deactivate if the client framerate exceeds - the host monitor's current refresh rate. - - .. Note:: If you disable this option, you may see video stuttering during mouse movement in certain scenarios. - It is recommended to leave enabled when possible. - -**Default** - ``enabled`` - -**Example** - .. code-block:: text - - dwmflush = enabled - Audio ----- diff --git a/src/config.cpp b/src/config.cpp index 11c393a8cbc..9e1afa2ecff 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -314,10 +314,9 @@ video_t video { -1, }, // vt - {}, // encoder - {}, // adapter_name - {}, // output_name - true // dwmflush + {}, // encoder + {}, // adapter_name + {}, // output_name }; audio_t audio {}; @@ -834,7 +833,6 @@ void apply_config(std::unordered_map &&vars) { string_f(vars, "encoder", video.encoder); string_f(vars, "adapter_name", video.adapter_name); string_f(vars, "output_name", video.output_name); - bool_f(vars, "dwmflush", video.dwmflush); path_f(vars, "pkey", nvhttp.pkey); path_f(vars, "cert", nvhttp.cert); diff --git a/src/config.h b/src/config.h index a95e0f854ae..52d60993562 100644 --- a/src/config.h +++ b/src/config.h @@ -51,7 +51,6 @@ struct video_t { std::string encoder; std::string adapter_name; std::string output_name; - bool dwmflush; }; struct audio_t { diff --git a/src/platform/windows/display.h b/src/platform/windows/display.h index a72c94bde12..74a52a17e49 100644 --- a/src/platform/windows/display.h +++ b/src/platform/windows/display.h @@ -105,7 +105,6 @@ class duplication_t { public: dup_t dup; bool has_frame {}; - bool use_dwmflush {}; capture_e next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p); capture_e reset(dup_t::pointer dup_p = dup_t::pointer()); diff --git a/src/platform/windows/display_base.cpp b/src/platform/windows/display_base.cpp index 5706f86c94e..984ad8a5e82 100644 --- a/src/platform/windows/display_base.cpp +++ b/src/platform/windows/display_base.cpp @@ -26,15 +26,6 @@ namespace platf::dxgi { namespace bp = boost::process; capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p) { - auto capture_status = release_frame(); - if(capture_status != capture_e::ok) { - return capture_status; - } - - if(use_dwmflush) { - DwmFlush(); - } - auto status = dup->AcquireNextFrame(timeout.count(), &frame_info, res_p); switch(status) { @@ -46,6 +37,7 @@ capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::ch case WAIT_ABANDONED: case DXGI_ERROR_ACCESS_LOST: case DXGI_ERROR_ACCESS_DENIED: + case DXGI_ERROR_INVALID_CALL: return capture_e::reinit; default: BOOST_LOG(error) << "Couldn't acquire next frame [0x"sv << util::hex(status).to_string_view(); @@ -114,10 +106,10 @@ capture_e display_base_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<: return platf::capture_e::reinit; } - // If the wait time is between 1 us and 1 second, wait the specified time + // If the wait time is between 1 us and the frame to frame delay interval, wait the specified time // and offset the next frame time from the exact current frame time target. auto wait_time_us = std::chrono::duration_cast(next_frame - std::chrono::steady_clock::now()).count(); - if(wait_time_us > 0 && wait_time_us < 1000000) { + if(wait_time_us > 0 && wait_time_us < std::chrono::duration_cast(delay).count()) { LARGE_INTEGER due_time { .QuadPart = -10LL * wait_time_us }; SetWaitableTimer(timer, &due_time, 0, nullptr, nullptr, false); WaitForSingleObject(timer, INFINITE); @@ -125,21 +117,23 @@ capture_e display_base_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<: } else { // If the wait time is negative (meaning the frame is past due) or the - // computed wait time is beyond a second (meaning possible clock issues), + // computed wait time is beyond the delay interval (meaning possible clock issues), // just capture the frame now and resynchronize the frame interval with // the current time. next_frame = std::chrono::steady_clock::now() + delay; } - auto status = snapshot(img.get(), 1000ms, *cursor); + auto status = snapshot(img.get(), std::chrono::duration_cast(delay / 2), *cursor); switch(status) { case platf::capture_e::reinit: case platf::capture_e::error: return status; case platf::capture_e::timeout: + next_frame -= (delay / 2); // try to reacquire with remaining delay interval (or force resync) img = snapshot_cb(img, false); break; case platf::capture_e::ok: + dup.release_frame(); img = snapshot_cb(img, true); break; default: @@ -427,21 +421,6 @@ int display_base_t::init(const ::video::config_t &config, const std::string &dis << "Offset : "sv << offset_x << 'x' << offset_y << std::endl << "Virtual Desktop : "sv << env_width << 'x' << env_height; - // Enable DwmFlush() only if the current refresh rate can match the client framerate. - auto refresh_rate = config.framerate; - DWM_TIMING_INFO timing_info; - timing_info.cbSize = sizeof(timing_info); - - status = DwmGetCompositionTimingInfo(NULL, &timing_info); - if(FAILED(status)) { - BOOST_LOG(warning) << "Failed to detect active refresh rate."; - } - else { - refresh_rate = std::round((double)timing_info.rateRefresh.uiNumerator / (double)timing_info.rateRefresh.uiDenominator); - } - - dup.use_dwmflush = config::video.dwmflush && !(config.framerate > refresh_rate) ? true : false; - // Bump up thread priority { const DWORD flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY; diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index 1bc06507e4d..455ce5e6ead 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -416,18 +416,6 @@

Configuration

tools\dxgi-info.exe
- -
- - -
- Improves capture latency/smoothness during mouse movement.
- Disable if you encounter any VSync-related issues. -
-
Configuration this.config.key_rightalt_to_key_win || "disabled"; this.config.gamepad = this.config.gamepad || "x360"; this.config.upnp = this.config.upnp || "disabled"; - this.config.dwmflush = this.config.dwmflush || "enabled"; this.config.min_log_level = this.config.min_log_level || 2; this.config.origin_pin_allowed = this.config.origin_pin_allowed || "pc";