capture_scheduler_unittest.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/capture_scheduler.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/memory/ptr_util.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/test/simple_test_tick_clock.h"
  12. #include "base/test/task_environment.h"
  13. #include "base/timer/mock_timer.h"
  14. #include "remoting/proto/video.pb.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. namespace remoting {
  17. namespace protocol {
  18. static const int kTestInputs[] = { 100, 50, 30, 20, 10, 30, 60, 80 };
  19. static const int kMinumumFrameIntervalMs = 50;
  20. class CaptureSchedulerTest : public testing::Test {
  21. public:
  22. CaptureSchedulerTest() : capture_called_(false) {}
  23. void InitScheduler() {
  24. scheduler_ = std::make_unique<CaptureScheduler>(base::BindRepeating(
  25. &CaptureSchedulerTest::DoCapture, base::Unretained(this)));
  26. scheduler_->set_minimum_interval(
  27. base::Milliseconds(kMinumumFrameIntervalMs));
  28. scheduler_->SetTickClockForTest(&tick_clock_);
  29. capture_timer_ = new base::MockOneShotTimer();
  30. scheduler_->SetTimerForTest(base::WrapUnique(capture_timer_.get()));
  31. scheduler_->Start();
  32. }
  33. void DoCapture() {
  34. capture_called_ = true;
  35. }
  36. void CheckCaptureCalled() {
  37. EXPECT_TRUE(capture_called_);
  38. capture_called_ = false;
  39. }
  40. void SimulateSingleFrameCapture(
  41. base::TimeDelta capture_delay,
  42. base::TimeDelta encode_delay,
  43. base::TimeDelta expected_delay_between_frames) {
  44. capture_timer_->Fire();
  45. CheckCaptureCalled();
  46. tick_clock_.Advance(capture_delay);
  47. scheduler_->OnCaptureCompleted();
  48. VideoPacket packet;
  49. packet.set_encode_time_ms(encode_delay.InMilliseconds());
  50. scheduler_->OnFrameEncoded(&packet);
  51. scheduler_->OnFrameSent();
  52. std::unique_ptr<VideoAck> ack(new VideoAck());
  53. ack->set_frame_id(packet.frame_id());
  54. scheduler_->ProcessVideoAck(std::move(ack));
  55. EXPECT_TRUE(capture_timer_->IsRunning());
  56. EXPECT_EQ(std::max(base::TimeDelta(),
  57. expected_delay_between_frames - capture_delay),
  58. capture_timer_->GetCurrentDelay());
  59. }
  60. protected:
  61. base::test::SingleThreadTaskEnvironment task_environment_;
  62. std::unique_ptr<CaptureScheduler> scheduler_;
  63. base::SimpleTestTickClock tick_clock_;
  64. // Owned by |scheduler_|.
  65. raw_ptr<base::MockOneShotTimer> capture_timer_;
  66. bool capture_called_;
  67. };
  68. TEST_F(CaptureSchedulerTest, SingleSampleSameTimes) {
  69. const int kTestResults[][std::size(kTestInputs)] = {
  70. {400, 200, 120, 80, 50, 120, 240, 320}, // One core.
  71. {200, 100, 60, 50, 50, 60, 120, 160}, // Two cores.
  72. {100, 50, 50, 50, 50, 50, 60, 80}, // Four cores.
  73. {50, 50, 50, 50, 50, 50, 50, 50} // Eight cores.
  74. };
  75. for (size_t i = 0; i < std::size(kTestResults); ++i) {
  76. for (size_t j = 0; j < std::size(kTestInputs); ++j) {
  77. InitScheduler();
  78. scheduler_->SetNumOfProcessorsForTest(1 << i);
  79. SimulateSingleFrameCapture(base::Milliseconds(kTestInputs[j]),
  80. base::Milliseconds(kTestInputs[j]),
  81. base::Milliseconds(kTestResults[i][j]));
  82. }
  83. }
  84. }
  85. TEST_F(CaptureSchedulerTest, SingleSampleDifferentTimes) {
  86. const int kTestResults[][std::size(kTestInputs)] = {
  87. {360, 220, 120, 60, 60, 120, 220, 360}, // One core.
  88. {180, 110, 60, 50, 50, 60, 110, 180}, // Two cores.
  89. {90, 55, 50, 50, 50, 50, 55, 90}, // Four cores.
  90. {50, 50, 50, 50, 50, 50, 50, 50} // Eight cores.
  91. };
  92. for (size_t i = 0; i < std::size(kTestResults); ++i) {
  93. for (size_t j = 0; j < std::size(kTestInputs); ++j) {
  94. InitScheduler();
  95. scheduler_->SetNumOfProcessorsForTest(1 << i);
  96. SimulateSingleFrameCapture(
  97. base::Milliseconds(kTestInputs[j]),
  98. base::Milliseconds(kTestInputs[std::size(kTestInputs) - 1 - j]),
  99. base::Milliseconds(kTestResults[i][j]));
  100. }
  101. }
  102. }
  103. TEST_F(CaptureSchedulerTest, RollingAverageDifferentTimes) {
  104. const double kTestResults[][std::size(kTestInputs)] = {
  105. {360, 290, 233.333, 133.333, 80, 80, 133.333, 233.333}, // One core.
  106. {180, 145, 116.666, 66.666, 50, 50, 66.666, 116.666}, // Two cores.
  107. {90, 72.5, 58.333, 50, 50, 50, 50, 58.333}, // Four cores.
  108. {50, 50, 50, 50, 50, 50, 50, 50} // Eight cores.
  109. };
  110. for (size_t i = 0; i < std::size(kTestResults); ++i) {
  111. InitScheduler();
  112. scheduler_->SetNumOfProcessorsForTest(1 << i);
  113. for (size_t j = 0; j < std::size(kTestInputs); ++j) {
  114. SimulateSingleFrameCapture(
  115. base::Milliseconds(kTestInputs[j]),
  116. base::Milliseconds(kTestInputs[std::size(kTestInputs) - 1 - j]),
  117. base::Milliseconds(kTestResults[i][j]));
  118. }
  119. }
  120. }
  121. // Verify that we never have more than 2 encoding frames.
  122. TEST_F(CaptureSchedulerTest, MaximumEncodingFrames) {
  123. InitScheduler();
  124. // Process the first frame to let the scheduler know that receiver supports
  125. // ACKs.
  126. SimulateSingleFrameCapture(base::TimeDelta(), base::TimeDelta(),
  127. base::Milliseconds(kMinumumFrameIntervalMs));
  128. capture_timer_->Fire();
  129. CheckCaptureCalled();
  130. scheduler_->OnCaptureCompleted();
  131. capture_timer_->Fire();
  132. CheckCaptureCalled();
  133. scheduler_->OnCaptureCompleted();
  134. EXPECT_FALSE(capture_timer_->IsRunning());
  135. VideoPacket packet;
  136. scheduler_->OnFrameEncoded(&packet);
  137. EXPECT_TRUE(capture_timer_->IsRunning());
  138. }
  139. // Verify that the scheduler doesn't exceed maximum number of pending frames.
  140. TEST_F(CaptureSchedulerTest, MaximumPendingFrames) {
  141. InitScheduler();
  142. // Process the first frame to let the scheduler know that receiver supports
  143. // ACKs.
  144. SimulateSingleFrameCapture(base::TimeDelta(), base::TimeDelta(),
  145. base::Milliseconds(kMinumumFrameIntervalMs));
  146. // Queue some frames until the sender is blocked.
  147. while (capture_timer_->IsRunning()) {
  148. capture_timer_->Fire();
  149. CheckCaptureCalled();
  150. scheduler_->OnCaptureCompleted();
  151. VideoPacket packet;
  152. scheduler_->OnFrameEncoded(&packet);
  153. scheduler_->OnFrameSent();
  154. }
  155. // Next frame should be scheduled, once one of the queued frames is
  156. // acknowledged.
  157. EXPECT_FALSE(capture_timer_->IsRunning());
  158. scheduler_->ProcessVideoAck(base::WrapUnique(new VideoAck()));
  159. EXPECT_TRUE(capture_timer_->IsRunning());
  160. }
  161. } // namespace protocol
  162. } // namespace remoting