0
Files
src/remoting/protocol/webrtc_frame_scheduler_unittest.cc
Joe Downing 3ed9c16351 Adjust the capture interval to account for post task delays
I've noticed that even on high powered machines with the target
framerate set to 30, the max encode FPS sits at ~28.  Looking at the
capture and encode times, the host should have been able encode at 30
FPS but that wasn't occurring. The same happens for our other standard
framerates (the actual encode rate was always 1-2 FPS below the target).

It looks like the issue is that we are scheduling captures at the target
framerate w/o accounting for common post task delays so the result is
that the capture rate is a bit slower than the interval we expect.

This CL adjusts the capture interval by a couple of MS which allows the
host hit the target rate.

Bug: b:217468304
Change-Id: Ib86e2de22e3c324900de845f16235415e1ba83a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4184285
Reviewed-by: Lambros Lambrou <lambroslambrou@chromium.org>
Commit-Queue: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1095938}
2023-01-24 00:55:55 +00:00

116 lines
3.4 KiB
C++

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "remoting/protocol/webrtc_frame_scheduler.h"
#include "base/functional/bind.h"
#include "base/test/task_environment.h"
#include "remoting/base/session_options.h"
#include "remoting/protocol/frame_stats.h"
#include "remoting/protocol/webrtc_frame_scheduler_constant_rate.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
using webrtc::BasicDesktopFrame;
using webrtc::DesktopRect;
using webrtc::DesktopSize;
namespace remoting::protocol {
class WebrtcFrameSchedulerTest : public ::testing::Test {
public:
WebrtcFrameSchedulerTest() = default;
~WebrtcFrameSchedulerTest() override = default;
void InitConstantRateScheduler() {
scheduler_ = std::make_unique<WebrtcFrameSchedulerConstantRate>();
scheduler_->SetPostTaskAdjustmentForTest(base::Milliseconds(0));
scheduler_->Start(base::BindRepeating(
&WebrtcFrameSchedulerTest::CaptureCallback, base::Unretained(this)));
}
void CaptureCallback() {
capture_callback_count_++;
if (simulate_capture_) {
scheduler_->OnFrameCaptured(&frame_);
}
}
protected:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
std::unique_ptr<WebrtcFrameSchedulerConstantRate> scheduler_;
int capture_callback_count_ = 0;
bool simulate_capture_ = true;
BasicDesktopFrame frame_{DesktopSize(1, 1)};
};
TEST_F(WebrtcFrameSchedulerTest, NoCapturesIfZeroFps) {
InitConstantRateScheduler();
scheduler_->SetMaxFramerateFps(0);
task_environment_.FastForwardBy(base::Seconds(1));
EXPECT_EQ(0, capture_callback_count_);
}
TEST_F(WebrtcFrameSchedulerTest, CapturesAtRequestedFramerate) {
InitConstantRateScheduler();
scheduler_->SetMaxFramerateFps(60);
task_environment_.FastForwardBy(base::Seconds(1));
// There should be approximately 60 captures in 1 second, making an allowance
// for any off-by-one artifacts in timing.
EXPECT_LE(59, capture_callback_count_);
EXPECT_LE(capture_callback_count_, 61);
}
TEST_F(WebrtcFrameSchedulerTest, PostTaskAdjustmentApplied) {
InitConstantRateScheduler();
scheduler_->SetPostTaskAdjustmentForTest(base::Milliseconds(3));
scheduler_->SetMaxFramerateFps(30);
task_environment_.FastForwardBy(base::Seconds(1));
// There should be approximately ~33 captures in 1 second, making an allowance
// for any off-by-one artifacts in timing.
EXPECT_GE(capture_callback_count_, 32);
EXPECT_LE(capture_callback_count_, 34);
}
TEST_F(WebrtcFrameSchedulerTest, NoCaptureWhileCapturePending) {
InitConstantRateScheduler();
simulate_capture_ = false;
scheduler_->SetMaxFramerateFps(60);
task_environment_.FastForwardBy(base::Seconds(1));
// Only 1 capture callback, because the fake "capturer" never returns a
// captured frame. The scheduler should only do 1 capture at a time.
EXPECT_EQ(1, capture_callback_count_);
}
TEST_F(WebrtcFrameSchedulerTest, NoCaptureWhilePaused) {
InitConstantRateScheduler();
scheduler_->SetMaxFramerateFps(60);
scheduler_->Pause(true);
task_environment_.FastForwardBy(base::Seconds(1));
EXPECT_EQ(0, capture_callback_count_);
scheduler_->Pause(false);
task_environment_.FastForwardBy(base::Seconds(1));
EXPECT_LE(1, capture_callback_count_);
}
} // namespace remoting::protocol