Skip to content

Commit

Permalink
Avoids initial kFrameDropped burst for WGC
Browse files Browse the repository at this point in the history
Bug: chromium:1412584
Change-Id: I6bfdcec98dfae0f99bfce51ace15795a044eb7d5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/295504
Commit-Queue: Henrik Andreassson <henrika@webrtc.org>
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/main@{#39435}
  • Loading branch information
henrikand authored and WebRTC LUCI CQ committed Mar 1, 2023
1 parent a1ceae2 commit d2ee133
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
17 changes: 15 additions & 2 deletions modules/desktop_capture/win/wgc_capture_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ bool WgcCaptureSession::GetFrame(std::unique_ptr<DesktopFrame>* output_frame) {
// causing us to wait two frames when we mostly seem to only need to wait for
// one. This approach should ensure that GetFrame() always delivers a valid
// frame with a max latency of 200ms and often after sleeping only once.
// We also build up an `empty_frame_credit_count_` for each sleep call. As
// long as this credit is above zero, error logs for "empty frame" are
// avoided. The counter is reduced by one for each successful call to
// ProcessFrame() until the number of credits is zero. This counter is only
// expected to be above zero during a short startup phase. The scheme is
// heuristic and based on manual testing.
// (*) On a modern system, the FPS / monitor refresh rate is usually larger
// than or equal to 60.
const int max_sleep_count = 10;
Expand All @@ -223,6 +229,7 @@ bool WgcCaptureSession::GetFrame(std::unique_ptr<DesktopFrame>* output_frame) {
int sleep_count = 0;
while (!queue_.current_frame() && sleep_count < max_sleep_count) {
sleep_count++;
empty_frame_credit_count_ = sleep_count + 1;
webrtc::SleepMs(sleep_time_ms);
ProcessFrame();
}
Expand Down Expand Up @@ -299,8 +306,12 @@ HRESULT WgcCaptureSession::ProcessFrame() {
}

if (!capture_frame) {
RTC_DLOG(LS_WARNING) << "Frame pool was empty.";
RecordGetFrameResult(GetFrameResult::kFrameDropped);
// Avoid logging errors while we still have credits (or allowance) to
// consider this condition as expected and not as an error.
if (empty_frame_credit_count_ == 0) {
RTC_DLOG(LS_WARNING) << "Frame pool was empty => kFrameDropped.";
RecordGetFrameResult(GetFrameResult::kFrameDropped);
}
return E_FAIL;
}

Expand Down Expand Up @@ -422,6 +433,8 @@ HRESULT WgcCaptureSession::ProcessFrame() {

d3d_context->Unmap(mapped_texture_.Get(), 0);

if (empty_frame_credit_count_ > 0)
--empty_frame_credit_count_;
size_ = new_size;
RecordGetFrameResult(GetFrameResult::kSuccess);
return hr;
Expand Down
10 changes: 10 additions & 0 deletions modules/desktop_capture/win/wgc_capture_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ class WgcCaptureSession final {
bool item_closed_ = false;
bool is_capture_started_ = false;

// Counts number of "empty frame credits" which have built up in GetFrame()
// when a sequence of calls to ProcessFrame() was called with 20ms sleep calls
// between each. The counter is reduced by one (to a minimum of zero) when
// ProcessFrame() succeeds. As long as the counter is larger than zero, calls
// to RecordGetFrameResult(kTryGetNextFrameFailed) are disabled.
// The reason for adding this scheme is to prevent logs of
// kTryGetNextFrameFailed in the startup phase when some empty frames is
// expected and should not be seen as an error.
int empty_frame_credit_count_ = 0;

SequenceChecker sequence_checker_;
};

Expand Down

0 comments on commit d2ee133

Please sign in to comment.