| 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 |