diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc index 827f257717..2f7fac9f02 100644 --- a/modules/desktop_capture/win/wgc_capture_session.cc +++ b/modules/desktop_capture/win/wgc_capture_session.cc @@ -256,10 +256,16 @@ void WgcCaptureSession::EnsureFrame() { << "Unable to process a valid frame even after trying 10 times."; } -bool WgcCaptureSession::GetFrame(std::unique_ptr* output_frame) { +bool WgcCaptureSession::GetFrame(std::unique_ptr* output_frame, + bool source_should_be_capturable) { RTC_DCHECK_RUN_ON(&sequence_checker_); - EnsureFrame(); + // Try to process the captured frame and wait some if needed. Avoid trying + // if we know that the source will not be capturable. This can happen e.g. + // when captured window is minimized and if EnsureFrame() was called in this + // state a large amount of kFrameDropped errors would be logged. + if (source_should_be_capturable) + EnsureFrame(); // Return a NULL frame and false as `result` if we still don't have a valid // frame. This will lead to a DesktopCapturer::Result::ERROR_PERMANENT being diff --git a/modules/desktop_capture/win/wgc_capture_session.h b/modules/desktop_capture/win/wgc_capture_session.h index 499c75ee98..8084bf1e37 100644 --- a/modules/desktop_capture/win/wgc_capture_session.h +++ b/modules/desktop_capture/win/wgc_capture_session.h @@ -44,7 +44,8 @@ class WgcCaptureSession final { HRESULT StartCapture(const DesktopCaptureOptions& options); // Returns a frame from the local frame queue, if any are present. - bool GetFrame(std::unique_ptr* output_frame); + bool GetFrame(std::unique_ptr* output_frame, + bool source_should_be_capturable); bool IsCaptureStarted() const { RTC_DCHECK_RUN_ON(&sequence_checker_); diff --git a/modules/desktop_capture/win/wgc_capture_source.cc b/modules/desktop_capture/win/wgc_capture_source.cc index 24e6129ec7..9eab3dbb8f 100644 --- a/modules/desktop_capture/win/wgc_capture_source.cc +++ b/modules/desktop_capture/win/wgc_capture_source.cc @@ -29,6 +29,10 @@ WgcCaptureSource::WgcCaptureSource(DesktopCapturer::SourceId source_id) : source_id_(source_id) {} WgcCaptureSource::~WgcCaptureSource() = default; +bool WgcCaptureSource::ShouldBeCapturable() { + return true; +} + bool WgcCaptureSource::IsCapturable() { // If we can create a capture item, then we can capture it. Unfortunately, // we can't cache this item because it may be created in a different COM @@ -105,9 +109,17 @@ ABI::Windows::Graphics::SizeInt32 WgcWindowSource::GetSize() { window_rect.bottom - window_rect.top}; } +// Light-weight version of IsCapturable(). Avoids calling +// WgcCaptureSource::IsCapturable() which allocates/deallocates a new COM object +// for each call. Will return false when a window has been minimized. +bool WgcWindowSource::ShouldBeCapturable() { + return IsWindowValidAndVisible(reinterpret_cast(GetSourceId())); +} + bool WgcWindowSource::IsCapturable() { - if (!IsWindowValidAndVisible(reinterpret_cast(GetSourceId()))) + if (!ShouldBeCapturable()) { return false; + } return WgcCaptureSource::IsCapturable(); } diff --git a/modules/desktop_capture/win/wgc_capture_source.h b/modules/desktop_capture/win/wgc_capture_source.h index d1275b6168..87227fc309 100644 --- a/modules/desktop_capture/win/wgc_capture_source.h +++ b/modules/desktop_capture/win/wgc_capture_source.h @@ -33,6 +33,7 @@ class WgcCaptureSource { virtual ~WgcCaptureSource(); virtual DesktopVector GetTopLeft() = 0; + virtual bool ShouldBeCapturable(); virtual bool IsCapturable(); virtual bool FocusOnSource(); virtual ABI::Windows::Graphics::SizeInt32 GetSize(); @@ -99,6 +100,7 @@ class WgcWindowSource final : public WgcCaptureSource { DesktopVector GetTopLeft() override; ABI::Windows::Graphics::SizeInt32 GetSize() override; + bool ShouldBeCapturable() override; bool IsCapturable() override; bool FocusOnSource() override; diff --git a/modules/desktop_capture/win/wgc_capturer_win.cc b/modules/desktop_capture/win/wgc_capturer_win.cc index 20d4eb938d..9c545597aa 100644 --- a/modules/desktop_capture/win/wgc_capturer_win.cc +++ b/modules/desktop_capture/win/wgc_capturer_win.cc @@ -323,7 +323,8 @@ void WgcCapturerWin::CaptureFrame() { } std::unique_ptr frame; - if (!capture_session->GetFrame(&frame)) { + if (!capture_session->GetFrame(&frame, + capture_source_->ShouldBeCapturable())) { RTC_LOG(LS_ERROR) << "GetFrame failed."; ongoing_captures_.erase(capture_source_->GetSourceId()); callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,