Index: webrtc/video/overuse_frame_detector_unittest.cc |
diff --git a/webrtc/video/overuse_frame_detector_unittest.cc b/webrtc/video/overuse_frame_detector_unittest.cc |
index 65e006b485411c796bfafe0a17c7083038037aad..1a6384ca8a8114281b5275cf4e1e7f8af992d480 100644 |
--- a/webrtc/video/overuse_frame_detector_unittest.cc |
+++ b/webrtc/video/overuse_frame_detector_unittest.cc |
@@ -15,6 +15,7 @@ |
#include "webrtc/base/scoped_ptr.h" |
#include "webrtc/system_wrappers/include/clock.h" |
+#include "webrtc/video_frame.h" |
namespace webrtc { |
namespace { |
@@ -59,11 +60,12 @@ class OveruseFrameDetectorTest : public ::testing::Test, |
} |
void ReinitializeOveruseDetector() { |
- overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_, |
- observer_.get(), this)); |
+ overuse_detector_.reset(new OveruseFrameDetector( |
+ clock_.get(), options_, observer_.get(), nullptr, this)); |
} |
- void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override { |
+ void OnEncodedFrameTimeMeasured(int encode_time_ms, |
+ const CpuOveruseMetrics& metrics) override { |
metrics_ = metrics; |
} |
@@ -72,17 +74,31 @@ class OveruseFrameDetectorTest : public ::testing::Test, |
options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5; |
} |
- void InsertAndSendFramesWithInterval( |
- int num_frames, int interval_ms, int width, int height, int delay_ms) { |
+ void InsertAndSendFramesWithInterval(int num_frames, |
+ int interval_ms, |
+ int width, |
+ int height, |
+ int delay_ms) { |
+ VideoFrame frame; |
+ frame.CreateEmptyFrame(width, height, width, width / 2, width / 2); |
+ uint32_t timestamp = 0; |
while (num_frames-- > 0) { |
- int64_t capture_time_ms = clock_->TimeInMilliseconds(); |
- overuse_detector_->FrameCaptured(width, height, capture_time_ms); |
+ frame.set_timestamp(timestamp); |
+ overuse_detector_->FrameCaptured(frame); |
clock_->AdvanceTimeMilliseconds(delay_ms); |
- overuse_detector_->FrameSent(capture_time_ms); |
+ overuse_detector_->FrameSent(timestamp); |
clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms); |
+ timestamp += interval_ms * 90; |
} |
} |
+ void ForceUpdate(int width, int height) { |
+ // Insert one frame, wait a second and then put in another to force update |
+ // the usage. From the tests where these are used, adding another sample |
+ // doesn't affect the expected outcome (this is mainly to check initial |
+ // values and whether the overuse detector has been reset or not). |
+ InsertAndSendFramesWithInterval(2, 1000, width, height, kFrameInterval33ms); |
+ } |
void TriggerOveruse(int num_times) { |
const int kDelayMs = 32; |
for (int i = 0; i < num_times; ++i) { |
@@ -131,7 +147,7 @@ TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { |
TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { |
overuse_detector_.reset( |
- new OveruseFrameDetector(clock_.get(), options_, nullptr, this)); |
+ new OveruseFrameDetector(clock_.get(), options_, nullptr, nullptr, this)); |
EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); |
TriggerOveruse(options_.high_threshold_consecutive_count); |
EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); |
@@ -149,8 +165,8 @@ TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { |
TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { |
options_.min_process_count = 1; |
CpuOveruseObserverImpl overuse_observer; |
- overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_, |
- &overuse_observer, this)); |
+ overuse_detector_.reset(new OveruseFrameDetector( |
+ clock_.get(), options_, &overuse_observer, nullptr, this)); |
InsertAndSendFramesWithInterval( |
1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); |
overuse_detector_->Process(); |
@@ -189,17 +205,18 @@ TEST_F(OveruseFrameDetectorTest, ProcessingUsage) { |
} |
TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) { |
+ ForceUpdate(kWidth, kHeight); |
EXPECT_EQ(InitialUsage(), UsagePercent()); |
InsertAndSendFramesWithInterval( |
1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); |
EXPECT_NE(InitialUsage(), UsagePercent()); |
- // Verify reset. |
- InsertAndSendFramesWithInterval( |
- 1, kFrameInterval33ms, kWidth, kHeight + 1, kProcessTime5ms); |
+ // Verify reset (with new width/height). |
+ ForceUpdate(kWidth, kHeight + 1); |
EXPECT_EQ(InitialUsage(), UsagePercent()); |
} |
TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) { |
+ ForceUpdate(kWidth, kHeight); |
EXPECT_EQ(InitialUsage(), UsagePercent()); |
InsertAndSendFramesWithInterval( |
1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); |
@@ -211,6 +228,7 @@ TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) { |
InsertAndSendFramesWithInterval( |
2, options_.frame_timeout_interval_ms + 1, kWidth, kHeight, |
kProcessTime5ms); |
+ ForceUpdate(kWidth, kHeight); |
EXPECT_EQ(InitialUsage(), UsagePercent()); |
} |
@@ -220,91 +238,65 @@ TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) { |
InsertAndSendFramesWithInterval( |
40, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); |
EXPECT_EQ(InitialUsage(), UsagePercent()); |
+ // Pass time far enough to digest all previous samples. |
+ clock_->AdvanceTimeMilliseconds(1000); |
+ InsertAndSendFramesWithInterval(1, kFrameInterval33ms, kWidth, kHeight, |
+ kProcessTime5ms); |
+ // The last sample has not been processed here. |
+ EXPECT_EQ(InitialUsage(), UsagePercent()); |
+ |
+ // Pass time far enough to digest all previous samples, 41 in total. |
+ clock_->AdvanceTimeMilliseconds(1000); |
InsertAndSendFramesWithInterval( |
1, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); |
EXPECT_NE(InitialUsage(), UsagePercent()); |
} |
TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) { |
+ ForceUpdate(kWidth, kHeight); |
EXPECT_EQ(InitialUsage(), UsagePercent()); |
} |
-TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrame) { |
- const int kProcessingTimeMs = 100; |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs()); |
- overuse_detector_->FrameSent(33); |
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs()); |
- EXPECT_EQ(0, overuse_detector_->FramesInQueue()); |
-} |
- |
-TEST_F(OveruseFrameDetectorTest, FrameDelay_TwoFrames) { |
- const int kProcessingTimeMs1 = 100; |
- const int kProcessingTimeMs2 = 50; |
- const int kTimeBetweenFramesMs = 200; |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs1); |
- overuse_detector_->FrameSent(33); |
- EXPECT_EQ(kProcessingTimeMs1, overuse_detector_->LastProcessingTimeMs()); |
- clock_->AdvanceTimeMilliseconds(kTimeBetweenFramesMs); |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 66); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs2); |
- overuse_detector_->FrameSent(66); |
- EXPECT_EQ(kProcessingTimeMs2, overuse_detector_->LastProcessingTimeMs()); |
-} |
- |
-TEST_F(OveruseFrameDetectorTest, FrameDelay_MaxQueueSize) { |
- const int kMaxQueueSize = 91; |
- for (int i = 0; i < kMaxQueueSize * 2; ++i) { |
- overuse_detector_->FrameCaptured(kWidth, kHeight, i); |
+TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) { |
+ EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(testing::AtLeast(1)); |
+ static const int kIntervalMs = 33; |
+ static const size_t kNumFramesEncodingDelay = 3; |
+ VideoFrame frame; |
+ frame.CreateEmptyFrame(kWidth, kHeight, kWidth, kWidth / 2, kWidth / 2); |
+ for (size_t i = 0; i < 1000; ++i) { |
+ // Unique timestamps. |
+ frame.set_timestamp(static_cast<uint32_t>(i)); |
+ overuse_detector_->FrameCaptured(frame); |
+ clock_->AdvanceTimeMilliseconds(kIntervalMs); |
+ if (i > kNumFramesEncodingDelay) { |
+ overuse_detector_->FrameSent( |
+ static_cast<uint32_t>(i - kNumFramesEncodingDelay)); |
+ } |
+ overuse_detector_->Process(); |
} |
- EXPECT_EQ(kMaxQueueSize, overuse_detector_->FramesInQueue()); |
-} |
- |
-TEST_F(OveruseFrameDetectorTest, FrameDelay_NonProcessedFramesRemoved) { |
- const int kProcessingTimeMs = 100; |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 35); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 66); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 99); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs()); |
- EXPECT_EQ(4, overuse_detector_->FramesInQueue()); |
- overuse_detector_->FrameSent(66); |
- // Frame 33, 35 removed, 66 processed, 99 not processed. |
- EXPECT_EQ(2 * kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs()); |
- EXPECT_EQ(1, overuse_detector_->FramesInQueue()); |
- overuse_detector_->FrameSent(99); |
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs()); |
- EXPECT_EQ(0, overuse_detector_->FramesInQueue()); |
} |
-TEST_F(OveruseFrameDetectorTest, FrameDelay_ResetClearsFrames) { |
- const int kProcessingTimeMs = 100; |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33); |
- EXPECT_EQ(1, overuse_detector_->FramesInQueue()); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- // Verify reset (resolution changed). |
- overuse_detector_->FrameCaptured(kWidth, kHeight + 1, 66); |
- EXPECT_EQ(1, overuse_detector_->FramesInQueue()); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- overuse_detector_->FrameSent(66); |
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs()); |
- EXPECT_EQ(0, overuse_detector_->FramesInQueue()); |
-} |
- |
-TEST_F(OveruseFrameDetectorTest, FrameDelay_NonMatchingSendFrameIgnored) { |
- const int kProcessingTimeMs = 100; |
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33); |
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs); |
- overuse_detector_->FrameSent(34); |
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs()); |
- overuse_detector_->FrameSent(33); |
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs()); |
+TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) { |
+ // >85% encoding time should trigger overuse. |
+ EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(testing::AtLeast(1)); |
+ static const int kIntervalMs = 33; |
+ static const int kDelayMs = 30; |
+ VideoFrame frame; |
+ frame.CreateEmptyFrame(kWidth, kHeight, kWidth, kWidth / 2, kWidth / 2); |
+ uint32_t timestamp = 0; |
+ for (size_t i = 0; i < 1000; ++i) { |
+ frame.set_timestamp(timestamp); |
+ overuse_detector_->FrameCaptured(frame); |
+ // Encode and send first parts almost instantly. |
+ clock_->AdvanceTimeMilliseconds(1); |
+ overuse_detector_->FrameSent(timestamp); |
+ // Encode heavier part, resulting in >85% usage total. |
+ clock_->AdvanceTimeMilliseconds(kDelayMs - 1); |
+ overuse_detector_->FrameSent(timestamp); |
+ clock_->AdvanceTimeMilliseconds(kIntervalMs - kDelayMs); |
+ timestamp += kIntervalMs * 90; |
+ overuse_detector_->Process(); |
+ } |
} |
} // namespace webrtc |