Avoids initial kFrameDropped burst for WGC

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}
This commit is contained in:
henrika 2023-03-01 10:23:06 +01:00 committed by WebRTC LUCI CQ
parent a1ceae206b
commit d2ee133c59
2 changed files with 25 additions and 2 deletions

View File

@ -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 // 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 // one. This approach should ensure that GetFrame() always delivers a valid
// frame with a max latency of 200ms and often after sleeping only once. // 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 // (*) On a modern system, the FPS / monitor refresh rate is usually larger
// than or equal to 60. // than or equal to 60.
const int max_sleep_count = 10; const int max_sleep_count = 10;
@ -223,6 +229,7 @@ bool WgcCaptureSession::GetFrame(std::unique_ptr<DesktopFrame>* output_frame) {
int sleep_count = 0; int sleep_count = 0;
while (!queue_.current_frame() && sleep_count < max_sleep_count) { while (!queue_.current_frame() && sleep_count < max_sleep_count) {
sleep_count++; sleep_count++;
empty_frame_credit_count_ = sleep_count + 1;
webrtc::SleepMs(sleep_time_ms); webrtc::SleepMs(sleep_time_ms);
ProcessFrame(); ProcessFrame();
} }
@ -299,8 +306,12 @@ HRESULT WgcCaptureSession::ProcessFrame() {
} }
if (!capture_frame) { if (!capture_frame) {
RTC_DLOG(LS_WARNING) << "Frame pool was empty."; // Avoid logging errors while we still have credits (or allowance) to
RecordGetFrameResult(GetFrameResult::kFrameDropped); // 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; return E_FAIL;
} }
@ -422,6 +433,8 @@ HRESULT WgcCaptureSession::ProcessFrame() {
d3d_context->Unmap(mapped_texture_.Get(), 0); d3d_context->Unmap(mapped_texture_.Get(), 0);
if (empty_frame_credit_count_ > 0)
--empty_frame_credit_count_;
size_ = new_size; size_ = new_size;
RecordGetFrameResult(GetFrameResult::kSuccess); RecordGetFrameResult(GetFrameResult::kSuccess);
return hr; return hr;

View File

@ -130,6 +130,16 @@ class WgcCaptureSession final {
bool item_closed_ = false; bool item_closed_ = false;
bool is_capture_started_ = 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_; SequenceChecker sequence_checker_;
}; };