diff --git a/webrtc/test/fake_encoder.cc b/webrtc/test/fake_encoder.cc index 0573c8af6d..41d0ea3c58 100644 --- a/webrtc/test/fake_encoder.cc +++ b/webrtc/test/fake_encoder.cc @@ -13,6 +13,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" +#include "webrtc/system_wrappers/interface/sleep.h" namespace webrtc { namespace test { @@ -180,5 +181,16 @@ int32_t FakeH264Encoder::Encoded(EncodedImage& encoded_image, } return callback_->Encoded(encoded_image, NULL, &fragmentation); } + +DelayedEncoder::DelayedEncoder(Clock* clock, int delay_ms) + : test::FakeEncoder(clock), + delay_ms_(delay_ms) {} + +int32_t DelayedEncoder::Encode(const I420VideoFrame& input_image, + const CodecSpecificInfo* codec_specific_info, + const std::vector* frame_types) { + SleepMs(delay_ms_); + return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); +} } // namespace test } // namespace webrtc diff --git a/webrtc/test/fake_encoder.h b/webrtc/test/fake_encoder.h index 50b86520e1..01b83f012d 100644 --- a/webrtc/test/fake_encoder.h +++ b/webrtc/test/fake_encoder.h @@ -69,6 +69,20 @@ class FakeH264Encoder : public FakeEncoder, public EncodedImageCallback { EncodedImageCallback* callback_; int idr_counter_; }; + +class DelayedEncoder : public test::FakeEncoder { + public: + DelayedEncoder(Clock* clock, int delay_ms); + virtual ~DelayedEncoder() {} + + virtual int32_t Encode( + const I420VideoFrame& input_image, + const CodecSpecificInfo* codec_specific_info, + const std::vector* frame_types) OVERRIDE; + + private: + const int delay_ms_; +}; } // namespace test } // namespace webrtc diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc index 9194b088dc..a93c072459 100644 --- a/webrtc/video/call_perf_tests.cc +++ b/webrtc/video/call_perf_tests.cc @@ -47,6 +47,8 @@ class CallPerfTest : public test::CallTest { protected: void TestAudioVideoSync(bool fec); + void TestCpuOveruse(LoadObserver::Load tested_load, int encode_delay_ms); + void TestMinTransmitBitrate(bool pad_to_min_bitrate); void TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config, @@ -449,14 +451,18 @@ TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) { TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs); } -TEST_F(CallPerfTest, RegisterCpuOveruseObserver) { - // Verifies that either a normal or overuse callback is triggered. +void CallPerfTest::TestCpuOveruse(LoadObserver::Load tested_load, + int encode_delay_ms) { class LoadObserver : public test::SendTest, public webrtc::LoadObserver { public: - LoadObserver() : SendTest(kLongTimeoutMs) {} + LoadObserver(LoadObserver::Load tested_load, int encode_delay_ms) + : SendTest(kLongTimeoutMs), + tested_load_(tested_load), + encoder_(Clock::GetRealTimeClock(), encode_delay_ms) {} virtual void OnLoadUpdate(Load load) OVERRIDE { - observation_complete_->Set(); + if (load == tested_load_) + observation_complete_->Set(); } virtual Call::Config GetSenderCallConfig() OVERRIDE { @@ -465,15 +471,35 @@ TEST_F(CallPerfTest, RegisterCpuOveruseObserver) { return config; } + virtual void ModifyConfigs( + VideoSendStream::Config* send_config, + std::vector* receive_configs, + VideoEncoderConfig* encoder_config) OVERRIDE { + send_config->encoder_settings.encoder = &encoder_; + } + virtual void PerformTest() OVERRIDE { EXPECT_EQ(kEventSignaled, Wait()) << "Timed out before receiving an overuse callback."; } - } test; + + LoadObserver::Load tested_load_; + test::DelayedEncoder encoder_; + } test(tested_load, encode_delay_ms); RunBaseTest(&test); } +TEST_F(CallPerfTest, ReceivesCpuUnderuse) { + const int kEncodeDelayMs = 2; + TestCpuOveruse(LoadObserver::kUnderuse, kEncodeDelayMs); +} + +TEST_F(CallPerfTest, ReceivesCpuOveruse) { + const int kEncodeDelayMs = 35; + TestCpuOveruse(LoadObserver::kOveruse, kEncodeDelayMs); +} + void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { static const int kMaxEncodeBitrateKbps = 30; static const int kMinTransmitBitrateBps = 150000; diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc index 8aae7031c1..bbfd3822aa 100644 --- a/webrtc/video/video_send_stream_tests.cc +++ b/webrtc/video/video_send_stream_tests.cc @@ -168,10 +168,12 @@ TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { static const uint8_t kTOffsetExtensionId = 13; + static const int kEncodeDelayMs = 5; class TransmissionTimeOffsetObserver : public test::SendTest { public: TransmissionTimeOffsetObserver() - : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) { + : SendTest(kDefaultTimeoutMs), + encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) { EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId)); } @@ -204,22 +206,7 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { << "Timed out while waiting for a single RTP packet."; } - class DelayedEncoder : public test::FakeEncoder { - public: - explicit DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {} - virtual int32_t Encode( - const I420VideoFrame& input_image, - const CodecSpecificInfo* codec_specific_info, - const std::vector* frame_types) OVERRIDE { - // A delay needs to be introduced to assure that we get a timestamp - // offset. - SleepMs(5); - return FakeEncoder::Encode( - input_image, codec_specific_info, frame_types); - } - }; - - DelayedEncoder encoder_; + test::DelayedEncoder encoder_; } test; RunBaseTest(&test); diff --git a/webrtc/video_engine/include/vie_base.h b/webrtc/video_engine/include/vie_base.h index ae80cd7823..04e23de158 100644 --- a/webrtc/video_engine/include/vie_base.h +++ b/webrtc/video_engine/include/vie_base.h @@ -41,12 +41,12 @@ class CpuOveruseObserver { struct CpuOveruseOptions { CpuOveruseOptions() - : enable_capture_jitter_method(true), + : enable_capture_jitter_method(false), low_capture_jitter_threshold_ms(20.0f), high_capture_jitter_threshold_ms(30.0f), - enable_encode_usage_method(false), - low_encode_usage_threshold_percent(60), - high_encode_usage_threshold_percent(90), + enable_encode_usage_method(true), + low_encode_usage_threshold_percent(55), + high_encode_usage_threshold_percent(85), low_encode_time_rsd_threshold(-1), high_encode_time_rsd_threshold(-1), enable_extended_processing_usage(true), diff --git a/webrtc/video_engine/overuse_frame_detector_unittest.cc b/webrtc/video_engine/overuse_frame_detector_unittest.cc index e2361695b3..84f0e0462e 100644 --- a/webrtc/video_engine/overuse_frame_detector_unittest.cc +++ b/webrtc/video_engine/overuse_frame_detector_unittest.cc @@ -152,12 +152,20 @@ class OveruseFrameDetectorTest : public ::testing::Test { // CaptureJitterMs() > high_capture_jitter_threshold_ms => overuse. // CaptureJitterMs() < low_capture_jitter_threshold_ms => underuse. TEST_F(OveruseFrameDetectorTest, TriggerOveruse) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; + overuse_detector_->SetOptions(options_); // capture_jitter > high => overuse EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); TriggerOveruse(options_.high_threshold_consecutive_count); } TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; + overuse_detector_->SetOptions(options_); // capture_jitter > high => overuse EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); TriggerOveruse(options_.high_threshold_consecutive_count); @@ -167,6 +175,10 @@ TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { } TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; + overuse_detector_->SetOptions(options_); overuse_detector_->SetObserver(NULL); EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); TriggerOveruse(options_.high_threshold_consecutive_count); @@ -177,6 +189,7 @@ TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithMethodDisabled) { options_.enable_capture_jitter_method = false; options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; overuse_detector_->SetOptions(options_); EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); TriggerOveruse(options_.high_threshold_consecutive_count); @@ -185,6 +198,10 @@ TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithMethodDisabled) { } TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; + overuse_detector_->SetOptions(options_); EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2); TriggerOveruse(options_.high_threshold_consecutive_count); TriggerOveruse(options_.high_threshold_consecutive_count); @@ -193,6 +210,9 @@ TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { } TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; CpuOveruseObserverImpl overuse_observer_; overuse_detector_->SetObserver(&overuse_observer_); options_.min_process_count = 1; @@ -206,6 +226,10 @@ TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { } TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; + overuse_detector_->SetOptions(options_); EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64); for(size_t i = 0; i < 64; ++i) { @@ -214,6 +238,9 @@ TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { } TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); options_.high_threshold_consecutive_count = 2; overuse_detector_->SetOptions(options_); @@ -221,6 +248,9 @@ TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) { } TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) { + options_.enable_capture_jitter_method = true; + options_.enable_encode_usage_method = false; + options_.enable_extended_processing_usage = false; EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); options_.high_threshold_consecutive_count = 2; overuse_detector_->SetOptions(options_);