Index: webrtc/video/vie_encoder_unittest.cc |
diff --git a/webrtc/video/vie_encoder_unittest.cc b/webrtc/video/vie_encoder_unittest.cc |
index b3629814b41bf0ac68036b8cbf0e9f912634cacd..1f555139d007fcfd1217e825cba39147b43f77ea 100644 |
--- a/webrtc/video/vie_encoder_unittest.cc |
+++ b/webrtc/video/vie_encoder_unittest.cc |
@@ -38,6 +38,7 @@ class TestBuffer : public webrtc::I420Buffer { |
class ViEEncoderUnderTest : public ViEEncoder { |
public: |
+ using ScalingObserverInterface::ScaleReason; |
ViEEncoderUnderTest( |
SendStatisticsProxy* stats_proxy, |
const webrtc::VideoSendStream::Config::EncoderSettings& settings) |
@@ -47,23 +48,22 @@ class ViEEncoderUnderTest : public ViEEncoder { |
nullptr /* pre_encode_callback */, |
nullptr /* encoder_timing */) {} |
- void TriggerCpuOveruse() { |
+ void PostTaskAndWait(bool down, ScaleReason reason) { |
rtc::Event event(false, false); |
- encoder_queue()->PostTask([this, &event] { |
- OveruseDetected(); |
+ encoder_queue()->PostTask([this, &event, reason, down] { |
+ down ? ScaleDown(reason) : ScaleUp(reason); |
event.Set(); |
}); |
- event.Wait(rtc::Event::kForever); |
+ RTC_DCHECK(event.Wait(5000)); |
} |
- void TriggerCpuNormalUsage() { |
- rtc::Event event(false, false); |
- encoder_queue()->PostTask([this, &event] { |
- NormalUsage(); |
- event.Set(); |
- }); |
- event.Wait(rtc::Event::kForever); |
- } |
+ void TriggerCpuOveruse() { PostTaskAndWait(true, kCpu); } |
+ |
+ void TriggerCpuNormalUsage() { PostTaskAndWait(false, kCpu); } |
+ |
+ void TriggerQualityLow() { PostTaskAndWait(true, kQuality); } |
+ |
+ void TriggerQualityHigh() { PostTaskAndWait(false, kQuality); } |
}; |
} // namespace |
@@ -146,6 +146,10 @@ class ViEEncoderTest : public ::testing::Test { |
block_next_encode_ = true; |
} |
+ QualityScaler::Settings GetQPThresholds() const override { |
+ return QualityScaler::Settings(true, 1, 2); |
+ } |
+ |
void ContinueEncode() { continue_encode_event_.Set(); } |
void CheckLastTimeStampsMatch(int64_t ntp_time_ms, |
@@ -437,7 +441,7 @@ TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) { |
frame_height /= 2; |
} |
- // Trigger CPU overuse a one more time. This should not trigger a request for |
+ // Trigger CPU overuse one more time. This should not trigger a request for |
// lower resolution. |
rtc::VideoSinkWants current_wants = video_source_.current_sink_wants(); |
video_source_.IncomingCapturedFrame(CreateFrame( |
@@ -541,6 +545,67 @@ TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) { |
vie_encoder_->Stop(); |
} |
+TEST_F(ViEEncoderTest, SwitchingSourceKeepsAdaptation) { |
+ const int kTargetBitrateBps = 100000; |
+ vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
+ |
+ int frame_width = 1280; |
+ int frame_height = 720; |
+ video_source_.IncomingCapturedFrame( |
+ CreateFrame(1, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(1); |
+ |
+ VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.cpu_limited_resolution); |
+ EXPECT_FALSE(stats.bw_limited_resolution); |
+ EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
+ |
+ // Set new source with adaptation still enabled. |
+ test::FrameForwarder new_video_source; |
+ vie_encoder_->SetSource(&new_video_source, |
+ false /* disable_resolution_scaling*/); |
+ |
+ new_video_source.IncomingCapturedFrame( |
+ CreateFrame(2, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(2); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.cpu_limited_resolution); |
+ EXPECT_FALSE(stats.bw_limited_resolution); |
+ EXPECT_EQ(0, stats.number_of_cpu_adapt_changes); |
+ |
+ vie_encoder_->TriggerQualityLow(); |
+ |
+ new_video_source.IncomingCapturedFrame( |
+ CreateFrame(3, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(3); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.cpu_limited_resolution); |
+ EXPECT_TRUE(stats.bw_limited_resolution); |
+ |
+ vie_encoder_->SetSource(&new_video_source, |
+ false /* disable_resolution_scaling*/); |
+ |
+ new_video_source.IncomingCapturedFrame( |
+ CreateFrame(4, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(4); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.cpu_limited_resolution); |
+ EXPECT_TRUE(stats.bw_limited_resolution); |
+ |
+ // Set adaptation disabled. |
+ vie_encoder_->SetSource(&new_video_source, |
+ true /* disable_resolution_scaling*/); |
+ |
+ new_video_source.IncomingCapturedFrame( |
+ CreateFrame(5, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(5); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.cpu_limited_resolution); |
+ EXPECT_FALSE(stats.bw_limited_resolution); |
+ |
+ vie_encoder_->Stop(); |
+} |
+ |
TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { |
const int kTargetBitrateBps = 100000; |
vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
@@ -602,6 +667,63 @@ TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) { |
vie_encoder_->Stop(); |
} |
+TEST_F(ViEEncoderTest, StatsTracksQualityAdaptationStatsWhenSwitchingSource) { |
+ const int kTargetBitrateBps = 100000; |
+ vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
+ |
+ // Trigger CPU overuse. |
+ vie_encoder_->TriggerQualityLow(); |
+ int frame_width = 1280; |
+ int frame_height = 720; |
+ |
+ video_source_.IncomingCapturedFrame( |
+ CreateFrame(1, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(1); |
+ |
+ VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
+ EXPECT_TRUE(stats.bw_limited_resolution); |
+ |
+ // Set new source with adaptation still enabled. |
+ test::FrameForwarder new_video_source; |
+ vie_encoder_->SetSource(&new_video_source, |
+ false /* disable_resolution_scaling*/); |
+ |
+ new_video_source.IncomingCapturedFrame( |
+ CreateFrame(2, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(2); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_TRUE(stats.bw_limited_resolution); |
+ |
+ // Set adaptation disabled. |
+ vie_encoder_->SetSource(&new_video_source, |
+ true /* disable_resolution_scaling*/); |
+ |
+ new_video_source.IncomingCapturedFrame( |
+ CreateFrame(3, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(3); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.bw_limited_resolution); |
+ |
+ // Switch back the source with adaptation enabled. |
+ vie_encoder_->SetSource(&video_source_, |
+ false /* disable_resolution_scaling*/); |
+ video_source_.IncomingCapturedFrame( |
+ CreateFrame(4, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(4); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_TRUE(stats.bw_limited_resolution); |
+ |
+ // Trigger CPU normal usage. |
+ vie_encoder_->TriggerQualityHigh(); |
+ video_source_.IncomingCapturedFrame( |
+ CreateFrame(5, frame_width, frame_height)); |
+ sink_.WaitForEncodedFrame(5); |
+ stats = stats_proxy_->GetStats(); |
+ EXPECT_FALSE(stats.bw_limited_resolution); |
+ |
+ vie_encoder_->Stop(); |
+} |
+ |
TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { |
const int kTargetBitrateBps = 100000; |
vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |