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

Unified Diff: webrtc/video/vie_encoder_unittest.cc

Issue 2800403002: Scale counter and resolution downgrade stats may be incorrect. (Closed)
Patch Set: address comments Created 3 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/video/vie_encoder.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/video/vie_encoder_unittest.cc
diff --git a/webrtc/video/vie_encoder_unittest.cc b/webrtc/video/vie_encoder_unittest.cc
index 79a08b354a37195d2b94c17966c09c67677b0334..d6d4d07ac4f688fbcf95a459a7d245fa8fd1e448 100644
--- a/webrtc/video/vie_encoder_unittest.cc
+++ b/webrtc/video/vie_encoder_unittest.cc
@@ -29,13 +29,9 @@
#include "webrtc/video/vie_encoder.h"
namespace {
-#if defined(WEBRTC_ANDROID)
// TODO(kthelgason): Lower this limit when better testing
// on MediaCodec and fallback implementations are in place.
const int kMinPixelsPerFrame = 320 * 180;
-#else
-const int kMinPixelsPerFrame = 120 * 90;
-#endif
const int kMinFramerateFps = 2;
const int64_t kFrameTimeoutMs = 100;
} // namespace
@@ -726,6 +722,7 @@ TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
}
TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
+ const int kMaxDowngrades = ViEEncoder::kMaxCpuResolutionDowngrades;
vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
VerifyNoLimitation(video_source_.sink_wants());
@@ -735,7 +732,7 @@ TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
// Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
// request lower resolution.
- for (int i = 1; i <= ViEEncoder::kMaxCpuResolutionDowngrades; ++i) {
+ for (int i = 1; i <= kMaxDowngrades; ++i) {
video_source_.IncomingCapturedFrame(
CreateFrame(i, frame_width, frame_height));
sink_.WaitForEncodedFrame(i);
@@ -745,6 +742,8 @@ TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
EXPECT_FALSE(video_source_.sink_wants().target_pixel_count);
EXPECT_LT(video_source_.sink_wants().max_pixel_count,
frame_width * frame_height);
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(i, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
frame_width /= 2;
frame_height /= 2;
@@ -753,14 +752,17 @@ TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
// Trigger CPU overuse one more time. This should not trigger a request for
// lower resolution.
rtc::VideoSinkWants current_wants = video_source_.sink_wants();
- video_source_.IncomingCapturedFrame(CreateFrame(
- ViEEncoder::kMaxCpuResolutionDowngrades + 1, frame_width, frame_height));
- sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuResolutionDowngrades + 1);
+ video_source_.IncomingCapturedFrame(
+ CreateFrame(kMaxDowngrades + 1, frame_width, frame_height));
+ sink_.WaitForEncodedFrame(kMaxDowngrades + 1);
vie_encoder_->TriggerCpuOveruse();
EXPECT_EQ(video_source_.sink_wants().target_pixel_count,
current_wants.target_pixel_count);
EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
current_wants.max_pixel_count);
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(kMaxDowngrades,
+ stats_proxy_->GetStats().number_of_cpu_adapt_changes);
// Trigger CPU normal use.
vie_encoder_->TriggerCpuNormalUsage();
@@ -768,6 +770,9 @@ TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
video_source_.sink_wants().target_pixel_count.value_or(0));
EXPECT_EQ(frame_width * frame_height * 4,
video_source_.sink_wants().max_pixel_count);
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(kMaxDowngrades + 1,
+ stats_proxy_->GetStats().number_of_cpu_adapt_changes);
vie_encoder_->Stop();
}
@@ -1408,19 +1413,197 @@ TEST_F(ViEEncoderTest, AdaptsResolutionForLowQuality_MaintainFramerateMode) {
vie_encoder_->Stop();
}
-TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) {
- int frame_width = 1280;
- int frame_height = 720;
+TEST_F(ViEEncoderTest, DoesNotScaleBelowSetResolutionLimit) {
+ const int kWidth = 1280;
+ const int kHeight = 720;
+ const size_t kNumFrames = 10;
+
vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
- for (size_t i = 1; i <= 10; i++) {
- video_source_.IncomingCapturedFrame(
- CreateFrame(i, frame_width, frame_height));
+ // Enable adapter, expected input resolutions when downscaling:
+ // 1280x720 -> 960x540 -> 640x360 -> 480x270 -> 320x180 (min resolution limit)
+ video_source_.set_adaptation_enabled(true);
+
+ EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ int downscales = 0;
+ for (size_t i = 1; i <= kNumFrames; i++) {
+ video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight));
sink_.WaitForEncodedFrame(i);
+
// Trigger scale down.
+ rtc::VideoSinkWants last_wants = video_source_.sink_wants();
vie_encoder_->TriggerQualityLow();
EXPECT_GE(video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame);
+
+ if (video_source_.sink_wants().max_pixel_count < last_wants.max_pixel_count)
+ ++downscales;
+
+ EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(downscales,
+ stats_proxy_->GetStats().number_of_quality_adapt_changes);
+ EXPECT_GT(downscales, 0);
}
+ vie_encoder_->Stop();
+}
+
+TEST_F(ViEEncoderTest,
+ AdaptsResolutionUpAndDownTwiceOnOveruse_MaintainFramerateMode) {
+ const int kWidth = 1280;
+ const int kHeight = 720;
+ vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+
+ // Enable kMaintainFramerate preference, no initial limitation.
+ AdaptingFrameForwarder source;
+ source.set_adaptation_enabled(true);
+ vie_encoder_->SetSource(
+ &source, VideoSendStream::DegradationPreference::kMaintainFramerate);
+
+ source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(1);
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+
+ // Trigger adapt down, expect scaled down resolution.
+ vie_encoder_->TriggerCpuOveruse();
+ source.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(2);
+ VerifyResolutionLimitationLessThan(source.sink_wants(), kWidth * kHeight);
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+
+ // Trigger adapt up, expect no restriction.
+ vie_encoder_->TriggerCpuNormalUsage();
+ source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(3);
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+
+ // Trigger adapt down, expect scaled down resolution.
+ vie_encoder_->TriggerCpuOveruse();
+ source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(4);
+ VerifyResolutionLimitationLessThan(source.sink_wants(), kWidth * kHeight);
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+
+ // Trigger adapt up, expect no restriction.
+ vie_encoder_->TriggerCpuNormalUsage();
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+
+ vie_encoder_->Stop();
+}
+
+TEST_F(ViEEncoderTest,
+ AdaptsResolutionOnOveruseAndLowQuality_MaintainFramerateMode) {
+ const int kWidth = 1280;
+ const int kHeight = 720;
+ vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+
+ // Enable kMaintainFramerate preference, no initial limitation.
+ AdaptingFrameForwarder source;
+ source.set_adaptation_enabled(true);
+ vie_encoder_->SetSource(
+ &source, VideoSendStream::DegradationPreference::kMaintainFramerate);
+
+ source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(kWidth, kHeight);
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger cpu adapt down, expect scaled down resolution (960x540).
+ vie_encoder_->TriggerCpuOveruse();
+ source.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(2);
+ VerifyResolutionLimitationLessThan(source.sink_wants(), kWidth * kHeight);
+ rtc::VideoSinkWants last_wants = source.sink_wants();
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger cpu adapt down, expect scaled down resolution (640x360).
+ vie_encoder_->TriggerCpuOveruse();
+ source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(3);
+ EXPECT_LT(source.sink_wants().max_pixel_count, last_wants.max_pixel_count);
+ last_wants = source.sink_wants();
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger cpu adapt down, max cpu downgrades reached, expect no change.
+ vie_encoder_->TriggerCpuOveruse();
+ source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(4);
+ EXPECT_EQ(last_wants.max_pixel_count, source.sink_wants().max_pixel_count);
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger quality adapt down, expect scaled down resolution (480x270).
+ vie_encoder_->TriggerQualityLow();
+ source.IncomingCapturedFrame(CreateFrame(5, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(5);
+ EXPECT_LT(source.sink_wants().max_pixel_count, last_wants.max_pixel_count);
+ last_wants = source.sink_wants();
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger cpu adapt up, expect upscaled resolution (640x360).
+ vie_encoder_->TriggerCpuNormalUsage();
+ source.IncomingCapturedFrame(CreateFrame(6, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(6);
+ EXPECT_GT(source.sink_wants().max_pixel_count, last_wants.max_pixel_count);
+ last_wants = source.sink_wants();
+ EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger cpu adapt up, expect upscaled resolution (960x540).
+ vie_encoder_->TriggerCpuNormalUsage();
+ source.IncomingCapturedFrame(CreateFrame(7, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(7);
+ EXPECT_GT(source.sink_wants().max_pixel_count, last_wants.max_pixel_count);
+ last_wants = source.sink_wants();
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger cpu adapt up, no cpu downgrades, expect no change (960x540).
+ vie_encoder_->TriggerCpuNormalUsage();
+ source.IncomingCapturedFrame(CreateFrame(8, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(8);
+ EXPECT_EQ(last_wants.max_pixel_count, source.sink_wants().max_pixel_count);
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
+
+ // Trigger quality adapt up, expect no restriction (1280x720).
+ vie_encoder_->TriggerQualityHigh();
+ source.IncomingCapturedFrame(CreateFrame(9, kWidth, kHeight));
+ sink_.WaitForEncodedFrame(kWidth, kHeight);
+ EXPECT_GT(source.sink_wants().max_pixel_count, last_wants.max_pixel_count);
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
+ EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+ EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
vie_encoder_->Stop();
}
@@ -1582,6 +1765,30 @@ TEST_F(ViEEncoderTest, InitialFrameDropOffWhenEncoderDisabledScaling) {
fake_encoder_.SetQualityScaling(true);
}
+TEST_F(ViEEncoderTest,
+ ResolutionNotAdaptedForTooSmallFrame_MaintainFramerateMode) {
+ const int kTooSmallWidth = 10;
+ const int kTooSmallHeight = 10;
+ vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
+
+ // Enable kMaintainFramerate preference, no initial limitation.
+ test::FrameForwarder source;
+ vie_encoder_->SetSource(
+ &source, VideoSendStream::DegradationPreference::kMaintainFramerate);
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+
+ // Trigger adapt down, too small frame, expect no change.
+ source.IncomingCapturedFrame(CreateFrame(1, kTooSmallWidth, kTooSmallHeight));
+ sink_.WaitForEncodedFrame(1);
+ vie_encoder_->TriggerCpuOveruse();
+ VerifyNoLimitation(source.sink_wants());
+ EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
+ EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
+
+ vie_encoder_->Stop();
+}
+
TEST_F(ViEEncoderTest, FailingInitEncodeDoesntCauseCrash) {
fake_encoder_.ForceInitEncodeFailure(true);
vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
@@ -1595,7 +1802,7 @@ TEST_F(ViEEncoderTest, FailingInitEncodeDoesntCauseCrash) {
}
// TODO(sprang): Extend this with fps throttling and any "balanced" extensions.
-TEST_F(ViEEncoderTest, AdaptsResolutionOnOveruse) {
+TEST_F(ViEEncoderTest, AdaptsResolutionOnOveruse_MaintainFramerateMode) {
vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
const int kFrameWidth = 1280;
« no previous file with comments | « webrtc/video/vie_encoder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698