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 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 const int kDelayUs2 = 6000; | 132 const int kDelayUs2 = 6000; |
133 InsertAndSendFramesWithInterval( | 133 InsertAndSendFramesWithInterval( |
134 1300, kFrameIntervalUs, kWidth, kHeight, kDelayUs1); | 134 1300, kFrameIntervalUs, kWidth, kHeight, kDelayUs1); |
135 InsertAndSendFramesWithInterval( | 135 InsertAndSendFramesWithInterval( |
136 1, kFrameIntervalUs, kWidth, kHeight, kDelayUs2); | 136 1, kFrameIntervalUs, kWidth, kHeight, kDelayUs2); |
137 overuse_detector_->CheckForOveruse(); | 137 overuse_detector_->CheckForOveruse(); |
138 } | 138 } |
139 | 139 |
140 int UsagePercent() { return metrics_.encode_usage_percent; } | 140 int UsagePercent() { return metrics_.encode_usage_percent; } |
141 | 141 |
| 142 int64_t OveruseProcessingTimeLimitForFramerate(int fps) const { |
| 143 int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps; |
| 144 int64_t max_processing_time_us = |
| 145 (frame_interval * options_.high_encode_usage_threshold_percent) / 100; |
| 146 return max_processing_time_us; |
| 147 } |
| 148 |
| 149 int64_t UnderuseProcessingTimeLimitForFramerate(int fps) const { |
| 150 int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps; |
| 151 int64_t max_processing_time_us = |
| 152 (frame_interval * options_.low_encode_usage_threshold_percent) / 100; |
| 153 return max_processing_time_us; |
| 154 } |
| 155 |
142 CpuOveruseOptions options_; | 156 CpuOveruseOptions options_; |
143 rtc::ScopedFakeClock clock_; | 157 rtc::ScopedFakeClock clock_; |
144 std::unique_ptr<MockCpuOveruseObserver> observer_; | 158 std::unique_ptr<MockCpuOveruseObserver> observer_; |
145 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_; | 159 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_; |
146 CpuOveruseMetrics metrics_; | 160 CpuOveruseMetrics metrics_; |
147 | 161 |
148 static const auto reason_ = AdaptationObserverInterface::AdaptReason::kCpu; | 162 static const auto reason_ = AdaptationObserverInterface::AdaptReason::kCpu; |
149 }; | 163 }; |
150 | 164 |
151 | 165 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec; | 362 const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec; |
349 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight, | 363 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight, |
350 kDelayUs1); | 364 kDelayUs1); |
351 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight, | 365 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight, |
352 kDelayUs2); | 366 kDelayUs2); |
353 }); | 367 }); |
354 | 368 |
355 EXPECT_TRUE(event.Wait(10000)); | 369 EXPECT_TRUE(event.Wait(10000)); |
356 } | 370 } |
357 | 371 |
| 372 TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) { |
| 373 const int kCapturerMaxFrameRate = 30; |
| 374 const int kEncodeMaxFrameRate = 20; // Maximum fps the encoder can sustain. |
| 375 |
| 376 // Trigger overuse. |
| 377 int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate; |
| 378 // Processing time just below over use limit given kEncodeMaxFrameRate. |
| 379 int64_t processing_time_us = |
| 380 (98 * OveruseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100; |
| 381 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1); |
| 382 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 383 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight, |
| 384 processing_time_us); |
| 385 overuse_detector_->CheckForOveruse(); |
| 386 } |
| 387 |
| 388 // Simulate frame rate reduction and normal usage. |
| 389 frame_interval_us = rtc::kNumMicrosecsPerSec / kEncodeMaxFrameRate; |
| 390 overuse_detector_->OnTargetFramerateUpdated(kEncodeMaxFrameRate); |
| 391 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0); |
| 392 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 393 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight, |
| 394 processing_time_us); |
| 395 overuse_detector_->CheckForOveruse(); |
| 396 } |
| 397 |
| 398 // Reduce processing time to trigger underuse. |
| 399 processing_time_us = |
| 400 (98 * UnderuseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100; |
| 401 EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(1); |
| 402 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight, |
| 403 processing_time_us); |
| 404 overuse_detector_->CheckForOveruse(); |
| 405 } |
| 406 |
| 407 TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) { |
| 408 const int kMinFrameRate = 7; // Minimum fps allowed by current detector impl. |
| 409 overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate); |
| 410 |
| 411 // Normal usage just at the limit. |
| 412 int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMinFrameRate; |
| 413 // Processing time just below over use limit given kEncodeMaxFrameRate. |
| 414 int64_t processing_time_us = |
| 415 (98 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100; |
| 416 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0); |
| 417 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 418 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight, |
| 419 processing_time_us); |
| 420 overuse_detector_->CheckForOveruse(); |
| 421 } |
| 422 |
| 423 // Over the limit to overuse. |
| 424 processing_time_us = |
| 425 (102 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100; |
| 426 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1); |
| 427 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 428 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight, |
| 429 processing_time_us); |
| 430 overuse_detector_->CheckForOveruse(); |
| 431 } |
| 432 |
| 433 // Reduce input frame rate. Should still trigger overuse. |
| 434 overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate - 1); |
| 435 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1); |
| 436 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 437 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight, |
| 438 processing_time_us); |
| 439 overuse_detector_->CheckForOveruse(); |
| 440 } |
| 441 } |
| 442 |
| 443 TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) { |
| 444 const int kMaxFrameRate = 20; |
| 445 overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate); |
| 446 int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate; |
| 447 // Maximum frame interval allowed is 35% above ideal. |
| 448 int64_t max_frame_interval_us = (135 * frame_interval_us) / 100; |
| 449 // Maximum processing time, without triggering overuse, allowed with the above |
| 450 // frame interval. |
| 451 int64_t max_processing_time_us = |
| 452 (max_frame_interval_us * options_.high_encode_usage_threshold_percent) / |
| 453 100; |
| 454 |
| 455 // Processing time just below overuse limit given kMaxFrameRate. |
| 456 int64_t processing_time_us = (98 * max_processing_time_us) / 100; |
| 457 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0); |
| 458 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 459 InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth, |
| 460 kHeight, processing_time_us); |
| 461 overuse_detector_->CheckForOveruse(); |
| 462 } |
| 463 |
| 464 // Go above limit, trigger overuse. |
| 465 processing_time_us = (102 * max_processing_time_us) / 100; |
| 466 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1); |
| 467 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 468 InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth, |
| 469 kHeight, processing_time_us); |
| 470 overuse_detector_->CheckForOveruse(); |
| 471 } |
| 472 |
| 473 // Increase frame interval, should still trigger overuse. |
| 474 max_frame_interval_us *= 2; |
| 475 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1); |
| 476 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) { |
| 477 InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth, |
| 478 kHeight, processing_time_us); |
| 479 overuse_detector_->CheckForOveruse(); |
| 480 } |
| 481 } |
| 482 |
358 } // namespace webrtc | 483 } // namespace webrtc |
OLD | NEW |