From 03da3c834b3419d773a7dfbf9fd898762585d716 Mon Sep 17 00:00:00 2001 From: SendableMetatype <263203301+SendableMetatype@users.noreply.github.com> Date: Mon, 7 Sep 2026 17:47:48 +0200 Subject: [PATCH] fix: keep the desktop capture frame rate at the configured value The capture loop slept for a full frame interval after every CaptureFrame call, ignoring the time the capture itself took. With DXGI a capture can take a whole display refresh, so a source configured for 60 frames per second produced 30, and higher settings changed nothing. The loop now measures the capture and sleeps only for the remainder of the interval. --- .../src/media/video/VideoTrackDesktopSource.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/webrtc-jni/src/main/cpp/src/media/video/VideoTrackDesktopSource.cpp b/webrtc-jni/src/main/cpp/src/media/video/VideoTrackDesktopSource.cpp index 2f18b5b5..3d9cf721 100644 --- a/webrtc-jni/src/main/cpp/src/media/video/VideoTrackDesktopSource.cpp +++ b/webrtc-jni/src/main/cpp/src/media/video/VideoTrackDesktopSource.cpp @@ -25,6 +25,7 @@ #include "third_party/libyuv/include/libyuv/video_common.h" #include "rtc_base/logging.h" #include "rtc_base/thread.h" +#include "rtc_base/time_utils.h" #include "modules/desktop_capture/desktop_capturer.h" #include "modules/desktop_capture/desktop_and_cursor_composer.h" @@ -301,15 +302,24 @@ namespace jni sourceState = kLive; - int msPerFrame = 1000 / frameRate; + const int64_t msPerFrame = 1000 / frameRate; while (isCapturing) { + const int64_t frameStart = webrtc::TimeMillis(); + #if defined(WEBRTC_MAC) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true); #endif capturer->CaptureFrame(); - webrtc::Thread::SleepMs(msPerFrame); + // CaptureFrame takes time of its own, up to a full display refresh + // with DXGI, so sleeping the whole interval afterwards halved the + // effective frame rate. Sleep only for what is left of the interval. + const int64_t elapsed = webrtc::TimeMillis() - frameStart; + + if (elapsed < msPerFrame) { + webrtc::Thread::SleepMs(static_cast(msPerFrame - elapsed)); + } } capturer.reset();