/* * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include #include #include "api/rtp_parameters.h" #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" #include "api/video_codecs/video_encoder_config.h" #include "call/video_receive_stream.h" #include "call/video_send_stream.h" #include "rtc_base/checks.h" #include "rtc_base/event.h" #include "test/call_test.h" #include "test/field_trial.h" #include "test/frame_generator_capturer.h" #include "test/gtest.h" namespace webrtc { namespace { constexpr int kWidth = 1280; constexpr int kHeight = 720; constexpr int kFps = 28; } // namespace // Minimal normal usage at start, then 60s overuse. class CpuOveruseTest : public test::CallTest { protected: CpuOveruseTest() : field_trials_("WebRTC-ForceSimulatedOveruseIntervalMs/1-60000-60000/") { } void RunTestAndCheckForAdaptation( const DegradationPreference& degradation_preference, bool expect_adaptation); test::ScopedFieldTrials field_trials_; }; void CpuOveruseTest::RunTestAndCheckForAdaptation( const DegradationPreference& degradation_preference, bool expect_adaptation) { class OveruseObserver : public test::SendTest, public test::FrameGeneratorCapturer::SinkWantsObserver { public: OveruseObserver(const DegradationPreference& degradation_preference, bool expect_adaptation) : SendTest(expect_adaptation ? kLongTimeoutMs : kDefaultTimeoutMs), degradation_preference_(degradation_preference), expect_adaptation_(expect_adaptation) {} private: void OnFrameGeneratorCapturerCreated( test::FrameGeneratorCapturer* frame_generator_capturer) override { frame_generator_capturer->SetSinkWantsObserver(this); // Set initial resolution. frame_generator_capturer->ChangeResolution(kWidth, kHeight); } // Called when FrameGeneratorCapturer::AddOrUpdateSink is called. void OnSinkWantsChanged(rtc::VideoSinkInterface* sink, const rtc::VideoSinkWants& wants) override { if (wants.max_pixel_count == std::numeric_limits::max() && wants.max_framerate_fps == kFps) { // Max configured framerate is initially set. return; } switch (degradation_preference_) { case DegradationPreference::MAINTAIN_FRAMERATE: EXPECT_LT(wants.max_pixel_count, kWidth * kHeight); observation_complete_.Set(); break; case DegradationPreference::MAINTAIN_RESOLUTION: EXPECT_LT(wants.max_framerate_fps, kFps); observation_complete_.Set(); break; case DegradationPreference::BALANCED: if (wants.max_pixel_count == std::numeric_limits::max() && wants.max_framerate_fps == std::numeric_limits::max()) { // `adapt_counters_` map in VideoStreamEncoder is reset when // balanced mode is set. break; } EXPECT_TRUE(wants.max_pixel_count < kWidth * kHeight || wants.max_framerate_fps < kFps); observation_complete_.Set(); break; default: RTC_DCHECK_NOTREACHED(); } } void ModifyVideoConfigs( VideoSendStream::Config* send_config, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { EXPECT_FALSE(encoder_config->simulcast_layers.empty()); encoder_config->simulcast_layers[0].max_framerate = kFps; } void ModifyVideoDegradationPreference( DegradationPreference* degradation_preference) override { *degradation_preference = degradation_preference_; } void PerformTest() override { EXPECT_EQ(expect_adaptation_, Wait()) << "Timed out while waiting for a scale down."; } const DegradationPreference degradation_preference_; const bool expect_adaptation_; } test(degradation_preference, expect_adaptation); RunBaseTest(&test); } TEST_F(CpuOveruseTest, AdaptsDownInResolutionOnOveruse) { RunTestAndCheckForAdaptation(DegradationPreference::MAINTAIN_FRAMERATE, true); } TEST_F(CpuOveruseTest, AdaptsDownInFpsOnOveruse) { RunTestAndCheckForAdaptation(DegradationPreference::MAINTAIN_RESOLUTION, true); } TEST_F(CpuOveruseTest, AdaptsDownInResolutionOrFpsOnOveruse) { RunTestAndCheckForAdaptation(DegradationPreference::BALANCED, true); } TEST_F(CpuOveruseTest, NoAdaptDownOnOveruse) { RunTestAndCheckForAdaptation(DegradationPreference::DISABLED, false); } } // namespace webrtc