Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1018)

Side by Side Diff: webrtc/video/vie_encoder_unittest.cc

Issue 2398963003: Move usage of QualityScaler to ViEEncoder. (Closed)
Patch Set: rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/video/vie_encoder.cc ('k') | webrtc/video_encoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 using ScaleReason = ScalingObserverInterface::ScaleReason;
27
25 namespace { 28 namespace {
26 const size_t kMaxPayloadLength = 1440; 29 const size_t kMaxPayloadLength = 1440;
27 const int kTargetBitrateBps = 100000; 30 const int kTargetBitrateBps = 100000;
28 31
29 class TestBuffer : public webrtc::I420Buffer { 32 class TestBuffer : public webrtc::I420Buffer {
30 public: 33 public:
31 TestBuffer(rtc::Event* event, int width, int height) 34 TestBuffer(rtc::Event* event, int width, int height)
32 : I420Buffer(width, height), event_(event) {} 35 : I420Buffer(width, height), event_(event) {}
33 36
34 private: 37 private:
35 friend class rtc::RefCountedObject<TestBuffer>; 38 friend class rtc::RefCountedObject<TestBuffer>;
36 ~TestBuffer() override { 39 ~TestBuffer() override {
37 if (event_) 40 if (event_)
38 event_->Set(); 41 event_->Set();
39 } 42 }
40 rtc::Event* const event_; 43 rtc::Event* const event_;
41 }; 44 };
42 45
43 class ViEEncoderUnderTest : public ViEEncoder { 46 class ViEEncoderUnderTest : public ViEEncoder {
44 public: 47 public:
45 ViEEncoderUnderTest( 48 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
46 SendStatisticsProxy* stats_proxy, 49 const VideoSendStream::Config::EncoderSettings& settings)
47 const webrtc::VideoSendStream::Config::EncoderSettings& settings)
48 : ViEEncoder(1 /* number_of_cores */, 50 : ViEEncoder(1 /* number_of_cores */,
49 stats_proxy, 51 stats_proxy,
50 settings, 52 settings,
51 nullptr /* pre_encode_callback */, 53 nullptr /* pre_encode_callback */,
52 nullptr /* encoder_timing */) {} 54 nullptr /* encoder_timing */) {}
53 55
54 void TriggerCpuOveruse() { 56 void PostTaskAndWait(bool down, ScaleReason reason) {
55 rtc::Event event(false, false); 57 rtc::Event event(false, false);
56 encoder_queue()->PostTask([this, &event] { 58 encoder_queue()->PostTask([this, &event, reason, down] {
57 OveruseDetected(); 59 down ? ScaleDown(reason) : ScaleUp(reason);
58 event.Set(); 60 event.Set();
59 }); 61 });
60 event.Wait(rtc::Event::kForever); 62 RTC_DCHECK(event.Wait(5000));
61 } 63 }
62 64
63 void TriggerCpuNormalUsage() { 65 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); }
64 rtc::Event event(false, false); 66
65 encoder_queue()->PostTask([this, &event] { 67 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); }
66 NormalUsage(); 68
67 event.Set(); 69 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); }
68 }); 70
69 event.Wait(rtc::Event::kForever); 71 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); }
70 }
71 }; 72 };
72 73
73 class VideoStreamFactory 74 class VideoStreamFactory
74 : public VideoEncoderConfig::VideoStreamFactoryInterface { 75 : public VideoEncoderConfig::VideoStreamFactoryInterface {
75 public: 76 public:
76 explicit VideoStreamFactory(size_t num_temporal_layers) 77 explicit VideoStreamFactory(size_t num_temporal_layers)
77 : num_temporal_layers_(num_temporal_layers) { 78 : num_temporal_layers_(num_temporal_layers) {
78 EXPECT_GT(num_temporal_layers, 0u); 79 EXPECT_GT(num_temporal_layers, 0u);
79 } 80 }
80 81
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 VideoCodec codec_config() { 177 VideoCodec codec_config() {
177 rtc::CritScope lock(&crit_); 178 rtc::CritScope lock(&crit_);
178 return config_; 179 return config_;
179 } 180 }
180 181
181 void BlockNextEncode() { 182 void BlockNextEncode() {
182 rtc::CritScope lock(&crit_); 183 rtc::CritScope lock(&crit_);
183 block_next_encode_ = true; 184 block_next_encode_ = true;
184 } 185 }
185 186
187 VideoEncoder::ScalingSettings GetScalingSettings() const override {
188 return VideoEncoder::ScalingSettings(true, 1, 2);
189 }
190
186 void ContinueEncode() { continue_encode_event_.Set(); } 191 void ContinueEncode() { continue_encode_event_.Set(); }
187 192
188 void CheckLastTimeStampsMatch(int64_t ntp_time_ms, 193 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
189 uint32_t timestamp) const { 194 uint32_t timestamp) const {
190 rtc::CritScope lock(&crit_); 195 rtc::CritScope lock(&crit_);
191 EXPECT_EQ(timestamp_, timestamp); 196 EXPECT_EQ(timestamp_, timestamp);
192 EXPECT_EQ(ntp_time_ms_, ntp_time_ms); 197 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
193 } 198 }
194 199
195 private: 200 private:
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 547
543 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( 548 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
544 std::numeric_limits<int>::max()), 549 std::numeric_limits<int>::max()),
545 frame_width * frame_height); 550 frame_width * frame_height);
546 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); 551 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
547 552
548 frame_width /= 2; 553 frame_width /= 2;
549 frame_height /= 2; 554 frame_height /= 2;
550 } 555 }
551 556
552 // Trigger CPU overuse a one more time. This should not trigger request for 557 // Trigger CPU overuse one more time. This should not trigger a request for
553 // lower resolution. 558 // lower resolution.
554 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); 559 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
555 video_source_.IncomingCapturedFrame(CreateFrame( 560 video_source_.IncomingCapturedFrame(CreateFrame(
556 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); 561 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
557 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); 562 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
558 vie_encoder_->TriggerCpuOveruse(); 563 vie_encoder_->TriggerCpuOveruse();
559 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, 564 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
560 current_wants.max_pixel_count); 565 current_wants.max_pixel_count);
561 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up, 566 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
562 current_wants.max_pixel_count_step_up); 567 current_wants.max_pixel_count_step_up);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 CreateFrame(3, frame_width, frame_height)); 651 CreateFrame(3, frame_width, frame_height));
647 sink_.WaitForEncodedFrame(3); 652 sink_.WaitForEncodedFrame(3);
648 653
649 stats = stats_proxy_->GetStats(); 654 stats = stats_proxy_->GetStats();
650 EXPECT_FALSE(stats.cpu_limited_resolution); 655 EXPECT_FALSE(stats.cpu_limited_resolution);
651 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); 656 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
652 657
653 vie_encoder_->Stop(); 658 vie_encoder_->Stop();
654 } 659 }
655 660
661 TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
662 const int kTargetBitrateBps = 100000;
663 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
664
665 int frame_width = 1280;
666 int frame_height = 720;
667 video_source_.IncomingCapturedFrame(
668 CreateFrame(1, frame_width, frame_height));
669 sink_.WaitForEncodedFrame(1);
670
671 VideoSendStream::Stats stats = stats_proxy_->GetStats();
672 EXPECT_FALSE(stats.cpu_limited_resolution);
673 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
674
675 vie_encoder_->TriggerCpuOveruse();
676
677 video_source_.IncomingCapturedFrame(
678 CreateFrame(2, frame_width, frame_height));
679 sink_.WaitForEncodedFrame(2);
680 stats = stats_proxy_->GetStats();
681 EXPECT_TRUE(stats.cpu_limited_resolution);
682 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
683
684 // Set new source with adaptation still enabled.
685 test::FrameForwarder new_video_source;
686 vie_encoder_->SetSource(&new_video_source,
687 VideoSendStream::DegradationPreference::kBalanced);
688
689 new_video_source.IncomingCapturedFrame(
690 CreateFrame(3, frame_width, frame_height));
691 sink_.WaitForEncodedFrame(3);
692 stats = stats_proxy_->GetStats();
693 EXPECT_TRUE(stats.cpu_limited_resolution);
694 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
695
696 // Set adaptation disabled.
697 vie_encoder_->SetSource(
698 &new_video_source,
699 VideoSendStream::DegradationPreference::kMaintainResolution);
700
701 new_video_source.IncomingCapturedFrame(
702 CreateFrame(4, frame_width, frame_height));
703 sink_.WaitForEncodedFrame(4);
704 stats = stats_proxy_->GetStats();
705 EXPECT_FALSE(stats.cpu_limited_resolution);
706 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
707
708 // Set adaptation back to enabled.
709 vie_encoder_->SetSource(&new_video_source,
710 VideoSendStream::DegradationPreference::kBalanced);
711
712 new_video_source.IncomingCapturedFrame(
713 CreateFrame(5, frame_width, frame_height));
714 sink_.WaitForEncodedFrame(5);
715 stats = stats_proxy_->GetStats();
716 EXPECT_TRUE(stats.cpu_limited_resolution);
717 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
718
719 vie_encoder_->TriggerCpuNormalUsage();
720
721 new_video_source.IncomingCapturedFrame(
722 CreateFrame(6, frame_width, frame_height));
723 sink_.WaitForEncodedFrame(6);
724 stats = stats_proxy_->GetStats();
725 EXPECT_FALSE(stats.cpu_limited_resolution);
726 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
727
728 vie_encoder_->Stop();
729 }
730
731 TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
732 const int kTargetBitrateBps = 100000;
733 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
734
735 int frame_width = 1280;
736 int frame_height = 720;
737 video_source_.IncomingCapturedFrame(
738 CreateFrame(1, frame_width, frame_height));
739 sink_.WaitForEncodedFrame(1);
740
741 VideoSendStream::Stats stats = stats_proxy_->GetStats();
742 EXPECT_FALSE(stats.cpu_limited_resolution);
743 EXPECT_FALSE(stats.bw_limited_resolution);
744 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
745
746 // Set new source with adaptation still enabled.
747 test::FrameForwarder new_video_source;
748 vie_encoder_->SetSource(&new_video_source,
749 VideoSendStream::DegradationPreference::kBalanced);
750
751 new_video_source.IncomingCapturedFrame(
752 CreateFrame(2, frame_width, frame_height));
753 sink_.WaitForEncodedFrame(2);
754 stats = stats_proxy_->GetStats();
755 EXPECT_FALSE(stats.cpu_limited_resolution);
756 EXPECT_FALSE(stats.bw_limited_resolution);
757 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
758
759 vie_encoder_->TriggerQualityLow();
760
761 new_video_source.IncomingCapturedFrame(
762 CreateFrame(3, frame_width, frame_height));
763 sink_.WaitForEncodedFrame(3);
764 stats = stats_proxy_->GetStats();
765 EXPECT_FALSE(stats.cpu_limited_resolution);
766 EXPECT_TRUE(stats.bw_limited_resolution);
767
768 vie_encoder_->SetSource(&new_video_source,
769 VideoSendStream::DegradationPreference::kBalanced);
770
771 new_video_source.IncomingCapturedFrame(
772 CreateFrame(4, frame_width, frame_height));
773 sink_.WaitForEncodedFrame(4);
774 stats = stats_proxy_->GetStats();
775 EXPECT_FALSE(stats.cpu_limited_resolution);
776 EXPECT_TRUE(stats.bw_limited_resolution);
777
778 // Set adaptation disabled.
779 vie_encoder_->SetSource(
780 &new_video_source,
781 VideoSendStream::DegradationPreference::kMaintainResolution);
782
783 new_video_source.IncomingCapturedFrame(
784 CreateFrame(5, frame_width, frame_height));
785 sink_.WaitForEncodedFrame(5);
786 stats = stats_proxy_->GetStats();
787 EXPECT_FALSE(stats.cpu_limited_resolution);
788 EXPECT_FALSE(stats.bw_limited_resolution);
789
790 vie_encoder_->Stop();
791 }
792
656 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { 793 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
657 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); 794 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
658 795
659 // Trigger CPU overuse. 796 // Trigger CPU overuse.
660 vie_encoder_->TriggerCpuOveruse(); 797 vie_encoder_->TriggerCpuOveruse();
661 int frame_width = 1280; 798 int frame_width = 1280;
662 int frame_height = 720; 799 int frame_height = 720;
663 800
664 video_source_.IncomingCapturedFrame( 801 video_source_.IncomingCapturedFrame(
665 CreateFrame(1, frame_width, frame_height)); 802 CreateFrame(1, frame_width, frame_height));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720)); 857 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
721 sink_.WaitForEncodedFrame(1); 858 sink_.WaitForEncodedFrame(1);
722 859
723 VideoSendStream::Stats stats = stats_proxy_->GetStats(); 860 VideoSendStream::Stats stats = stats_proxy_->GetStats();
724 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, 861 EXPECT_EQ(video_encoder_config_.max_bitrate_bps,
725 stats.preferred_media_bitrate_bps); 862 stats.preferred_media_bitrate_bps);
726 863
727 vie_encoder_->Stop(); 864 vie_encoder_->Stop();
728 } 865 }
729 866
867 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) {
868 const int kTargetBitrateBps = 100000;
869 int frame_width = 1280;
870 int frame_height = 720;
871 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
872
873 // Expect no scaling to begin with
874 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
875 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
876
877 // Trigger scale down
878 vie_encoder_->TriggerQualityLow();
879 video_source_.IncomingCapturedFrame(
880 CreateFrame(1, frame_width, frame_height));
881 sink_.WaitForEncodedFrame(1);
882
883 // Expect a scale down.
884 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count);
885 EXPECT_LT(*video_source_.sink_wants().max_pixel_count,
886 frame_width * frame_height);
887
888 // Set adaptation disabled.
889 test::FrameForwarder new_video_source;
890 vie_encoder_->SetSource(
891 &new_video_source,
892 VideoSendStream::DegradationPreference::kMaintainResolution);
893
894 // Trigger scale down
895 vie_encoder_->TriggerQualityLow();
896 new_video_source.IncomingCapturedFrame(
897 CreateFrame(2, frame_width, frame_height));
898 sink_.WaitForEncodedFrame(2);
899
900 // Expect no scaling
901 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
902
903 // Trigger scale up
904 vie_encoder_->TriggerQualityHigh();
905 new_video_source.IncomingCapturedFrame(
906 CreateFrame(3, frame_width, frame_height));
907 sink_.WaitForEncodedFrame(3);
908
909 // Expect nothing to change, still no scaling
910 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
911
912 vie_encoder_->Stop();
913 }
914
730 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { 915 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
731 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); 916 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
732 917
733 int frame_width = 640; 918 int frame_width = 640;
734 int frame_height = 360; 919 int frame_height = 360;
735 920
736 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { 921 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
737 video_source_.IncomingCapturedFrame( 922 video_source_.IncomingCapturedFrame(
738 CreateFrame(i, frame_width, frame_height)); 923 CreateFrame(i, frame_width, frame_height));
739 sink_.WaitForEncodedFrame(i); 924 sink_.WaitForEncodedFrame(i);
(...skipping 11 matching lines...) Expand all
751 vie_encoder_->Stop(); 936 vie_encoder_->Stop();
752 937
753 stats_proxy_.reset(); 938 stats_proxy_.reset();
754 EXPECT_EQ(1, 939 EXPECT_EQ(1,
755 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); 940 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
756 EXPECT_EQ( 941 EXPECT_EQ(
757 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); 942 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
758 } 943 }
759 944
760 } // namespace webrtc 945 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/vie_encoder.cc ('k') | webrtc/video_encoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698