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 |
(...skipping 20 matching lines...) Expand all Loading... |
31 friend class rtc::RefCountedObject<TestBuffer>; | 31 friend class rtc::RefCountedObject<TestBuffer>; |
32 ~TestBuffer() override { | 32 ~TestBuffer() override { |
33 if (event_) | 33 if (event_) |
34 event_->Set(); | 34 event_->Set(); |
35 } | 35 } |
36 rtc::Event* const event_; | 36 rtc::Event* const event_; |
37 }; | 37 }; |
38 | 38 |
39 class ViEEncoderUnderTest : public ViEEncoder { | 39 class ViEEncoderUnderTest : public ViEEncoder { |
40 public: | 40 public: |
| 41 using ScalingObserverInterface::ScaleReason; |
41 ViEEncoderUnderTest( | 42 ViEEncoderUnderTest( |
42 SendStatisticsProxy* stats_proxy, | 43 SendStatisticsProxy* stats_proxy, |
43 const webrtc::VideoSendStream::Config::EncoderSettings& settings) | 44 const webrtc::VideoSendStream::Config::EncoderSettings& settings) |
44 : ViEEncoder(1 /* number_of_cores */, | 45 : ViEEncoder(1 /* number_of_cores */, |
45 stats_proxy, | 46 stats_proxy, |
46 settings, | 47 settings, |
47 nullptr /* pre_encode_callback */, | 48 nullptr /* pre_encode_callback */, |
48 nullptr /* encoder_timing */) {} | 49 nullptr /* encoder_timing */) {} |
49 | 50 |
50 void TriggerCpuOveruse() { | 51 void PostTaskAndWait(bool down, ScaleReason reason) { |
51 rtc::Event event(false, false); | 52 rtc::Event event(false, false); |
52 encoder_queue()->PostTask([this, &event] { | 53 encoder_queue()->PostTask([this, &event, reason, down] { |
53 OveruseDetected(); | 54 down ? ScaleDown(reason) : ScaleUp(reason); |
54 event.Set(); | 55 event.Set(); |
55 }); | 56 }); |
56 event.Wait(rtc::Event::kForever); | 57 RTC_DCHECK(event.Wait(5000)); |
57 } | 58 } |
58 | 59 |
59 void TriggerCpuNormalUsage() { | 60 void TriggerCpuOveruse() { PostTaskAndWait(true, kCpu); } |
60 rtc::Event event(false, false); | 61 |
61 encoder_queue()->PostTask([this, &event] { | 62 void TriggerCpuNormalUsage() { PostTaskAndWait(false, kCpu); } |
62 NormalUsage(); | 63 |
63 event.Set(); | 64 void TriggerQualityLow() { PostTaskAndWait(true, kQuality); } |
64 }); | 65 |
65 event.Wait(rtc::Event::kForever); | 66 void TriggerQualityHigh() { PostTaskAndWait(false, kQuality); } |
66 } | |
67 }; | 67 }; |
68 | 68 |
69 } // namespace | 69 } // namespace |
70 | 70 |
71 class ViEEncoderTest : public ::testing::Test { | 71 class ViEEncoderTest : public ::testing::Test { |
72 public: | 72 public: |
73 static const int kDefaultTimeoutMs = 30 * 1000; | 73 static const int kDefaultTimeoutMs = 30 * 1000; |
74 | 74 |
75 ViEEncoderTest() | 75 ViEEncoderTest() |
76 : video_send_config_(VideoSendStream::Config(nullptr)), | 76 : video_send_config_(VideoSendStream::Config(nullptr)), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 VideoCodec codec_config() { | 139 VideoCodec codec_config() { |
140 rtc::CritScope lock(&crit_); | 140 rtc::CritScope lock(&crit_); |
141 return config_; | 141 return config_; |
142 } | 142 } |
143 | 143 |
144 void BlockNextEncode() { | 144 void BlockNextEncode() { |
145 rtc::CritScope lock(&crit_); | 145 rtc::CritScope lock(&crit_); |
146 block_next_encode_ = true; | 146 block_next_encode_ = true; |
147 } | 147 } |
148 | 148 |
| 149 QualityScaler::Settings GetQPThresholds() const override { |
| 150 return QualityScaler::Settings(true, 1, 2); |
| 151 } |
| 152 |
149 void ContinueEncode() { continue_encode_event_.Set(); } | 153 void ContinueEncode() { continue_encode_event_.Set(); } |
150 | 154 |
151 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, | 155 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, |
152 uint32_t timestamp) const { | 156 uint32_t timestamp) const { |
153 rtc::CritScope lock(&crit_); | 157 rtc::CritScope lock(&crit_); |
154 EXPECT_EQ(timestamp_, timestamp); | 158 EXPECT_EQ(timestamp_, timestamp); |
155 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); | 159 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); |
156 } | 160 } |
157 | 161 |
158 private: | 162 private: |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 vie_encoder_->TriggerCpuOveruse(); | 434 vie_encoder_->TriggerCpuOveruse(); |
431 | 435 |
432 EXPECT_LT(video_source_.current_sink_wants().max_pixel_count.value_or(0), | 436 EXPECT_LT(video_source_.current_sink_wants().max_pixel_count.value_or(0), |
433 frame_width * frame_height); | 437 frame_width * frame_height); |
434 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count_step_up); | 438 EXPECT_FALSE(video_source_.current_sink_wants().max_pixel_count_step_up); |
435 | 439 |
436 frame_width /= 2; | 440 frame_width /= 2; |
437 frame_height /= 2; | 441 frame_height /= 2; |
438 } | 442 } |
439 | 443 |
440 // Trigger CPU overuse a one more time. This should not trigger a request for | 444 // Trigger CPU overuse one more time. This should not trigger a request for |
441 // lower resolution. | 445 // lower resolution. |
442 rtc::VideoSinkWants current_wants = video_source_.current_sink_wants(); | 446 rtc::VideoSinkWants current_wants = video_source_.current_sink_wants(); |
443 video_source_.IncomingCapturedFrame(CreateFrame( | 447 video_source_.IncomingCapturedFrame(CreateFrame( |
444 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); | 448 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); |
445 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); | 449 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); |
446 vie_encoder_->TriggerCpuOveruse(); | 450 vie_encoder_->TriggerCpuOveruse(); |
447 EXPECT_EQ(video_source_.current_sink_wants().max_pixel_count, | 451 EXPECT_EQ(video_source_.current_sink_wants().max_pixel_count, |
448 current_wants.max_pixel_count); | 452 current_wants.max_pixel_count); |
449 EXPECT_EQ(video_source_.current_sink_wants().max_pixel_count_step_up, | 453 EXPECT_EQ(video_source_.current_sink_wants().max_pixel_count_step_up, |
450 current_wants.max_pixel_count_step_up); | 454 current_wants.max_pixel_count_step_up); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 CreateFrame(3, frame_width, frame_height)); | 538 CreateFrame(3, frame_width, frame_height)); |
535 sink_.WaitForEncodedFrame(3); | 539 sink_.WaitForEncodedFrame(3); |
536 | 540 |
537 stats = stats_proxy_->GetStats(); | 541 stats = stats_proxy_->GetStats(); |
538 EXPECT_FALSE(stats.cpu_limited_resolution); | 542 EXPECT_FALSE(stats.cpu_limited_resolution); |
539 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 543 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
540 | 544 |
541 vie_encoder_->Stop(); | 545 vie_encoder_->Stop(); |
542 } | 546 } |
543 | 547 |
| 548 TEST_F(ViEEncoderTest, SwitchingSourceKeepsAdaptation) { |
| 549 const int kTargetBitrateBps = 100000; |
| 550 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 551 |
| 552 int frame_width = 1280; |
| 553 int frame_height = 720; |
| 554 video_source_.IncomingCapturedFrame( |
| 555 CreateFrame(1, frame_width, frame_height)); |
| 556 sink_.WaitForEncodedFrame(1); |
| 557 |
| 558 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 559 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 560 EXPECT_FALSE(stats.bw_limited_resolution); |
| 561 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 562 |
| 563 // Set new source with adaptation still enabled. |
| 564 test::FrameForwarder new_video_source; |
| 565 vie_encoder_->SetSource(&new_video_source, |
| 566 false /* disable_resolution_scaling*/); |
| 567 |
| 568 new_video_source.IncomingCapturedFrame( |
| 569 CreateFrame(2, frame_width, frame_height)); |
| 570 sink_.WaitForEncodedFrame(2); |
| 571 stats = stats_proxy_->GetStats(); |
| 572 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 573 EXPECT_FALSE(stats.bw_limited_resolution); |
| 574 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
| 575 |
| 576 vie_encoder_->TriggerQualityLow(); |
| 577 |
| 578 new_video_source.IncomingCapturedFrame( |
| 579 CreateFrame(3, frame_width, frame_height)); |
| 580 sink_.WaitForEncodedFrame(3); |
| 581 stats = stats_proxy_->GetStats(); |
| 582 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 583 EXPECT_TRUE(stats.bw_limited_resolution); |
| 584 |
| 585 vie_encoder_->SetSource(&new_video_source, |
| 586 false /* disable_resolution_scaling*/); |
| 587 |
| 588 new_video_source.IncomingCapturedFrame( |
| 589 CreateFrame(4, frame_width, frame_height)); |
| 590 sink_.WaitForEncodedFrame(4); |
| 591 stats = stats_proxy_->GetStats(); |
| 592 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 593 EXPECT_TRUE(stats.bw_limited_resolution); |
| 594 |
| 595 // Set adaptation disabled. |
| 596 vie_encoder_->SetSource(&new_video_source, |
| 597 true /* disable_resolution_scaling*/); |
| 598 |
| 599 new_video_source.IncomingCapturedFrame( |
| 600 CreateFrame(5, frame_width, frame_height)); |
| 601 sink_.WaitForEncodedFrame(5); |
| 602 stats = stats_proxy_->GetStats(); |
| 603 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 604 EXPECT_FALSE(stats.bw_limited_resolution); |
| 605 |
| 606 vie_encoder_->Stop(); |
| 607 } |
| 608 |
544 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { | 609 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { |
545 const int kTargetBitrateBps = 100000; | 610 const int kTargetBitrateBps = 100000; |
546 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 611 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
547 | 612 |
548 // Trigger CPU overuse. | 613 // Trigger CPU overuse. |
549 vie_encoder_->TriggerCpuOveruse(); | 614 vie_encoder_->TriggerCpuOveruse(); |
550 int frame_width = 1280; | 615 int frame_width = 1280; |
551 int frame_height = 720; | 616 int frame_height = 720; |
552 | 617 |
553 video_source_.IncomingCapturedFrame( | 618 video_source_.IncomingCapturedFrame( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 video_source_.IncomingCapturedFrame( | 660 video_source_.IncomingCapturedFrame( |
596 CreateFrame(5, frame_width, frame_height)); | 661 CreateFrame(5, frame_width, frame_height)); |
597 sink_.WaitForEncodedFrame(5); | 662 sink_.WaitForEncodedFrame(5); |
598 stats = stats_proxy_->GetStats(); | 663 stats = stats_proxy_->GetStats(); |
599 EXPECT_FALSE(stats.cpu_limited_resolution); | 664 EXPECT_FALSE(stats.cpu_limited_resolution); |
600 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 665 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
601 | 666 |
602 vie_encoder_->Stop(); | 667 vie_encoder_->Stop(); |
603 } | 668 } |
604 | 669 |
| 670 TEST_F(ViEEncoderTest, StatsTracksQualityAdaptationStatsWhenSwitchingSource) { |
| 671 const int kTargetBitrateBps = 100000; |
| 672 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 673 |
| 674 // Trigger CPU overuse. |
| 675 vie_encoder_->TriggerQualityLow(); |
| 676 int frame_width = 1280; |
| 677 int frame_height = 720; |
| 678 |
| 679 video_source_.IncomingCapturedFrame( |
| 680 CreateFrame(1, frame_width, frame_height)); |
| 681 sink_.WaitForEncodedFrame(1); |
| 682 |
| 683 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 684 EXPECT_TRUE(stats.bw_limited_resolution); |
| 685 |
| 686 // Set new source with adaptation still enabled. |
| 687 test::FrameForwarder new_video_source; |
| 688 vie_encoder_->SetSource(&new_video_source, |
| 689 false /* disable_resolution_scaling*/); |
| 690 |
| 691 new_video_source.IncomingCapturedFrame( |
| 692 CreateFrame(2, frame_width, frame_height)); |
| 693 sink_.WaitForEncodedFrame(2); |
| 694 stats = stats_proxy_->GetStats(); |
| 695 EXPECT_TRUE(stats.bw_limited_resolution); |
| 696 |
| 697 // Set adaptation disabled. |
| 698 vie_encoder_->SetSource(&new_video_source, |
| 699 true /* disable_resolution_scaling*/); |
| 700 |
| 701 new_video_source.IncomingCapturedFrame( |
| 702 CreateFrame(3, frame_width, frame_height)); |
| 703 sink_.WaitForEncodedFrame(3); |
| 704 stats = stats_proxy_->GetStats(); |
| 705 EXPECT_FALSE(stats.bw_limited_resolution); |
| 706 |
| 707 // Switch back the source with adaptation enabled. |
| 708 vie_encoder_->SetSource(&video_source_, |
| 709 false /* disable_resolution_scaling*/); |
| 710 video_source_.IncomingCapturedFrame( |
| 711 CreateFrame(4, frame_width, frame_height)); |
| 712 sink_.WaitForEncodedFrame(4); |
| 713 stats = stats_proxy_->GetStats(); |
| 714 EXPECT_TRUE(stats.bw_limited_resolution); |
| 715 |
| 716 // Trigger CPU normal usage. |
| 717 vie_encoder_->TriggerQualityHigh(); |
| 718 video_source_.IncomingCapturedFrame( |
| 719 CreateFrame(5, frame_width, frame_height)); |
| 720 sink_.WaitForEncodedFrame(5); |
| 721 stats = stats_proxy_->GetStats(); |
| 722 EXPECT_FALSE(stats.bw_limited_resolution); |
| 723 |
| 724 vie_encoder_->Stop(); |
| 725 } |
| 726 |
605 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { | 727 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { |
606 const int kTargetBitrateBps = 100000; | 728 const int kTargetBitrateBps = 100000; |
607 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 729 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
608 | 730 |
609 int frame_width = 640; | 731 int frame_width = 640; |
610 int frame_height = 360; | 732 int frame_height = 360; |
611 | 733 |
612 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredUMASamples; ++i) { | 734 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredUMASamples; ++i) { |
613 video_source_.IncomingCapturedFrame( | 735 video_source_.IncomingCapturedFrame( |
614 CreateFrame(i, frame_width, frame_height)); | 736 CreateFrame(i, frame_width, frame_height)); |
(...skipping 11 matching lines...) Expand all Loading... |
626 vie_encoder_->Stop(); | 748 vie_encoder_->Stop(); |
627 | 749 |
628 stats_proxy_.reset(); | 750 stats_proxy_.reset(); |
629 EXPECT_EQ(1, | 751 EXPECT_EQ(1, |
630 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); | 752 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); |
631 EXPECT_EQ( | 753 EXPECT_EQ( |
632 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); | 754 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); |
633 } | 755 } |
634 | 756 |
635 } // namespace webrtc | 757 } // namespace webrtc |
OLD | NEW |