| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 | |
| 5 #include "remoting/host/capture_scheduler.h" | |
| 6 | |
| 7 #include "base/message_loop/message_loop.h" | |
| 8 #include "base/test/simple_test_tick_clock.h" | |
| 9 #include "base/timer/mock_timer.h" | |
| 10 #include "remoting/proto/video.pb.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 | |
| 13 namespace remoting { | |
| 14 | |
| 15 static const int kTestInputs[] = { 100, 50, 30, 20, 10, 30, 60, 80 }; | |
| 16 static const int kMinumumFrameIntervalMs = 50; | |
| 17 | |
| 18 class CaptureSchedulerTest : public testing::Test { | |
| 19 public: | |
| 20 CaptureSchedulerTest() : capture_called_(false) {} | |
| 21 | |
| 22 void InitScheduler() { | |
| 23 scheduler_.reset(new CaptureScheduler( | |
| 24 base::Bind(&CaptureSchedulerTest::DoCapture, base::Unretained(this)))); | |
| 25 scheduler_->set_minimum_interval( | |
| 26 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); | |
| 27 tick_clock_ = new base::SimpleTestTickClock(); | |
| 28 scheduler_->SetTickClockForTest(make_scoped_ptr(tick_clock_)); | |
| 29 capture_timer_ = new base::MockTimer(false, false); | |
| 30 scheduler_->SetTimerForTest(make_scoped_ptr(capture_timer_)); | |
| 31 scheduler_->Start(); | |
| 32 } | |
| 33 | |
| 34 void DoCapture() { | |
| 35 capture_called_ = true; | |
| 36 } | |
| 37 | |
| 38 void CheckCaptureCalled() { | |
| 39 EXPECT_TRUE(capture_called_); | |
| 40 capture_called_ = false; | |
| 41 } | |
| 42 | |
| 43 void SimulateSingleFrameCapture( | |
| 44 base::TimeDelta capture_delay, | |
| 45 base::TimeDelta encode_delay, | |
| 46 base::TimeDelta expected_delay_between_frames) { | |
| 47 capture_timer_->Fire(); | |
| 48 CheckCaptureCalled(); | |
| 49 tick_clock_->Advance(capture_delay); | |
| 50 scheduler_->OnCaptureCompleted(); | |
| 51 | |
| 52 VideoPacket packet; | |
| 53 packet.set_encode_time_ms(encode_delay.InMilliseconds()); | |
| 54 scheduler_->OnFrameEncoded(&packet); | |
| 55 | |
| 56 scheduler_->OnFrameSent(); | |
| 57 | |
| 58 scoped_ptr<VideoAck> ack(new VideoAck()); | |
| 59 ack->set_frame_id(packet.frame_id()); | |
| 60 scheduler_->ProcessVideoAck(ack.Pass()); | |
| 61 | |
| 62 EXPECT_TRUE(capture_timer_->IsRunning()); | |
| 63 EXPECT_EQ(std::max(base::TimeDelta(), | |
| 64 expected_delay_between_frames - capture_delay), | |
| 65 capture_timer_->GetCurrentDelay()); | |
| 66 } | |
| 67 | |
| 68 protected: | |
| 69 base::MessageLoop message_loop_; | |
| 70 | |
| 71 scoped_ptr<CaptureScheduler> scheduler_; | |
| 72 | |
| 73 // Owned by |scheduler_|. | |
| 74 base::SimpleTestTickClock* tick_clock_; | |
| 75 base::MockTimer* capture_timer_; | |
| 76 | |
| 77 bool capture_called_; | |
| 78 }; | |
| 79 | |
| 80 TEST_F(CaptureSchedulerTest, SingleSampleSameTimes) { | |
| 81 const int kTestResults[][arraysize(kTestInputs)] = { | |
| 82 { 400, 200, 120, 80, 50, 120, 240, 320 }, // One core. | |
| 83 { 200, 100, 60, 50, 50, 60, 120, 160 }, // Two cores. | |
| 84 { 100, 50, 50, 50, 50, 50, 60, 80 }, // Four cores. | |
| 85 { 50, 50, 50, 50, 50, 50, 50, 50 } // Eight cores. | |
| 86 }; | |
| 87 | |
| 88 for (size_t i = 0; i < arraysize(kTestResults); ++i) { | |
| 89 for (size_t j = 0; j < arraysize(kTestInputs); ++j) { | |
| 90 InitScheduler(); | |
| 91 scheduler_->SetNumOfProcessorsForTest(1 << i); | |
| 92 | |
| 93 SimulateSingleFrameCapture( | |
| 94 base::TimeDelta::FromMilliseconds(kTestInputs[j]), | |
| 95 base::TimeDelta::FromMilliseconds(kTestInputs[j]), | |
| 96 base::TimeDelta::FromMilliseconds(kTestResults[i][j])); | |
| 97 } | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 TEST_F(CaptureSchedulerTest, SingleSampleDifferentTimes) { | |
| 102 const int kTestResults[][arraysize(kTestInputs)] = { | |
| 103 { 360, 220, 120, 60, 60, 120, 220, 360 }, // One core. | |
| 104 { 180, 110, 60, 50, 50, 60, 110, 180 }, // Two cores. | |
| 105 { 90, 55, 50, 50, 50, 50, 55, 90 }, // Four cores. | |
| 106 { 50, 50, 50, 50, 50, 50, 50, 50 } // Eight cores. | |
| 107 }; | |
| 108 | |
| 109 for (size_t i = 0; i < arraysize(kTestResults); ++i) { | |
| 110 for (size_t j = 0; j < arraysize(kTestInputs); ++j) { | |
| 111 InitScheduler(); | |
| 112 scheduler_->SetNumOfProcessorsForTest(1 << i); | |
| 113 | |
| 114 SimulateSingleFrameCapture( | |
| 115 base::TimeDelta::FromMilliseconds(kTestInputs[j]), | |
| 116 base::TimeDelta::FromMilliseconds( | |
| 117 kTestInputs[arraysize(kTestInputs) - 1 - j]), | |
| 118 base::TimeDelta::FromMilliseconds(kTestResults[i][j])); | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 TEST_F(CaptureSchedulerTest, RollingAverageDifferentTimes) { | |
| 124 const int kTestResults[][arraysize(kTestInputs)] = { | |
| 125 { 360, 290, 233, 133, 80, 80, 133, 233 }, // One core. | |
| 126 { 180, 145, 116, 66, 50, 50, 66, 116 }, // Two cores. | |
| 127 { 90, 72, 58, 50, 50, 50, 50, 58 }, // Four cores. | |
| 128 { 50, 50, 50, 50, 50, 50, 50, 50 } // Eight cores. | |
| 129 }; | |
| 130 | |
| 131 for (size_t i = 0; i < arraysize(kTestResults); ++i) { | |
| 132 InitScheduler(); | |
| 133 scheduler_->SetNumOfProcessorsForTest(1 << i); | |
| 134 for (size_t j = 0; j < arraysize(kTestInputs); ++j) { | |
| 135 SimulateSingleFrameCapture( | |
| 136 base::TimeDelta::FromMilliseconds(kTestInputs[j]), | |
| 137 base::TimeDelta::FromMilliseconds( | |
| 138 kTestInputs[arraysize(kTestInputs) - 1 - j]), | |
| 139 base::TimeDelta::FromMilliseconds(kTestResults[i][j])); | |
| 140 } | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 // Verify that we never have more than 2 encoding frames. | |
| 145 TEST_F(CaptureSchedulerTest, MaximumEncodingFrames) { | |
| 146 InitScheduler(); | |
| 147 | |
| 148 // Process the first frame to let the scheduler know that receiver supports | |
| 149 // ACKs. | |
| 150 SimulateSingleFrameCapture( | |
| 151 base::TimeDelta(), base::TimeDelta(), | |
| 152 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); | |
| 153 | |
| 154 capture_timer_->Fire(); | |
| 155 CheckCaptureCalled(); | |
| 156 scheduler_->OnCaptureCompleted(); | |
| 157 | |
| 158 capture_timer_->Fire(); | |
| 159 CheckCaptureCalled(); | |
| 160 scheduler_->OnCaptureCompleted(); | |
| 161 | |
| 162 EXPECT_FALSE(capture_timer_->IsRunning()); | |
| 163 VideoPacket packet; | |
| 164 scheduler_->OnFrameEncoded(&packet); | |
| 165 EXPECT_TRUE(capture_timer_->IsRunning()); | |
| 166 } | |
| 167 | |
| 168 // Verify that the scheduler doesn't exceed maximum number of pending frames. | |
| 169 TEST_F(CaptureSchedulerTest, MaximumPendingFrames) { | |
| 170 InitScheduler(); | |
| 171 | |
| 172 // Process the first frame to let the scheduler know that receiver supports | |
| 173 // ACKs. | |
| 174 SimulateSingleFrameCapture( | |
| 175 base::TimeDelta(), base::TimeDelta(), | |
| 176 base::TimeDelta::FromMilliseconds(kMinumumFrameIntervalMs)); | |
| 177 | |
| 178 // Queue some frames until the sender is blocked. | |
| 179 while (capture_timer_->IsRunning()) { | |
| 180 capture_timer_->Fire(); | |
| 181 CheckCaptureCalled(); | |
| 182 scheduler_->OnCaptureCompleted(); | |
| 183 VideoPacket packet; | |
| 184 scheduler_->OnFrameEncoded(&packet); | |
| 185 scheduler_->OnFrameSent(); | |
| 186 } | |
| 187 | |
| 188 // Next frame should be scheduled, once one of the queued frames is | |
| 189 // acknowledged. | |
| 190 EXPECT_FALSE(capture_timer_->IsRunning()); | |
| 191 scheduler_->ProcessVideoAck(make_scoped_ptr(new VideoAck())); | |
| 192 EXPECT_TRUE(capture_timer_->IsRunning()); | |
| 193 } | |
| 194 | |
| 195 } // namespace remoting | |
| OLD | NEW |