OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
12 | 12 |
13 #include "webrtc/api/video/i420_buffer.h" | 13 #include "webrtc/api/video/i420_buffer.h" |
14 #include "webrtc/base/event.h" | 14 #include "webrtc/base/event.h" |
15 #include "webrtc/system_wrappers/include/clock.h" | 15 #include "webrtc/base/fakeclock.h" |
16 #include "webrtc/test/gmock.h" | 16 #include "webrtc/test/gmock.h" |
17 #include "webrtc/test/gtest.h" | 17 #include "webrtc/test/gtest.h" |
18 #include "webrtc/video/overuse_frame_detector.h" | 18 #include "webrtc/video/overuse_frame_detector.h" |
19 #include "webrtc/video_frame.h" | 19 #include "webrtc/video_frame.h" |
20 #include "webrtc/modules/video_coding/utility/quality_scaler.h" | 20 #include "webrtc/modules/video_coding/utility/quality_scaler.h" |
21 | 21 |
22 namespace webrtc { | 22 namespace webrtc { |
23 | 23 |
24 using ::testing::InvokeWithoutArgs; | 24 using ::testing::InvokeWithoutArgs; |
25 | 25 |
26 namespace { | 26 namespace { |
27 const int kWidth = 640; | 27 const int kWidth = 640; |
28 const int kHeight = 480; | 28 const int kHeight = 480; |
29 const int kFrameInterval33ms = 33; | 29 const int kFrameIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec; |
30 const int kProcessIntervalMs = 5000; | 30 const int kProcessTimeUs = 5 * rtc::kNumMicrosecsPerMillisec; |
31 const int kProcessTime5ms = 5; | |
32 } // namespace | 31 } // namespace |
33 | 32 |
34 class MockCpuOveruseObserver : public ScalingObserverInterface { | 33 class MockCpuOveruseObserver : public ScalingObserverInterface { |
35 public: | 34 public: |
36 MockCpuOveruseObserver() {} | 35 MockCpuOveruseObserver() {} |
37 virtual ~MockCpuOveruseObserver() {} | 36 virtual ~MockCpuOveruseObserver() {} |
38 | 37 |
39 MOCK_METHOD1(ScaleUp, void(ScaleReason)); | 38 MOCK_METHOD1(ScaleUp, void(ScaleReason)); |
40 MOCK_METHOD1(ScaleDown, void(ScaleReason)); | 39 MOCK_METHOD1(ScaleDown, void(ScaleReason)); |
41 }; | 40 }; |
42 | 41 |
43 class CpuOveruseObserverImpl : public ScalingObserverInterface { | 42 class CpuOveruseObserverImpl : public ScalingObserverInterface { |
44 public: | 43 public: |
45 CpuOveruseObserverImpl() : | 44 CpuOveruseObserverImpl() : |
46 overuse_(0), | 45 overuse_(0), |
47 normaluse_(0) {} | 46 normaluse_(0) {} |
48 virtual ~CpuOveruseObserverImpl() {} | 47 virtual ~CpuOveruseObserverImpl() {} |
49 | 48 |
50 void ScaleDown(ScaleReason) { ++overuse_; } | 49 void ScaleDown(ScaleReason) { ++overuse_; } |
51 void ScaleUp(ScaleReason) { ++normaluse_; } | 50 void ScaleUp(ScaleReason) { ++normaluse_; } |
52 | 51 |
53 int overuse_; | 52 int overuse_; |
54 int normaluse_; | 53 int normaluse_; |
55 }; | 54 }; |
56 | 55 |
57 class OveruseFrameDetectorUnderTest : public OveruseFrameDetector { | 56 class OveruseFrameDetectorUnderTest : public OveruseFrameDetector { |
58 public: | 57 public: |
59 OveruseFrameDetectorUnderTest(Clock* clock, | 58 OveruseFrameDetectorUnderTest(const CpuOveruseOptions& options, |
60 const CpuOveruseOptions& options, | |
61 ScalingObserverInterface* overuse_observer, | 59 ScalingObserverInterface* overuse_observer, |
62 EncodedFrameObserver* encoder_timing, | 60 EncodedFrameObserver* encoder_timing, |
63 CpuOveruseMetricsObserver* metrics_observer) | 61 CpuOveruseMetricsObserver* metrics_observer) |
64 : OveruseFrameDetector(clock, | 62 : OveruseFrameDetector(options, |
65 options, | |
66 overuse_observer, | 63 overuse_observer, |
67 encoder_timing, | 64 encoder_timing, |
68 metrics_observer) {} | 65 metrics_observer) {} |
69 ~OveruseFrameDetectorUnderTest() {} | 66 ~OveruseFrameDetectorUnderTest() {} |
70 | 67 |
71 using OveruseFrameDetector::CheckForOveruse; | 68 using OveruseFrameDetector::CheckForOveruse; |
72 }; | 69 }; |
73 | 70 |
74 class OveruseFrameDetectorTest : public ::testing::Test, | 71 class OveruseFrameDetectorTest : public ::testing::Test, |
75 public CpuOveruseMetricsObserver { | 72 public CpuOveruseMetricsObserver { |
76 protected: | 73 protected: |
77 void SetUp() override { | 74 void SetUp() override { |
78 clock_.reset(new SimulatedClock(1234)); | |
79 observer_.reset(new MockCpuOveruseObserver()); | 75 observer_.reset(new MockCpuOveruseObserver()); |
80 options_.min_process_count = 0; | 76 options_.min_process_count = 0; |
81 ReinitializeOveruseDetector(); | 77 ReinitializeOveruseDetector(); |
82 } | 78 } |
83 | 79 |
84 void ReinitializeOveruseDetector() { | 80 void ReinitializeOveruseDetector() { |
85 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( | 81 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( |
86 clock_.get(), options_, observer_.get(), nullptr, this)); | 82 options_, observer_.get(), nullptr, this)); |
87 } | 83 } |
88 | 84 |
89 void OnEncodedFrameTimeMeasured(int encode_time_ms, | 85 void OnEncodedFrameTimeMeasured(int encode_time_ms, |
90 const CpuOveruseMetrics& metrics) override { | 86 const CpuOveruseMetrics& metrics) override { |
91 metrics_ = metrics; | 87 metrics_ = metrics; |
92 } | 88 } |
93 | 89 |
94 int InitialUsage() { | 90 int InitialUsage() { |
95 return ((options_.low_encode_usage_threshold_percent + | 91 return ((options_.low_encode_usage_threshold_percent + |
96 options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5; | 92 options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5; |
97 } | 93 } |
98 | 94 |
99 void InsertAndSendFramesWithInterval(int num_frames, | 95 void InsertAndSendFramesWithInterval(int num_frames, |
100 int interval_ms, | 96 int interval_us, |
101 int width, | 97 int width, |
102 int height, | 98 int height, |
103 int delay_ms) { | 99 int delay_us) { |
104 VideoFrame frame(I420Buffer::Create(width, height), | 100 VideoFrame frame(I420Buffer::Create(width, height), |
105 webrtc::kVideoRotation_0, 0); | 101 webrtc::kVideoRotation_0, 0); |
106 uint32_t timestamp = 0; | 102 uint32_t timestamp = 0; |
107 while (num_frames-- > 0) { | 103 while (num_frames-- > 0) { |
108 frame.set_timestamp(timestamp); | 104 frame.set_timestamp(timestamp); |
109 overuse_detector_->FrameCaptured(frame, clock_->TimeInMilliseconds()); | 105 overuse_detector_->FrameCaptured(frame, rtc::TimeMicros()); |
110 clock_->AdvanceTimeMilliseconds(delay_ms); | 106 clock_.AdvanceTimeMicros(delay_us); |
111 overuse_detector_->FrameSent(timestamp, clock_->TimeInMilliseconds()); | 107 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros()); |
112 clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms); | 108 clock_.AdvanceTimeMicros(interval_us - delay_us); |
113 timestamp += interval_ms * 90; | 109 timestamp += interval_us * 90 / 1000; |
114 } | 110 } |
115 } | 111 } |
116 | 112 |
117 void ForceUpdate(int width, int height) { | 113 void ForceUpdate(int width, int height) { |
118 // Insert one frame, wait a second and then put in another to force update | 114 // Insert one frame, wait a second and then put in another to force update |
119 // the usage. From the tests where these are used, adding another sample | 115 // the usage. From the tests where these are used, adding another sample |
120 // doesn't affect the expected outcome (this is mainly to check initial | 116 // doesn't affect the expected outcome (this is mainly to check initial |
121 // values and whether the overuse detector has been reset or not). | 117 // values and whether the overuse detector has been reset or not). |
122 InsertAndSendFramesWithInterval(2, 1000, width, height, kFrameInterval33ms); | 118 InsertAndSendFramesWithInterval(2, rtc::kNumMicrosecsPerSec, |
| 119 width, height, kFrameIntervalUs); |
123 } | 120 } |
124 void TriggerOveruse(int num_times) { | 121 void TriggerOveruse(int num_times) { |
125 const int kDelayMs = 32; | 122 const int kDelayUs = 32 * rtc::kNumMicrosecsPerMillisec; |
126 for (int i = 0; i < num_times; ++i) { | 123 for (int i = 0; i < num_times; ++i) { |
127 InsertAndSendFramesWithInterval( | 124 InsertAndSendFramesWithInterval( |
128 1000, kFrameInterval33ms, kWidth, kHeight, kDelayMs); | 125 1000, kFrameIntervalUs, kWidth, kHeight, kDelayUs); |
129 overuse_detector_->CheckForOveruse(); | 126 overuse_detector_->CheckForOveruse(); |
130 } | 127 } |
131 } | 128 } |
132 | 129 |
133 void TriggerUnderuse() { | 130 void TriggerUnderuse() { |
134 const int kDelayMs1 = 5; | 131 const int kDelayUs1 = 5000; |
135 const int kDelayMs2 = 6; | 132 const int kDelayUs2 = 6000; |
136 InsertAndSendFramesWithInterval( | 133 InsertAndSendFramesWithInterval( |
137 1300, kFrameInterval33ms, kWidth, kHeight, kDelayMs1); | 134 1300, kFrameIntervalUs, kWidth, kHeight, kDelayUs1); |
138 InsertAndSendFramesWithInterval( | 135 InsertAndSendFramesWithInterval( |
139 1, kFrameInterval33ms, kWidth, kHeight, kDelayMs2); | 136 1, kFrameIntervalUs, kWidth, kHeight, kDelayUs2); |
140 overuse_detector_->CheckForOveruse(); | 137 overuse_detector_->CheckForOveruse(); |
141 } | 138 } |
142 | 139 |
143 int UsagePercent() { return metrics_.encode_usage_percent; } | 140 int UsagePercent() { return metrics_.encode_usage_percent; } |
144 | 141 |
145 CpuOveruseOptions options_; | 142 CpuOveruseOptions options_; |
146 std::unique_ptr<SimulatedClock> clock_; | 143 rtc::ScopedFakeClock clock_; |
147 std::unique_ptr<MockCpuOveruseObserver> observer_; | 144 std::unique_ptr<MockCpuOveruseObserver> observer_; |
148 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_; | 145 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_; |
149 CpuOveruseMetrics metrics_; | 146 CpuOveruseMetrics metrics_; |
150 | 147 |
151 static const auto reason_ = ScalingObserverInterface::ScaleReason::kCpu; | 148 static const auto reason_ = ScalingObserverInterface::ScaleReason::kCpu; |
152 }; | 149 }; |
153 | 150 |
154 | 151 |
155 // UsagePercent() > high_encode_usage_threshold_percent => overuse. | 152 // UsagePercent() > high_encode_usage_threshold_percent => overuse. |
156 // UsagePercent() < low_encode_usage_threshold_percent => underuse. | 153 // UsagePercent() < low_encode_usage_threshold_percent => underuse. |
157 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) { | 154 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) { |
158 // usage > high => overuse | 155 // usage > high => overuse |
159 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(1); | 156 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(1); |
160 TriggerOveruse(options_.high_threshold_consecutive_count); | 157 TriggerOveruse(options_.high_threshold_consecutive_count); |
161 } | 158 } |
162 | 159 |
163 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { | 160 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { |
164 // usage > high => overuse | 161 // usage > high => overuse |
165 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(1); | 162 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(1); |
166 TriggerOveruse(options_.high_threshold_consecutive_count); | 163 TriggerOveruse(options_.high_threshold_consecutive_count); |
167 // usage < low => underuse | 164 // usage < low => underuse |
168 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(testing::AtLeast(1)); | 165 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(testing::AtLeast(1)); |
169 TriggerUnderuse(); | 166 TriggerUnderuse(); |
170 } | 167 } |
171 | 168 |
172 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { | 169 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { |
173 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( | 170 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( |
174 clock_.get(), options_, nullptr, nullptr, this)); | 171 options_, nullptr, nullptr, this)); |
175 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(0); | 172 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(0); |
176 TriggerOveruse(options_.high_threshold_consecutive_count); | 173 TriggerOveruse(options_.high_threshold_consecutive_count); |
177 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(0); | 174 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(0); |
178 TriggerUnderuse(); | 175 TriggerUnderuse(); |
179 } | 176 } |
180 | 177 |
181 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { | 178 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { |
182 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(2); | 179 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(2); |
183 TriggerOveruse(options_.high_threshold_consecutive_count); | 180 TriggerOveruse(options_.high_threshold_consecutive_count); |
184 TriggerOveruse(options_.high_threshold_consecutive_count); | 181 TriggerOveruse(options_.high_threshold_consecutive_count); |
185 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(testing::AtLeast(1)); | 182 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(testing::AtLeast(1)); |
186 TriggerUnderuse(); | 183 TriggerUnderuse(); |
187 } | 184 } |
188 | 185 |
189 TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { | 186 TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { |
| 187 const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec; |
190 options_.min_process_count = 1; | 188 options_.min_process_count = 1; |
191 CpuOveruseObserverImpl overuse_observer; | 189 CpuOveruseObserverImpl overuse_observer; |
192 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( | 190 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( |
193 clock_.get(), options_, &overuse_observer, nullptr, this)); | 191 options_, &overuse_observer, nullptr, this)); |
194 InsertAndSendFramesWithInterval( | 192 InsertAndSendFramesWithInterval( |
195 1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 193 1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs); |
196 overuse_detector_->CheckForOveruse(); | 194 overuse_detector_->CheckForOveruse(); |
197 EXPECT_EQ(0, overuse_observer.normaluse_); | 195 EXPECT_EQ(0, overuse_observer.normaluse_); |
198 clock_->AdvanceTimeMilliseconds(kProcessIntervalMs); | 196 clock_.AdvanceTimeMicros(kProcessIntervalUs); |
199 overuse_detector_->CheckForOveruse(); | 197 overuse_detector_->CheckForOveruse(); |
200 EXPECT_EQ(1, overuse_observer.normaluse_); | 198 EXPECT_EQ(1, overuse_observer.normaluse_); |
201 } | 199 } |
202 | 200 |
203 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { | 201 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { |
204 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(0); | 202 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)).Times(0); |
205 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(64); | 203 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(64); |
206 for (size_t i = 0; i < 64; ++i) { | 204 for (size_t i = 0; i < 64; ++i) { |
207 TriggerOveruse(options_.high_threshold_consecutive_count); | 205 TriggerOveruse(options_.high_threshold_consecutive_count); |
208 } | 206 } |
209 } | 207 } |
210 | 208 |
211 TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) { | 209 TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) { |
212 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(1); | 210 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(1); |
213 options_.high_threshold_consecutive_count = 2; | 211 options_.high_threshold_consecutive_count = 2; |
214 ReinitializeOveruseDetector(); | 212 ReinitializeOveruseDetector(); |
215 TriggerOveruse(2); | 213 TriggerOveruse(2); |
216 } | 214 } |
217 | 215 |
218 TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) { | 216 TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) { |
219 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(0); | 217 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)).Times(0); |
220 options_.high_threshold_consecutive_count = 2; | 218 options_.high_threshold_consecutive_count = 2; |
221 ReinitializeOveruseDetector(); | 219 ReinitializeOveruseDetector(); |
222 TriggerOveruse(1); | 220 TriggerOveruse(1); |
223 } | 221 } |
224 | 222 |
225 TEST_F(OveruseFrameDetectorTest, ProcessingUsage) { | 223 TEST_F(OveruseFrameDetectorTest, ProcessingUsage) { |
226 InsertAndSendFramesWithInterval( | 224 InsertAndSendFramesWithInterval( |
227 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 225 1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs); |
228 EXPECT_EQ(kProcessTime5ms * 100 / kFrameInterval33ms, UsagePercent()); | 226 EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent()); |
229 } | 227 } |
230 | 228 |
231 TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) { | 229 TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) { |
232 ForceUpdate(kWidth, kHeight); | 230 ForceUpdate(kWidth, kHeight); |
233 EXPECT_EQ(InitialUsage(), UsagePercent()); | 231 EXPECT_EQ(InitialUsage(), UsagePercent()); |
234 InsertAndSendFramesWithInterval( | 232 InsertAndSendFramesWithInterval( |
235 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 233 1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs); |
236 EXPECT_NE(InitialUsage(), UsagePercent()); | 234 EXPECT_NE(InitialUsage(), UsagePercent()); |
237 // Verify reset (with new width/height). | 235 // Verify reset (with new width/height). |
238 ForceUpdate(kWidth, kHeight + 1); | 236 ForceUpdate(kWidth, kHeight + 1); |
239 EXPECT_EQ(InitialUsage(), UsagePercent()); | 237 EXPECT_EQ(InitialUsage(), UsagePercent()); |
240 } | 238 } |
241 | 239 |
242 TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) { | 240 TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) { |
243 ForceUpdate(kWidth, kHeight); | 241 ForceUpdate(kWidth, kHeight); |
244 EXPECT_EQ(InitialUsage(), UsagePercent()); | 242 EXPECT_EQ(InitialUsage(), UsagePercent()); |
245 InsertAndSendFramesWithInterval( | 243 InsertAndSendFramesWithInterval( |
246 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 244 1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs); |
247 EXPECT_NE(InitialUsage(), UsagePercent()); | 245 EXPECT_NE(InitialUsage(), UsagePercent()); |
248 InsertAndSendFramesWithInterval( | 246 InsertAndSendFramesWithInterval( |
249 2, options_.frame_timeout_interval_ms, kWidth, kHeight, kProcessTime5ms); | 247 2, options_.frame_timeout_interval_ms * |
| 248 rtc::kNumMicrosecsPerMillisec, kWidth, kHeight, kProcessTimeUs); |
250 EXPECT_NE(InitialUsage(), UsagePercent()); | 249 EXPECT_NE(InitialUsage(), UsagePercent()); |
251 // Verify reset. | 250 // Verify reset. |
252 InsertAndSendFramesWithInterval( | 251 InsertAndSendFramesWithInterval( |
253 2, options_.frame_timeout_interval_ms + 1, kWidth, kHeight, | 252 2, (options_.frame_timeout_interval_ms + 1) * |
254 kProcessTime5ms); | 253 rtc::kNumMicrosecsPerMillisec, kWidth, kHeight, kProcessTimeUs); |
255 ForceUpdate(kWidth, kHeight); | 254 ForceUpdate(kWidth, kHeight); |
256 EXPECT_EQ(InitialUsage(), UsagePercent()); | 255 EXPECT_EQ(InitialUsage(), UsagePercent()); |
257 } | 256 } |
258 | 257 |
259 TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) { | 258 TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) { |
260 options_.min_frame_samples = 40; | 259 options_.min_frame_samples = 40; |
261 ReinitializeOveruseDetector(); | 260 ReinitializeOveruseDetector(); |
262 InsertAndSendFramesWithInterval( | 261 InsertAndSendFramesWithInterval( |
263 40, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 262 40, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs); |
264 EXPECT_EQ(InitialUsage(), UsagePercent()); | 263 EXPECT_EQ(InitialUsage(), UsagePercent()); |
265 // Pass time far enough to digest all previous samples. | 264 // Pass time far enough to digest all previous samples. |
266 clock_->AdvanceTimeMilliseconds(1000); | 265 clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerSec); |
267 InsertAndSendFramesWithInterval(1, kFrameInterval33ms, kWidth, kHeight, | 266 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight, |
268 kProcessTime5ms); | 267 kProcessTimeUs); |
269 // The last sample has not been processed here. | 268 // The last sample has not been processed here. |
270 EXPECT_EQ(InitialUsage(), UsagePercent()); | 269 EXPECT_EQ(InitialUsage(), UsagePercent()); |
271 | 270 |
272 // Pass time far enough to digest all previous samples, 41 in total. | 271 // Pass time far enough to digest all previous samples, 41 in total. |
273 clock_->AdvanceTimeMilliseconds(1000); | 272 clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerSec); |
274 InsertAndSendFramesWithInterval( | 273 InsertAndSendFramesWithInterval( |
275 1, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 274 1, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs); |
276 EXPECT_NE(InitialUsage(), UsagePercent()); | 275 EXPECT_NE(InitialUsage(), UsagePercent()); |
277 } | 276 } |
278 | 277 |
279 TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) { | 278 TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) { |
280 ForceUpdate(kWidth, kHeight); | 279 ForceUpdate(kWidth, kHeight); |
281 EXPECT_EQ(InitialUsage(), UsagePercent()); | 280 EXPECT_EQ(InitialUsage(), UsagePercent()); |
282 } | 281 } |
283 | 282 |
284 TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) { | 283 TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) { |
285 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)) | 284 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)) |
286 .Times(testing::AtLeast(1)); | 285 .Times(testing::AtLeast(1)); |
287 static const int kIntervalMs = 33; | 286 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec; |
288 static const size_t kNumFramesEncodingDelay = 3; | 287 static const size_t kNumFramesEncodingDelay = 3; |
289 VideoFrame frame(I420Buffer::Create(kWidth, kHeight), | 288 VideoFrame frame(I420Buffer::Create(kWidth, kHeight), |
290 webrtc::kVideoRotation_0, 0); | 289 webrtc::kVideoRotation_0, 0); |
291 for (size_t i = 0; i < 1000; ++i) { | 290 for (size_t i = 0; i < 1000; ++i) { |
292 // Unique timestamps. | 291 // Unique timestamps. |
293 frame.set_timestamp(static_cast<uint32_t>(i)); | 292 frame.set_timestamp(static_cast<uint32_t>(i)); |
294 overuse_detector_->FrameCaptured(frame, clock_->TimeInMilliseconds()); | 293 overuse_detector_->FrameCaptured(frame, rtc::TimeMicros()); |
295 clock_->AdvanceTimeMilliseconds(kIntervalMs); | 294 clock_.AdvanceTimeMicros(kIntervalUs); |
296 if (i > kNumFramesEncodingDelay) { | 295 if (i > kNumFramesEncodingDelay) { |
297 overuse_detector_->FrameSent( | 296 overuse_detector_->FrameSent( |
298 static_cast<uint32_t>(i - kNumFramesEncodingDelay), | 297 static_cast<uint32_t>(i - kNumFramesEncodingDelay), |
299 clock_->TimeInMilliseconds()); | 298 rtc::TimeMicros()); |
300 } | 299 } |
301 overuse_detector_->CheckForOveruse(); | 300 overuse_detector_->CheckForOveruse(); |
302 } | 301 } |
303 } | 302 } |
304 | 303 |
305 TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) { | 304 TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) { |
306 // >85% encoding time should trigger overuse. | 305 // >85% encoding time should trigger overuse. |
307 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)) | 306 EXPECT_CALL(*(observer_.get()), ScaleDown(reason_)) |
308 .Times(testing::AtLeast(1)); | 307 .Times(testing::AtLeast(1)); |
309 static const int kIntervalMs = 33; | 308 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec; |
310 static const int kDelayMs = 30; | 309 static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec; |
311 VideoFrame frame(I420Buffer::Create(kWidth, kHeight), | 310 VideoFrame frame(I420Buffer::Create(kWidth, kHeight), |
312 webrtc::kVideoRotation_0, 0); | 311 webrtc::kVideoRotation_0, 0); |
313 uint32_t timestamp = 0; | 312 uint32_t timestamp = 0; |
314 for (size_t i = 0; i < 1000; ++i) { | 313 for (size_t i = 0; i < 1000; ++i) { |
315 frame.set_timestamp(timestamp); | 314 frame.set_timestamp(timestamp); |
316 overuse_detector_->FrameCaptured(frame, clock_->TimeInMilliseconds()); | 315 overuse_detector_->FrameCaptured(frame, rtc::TimeMicros()); |
317 // Encode and send first parts almost instantly. | 316 // Encode and send first parts almost instantly. |
318 clock_->AdvanceTimeMilliseconds(1); | 317 clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerMillisec); |
319 overuse_detector_->FrameSent(timestamp, clock_->TimeInMilliseconds()); | 318 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros()); |
320 // Encode heavier part, resulting in >85% usage total. | 319 // Encode heavier part, resulting in >85% usage total. |
321 clock_->AdvanceTimeMilliseconds(kDelayMs - 1); | 320 clock_.AdvanceTimeMicros(kDelayUs - rtc::kNumMicrosecsPerMillisec); |
322 overuse_detector_->FrameSent(timestamp, clock_->TimeInMilliseconds()); | 321 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros()); |
323 clock_->AdvanceTimeMilliseconds(kIntervalMs - kDelayMs); | 322 clock_.AdvanceTimeMicros(kIntervalUs - kDelayUs); |
324 timestamp += kIntervalMs * 90; | 323 timestamp += kIntervalUs * 90 / 1000; |
325 overuse_detector_->CheckForOveruse(); | 324 overuse_detector_->CheckForOveruse(); |
326 } | 325 } |
327 } | 326 } |
328 | 327 |
329 TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) { | 328 TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) { |
330 rtc::TaskQueue queue("OveruseFrameDetectorTestQueue"); | 329 rtc::TaskQueue queue("OveruseFrameDetectorTestQueue"); |
331 | 330 |
332 rtc::Event event(false, false); | 331 rtc::Event event(false, false); |
333 queue.PostTask([this, &event] { | 332 queue.PostTask([this, &event] { |
334 overuse_detector_->StartCheckForOveruse(); | 333 overuse_detector_->StartCheckForOveruse(); |
335 event.Set(); | 334 event.Set(); |
336 }); | 335 }); |
337 event.Wait(rtc::Event::kForever); | 336 event.Wait(rtc::Event::kForever); |
338 | 337 |
339 // Expect NormalUsage(). When called, stop the |overuse_detector_| and then | 338 // Expect NormalUsage(). When called, stop the |overuse_detector_| and then |
340 // set |event| to end the test. | 339 // set |event| to end the test. |
341 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)) | 340 EXPECT_CALL(*(observer_.get()), ScaleUp(reason_)) |
342 .WillOnce(InvokeWithoutArgs([this, &event] { | 341 .WillOnce(InvokeWithoutArgs([this, &event] { |
343 overuse_detector_->StopCheckForOveruse(); | 342 overuse_detector_->StopCheckForOveruse(); |
344 event.Set(); | 343 event.Set(); |
345 })); | 344 })); |
346 | 345 |
347 queue.PostTask([this, &event] { | 346 queue.PostTask([this, &event] { |
348 const int kDelayMs1 = 5; | 347 const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec; |
349 const int kDelayMs2 = 6; | 348 const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec; |
350 InsertAndSendFramesWithInterval(1300, kFrameInterval33ms, kWidth, kHeight, | 349 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight, |
351 kDelayMs1); | 350 kDelayUs1); |
352 InsertAndSendFramesWithInterval(1, kFrameInterval33ms, kWidth, kHeight, | 351 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight, |
353 kDelayMs2); | 352 kDelayUs2); |
354 }); | 353 }); |
355 | 354 |
356 EXPECT_TRUE(event.Wait(10000)); | 355 EXPECT_TRUE(event.Wait(10000)); |
357 } | 356 } |
358 | 357 |
359 } // namespace webrtc | 358 } // namespace webrtc |
OLD | NEW |