Avoids spamming WebRTC.DesktopCapture.Win.WgcCaptureSessionGetFrameResult with FrameDropped

Without this change a FrameDropped sample will be added to
WebRTC.DesktopCapture.Win.WgcCaptureSessionGetFrameResult at the
current capture rate as long as a captured window is minimized.

Bug: webrtc:1314868
Change-Id: I9b68675486642e7ca25674df689c207ac94a206e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/323882
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/main@{#40969}
diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc
index 827f257..2f7fac9 100644
--- a/modules/desktop_capture/win/wgc_capture_session.cc
+++ b/modules/desktop_capture/win/wgc_capture_session.cc
@@ -256,10 +256,16 @@
       << "Unable to process a valid frame even after trying 10 times.";
 }
 
-bool WgcCaptureSession::GetFrame(std::unique_ptr<DesktopFrame>* output_frame) {
+bool WgcCaptureSession::GetFrame(std::unique_ptr<DesktopFrame>* 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 499c75e..8084bf1 100644
--- a/modules/desktop_capture/win/wgc_capture_session.h
+++ b/modules/desktop_capture/win/wgc_capture_session.h
@@ -44,7 +44,8 @@
   HRESULT StartCapture(const DesktopCaptureOptions& options);
 
   // Returns a frame from the local frame queue, if any are present.
-  bool GetFrame(std::unique_ptr<DesktopFrame>* output_frame);
+  bool GetFrame(std::unique_ptr<DesktopFrame>* 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 24e6129..9eab3db 100644
--- a/modules/desktop_capture/win/wgc_capture_source.cc
+++ b/modules/desktop_capture/win/wgc_capture_source.cc
@@ -29,6 +29,10 @@
     : 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 @@
           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<HWND>(GetSourceId()));
+}
+
 bool WgcWindowSource::IsCapturable() {
-  if (!IsWindowValidAndVisible(reinterpret_cast<HWND>(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 d1275b6..87227fc 100644
--- a/modules/desktop_capture/win/wgc_capture_source.h
+++ b/modules/desktop_capture/win/wgc_capture_source.h
@@ -33,6 +33,7 @@
   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 @@
 
   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 20d4eb9..9c54559 100644
--- a/modules/desktop_capture/win/wgc_capturer_win.cc
+++ b/modules/desktop_capture/win/wgc_capturer_win.cc
@@ -323,7 +323,8 @@
   }
 
   std::unique_ptr<DesktopFrame> 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,