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}
This commit is contained in:
henrika 2023-10-18 11:21:57 +02:00 committed by WebRTC LUCI CQ
parent 94c1b77baa
commit 2bf3620e13
5 changed files with 27 additions and 5 deletions

View File

@ -256,10 +256,16 @@ void WgcCaptureSession::EnsureFrame() {
<< "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

View File

@ -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<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_);

View File

@ -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<HWND>(GetSourceId()));
}
bool WgcWindowSource::IsCapturable() {
if (!IsWindowValidAndVisible(reinterpret_cast<HWND>(GetSourceId())))
if (!ShouldBeCapturable()) {
return false;
}
return WgcCaptureSource::IsCapturable();
}

View File

@ -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;

View File

@ -323,7 +323,8 @@ void WgcCapturerWin::CaptureFrame() {
}
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,