| 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
|
|
|