OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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 <limits> | 11 #include <limits> |
12 #include <utility> | 12 #include <utility> |
13 | 13 |
14 #include "webrtc/base/logging.h" | 14 #include "webrtc/base/logging.h" |
15 #include "webrtc/system_wrappers/include/metrics_default.h" | 15 #include "webrtc/system_wrappers/include/metrics_default.h" |
16 #include "webrtc/test/encoder_settings.h" | 16 #include "webrtc/test/encoder_settings.h" |
17 #include "webrtc/test/fake_encoder.h" | 17 #include "webrtc/test/fake_encoder.h" |
18 #include "webrtc/test/frame_generator.h" | 18 #include "webrtc/test/frame_generator.h" |
19 #include "webrtc/test/gtest.h" | 19 #include "webrtc/test/gtest.h" |
20 #include "webrtc/video/send_statistics_proxy.h" | 20 #include "webrtc/video/send_statistics_proxy.h" |
21 #include "webrtc/video/vie_encoder.h" | 21 #include "webrtc/video/vie_encoder.h" |
22 | 22 |
23 namespace webrtc { | 23 namespace webrtc { |
24 | 24 |
| 25 using DegredationPreference = VideoSendStream::DegradationPreference; |
| 26 |
25 namespace { | 27 namespace { |
26 class TestBuffer : public webrtc::I420Buffer { | 28 class TestBuffer : public webrtc::I420Buffer { |
27 public: | 29 public: |
28 TestBuffer(rtc::Event* event, int width, int height) | 30 TestBuffer(rtc::Event* event, int width, int height) |
29 : I420Buffer(width, height), event_(event) {} | 31 : I420Buffer(width, height), event_(event) {} |
30 | 32 |
31 private: | 33 private: |
32 friend class rtc::RefCountedObject<TestBuffer>; | 34 friend class rtc::RefCountedObject<TestBuffer>; |
33 ~TestBuffer() override { | 35 ~TestBuffer() override { |
34 if (event_) | 36 if (event_) |
35 event_->Set(); | 37 event_->Set(); |
36 } | 38 } |
37 rtc::Event* const event_; | 39 rtc::Event* const event_; |
38 }; | 40 }; |
39 | 41 |
40 class ViEEncoderUnderTest : public ViEEncoder { | 42 class ViEEncoderUnderTest : public ViEEncoder { |
41 public: | 43 public: |
42 ViEEncoderUnderTest( | 44 using ScalingObserverInterface::ScaleReason; |
43 SendStatisticsProxy* stats_proxy, | 45 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy, |
44 const webrtc::VideoSendStream::Config::EncoderSettings& settings) | 46 const VideoSendStream::Config::EncoderSettings& settings) |
45 : ViEEncoder(1 /* number_of_cores */, | 47 : ViEEncoder(1 /* number_of_cores */, |
46 stats_proxy, | 48 stats_proxy, |
47 settings, | 49 settings, |
48 nullptr /* pre_encode_callback */, | 50 nullptr /* pre_encode_callback */, |
49 nullptr /* encoder_timing */) {} | 51 nullptr /* encoder_timing */) {} |
50 | 52 |
51 void TriggerCpuOveruse() { | 53 void PostTaskAndWait(bool down, ScaleReason reason) { |
52 rtc::Event event(false, false); | 54 rtc::Event event(false, false); |
53 encoder_queue()->PostTask([this, &event] { | 55 encoder_queue()->PostTask([this, &event, reason, down] { |
54 OveruseDetected(); | 56 down ? ScaleDown(reason) : ScaleUp(reason); |
55 event.Set(); | 57 event.Set(); |
56 }); | 58 }); |
57 event.Wait(rtc::Event::kForever); | 59 RTC_DCHECK(event.Wait(5000)); |
58 } | 60 } |
59 | 61 |
60 void TriggerCpuNormalUsage() { | 62 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); } |
61 rtc::Event event(false, false); | 63 |
62 encoder_queue()->PostTask([this, &event] { | 64 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); } |
63 NormalUsage(); | 65 |
64 event.Set(); | 66 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); } |
65 }); | 67 |
66 event.Wait(rtc::Event::kForever); | 68 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); } |
67 } | |
68 }; | 69 }; |
69 | 70 |
70 } // namespace | 71 } // namespace |
71 | 72 |
72 class ViEEncoderTest : public ::testing::Test { | 73 class ViEEncoderTest : public ::testing::Test { |
73 public: | 74 public: |
74 static const int kDefaultTimeoutMs = 30 * 1000; | 75 static const int kDefaultTimeoutMs = 30 * 1000; |
75 | 76 |
76 ViEEncoderTest() | 77 ViEEncoderTest() |
77 : video_send_config_(VideoSendStream::Config(nullptr)), | 78 : video_send_config_(VideoSendStream::Config(nullptr)), |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 VideoCodec codec_config() { | 128 VideoCodec codec_config() { |
128 rtc::CritScope lock(&crit_); | 129 rtc::CritScope lock(&crit_); |
129 return config_; | 130 return config_; |
130 } | 131 } |
131 | 132 |
132 void BlockNextEncode() { | 133 void BlockNextEncode() { |
133 rtc::CritScope lock(&crit_); | 134 rtc::CritScope lock(&crit_); |
134 block_next_encode_ = true; | 135 block_next_encode_ = true; |
135 } | 136 } |
136 | 137 |
| 138 VideoEncoder::ScalingSettings GetScalingSettings() const override { |
| 139 return VideoEncoder::ScalingSettings(true, 1, 2); |
| 140 } |
| 141 |
137 void ContinueEncode() { continue_encode_event_.Set(); } | 142 void ContinueEncode() { continue_encode_event_.Set(); } |
138 | 143 |
139 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, | 144 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, |
140 uint32_t timestamp) const { | 145 uint32_t timestamp) const { |
141 rtc::CritScope lock(&crit_); | 146 rtc::CritScope lock(&crit_); |
142 EXPECT_EQ(timestamp_, timestamp); | 147 EXPECT_EQ(timestamp_, timestamp); |
143 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); | 148 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); |
144 } | 149 } |
145 | 150 |
146 private: | 151 private: |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 | 425 |
421 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( | 426 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( |
422 std::numeric_limits<int>::max()), | 427 std::numeric_limits<int>::max()), |
423 frame_width * frame_height); | 428 frame_width * frame_height); |
424 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); | 429 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); |
425 | 430 |
426 frame_width /= 2; | 431 frame_width /= 2; |
427 frame_height /= 2; | 432 frame_height /= 2; |
428 } | 433 } |
429 | 434 |
430 // Trigger CPU overuse a one more time. This should not trigger request for | 435 // Trigger CPU overuse one more time. This should not trigger a request for |
431 // lower resolution. | 436 // lower resolution. |
432 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); | 437 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); |
433 video_source_.IncomingCapturedFrame(CreateFrame( | 438 video_source_.IncomingCapturedFrame(CreateFrame( |
434 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); | 439 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); |
435 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); | 440 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); |
436 vie_encoder_->TriggerCpuOveruse(); | 441 vie_encoder_->TriggerCpuOveruse(); |
437 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, | 442 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, |
438 current_wants.max_pixel_count); | 443 current_wants.max_pixel_count); |
439 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up, | 444 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up, |
440 current_wants.max_pixel_count_step_up); | 445 current_wants.max_pixel_count_step_up); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 CreateFrame(3, frame_width, frame_height)); | 531 CreateFrame(3, frame_width, frame_height)); |
527 sink_.WaitForEncodedFrame(3); | 532 sink_.WaitForEncodedFrame(3); |
528 | 533 |
529 stats = stats_proxy_->GetStats(); | 534 stats = stats_proxy_->GetStats(); |
530 EXPECT_FALSE(stats.cpu_limited_resolution); | 535 EXPECT_FALSE(stats.cpu_limited_resolution); |
531 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 536 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
532 | 537 |
533 vie_encoder_->Stop(); | 538 vie_encoder_->Stop(); |
534 } | 539 } |
535 | 540 |
536 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { | 541 TEST_F(ViEEncoderTest, SwitchingSourceKeepsAdaptation) { |
| 542 const int kTargetBitrateBps = 100000; |
| 543 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 544 |
| 545 int frame_width = 1280; |
| 546 int frame_height = 720; |
| 547 video_source_.IncomingCapturedFrame( |
| 548 CreateFrame(1, frame_width, frame_height)); |
| 549 sink_.WaitForEncodedFrame(1); |
| 550 |
| 551 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 552 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 553 EXPECT_FALSE(stats.bw_limited_resolution); |
| 554 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 555 |
| 556 // Set new source with adaptation still enabled. |
| 557 test::FrameForwarder new_video_source; |
| 558 vie_encoder_->SetSource(&new_video_source, |
| 559 VideoSendStream::DegradationPreference::kBalanced); |
| 560 |
| 561 new_video_source.IncomingCapturedFrame( |
| 562 CreateFrame(2, frame_width, frame_height)); |
| 563 sink_.WaitForEncodedFrame(2); |
| 564 stats = stats_proxy_->GetStats(); |
| 565 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 566 EXPECT_FALSE(stats.bw_limited_resolution); |
| 567 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 568 |
| 569 vie_encoder_->TriggerQualityLow(); |
| 570 |
| 571 new_video_source.IncomingCapturedFrame( |
| 572 CreateFrame(3, frame_width, frame_height)); |
| 573 sink_.WaitForEncodedFrame(3); |
| 574 stats = stats_proxy_->GetStats(); |
| 575 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 576 EXPECT_TRUE(stats.bw_limited_resolution); |
| 577 |
| 578 vie_encoder_->SetSource(&new_video_source, |
| 579 VideoSendStream::DegradationPreference::kBalanced); |
| 580 |
| 581 new_video_source.IncomingCapturedFrame( |
| 582 CreateFrame(4, frame_width, frame_height)); |
| 583 sink_.WaitForEncodedFrame(4); |
| 584 stats = stats_proxy_->GetStats(); |
| 585 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 586 EXPECT_TRUE(stats.bw_limited_resolution); |
| 587 |
| 588 // Set adaptation disabled. |
| 589 vie_encoder_->SetSource( |
| 590 &new_video_source, |
| 591 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 592 |
| 593 new_video_source.IncomingCapturedFrame( |
| 594 CreateFrame(5, frame_width, frame_height)); |
| 595 sink_.WaitForEncodedFrame(5); |
| 596 stats = stats_proxy_->GetStats(); |
| 597 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 598 EXPECT_FALSE(stats.bw_limited_resolution); |
| 599 |
| 600 vie_encoder_->Stop(); |
| 601 } |
| 602 |
| 603 TEST_F(ViEEncoderTest, StatsTracksQualityAdaptationStatsWhenSwitchingSource) { |
537 const int kTargetBitrateBps = 100000; | 604 const int kTargetBitrateBps = 100000; |
538 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 605 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
539 | 606 |
540 // Trigger CPU overuse. | 607 // Trigger CPU overuse. |
541 vie_encoder_->TriggerCpuOveruse(); | 608 vie_encoder_->TriggerQualityLow(); |
542 int frame_width = 1280; | 609 int frame_width = 1280; |
543 int frame_height = 720; | 610 int frame_height = 720; |
544 | 611 |
545 video_source_.IncomingCapturedFrame( | 612 video_source_.IncomingCapturedFrame( |
546 CreateFrame(1, frame_width, frame_height)); | 613 CreateFrame(1, frame_width, frame_height)); |
547 sink_.WaitForEncodedFrame(1); | 614 sink_.WaitForEncodedFrame(1); |
548 | 615 |
549 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | 616 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
550 EXPECT_TRUE(stats.cpu_limited_resolution); | 617 EXPECT_TRUE(stats.bw_limited_resolution); |
551 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
552 | 618 |
553 // Set new source with adaptation still enabled. | 619 // Set new source with adaptation still enabled. |
554 test::FrameForwarder new_video_source; | 620 test::FrameForwarder new_video_source; |
555 vie_encoder_->SetSource(&new_video_source, | 621 vie_encoder_->SetSource(&new_video_source, |
556 VideoSendStream::DegradationPreference::kBalanced); | 622 VideoSendStream::DegradationPreference::kBalanced); |
557 | 623 |
558 new_video_source.IncomingCapturedFrame( | 624 new_video_source.IncomingCapturedFrame( |
559 CreateFrame(2, frame_width, frame_height)); | 625 CreateFrame(2, frame_width, frame_height)); |
560 sink_.WaitForEncodedFrame(2); | 626 sink_.WaitForEncodedFrame(2); |
561 stats = stats_proxy_->GetStats(); | 627 stats = stats_proxy_->GetStats(); |
562 EXPECT_TRUE(stats.cpu_limited_resolution); | 628 EXPECT_TRUE(stats.bw_limited_resolution); |
563 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
564 | 629 |
565 // Set adaptation disabled. | 630 // Set adaptation disabled. |
566 vie_encoder_->SetSource( | 631 vie_encoder_->SetSource( |
567 &new_video_source, | 632 &new_video_source, |
568 VideoSendStream::DegradationPreference::kMaintainResolution); | 633 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 634 |
569 new_video_source.IncomingCapturedFrame( | 635 new_video_source.IncomingCapturedFrame( |
570 CreateFrame(3, frame_width, frame_height)); | 636 CreateFrame(3, frame_width, frame_height)); |
571 sink_.WaitForEncodedFrame(3); | 637 sink_.WaitForEncodedFrame(3); |
572 stats = stats_proxy_->GetStats(); | 638 stats = stats_proxy_->GetStats(); |
573 EXPECT_FALSE(stats.cpu_limited_resolution); | 639 EXPECT_FALSE(stats.bw_limited_resolution); |
574 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
575 | 640 |
576 // Switch back the source with adaptation enabled. | 641 // Switch back the source with adaptation enabled. |
577 vie_encoder_->SetSource(&video_source_, | 642 vie_encoder_->SetSource(&video_source_, |
578 VideoSendStream::DegradationPreference::kBalanced); | 643 VideoSendStream::DegradationPreference::kBalanced); |
579 video_source_.IncomingCapturedFrame( | 644 video_source_.IncomingCapturedFrame( |
580 CreateFrame(4, frame_width, frame_height)); | 645 CreateFrame(4, frame_width, frame_height)); |
581 sink_.WaitForEncodedFrame(4); | 646 sink_.WaitForEncodedFrame(4); |
582 stats = stats_proxy_->GetStats(); | 647 stats = stats_proxy_->GetStats(); |
583 EXPECT_TRUE(stats.cpu_limited_resolution); | 648 EXPECT_TRUE(stats.bw_limited_resolution); |
584 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | |
585 | 649 |
586 // Trigger CPU normal usage. | 650 // Trigger CPU normal usage. |
587 vie_encoder_->TriggerCpuNormalUsage(); | 651 vie_encoder_->TriggerQualityHigh(); |
588 video_source_.IncomingCapturedFrame( | 652 video_source_.IncomingCapturedFrame( |
589 CreateFrame(5, frame_width, frame_height)); | 653 CreateFrame(5, frame_width, frame_height)); |
590 sink_.WaitForEncodedFrame(5); | 654 sink_.WaitForEncodedFrame(5); |
591 stats = stats_proxy_->GetStats(); | 655 stats = stats_proxy_->GetStats(); |
592 EXPECT_FALSE(stats.cpu_limited_resolution); | 656 EXPECT_FALSE(stats.bw_limited_resolution); |
593 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | |
594 | 657 |
595 vie_encoder_->Stop(); | 658 vie_encoder_->Stop(); |
596 } | 659 } |
597 | 660 |
598 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { | 661 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { |
599 const int kTargetBitrateBps = 100000; | 662 const int kTargetBitrateBps = 100000; |
600 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 663 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
601 | 664 |
602 int frame_width = 640; | 665 int frame_width = 640; |
603 int frame_height = 360; | 666 int frame_height = 360; |
(...skipping 16 matching lines...) Expand all Loading... |
620 vie_encoder_->Stop(); | 683 vie_encoder_->Stop(); |
621 | 684 |
622 stats_proxy_.reset(); | 685 stats_proxy_.reset(); |
623 EXPECT_EQ(1, | 686 EXPECT_EQ(1, |
624 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); | 687 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); |
625 EXPECT_EQ( | 688 EXPECT_EQ( |
626 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); | 689 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); |
627 } | 690 } |
628 | 691 |
629 } // namespace webrtc | 692 } // namespace webrtc |
OLD | NEW |