| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "webrtc/api/video/i420_buffer.h" | 15 #include "webrtc/api/video/i420_buffer.h" |
| 16 #include "webrtc/base/fakeclock.h" | |
| 17 #include "webrtc/base/logging.h" | 16 #include "webrtc/base/logging.h" |
| 18 #include "webrtc/media/base/videoadapter.h" | 17 #include "webrtc/media/base/videoadapter.h" |
| 19 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 18 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
| 20 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h" | 19 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h" |
| 21 #include "webrtc/system_wrappers/include/metrics_default.h" | 20 #include "webrtc/system_wrappers/include/metrics_default.h" |
| 22 #include "webrtc/system_wrappers/include/sleep.h" | 21 #include "webrtc/system_wrappers/include/sleep.h" |
| 23 #include "webrtc/test/encoder_settings.h" | 22 #include "webrtc/test/encoder_settings.h" |
| 24 #include "webrtc/test/fake_encoder.h" | 23 #include "webrtc/test/fake_encoder.h" |
| 25 #include "webrtc/test/frame_generator.h" | 24 #include "webrtc/test/frame_generator.h" |
| 26 #include "webrtc/test/gmock.h" | 25 #include "webrtc/test/gmock.h" |
| 27 #include "webrtc/test/gtest.h" | 26 #include "webrtc/test/gtest.h" |
| 28 #include "webrtc/video/send_statistics_proxy.h" | 27 #include "webrtc/video/send_statistics_proxy.h" |
| 29 #include "webrtc/video/vie_encoder.h" | 28 #include "webrtc/video/vie_encoder.h" |
| 30 | 29 |
| 31 namespace { | 30 namespace { |
| 32 #if defined(WEBRTC_ANDROID) | 31 #if defined(WEBRTC_ANDROID) |
| 33 // TODO(kthelgason): Lower this limit when better testing | 32 // TODO(kthelgason): Lower this limit when better testing |
| 34 // on MediaCodec and fallback implementations are in place. | 33 // on MediaCodec and fallback implementations are in place. |
| 35 const int kMinPixelsPerFrame = 320 * 180; | 34 const int kMinPixelsPerFrame = 320 * 180; |
| 36 #else | 35 #else |
| 37 const int kMinPixelsPerFrame = 120 * 90; | 36 const int kMinPixelsPerFrame = 120 * 90; |
| 38 #endif | 37 #endif |
| 39 const int kMinFramerateFps = 2; | 38 } |
| 40 const int64_t kFrameTimeoutMs = 100; | |
| 41 } // namespace | |
| 42 | 39 |
| 43 namespace webrtc { | 40 namespace webrtc { |
| 44 | 41 |
| 45 using DegredationPreference = VideoSendStream::DegradationPreference; | 42 using DegredationPreference = VideoSendStream::DegradationPreference; |
| 46 using ScaleReason = AdaptationObserverInterface::AdaptReason; | 43 using ScaleReason = AdaptationObserverInterface::AdaptReason; |
| 47 using ::testing::_; | 44 using ::testing::_; |
| 48 using ::testing::Return; | 45 using ::testing::Return; |
| 49 | 46 |
| 50 namespace { | 47 namespace { |
| 51 const size_t kMaxPayloadLength = 1440; | 48 const size_t kMaxPayloadLength = 1440; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 bool adaption_enabled() { | 138 bool adaption_enabled() { |
| 142 rtc::CritScope cs(&crit_); | 139 rtc::CritScope cs(&crit_); |
| 143 return adaptation_enabled_; | 140 return adaptation_enabled_; |
| 144 } | 141 } |
| 145 | 142 |
| 146 void IncomingCapturedFrame(const VideoFrame& video_frame) override { | 143 void IncomingCapturedFrame(const VideoFrame& video_frame) override { |
| 147 int cropped_width = 0; | 144 int cropped_width = 0; |
| 148 int cropped_height = 0; | 145 int cropped_height = 0; |
| 149 int out_width = 0; | 146 int out_width = 0; |
| 150 int out_height = 0; | 147 int out_height = 0; |
| 151 if (adaption_enabled()) { | 148 if (adaption_enabled() && |
| 152 if (adapter_.AdaptFrameResolution( | 149 adapter_.AdaptFrameResolution(video_frame.width(), video_frame.height(), |
| 153 video_frame.width(), video_frame.height(), | 150 video_frame.timestamp_us() * 1000, |
| 154 video_frame.timestamp_us() * 1000, &cropped_width, | 151 &cropped_width, &cropped_height, |
| 155 &cropped_height, &out_width, &out_height)) { | 152 &out_width, &out_height)) { |
| 156 VideoFrame adapted_frame(new rtc::RefCountedObject<TestBuffer>( | 153 VideoFrame adapted_frame( |
| 157 nullptr, out_width, out_height), | 154 new rtc::RefCountedObject<TestBuffer>(nullptr, out_width, out_height), |
| 158 99, 99, kVideoRotation_0); | 155 99, 99, kVideoRotation_0); |
| 159 adapted_frame.set_ntp_time_ms(video_frame.ntp_time_ms()); | 156 adapted_frame.set_ntp_time_ms(video_frame.ntp_time_ms()); |
| 160 test::FrameForwarder::IncomingCapturedFrame(adapted_frame); | 157 test::FrameForwarder::IncomingCapturedFrame(adapted_frame); |
| 161 } | |
| 162 } else { | 158 } else { |
| 163 test::FrameForwarder::IncomingCapturedFrame(video_frame); | 159 test::FrameForwarder::IncomingCapturedFrame(video_frame); |
| 164 } | 160 } |
| 165 } | 161 } |
| 166 | 162 |
| 167 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink, | 163 void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink, |
| 168 const rtc::VideoSinkWants& wants) override { | 164 const rtc::VideoSinkWants& wants) override { |
| 169 rtc::CritScope cs(&crit_); | 165 rtc::CritScope cs(&crit_); |
| 170 adapter_.OnResolutionFramerateRequest(wants.target_pixel_count, | 166 adapter_.OnResolutionRequest(wants.target_pixel_count, |
| 171 wants.max_pixel_count, | 167 wants.max_pixel_count); |
| 172 wants.max_framerate_fps); | |
| 173 test::FrameForwarder::AddOrUpdateSink(sink, wants); | 168 test::FrameForwarder::AddOrUpdateSink(sink, wants); |
| 174 } | 169 } |
| 175 | 170 |
| 176 cricket::VideoAdapter adapter_; | 171 cricket::VideoAdapter adapter_; |
| 177 bool adaptation_enabled_ GUARDED_BY(crit_); | 172 bool adaptation_enabled_ GUARDED_BY(crit_); |
| 178 }; | 173 }; |
| 179 | |
| 180 class MockableSendStatisticsProxy : public SendStatisticsProxy { | |
| 181 public: | |
| 182 MockableSendStatisticsProxy(Clock* clock, | |
| 183 const VideoSendStream::Config& config, | |
| 184 VideoEncoderConfig::ContentType content_type) | |
| 185 : SendStatisticsProxy(clock, config, content_type) {} | |
| 186 | |
| 187 VideoSendStream::Stats GetStats() override { | |
| 188 rtc::CritScope cs(&lock_); | |
| 189 if (mock_stats_) | |
| 190 return *mock_stats_; | |
| 191 return SendStatisticsProxy::GetStats(); | |
| 192 } | |
| 193 | |
| 194 void SetMockStats(const VideoSendStream::Stats& stats) { | |
| 195 rtc::CritScope cs(&lock_); | |
| 196 mock_stats_.emplace(stats); | |
| 197 } | |
| 198 | |
| 199 void ResetMockStats() { | |
| 200 rtc::CritScope cs(&lock_); | |
| 201 mock_stats_.reset(); | |
| 202 } | |
| 203 | |
| 204 private: | |
| 205 rtc::CriticalSection lock_; | |
| 206 rtc::Optional<VideoSendStream::Stats> mock_stats_ GUARDED_BY(lock_); | |
| 207 }; | |
| 208 | |
| 209 } // namespace | 174 } // namespace |
| 210 | 175 |
| 211 class ViEEncoderTest : public ::testing::Test { | 176 class ViEEncoderTest : public ::testing::Test { |
| 212 public: | 177 public: |
| 213 static const int kDefaultTimeoutMs = 30 * 1000; | 178 static const int kDefaultTimeoutMs = 30 * 1000; |
| 214 | 179 |
| 215 ViEEncoderTest() | 180 ViEEncoderTest() |
| 216 : video_send_config_(VideoSendStream::Config(nullptr)), | 181 : video_send_config_(VideoSendStream::Config(nullptr)), |
| 217 codec_width_(320), | 182 codec_width_(320), |
| 218 codec_height_(240), | 183 codec_height_(240), |
| 219 fake_encoder_(), | 184 fake_encoder_(), |
| 220 stats_proxy_(new MockableSendStatisticsProxy( | 185 stats_proxy_(new SendStatisticsProxy( |
| 221 Clock::GetRealTimeClock(), | 186 Clock::GetRealTimeClock(), |
| 222 video_send_config_, | 187 video_send_config_, |
| 223 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)), | 188 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)), |
| 224 sink_(&fake_encoder_) {} | 189 sink_(&fake_encoder_) {} |
| 225 | 190 |
| 226 void SetUp() override { | 191 void SetUp() override { |
| 227 metrics::Reset(); | 192 metrics::Reset(); |
| 228 video_send_config_ = VideoSendStream::Config(nullptr); | 193 video_send_config_ = VideoSendStream::Config(nullptr); |
| 229 video_send_config_.encoder_settings.encoder = &fake_encoder_; | 194 video_send_config_.encoder_settings.encoder = &fake_encoder_; |
| 230 video_send_config_.encoder_settings.payload_name = "FAKE"; | 195 video_send_config_.encoder_settings.payload_name = "FAKE"; |
| 231 video_send_config_.encoder_settings.payload_type = 125; | 196 video_send_config_.encoder_settings.payload_type = 125; |
| 232 | 197 |
| 233 VideoEncoderConfig video_encoder_config; | 198 VideoEncoderConfig video_encoder_config; |
| 234 test::FillEncoderConfiguration(1, &video_encoder_config); | 199 test::FillEncoderConfiguration(1, &video_encoder_config); |
| 235 video_encoder_config_ = video_encoder_config.Copy(); | 200 video_encoder_config_ = video_encoder_config.Copy(); |
| 236 ConfigureEncoder(std::move(video_encoder_config), true /* nack_enabled */); | 201 ConfigureEncoder(std::move(video_encoder_config), true /* nack_enabled */); |
| 237 } | 202 } |
| 238 | 203 |
| 239 void ConfigureEncoder(VideoEncoderConfig video_encoder_config, | 204 void ConfigureEncoder(VideoEncoderConfig video_encoder_config, |
| 240 bool nack_enabled) { | 205 bool nack_enabled) { |
| 241 if (vie_encoder_) | 206 if (vie_encoder_) |
| 242 vie_encoder_->Stop(); | 207 vie_encoder_->Stop(); |
| 243 vie_encoder_.reset(new ViEEncoderUnderTest( | 208 vie_encoder_.reset(new ViEEncoderUnderTest( |
| 244 stats_proxy_.get(), video_send_config_.encoder_settings)); | 209 stats_proxy_.get(), video_send_config_.encoder_settings)); |
| 245 vie_encoder_->SetSink(&sink_, false /* rotation_applied */); | 210 vie_encoder_->SetSink(&sink_, false /* rotation_applied */); |
| 246 vie_encoder_->SetSource( | 211 vie_encoder_->SetSource(&video_source_, |
| 247 &video_source_, | 212 VideoSendStream::DegradationPreference::kBalanced); |
| 248 VideoSendStream::DegradationPreference::kMaintainFramerate); | |
| 249 vie_encoder_->SetStartBitrate(kTargetBitrateBps); | 213 vie_encoder_->SetStartBitrate(kTargetBitrateBps); |
| 250 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), | 214 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), |
| 251 kMaxPayloadLength, nack_enabled); | 215 kMaxPayloadLength, nack_enabled); |
| 252 vie_encoder_->WaitUntilTaskQueueIsIdle(); | 216 vie_encoder_->WaitUntilTaskQueueIsIdle(); |
| 253 } | 217 } |
| 254 | 218 |
| 255 void ResetEncoder(const std::string& payload_name, | 219 void ResetEncoder(const std::string& payload_name, |
| 256 size_t num_streams, | 220 size_t num_streams, |
| 257 size_t num_temporal_layers, | 221 size_t num_temporal_layers, |
| 258 bool nack_enabled) { | 222 bool nack_enabled) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 273 99, 99, kVideoRotation_0); | 237 99, 99, kVideoRotation_0); |
| 274 frame.set_ntp_time_ms(ntp_time_ms); | 238 frame.set_ntp_time_ms(ntp_time_ms); |
| 275 return frame; | 239 return frame; |
| 276 } | 240 } |
| 277 | 241 |
| 278 VideoFrame CreateFrame(int64_t ntp_time_ms, int width, int height) const { | 242 VideoFrame CreateFrame(int64_t ntp_time_ms, int width, int height) const { |
| 279 VideoFrame frame( | 243 VideoFrame frame( |
| 280 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99, | 244 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99, |
| 281 kVideoRotation_0); | 245 kVideoRotation_0); |
| 282 frame.set_ntp_time_ms(ntp_time_ms); | 246 frame.set_ntp_time_ms(ntp_time_ms); |
| 283 frame.set_timestamp_us(ntp_time_ms * 1000); | |
| 284 return frame; | 247 return frame; |
| 285 } | 248 } |
| 286 | 249 |
| 287 class TestEncoder : public test::FakeEncoder { | 250 class TestEncoder : public test::FakeEncoder { |
| 288 public: | 251 public: |
| 289 TestEncoder() | 252 TestEncoder() |
| 290 : FakeEncoder(Clock::GetRealTimeClock()), | 253 : FakeEncoder(Clock::GetRealTimeClock()), |
| 291 continue_encode_event_(false, false) {} | 254 continue_encode_event_(false, false) {} |
| 292 | 255 |
| 293 VideoCodec codec_config() { | 256 VideoCodec codec_config() { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); | 359 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); |
| 397 { | 360 { |
| 398 rtc::CritScope lock(&crit_); | 361 rtc::CritScope lock(&crit_); |
| 399 timestamp = last_timestamp_; | 362 timestamp = last_timestamp_; |
| 400 } | 363 } |
| 401 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp); | 364 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp); |
| 402 } | 365 } |
| 403 | 366 |
| 404 void WaitForEncodedFrame(uint32_t expected_width, | 367 void WaitForEncodedFrame(uint32_t expected_width, |
| 405 uint32_t expected_height) { | 368 uint32_t expected_height) { |
| 406 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); | |
| 407 CheckLastFrameSizeMathces(expected_width, expected_height); | |
| 408 } | |
| 409 | |
| 410 void CheckLastFrameSizeMathces(uint32_t expected_width, | |
| 411 uint32_t expected_height) { | |
| 412 uint32_t width = 0; | 369 uint32_t width = 0; |
| 413 uint32_t height = 0; | 370 uint32_t height = 0; |
| 371 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); |
| 414 { | 372 { |
| 415 rtc::CritScope lock(&crit_); | 373 rtc::CritScope lock(&crit_); |
| 416 width = last_width_; | 374 width = last_width_; |
| 417 height = last_height_; | 375 height = last_height_; |
| 418 } | 376 } |
| 419 EXPECT_EQ(expected_height, height); | 377 EXPECT_EQ(expected_height, height); |
| 420 EXPECT_EQ(expected_width, width); | 378 EXPECT_EQ(expected_width, width); |
| 421 } | 379 } |
| 422 | 380 |
| 423 void ExpectDroppedFrame() { EXPECT_FALSE(encoded_frame_event_.Wait(100)); } | 381 void ExpectDroppedFrame() { EXPECT_FALSE(encoded_frame_event_.Wait(100)); } |
| 424 | 382 |
| 425 bool WaitForFrame(int64_t timeout_ms) { | |
| 426 return encoded_frame_event_.Wait(timeout_ms); | |
| 427 } | |
| 428 | |
| 429 void SetExpectNoFrames() { | 383 void SetExpectNoFrames() { |
| 430 rtc::CritScope lock(&crit_); | 384 rtc::CritScope lock(&crit_); |
| 431 expect_frames_ = false; | 385 expect_frames_ = false; |
| 432 } | 386 } |
| 433 | 387 |
| 434 int number_of_reconfigurations() { | 388 int number_of_reconfigurations() { |
| 435 rtc::CritScope lock(&crit_); | 389 rtc::CritScope lock(&crit_); |
| 436 return number_of_reconfigurations_; | 390 return number_of_reconfigurations_; |
| 437 } | 391 } |
| 438 | 392 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 bool expect_frames_ = true; | 425 bool expect_frames_ = true; |
| 472 int number_of_reconfigurations_ = 0; | 426 int number_of_reconfigurations_ = 0; |
| 473 int min_transmit_bitrate_bps_ = 0; | 427 int min_transmit_bitrate_bps_ = 0; |
| 474 }; | 428 }; |
| 475 | 429 |
| 476 VideoSendStream::Config video_send_config_; | 430 VideoSendStream::Config video_send_config_; |
| 477 VideoEncoderConfig video_encoder_config_; | 431 VideoEncoderConfig video_encoder_config_; |
| 478 int codec_width_; | 432 int codec_width_; |
| 479 int codec_height_; | 433 int codec_height_; |
| 480 TestEncoder fake_encoder_; | 434 TestEncoder fake_encoder_; |
| 481 std::unique_ptr<MockableSendStatisticsProxy> stats_proxy_; | 435 std::unique_ptr<SendStatisticsProxy> stats_proxy_; |
| 482 TestSink sink_; | 436 TestSink sink_; |
| 483 AdaptingFrameForwarder video_source_; | 437 AdaptingFrameForwarder video_source_; |
| 484 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_; | 438 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_; |
| 485 }; | 439 }; |
| 486 | 440 |
| 487 TEST_F(ViEEncoderTest, EncodeOneFrame) { | 441 TEST_F(ViEEncoderTest, EncodeOneFrame) { |
| 488 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 442 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 489 rtc::Event frame_destroyed_event(false, false); | 443 rtc::Event frame_destroyed_event(false, false); |
| 490 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event)); | 444 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event)); |
| 491 sink_.WaitForEncodedFrame(1); | 445 sink_.WaitForEncodedFrame(1); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams); | 643 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams); |
| 690 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers); | 644 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers); |
| 691 // Resilience is on for temporal layers. | 645 // Resilience is on for temporal layers. |
| 692 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience); | 646 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience); |
| 693 vie_encoder_->Stop(); | 647 vie_encoder_->Stop(); |
| 694 } | 648 } |
| 695 | 649 |
| 696 TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) { | 650 TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) { |
| 697 EXPECT_TRUE(video_source_.has_sinks()); | 651 EXPECT_TRUE(video_source_.has_sinks()); |
| 698 test::FrameForwarder new_video_source; | 652 test::FrameForwarder new_video_source; |
| 699 vie_encoder_->SetSource( | 653 vie_encoder_->SetSource(&new_video_source, |
| 700 &new_video_source, | 654 VideoSendStream::DegradationPreference::kBalanced); |
| 701 VideoSendStream::DegradationPreference::kMaintainFramerate); | |
| 702 EXPECT_FALSE(video_source_.has_sinks()); | 655 EXPECT_FALSE(video_source_.has_sinks()); |
| 703 EXPECT_TRUE(new_video_source.has_sinks()); | 656 EXPECT_TRUE(new_video_source.has_sinks()); |
| 704 | 657 |
| 705 vie_encoder_->Stop(); | 658 vie_encoder_->Stop(); |
| 706 } | 659 } |
| 707 | 660 |
| 708 TEST_F(ViEEncoderTest, SinkWantsRotationApplied) { | 661 TEST_F(ViEEncoderTest, SinkWantsRotationApplied) { |
| 709 EXPECT_FALSE(video_source_.sink_wants().rotation_applied); | 662 EXPECT_FALSE(video_source_.sink_wants().rotation_applied); |
| 710 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/); | 663 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/); |
| 711 EXPECT_TRUE(video_source_.sink_wants().rotation_applied); | 664 EXPECT_TRUE(video_source_.sink_wants().rotation_applied); |
| 712 vie_encoder_->Stop(); | 665 vie_encoder_->Stop(); |
| 713 } | 666 } |
| 714 | 667 |
| 715 TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) { | 668 TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) { |
| 716 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 669 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 717 | 670 |
| 718 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); | 671 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); |
| 719 EXPECT_EQ(std::numeric_limits<int>::max(), | 672 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); |
| 720 video_source_.sink_wants().max_pixel_count); | |
| 721 | 673 |
| 722 int frame_width = 1280; | 674 int frame_width = 1280; |
| 723 int frame_height = 720; | 675 int frame_height = 720; |
| 724 | 676 |
| 725 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should | 677 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should |
| 726 // request lower resolution. | 678 // request lower resolution. |
| 727 for (int i = 1; i <= ViEEncoder::kMaxCpuResolutionDowngrades; ++i) { | 679 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) { |
| 728 video_source_.IncomingCapturedFrame( | 680 video_source_.IncomingCapturedFrame( |
| 729 CreateFrame(i, frame_width, frame_height)); | 681 CreateFrame(i, frame_width, frame_height)); |
| 730 sink_.WaitForEncodedFrame(i); | 682 sink_.WaitForEncodedFrame(i); |
| 731 | 683 |
| 732 vie_encoder_->TriggerCpuOveruse(); | 684 vie_encoder_->TriggerCpuOveruse(); |
| 733 | 685 |
| 734 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); | 686 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); |
| 735 EXPECT_LT(video_source_.sink_wants().max_pixel_count, | 687 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( |
| 688 std::numeric_limits<int>::max()), |
| 736 frame_width * frame_height); | 689 frame_width * frame_height); |
| 737 | 690 |
| 738 frame_width /= 2; | 691 frame_width /= 2; |
| 739 frame_height /= 2; | 692 frame_height /= 2; |
| 740 } | 693 } |
| 741 | 694 |
| 742 // Trigger CPU overuse one more time. This should not trigger a request for | 695 // Trigger CPU overuse one more time. This should not trigger a request for |
| 743 // lower resolution. | 696 // lower resolution. |
| 744 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); | 697 rtc::VideoSinkWants current_wants = video_source_.sink_wants(); |
| 745 video_source_.IncomingCapturedFrame(CreateFrame( | 698 video_source_.IncomingCapturedFrame(CreateFrame( |
| 746 ViEEncoder::kMaxCpuResolutionDowngrades + 1, frame_width, frame_height)); | 699 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height)); |
| 747 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuResolutionDowngrades + 1); | 700 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1); |
| 748 vie_encoder_->TriggerCpuOveruse(); | 701 vie_encoder_->TriggerCpuOveruse(); |
| 749 EXPECT_EQ(video_source_.sink_wants().target_pixel_count, | 702 EXPECT_EQ(video_source_.sink_wants().target_pixel_count, |
| 750 current_wants.target_pixel_count); | 703 current_wants.target_pixel_count); |
| 751 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, | 704 EXPECT_EQ(video_source_.sink_wants().max_pixel_count, |
| 752 current_wants.max_pixel_count); | 705 current_wants.max_pixel_count); |
| 753 | 706 |
| 754 // Trigger CPU normal use. | 707 // Trigger CPU normal use. |
| 755 vie_encoder_->TriggerCpuNormalUsage(); | 708 vie_encoder_->TriggerCpuNormalUsage(); |
| 756 EXPECT_EQ(frame_width * frame_height * 5 / 3, | 709 EXPECT_EQ(frame_width * frame_height * 5 / 3, |
| 757 video_source_.sink_wants().target_pixel_count.value_or(0)); | 710 video_source_.sink_wants().target_pixel_count.value_or(0)); |
| 758 EXPECT_EQ(frame_width * frame_height * 4, | 711 EXPECT_EQ(frame_width * frame_height * 4, |
| 759 video_source_.sink_wants().max_pixel_count); | 712 video_source_.sink_wants().max_pixel_count.value_or(0)); |
| 760 | 713 |
| 761 vie_encoder_->Stop(); | 714 vie_encoder_->Stop(); |
| 762 } | 715 } |
| 763 | 716 |
| 764 TEST_F(ViEEncoderTest, SinkWantsStoredByDegradationPreference) { | 717 TEST_F(ViEEncoderTest, |
| 718 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) { |
| 765 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 719 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 766 | 720 |
| 767 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); | 721 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); |
| 768 EXPECT_EQ(std::numeric_limits<int>::max(), | 722 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); |
| 769 video_source_.sink_wants().max_pixel_count); | |
| 770 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 771 video_source_.sink_wants().max_framerate_fps); | |
| 772 | 723 |
| 773 const int kFrameWidth = 1280; | 724 int frame_width = 1280; |
| 774 const int kFrameHeight = 720; | 725 int frame_height = 720; |
| 775 const int kFrameIntervalMs = 1000 / 30; | |
| 776 | |
| 777 int frame_timestamp = 1; | |
| 778 | 726 |
| 779 video_source_.IncomingCapturedFrame( | 727 video_source_.IncomingCapturedFrame( |
| 780 CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight)); | 728 CreateFrame(1, frame_width, frame_height)); |
| 781 sink_.WaitForEncodedFrame(frame_timestamp); | 729 sink_.WaitForEncodedFrame(1); |
| 782 frame_timestamp += kFrameIntervalMs; | |
| 783 | |
| 784 // Trigger CPU overuse. | 730 // Trigger CPU overuse. |
| 785 vie_encoder_->TriggerCpuOveruse(); | 731 vie_encoder_->TriggerCpuOveruse(); |
| 732 |
| 786 video_source_.IncomingCapturedFrame( | 733 video_source_.IncomingCapturedFrame( |
| 787 CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight)); | 734 CreateFrame(2, frame_width, frame_height)); |
| 788 sink_.WaitForEncodedFrame(frame_timestamp); | 735 sink_.WaitForEncodedFrame(2); |
| 789 frame_timestamp += kFrameIntervalMs; | 736 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); |
| 737 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or( |
| 738 std::numeric_limits<int>::max()), |
| 739 frame_width * frame_height); |
| 790 | 740 |
| 791 // Default degradation preference in maintain-framerate, so will lower max | 741 // Set new source. |
| 792 // wanted resolution. | |
| 793 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); | |
| 794 EXPECT_LT(video_source_.sink_wants().max_pixel_count, | |
| 795 kFrameWidth * kFrameHeight); | |
| 796 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 797 video_source_.sink_wants().max_framerate_fps); | |
| 798 | |
| 799 // Set new source, switch to maintain-resolution. | |
| 800 test::FrameForwarder new_video_source; | 742 test::FrameForwarder new_video_source; |
| 801 vie_encoder_->SetSource( | 743 vie_encoder_->SetSource( |
| 802 &new_video_source, | 744 &new_video_source, |
| 803 VideoSendStream::DegradationPreference::kMaintainResolution); | 745 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 804 | 746 |
| 805 // Initially no degradation registered. | |
| 806 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); | 747 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); |
| 807 EXPECT_EQ(std::numeric_limits<int>::max(), | 748 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
| 808 new_video_source.sink_wants().max_pixel_count); | |
| 809 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 810 new_video_source.sink_wants().max_framerate_fps); | |
| 811 | 749 |
| 812 // Force an input frame rate to be available, or the adaptation call won't | |
| 813 // know what framerate to adapt form. | |
| 814 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | |
| 815 stats.input_frame_rate = 30; | |
| 816 stats_proxy_->SetMockStats(stats); | |
| 817 | |
| 818 vie_encoder_->TriggerCpuOveruse(); | |
| 819 new_video_source.IncomingCapturedFrame( | 750 new_video_source.IncomingCapturedFrame( |
| 820 CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight)); | 751 CreateFrame(3, frame_width, frame_height)); |
| 821 sink_.WaitForEncodedFrame(frame_timestamp); | 752 sink_.WaitForEncodedFrame(3); |
| 822 frame_timestamp += kFrameIntervalMs; | |
| 823 | |
| 824 // Some framerate constraint should be set. | |
| 825 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); | 753 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); |
| 826 EXPECT_EQ(std::numeric_limits<int>::max(), | 754 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
| 827 new_video_source.sink_wants().max_pixel_count); | |
| 828 EXPECT_TRUE(new_video_source.sink_wants().max_framerate_fps); | |
| 829 | |
| 830 // Turn of degradation completely. | |
| 831 vie_encoder_->SetSource( | |
| 832 &new_video_source, | |
| 833 VideoSendStream::DegradationPreference::kDegradationDisabled); | |
| 834 | |
| 835 // Initially no degradation registered. | |
| 836 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); | |
| 837 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 838 new_video_source.sink_wants().max_pixel_count); | |
| 839 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 840 new_video_source.sink_wants().max_framerate_fps); | |
| 841 | |
| 842 vie_encoder_->TriggerCpuOveruse(); | |
| 843 new_video_source.IncomingCapturedFrame( | |
| 844 CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight)); | |
| 845 sink_.WaitForEncodedFrame(frame_timestamp); | |
| 846 frame_timestamp += kFrameIntervalMs; | |
| 847 | |
| 848 // Still no degradation. | |
| 849 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); | |
| 850 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 851 new_video_source.sink_wants().max_pixel_count); | |
| 852 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 853 new_video_source.sink_wants().max_framerate_fps); | |
| 854 | 755 |
| 855 // Calling SetSource with resolution scaling enabled apply the old SinkWants. | 756 // Calling SetSource with resolution scaling enabled apply the old SinkWants. |
| 856 vie_encoder_->SetSource( | 757 vie_encoder_->SetSource(&new_video_source, |
| 857 &new_video_source, | 758 VideoSendStream::DegradationPreference::kBalanced); |
| 858 VideoSendStream::DegradationPreference::kMaintainFramerate); | 759 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or( |
| 859 EXPECT_LT(new_video_source.sink_wants().max_pixel_count, | 760 std::numeric_limits<int>::max()), |
| 860 kFrameWidth * kFrameHeight); | 761 frame_width * frame_height); |
| 861 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); | 762 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); |
| 862 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 863 new_video_source.sink_wants().max_framerate_fps); | |
| 864 | |
| 865 // Calling SetSource with framerate scaling enabled apply the old SinkWants. | |
| 866 vie_encoder_->SetSource( | |
| 867 &new_video_source, | |
| 868 VideoSendStream::DegradationPreference::kMaintainResolution); | |
| 869 EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count); | |
| 870 EXPECT_EQ(std::numeric_limits<int>::max(), | |
| 871 new_video_source.sink_wants().max_pixel_count); | |
| 872 EXPECT_TRUE(new_video_source.sink_wants().max_framerate_fps); | |
| 873 | 763 |
| 874 vie_encoder_->Stop(); | 764 vie_encoder_->Stop(); |
| 875 } | 765 } |
| 876 | 766 |
| 877 TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) { | 767 TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) { |
| 878 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 768 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 879 | 769 |
| 880 int frame_width = 1280; | 770 int frame_width = 1280; |
| 881 int frame_height = 720; | 771 int frame_height = 720; |
| 882 | 772 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 | 817 |
| 928 video_source_.IncomingCapturedFrame( | 818 video_source_.IncomingCapturedFrame( |
| 929 CreateFrame(2, frame_width, frame_height)); | 819 CreateFrame(2, frame_width, frame_height)); |
| 930 sink_.WaitForEncodedFrame(2); | 820 sink_.WaitForEncodedFrame(2); |
| 931 stats = stats_proxy_->GetStats(); | 821 stats = stats_proxy_->GetStats(); |
| 932 EXPECT_TRUE(stats.cpu_limited_resolution); | 822 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 933 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 823 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 934 | 824 |
| 935 // Set new source with adaptation still enabled. | 825 // Set new source with adaptation still enabled. |
| 936 test::FrameForwarder new_video_source; | 826 test::FrameForwarder new_video_source; |
| 937 vie_encoder_->SetSource( | 827 vie_encoder_->SetSource(&new_video_source, |
| 938 &new_video_source, | 828 VideoSendStream::DegradationPreference::kBalanced); |
| 939 VideoSendStream::DegradationPreference::kMaintainFramerate); | |
| 940 | 829 |
| 941 new_video_source.IncomingCapturedFrame( | 830 new_video_source.IncomingCapturedFrame( |
| 942 CreateFrame(3, frame_width, frame_height)); | 831 CreateFrame(3, frame_width, frame_height)); |
| 943 sink_.WaitForEncodedFrame(3); | 832 sink_.WaitForEncodedFrame(3); |
| 944 stats = stats_proxy_->GetStats(); | 833 stats = stats_proxy_->GetStats(); |
| 945 EXPECT_TRUE(stats.cpu_limited_resolution); | 834 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 946 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 835 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 947 | 836 |
| 948 // Set adaptation disabled. | 837 // Set adaptation disabled. |
| 949 vie_encoder_->SetSource( | 838 vie_encoder_->SetSource( |
| 950 &new_video_source, | 839 &new_video_source, |
| 951 VideoSendStream::DegradationPreference::kDegradationDisabled); | 840 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 952 | 841 |
| 953 new_video_source.IncomingCapturedFrame( | 842 new_video_source.IncomingCapturedFrame( |
| 954 CreateFrame(4, frame_width, frame_height)); | 843 CreateFrame(4, frame_width, frame_height)); |
| 955 sink_.WaitForEncodedFrame(4); | 844 sink_.WaitForEncodedFrame(4); |
| 956 stats = stats_proxy_->GetStats(); | 845 stats = stats_proxy_->GetStats(); |
| 957 EXPECT_FALSE(stats.cpu_limited_resolution); | 846 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 958 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 847 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 959 | 848 |
| 960 // Set adaptation back to enabled. | 849 // Set adaptation back to enabled. |
| 961 vie_encoder_->SetSource( | 850 vie_encoder_->SetSource(&new_video_source, |
| 962 &new_video_source, | 851 VideoSendStream::DegradationPreference::kBalanced); |
| 963 VideoSendStream::DegradationPreference::kMaintainFramerate); | |
| 964 | 852 |
| 965 new_video_source.IncomingCapturedFrame( | 853 new_video_source.IncomingCapturedFrame( |
| 966 CreateFrame(5, frame_width, frame_height)); | 854 CreateFrame(5, frame_width, frame_height)); |
| 967 sink_.WaitForEncodedFrame(5); | 855 sink_.WaitForEncodedFrame(5); |
| 968 stats = stats_proxy_->GetStats(); | 856 stats = stats_proxy_->GetStats(); |
| 969 EXPECT_TRUE(stats.cpu_limited_resolution); | 857 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 970 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 858 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 971 | 859 |
| 972 vie_encoder_->TriggerCpuNormalUsage(); | 860 vie_encoder_->TriggerCpuNormalUsage(); |
| 973 | 861 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 video_source_.IncomingCapturedFrame( | 950 video_source_.IncomingCapturedFrame( |
| 1063 CreateFrame(sequence, frame_width, frame_height)); | 951 CreateFrame(sequence, frame_width, frame_height)); |
| 1064 sink_.WaitForEncodedFrame(sequence++); | 952 sink_.WaitForEncodedFrame(sequence++); |
| 1065 | 953 |
| 1066 stats = stats_proxy_->GetStats(); | 954 stats = stats_proxy_->GetStats(); |
| 1067 EXPECT_TRUE(stats.cpu_limited_resolution); | 955 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 1068 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 956 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 1069 | 957 |
| 1070 // Set new source with adaptation still enabled. | 958 // Set new source with adaptation still enabled. |
| 1071 test::FrameForwarder new_video_source; | 959 test::FrameForwarder new_video_source; |
| 1072 vie_encoder_->SetSource( | 960 vie_encoder_->SetSource(&new_video_source, |
| 1073 &new_video_source, | 961 VideoSendStream::DegradationPreference::kBalanced); |
| 1074 VideoSendStream::DegradationPreference::kMaintainFramerate); | |
| 1075 | 962 |
| 1076 new_video_source.IncomingCapturedFrame( | 963 new_video_source.IncomingCapturedFrame( |
| 1077 CreateFrame(sequence, frame_width, frame_height)); | 964 CreateFrame(sequence, frame_width, frame_height)); |
| 1078 sink_.WaitForEncodedFrame(sequence++); | 965 sink_.WaitForEncodedFrame(sequence++); |
| 1079 stats = stats_proxy_->GetStats(); | 966 stats = stats_proxy_->GetStats(); |
| 1080 EXPECT_TRUE(stats.cpu_limited_resolution); | 967 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 1081 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 968 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 1082 | 969 |
| 1083 // Set cpu adaptation by frame dropping. | 970 // Set adaptation disabled. |
| 1084 vie_encoder_->SetSource( | 971 vie_encoder_->SetSource( |
| 1085 &new_video_source, | 972 &new_video_source, |
| 1086 VideoSendStream::DegradationPreference::kMaintainResolution); | 973 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 1087 new_video_source.IncomingCapturedFrame( | 974 new_video_source.IncomingCapturedFrame( |
| 1088 CreateFrame(sequence, frame_width, frame_height)); | 975 CreateFrame(sequence, frame_width, frame_height)); |
| 1089 sink_.WaitForEncodedFrame(sequence++); | 976 sink_.WaitForEncodedFrame(sequence++); |
| 1090 stats = stats_proxy_->GetStats(); | 977 stats = stats_proxy_->GetStats(); |
| 1091 // Not adapted at first. | |
| 1092 EXPECT_FALSE(stats.cpu_limited_resolution); | 978 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 1093 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); | 979 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 1094 | 980 |
| 1095 // Force an input frame rate to be available, or the adaptation call won't | 981 // Switch back the source with adaptation enabled. |
| 1096 // know what framerate to adapt form. | 982 vie_encoder_->SetSource(&video_source_, |
| 1097 VideoSendStream::Stats mock_stats = stats_proxy_->GetStats(); | 983 VideoSendStream::DegradationPreference::kBalanced); |
| 1098 mock_stats.input_frame_rate = 30; | |
| 1099 stats_proxy_->SetMockStats(mock_stats); | |
| 1100 vie_encoder_->TriggerCpuOveruse(); | |
| 1101 stats_proxy_->ResetMockStats(); | |
| 1102 | |
| 1103 new_video_source.IncomingCapturedFrame( | |
| 1104 CreateFrame(sequence, frame_width, frame_height)); | |
| 1105 sink_.WaitForEncodedFrame(sequence++); | |
| 1106 | |
| 1107 // Framerate now adapted. | |
| 1108 stats = stats_proxy_->GetStats(); | |
| 1109 EXPECT_TRUE(stats.cpu_limited_resolution); | |
| 1110 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | |
| 1111 | |
| 1112 // Disable CPU adaptation. | |
| 1113 vie_encoder_->SetSource( | |
| 1114 &new_video_source, | |
| 1115 VideoSendStream::DegradationPreference::kDegradationDisabled); | |
| 1116 new_video_source.IncomingCapturedFrame( | |
| 1117 CreateFrame(sequence, frame_width, frame_height)); | |
| 1118 sink_.WaitForEncodedFrame(sequence++); | |
| 1119 | |
| 1120 stats = stats_proxy_->GetStats(); | |
| 1121 EXPECT_FALSE(stats.cpu_limited_resolution); | |
| 1122 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | |
| 1123 | |
| 1124 // Try to trigger overuse. Should not succeed. | |
| 1125 stats_proxy_->SetMockStats(mock_stats); | |
| 1126 vie_encoder_->TriggerCpuOveruse(); | |
| 1127 stats_proxy_->ResetMockStats(); | |
| 1128 | |
| 1129 stats = stats_proxy_->GetStats(); | |
| 1130 EXPECT_FALSE(stats.cpu_limited_resolution); | |
| 1131 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | |
| 1132 | |
| 1133 // Switch back the source with resolution adaptation enabled. | |
| 1134 vie_encoder_->SetSource( | |
| 1135 &video_source_, | |
| 1136 VideoSendStream::DegradationPreference::kMaintainFramerate); | |
| 1137 video_source_.IncomingCapturedFrame( | 984 video_source_.IncomingCapturedFrame( |
| 1138 CreateFrame(sequence, frame_width, frame_height)); | 985 CreateFrame(sequence, frame_width, frame_height)); |
| 1139 sink_.WaitForEncodedFrame(sequence++); | 986 sink_.WaitForEncodedFrame(sequence++); |
| 1140 stats = stats_proxy_->GetStats(); | 987 stats = stats_proxy_->GetStats(); |
| 1141 EXPECT_TRUE(stats.cpu_limited_resolution); | 988 EXPECT_TRUE(stats.cpu_limited_resolution); |
| 1142 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 989 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes); |
| 1143 | 990 |
| 1144 // Trigger CPU normal usage. | 991 // Trigger CPU normal usage. |
| 1145 vie_encoder_->TriggerCpuNormalUsage(); | 992 vie_encoder_->TriggerCpuNormalUsage(); |
| 1146 video_source_.IncomingCapturedFrame( | 993 video_source_.IncomingCapturedFrame( |
| 1147 CreateFrame(sequence, frame_width, frame_height)); | 994 CreateFrame(sequence, frame_width, frame_height)); |
| 1148 sink_.WaitForEncodedFrame(sequence++); | 995 sink_.WaitForEncodedFrame(sequence++); |
| 1149 stats = stats_proxy_->GetStats(); | 996 stats = stats_proxy_->GetStats(); |
| 1150 EXPECT_FALSE(stats.cpu_limited_resolution); | 997 EXPECT_FALSE(stats.cpu_limited_resolution); |
| 1151 EXPECT_EQ(3, stats.number_of_cpu_adapt_changes); | 998 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
| 1152 | |
| 1153 // Back to the source with adaptation off, set it back to maintain-resolution. | |
| 1154 vie_encoder_->SetSource( | |
| 1155 &new_video_source, | |
| 1156 VideoSendStream::DegradationPreference::kMaintainResolution); | |
| 1157 new_video_source.IncomingCapturedFrame( | |
| 1158 CreateFrame(sequence, frame_width, frame_height)); | |
| 1159 sink_.WaitForEncodedFrame(sequence++); | |
| 1160 stats = stats_proxy_->GetStats(); | |
| 1161 // Disabled, since we previously switched the source too disabled. | |
| 1162 EXPECT_FALSE(stats.cpu_limited_resolution); | |
| 1163 EXPECT_EQ(3, stats.number_of_cpu_adapt_changes); | |
| 1164 | |
| 1165 // Trigger CPU normal usage. | |
| 1166 vie_encoder_->TriggerCpuNormalUsage(); | |
| 1167 new_video_source.IncomingCapturedFrame( | |
| 1168 CreateFrame(sequence, frame_width, frame_height)); | |
| 1169 sink_.WaitForEncodedFrame(sequence++); | |
| 1170 stats = stats_proxy_->GetStats(); | |
| 1171 EXPECT_FALSE(stats.cpu_limited_resolution); | |
| 1172 EXPECT_EQ(4, stats.number_of_cpu_adapt_changes); | |
| 1173 | 999 |
| 1174 vie_encoder_->Stop(); | 1000 vie_encoder_->Stop(); |
| 1175 } | 1001 } |
| 1176 | 1002 |
| 1177 TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) { | 1003 TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) { |
| 1178 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 1004 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 1179 | 1005 |
| 1180 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720)); | 1006 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720)); |
| 1181 sink_.WaitForEncodedFrame(1); | 1007 sink_.WaitForEncodedFrame(1); |
| 1182 | 1008 |
| 1183 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | 1009 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
| 1184 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, | 1010 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, |
| 1185 stats.preferred_media_bitrate_bps); | 1011 stats.preferred_media_bitrate_bps); |
| 1186 | 1012 |
| 1187 vie_encoder_->Stop(); | 1013 vie_encoder_->Stop(); |
| 1188 } | 1014 } |
| 1189 | 1015 |
| 1190 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) { | 1016 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) { |
| 1191 int frame_width = 1280; | 1017 int frame_width = 1280; |
| 1192 int frame_height = 720; | 1018 int frame_height = 720; |
| 1193 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 1019 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 1194 | 1020 |
| 1195 // Expect no scaling to begin with | 1021 // Expect no scaling to begin with |
| 1196 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); | 1022 EXPECT_FALSE(video_source_.sink_wants().target_pixel_count); |
| 1197 EXPECT_EQ(std::numeric_limits<int>::max(), | 1023 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); |
| 1198 video_source_.sink_wants().max_pixel_count); | |
| 1199 | 1024 |
| 1200 video_source_.IncomingCapturedFrame( | 1025 video_source_.IncomingCapturedFrame( |
| 1201 CreateFrame(1, frame_width, frame_height)); | 1026 CreateFrame(1, frame_width, frame_height)); |
| 1202 sink_.WaitForEncodedFrame(1); | 1027 sink_.WaitForEncodedFrame(1); |
| 1203 | 1028 |
| 1204 // Trigger scale down | 1029 // Trigger scale down |
| 1205 vie_encoder_->TriggerQualityLow(); | 1030 vie_encoder_->TriggerQualityLow(); |
| 1206 | 1031 |
| 1207 video_source_.IncomingCapturedFrame( | 1032 video_source_.IncomingCapturedFrame( |
| 1208 CreateFrame(2, frame_width, frame_height)); | 1033 CreateFrame(2, frame_width, frame_height)); |
| 1209 sink_.WaitForEncodedFrame(2); | 1034 sink_.WaitForEncodedFrame(2); |
| 1210 | 1035 |
| 1211 // Expect a scale down. | 1036 // Expect a scale down. |
| 1212 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); | 1037 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); |
| 1213 EXPECT_LT(video_source_.sink_wants().max_pixel_count, | 1038 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, |
| 1214 frame_width * frame_height); | 1039 frame_width * frame_height); |
| 1215 | 1040 |
| 1216 // Set adaptation disabled. | 1041 // Set adaptation disabled. |
| 1217 test::FrameForwarder new_video_source; | 1042 test::FrameForwarder new_video_source; |
| 1218 vie_encoder_->SetSource( | 1043 vie_encoder_->SetSource( |
| 1219 &new_video_source, | 1044 &new_video_source, |
| 1220 VideoSendStream::DegradationPreference::kMaintainResolution); | 1045 VideoSendStream::DegradationPreference::kMaintainResolution); |
| 1221 | 1046 |
| 1222 // Trigger scale down | 1047 // Trigger scale down |
| 1223 vie_encoder_->TriggerQualityLow(); | 1048 vie_encoder_->TriggerQualityLow(); |
| 1224 new_video_source.IncomingCapturedFrame( | 1049 new_video_source.IncomingCapturedFrame( |
| 1225 CreateFrame(3, frame_width, frame_height)); | 1050 CreateFrame(3, frame_width, frame_height)); |
| 1226 sink_.WaitForEncodedFrame(3); | 1051 sink_.WaitForEncodedFrame(3); |
| 1227 | 1052 |
| 1228 // Expect no scaling | 1053 // Expect no scaling |
| 1229 EXPECT_EQ(std::numeric_limits<int>::max(), | 1054 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
| 1230 new_video_source.sink_wants().max_pixel_count); | |
| 1231 | 1055 |
| 1232 // Trigger scale up | 1056 // Trigger scale up |
| 1233 vie_encoder_->TriggerQualityHigh(); | 1057 vie_encoder_->TriggerQualityHigh(); |
| 1234 new_video_source.IncomingCapturedFrame( | 1058 new_video_source.IncomingCapturedFrame( |
| 1235 CreateFrame(4, frame_width, frame_height)); | 1059 CreateFrame(4, frame_width, frame_height)); |
| 1236 sink_.WaitForEncodedFrame(4); | 1060 sink_.WaitForEncodedFrame(4); |
| 1237 | 1061 |
| 1238 // Expect nothing to change, still no scaling | 1062 // Expect nothing to change, still no scaling |
| 1239 EXPECT_EQ(std::numeric_limits<int>::max(), | 1063 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
| 1240 new_video_source.sink_wants().max_pixel_count); | |
| 1241 | 1064 |
| 1242 vie_encoder_->Stop(); | 1065 vie_encoder_->Stop(); |
| 1243 } | 1066 } |
| 1244 | 1067 |
| 1245 TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) { | 1068 TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) { |
| 1246 int frame_width = 1280; | 1069 int frame_width = 1280; |
| 1247 int frame_height = 720; | 1070 int frame_height = 720; |
| 1248 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 1071 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 1249 | 1072 |
| 1250 for (size_t i = 1; i <= 10; i++) { | 1073 for (size_t i = 1; i <= 10; i++) { |
| 1251 video_source_.IncomingCapturedFrame( | 1074 video_source_.IncomingCapturedFrame( |
| 1252 CreateFrame(i, frame_width, frame_height)); | 1075 CreateFrame(i, frame_width, frame_height)); |
| 1253 sink_.WaitForEncodedFrame(i); | 1076 sink_.WaitForEncodedFrame(i); |
| 1254 // Trigger scale down | 1077 // Trigger scale down |
| 1255 vie_encoder_->TriggerQualityLow(); | 1078 vie_encoder_->TriggerQualityLow(); |
| 1256 EXPECT_GE(video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame); | 1079 EXPECT_GE(*video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame); |
| 1257 } | 1080 } |
| 1258 | 1081 |
| 1259 vie_encoder_->Stop(); | 1082 vie_encoder_->Stop(); |
| 1260 } | 1083 } |
| 1261 | 1084 |
| 1262 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { | 1085 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) { |
| 1263 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 1086 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 1264 | 1087 |
| 1265 int frame_width = 640; | 1088 int frame_width = 640; |
| 1266 int frame_height = 360; | 1089 int frame_height = 360; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 int frame_width = 640; | 1162 int frame_width = 640; |
| 1340 int frame_height = 360; | 1163 int frame_height = 360; |
| 1341 | 1164 |
| 1342 video_source_.IncomingCapturedFrame( | 1165 video_source_.IncomingCapturedFrame( |
| 1343 CreateFrame(1, frame_width, frame_height)); | 1166 CreateFrame(1, frame_width, frame_height)); |
| 1344 | 1167 |
| 1345 // Expect to drop this frame, the wait should time out. | 1168 // Expect to drop this frame, the wait should time out. |
| 1346 sink_.ExpectDroppedFrame(); | 1169 sink_.ExpectDroppedFrame(); |
| 1347 | 1170 |
| 1348 // Expect the sink_wants to specify a scaled frame. | 1171 // Expect the sink_wants to specify a scaled frame. |
| 1349 EXPECT_LT(video_source_.sink_wants().max_pixel_count, 1000 * 1000); | 1172 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); |
| 1173 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, 1000 * 1000); |
| 1350 | 1174 |
| 1351 int last_pixel_count = video_source_.sink_wants().max_pixel_count; | 1175 int last_pixel_count = *video_source_.sink_wants().max_pixel_count; |
| 1352 | 1176 |
| 1353 // Next frame is scaled | 1177 // Next frame is scaled |
| 1354 video_source_.IncomingCapturedFrame( | 1178 video_source_.IncomingCapturedFrame( |
| 1355 CreateFrame(2, frame_width * 3 / 4, frame_height * 3 / 4)); | 1179 CreateFrame(2, frame_width * 3 / 4, frame_height * 3 / 4)); |
| 1356 | 1180 |
| 1357 // Expect to drop this frame, the wait should time out. | 1181 // Expect to drop this frame, the wait should time out. |
| 1358 sink_.ExpectDroppedFrame(); | 1182 sink_.ExpectDroppedFrame(); |
| 1359 | 1183 |
| 1360 EXPECT_LT(video_source_.sink_wants().max_pixel_count, last_pixel_count); | 1184 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, last_pixel_count); |
| 1361 | 1185 |
| 1362 vie_encoder_->Stop(); | 1186 vie_encoder_->Stop(); |
| 1363 } | 1187 } |
| 1364 | 1188 |
| 1365 TEST_F(ViEEncoderTest, NrOfDroppedFramesLimited) { | 1189 TEST_F(ViEEncoderTest, NrOfDroppedFramesLimited) { |
| 1366 // 1kbps. This can never be achieved. | 1190 // 1kbps. This can never be achieved. |
| 1367 vie_encoder_->OnBitrateUpdated(1000, 0, 0); | 1191 vie_encoder_->OnBitrateUpdated(1000, 0, 0); |
| 1368 int frame_width = 640; | 1192 int frame_width = 640; |
| 1369 int frame_height = 360; | 1193 int frame_height = 360; |
| 1370 | 1194 |
| 1371 // We expect the n initial frames to get dropped. | 1195 // We expect the n initial frames to get dropped. |
| 1372 int i; | 1196 int i; |
| 1373 for (i = 1; i <= kMaxInitialFramedrop; ++i) { | 1197 for (i = 1; i <= kMaxInitialFramedrop; ++i) { |
| 1374 video_source_.IncomingCapturedFrame( | 1198 video_source_.IncomingCapturedFrame( |
| 1375 CreateFrame(i, frame_width, frame_height)); | 1199 CreateFrame(i, frame_width, frame_height)); |
| 1376 sink_.ExpectDroppedFrame(); | 1200 sink_.ExpectDroppedFrame(); |
| 1377 } | 1201 } |
| 1378 // The n+1th frame should not be dropped, even though it's size is too large. | 1202 // The n+1th frame should not be dropped, even though it's size is too large. |
| 1379 video_source_.IncomingCapturedFrame( | 1203 video_source_.IncomingCapturedFrame( |
| 1380 CreateFrame(i, frame_width, frame_height)); | 1204 CreateFrame(i, frame_width, frame_height)); |
| 1381 sink_.WaitForEncodedFrame(i); | 1205 sink_.WaitForEncodedFrame(i); |
| 1382 | 1206 |
| 1383 // Expect the sink_wants to specify a scaled frame. | 1207 // Expect the sink_wants to specify a scaled frame. |
| 1384 EXPECT_LT(video_source_.sink_wants().max_pixel_count, 1000 * 1000); | 1208 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); |
| 1209 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, 1000 * 1000); |
| 1385 | 1210 |
| 1386 vie_encoder_->Stop(); | 1211 vie_encoder_->Stop(); |
| 1387 } | 1212 } |
| 1388 | 1213 |
| 1389 TEST_F(ViEEncoderTest, InitialFrameDropOffWithMaintainResolutionPreference) { | 1214 TEST_F(ViEEncoderTest, InitialFrameDropOffWithMaintainResolutionPreference) { |
| 1390 int frame_width = 640; | 1215 int frame_width = 640; |
| 1391 int frame_height = 360; | 1216 int frame_height = 360; |
| 1392 vie_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0); | 1217 vie_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0); |
| 1393 | 1218 |
| 1394 // Set degradation preference. | 1219 // Set degradation preference. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1435 video_source_.IncomingCapturedFrame( | 1260 video_source_.IncomingCapturedFrame( |
| 1436 CreateFrame(1, kFrameWidth, kFrameHeight)); | 1261 CreateFrame(1, kFrameWidth, kFrameHeight)); |
| 1437 sink_.WaitForEncodedFrame(kFrameWidth, kFrameHeight); | 1262 sink_.WaitForEncodedFrame(kFrameWidth, kFrameHeight); |
| 1438 | 1263 |
| 1439 // Trigger CPU overuse, downscale by 3/4. | 1264 // Trigger CPU overuse, downscale by 3/4. |
| 1440 vie_encoder_->TriggerCpuOveruse(); | 1265 vie_encoder_->TriggerCpuOveruse(); |
| 1441 video_source_.IncomingCapturedFrame( | 1266 video_source_.IncomingCapturedFrame( |
| 1442 CreateFrame(2, kFrameWidth, kFrameHeight)); | 1267 CreateFrame(2, kFrameWidth, kFrameHeight)); |
| 1443 sink_.WaitForEncodedFrame((kFrameWidth * 3) / 4, (kFrameHeight * 3) / 4); | 1268 sink_.WaitForEncodedFrame((kFrameWidth * 3) / 4, (kFrameHeight * 3) / 4); |
| 1444 | 1269 |
| 1445 // Trigger CPU normal use, return to original resolution; | 1270 // Trigger CPU normal use, return to original resoluton; |
| 1446 vie_encoder_->TriggerCpuNormalUsage(); | 1271 vie_encoder_->TriggerCpuNormalUsage(); |
| 1447 video_source_.IncomingCapturedFrame( | 1272 video_source_.IncomingCapturedFrame( |
| 1448 CreateFrame(3, kFrameWidth, kFrameHeight)); | 1273 CreateFrame(3, kFrameWidth, kFrameHeight)); |
| 1449 sink_.WaitForEncodedFrame(kFrameWidth, kFrameHeight); | 1274 sink_.WaitForEncodedFrame(kFrameWidth, kFrameHeight); |
| 1450 | 1275 |
| 1451 vie_encoder_->Stop(); | 1276 vie_encoder_->Stop(); |
| 1452 } | 1277 } |
| 1453 | 1278 |
| 1454 TEST_F(ViEEncoderTest, FailingInitEncodeDoesntCauseCrash) { | 1279 TEST_F(ViEEncoderTest, FailingInitEncodeDoesntCauseCrash) { |
| 1455 fake_encoder_.ForceInitEncodeFailure(true); | 1280 fake_encoder_.ForceInitEncodeFailure(true); |
| 1456 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 1281 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
| 1457 ResetEncoder("VP8", 2, 1, true); | 1282 ResetEncoder("VP8", 2, 1, true); |
| 1458 const int kFrameWidth = 1280; | 1283 const int kFrameWidth = 1280; |
| 1459 const int kFrameHeight = 720; | 1284 const int kFrameHeight = 720; |
| 1460 video_source_.IncomingCapturedFrame( | 1285 video_source_.IncomingCapturedFrame( |
| 1461 CreateFrame(1, kFrameWidth, kFrameHeight)); | 1286 CreateFrame(1, kFrameWidth, kFrameHeight)); |
| 1462 sink_.ExpectDroppedFrame(); | 1287 sink_.ExpectDroppedFrame(); |
| 1463 vie_encoder_->Stop(); | 1288 vie_encoder_->Stop(); |
| 1464 } | 1289 } |
| 1465 | |
| 1466 TEST_F(ViEEncoderTest, AdaptsFrameOnOveruseWithMaintainResolution) { | |
| 1467 const int kDefaultFramerateFps = 30; | |
| 1468 const int kFrameIntervalMs = rtc::kNumMillisecsPerSec / kDefaultFramerateFps; | |
| 1469 const int kFrameWidth = 1280; | |
| 1470 const int kFrameHeight = 720; | |
| 1471 rtc::ScopedFakeClock fake_clock; | |
| 1472 | |
| 1473 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
| 1474 vie_encoder_->SetSource( | |
| 1475 &video_source_, | |
| 1476 VideoSendStream::DegradationPreference::kMaintainResolution); | |
| 1477 video_source_.set_adaptation_enabled(true); | |
| 1478 | |
| 1479 fake_clock.SetTimeMicros(kFrameIntervalMs * 1000); | |
| 1480 int64_t timestamp_ms = kFrameIntervalMs; | |
| 1481 | |
| 1482 video_source_.IncomingCapturedFrame( | |
| 1483 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1484 sink_.WaitForEncodedFrame(timestamp_ms); | |
| 1485 | |
| 1486 // Try to trigger overuse. No fps estimate available => no effect. | |
| 1487 vie_encoder_->TriggerCpuOveruse(); | |
| 1488 | |
| 1489 // Insert frames for one second to get a stable estimate. | |
| 1490 for (int i = 0; i < kDefaultFramerateFps; ++i) { | |
| 1491 timestamp_ms += kFrameIntervalMs; | |
| 1492 fake_clock.AdvanceTimeMicros(kFrameIntervalMs * 1000); | |
| 1493 video_source_.IncomingCapturedFrame( | |
| 1494 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1495 sink_.WaitForEncodedFrame(timestamp_ms); | |
| 1496 } | |
| 1497 | |
| 1498 // Trigger CPU overuse, reduce framerate by 2/3. | |
| 1499 vie_encoder_->TriggerCpuOveruse(); | |
| 1500 int num_frames_dropped = 0; | |
| 1501 for (int i = 0; i < kDefaultFramerateFps; ++i) { | |
| 1502 timestamp_ms += kFrameIntervalMs; | |
| 1503 fake_clock.AdvanceTimeMicros(kFrameIntervalMs * 1000); | |
| 1504 video_source_.IncomingCapturedFrame( | |
| 1505 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1506 if (!sink_.WaitForFrame(kFrameTimeoutMs)) { | |
| 1507 ++num_frames_dropped; | |
| 1508 } else { | |
| 1509 sink_.CheckLastFrameSizeMathces(kFrameWidth, kFrameHeight); | |
| 1510 } | |
| 1511 } | |
| 1512 | |
| 1513 // TODO(sprang): Find where there's rounding errors or stuff causing the | |
| 1514 // margin here to be a little larger than we'd like (input fps estimate is | |
| 1515 // off) and the frame dropping is a little too aggressive. | |
| 1516 const int kErrorMargin = 5; | |
| 1517 EXPECT_NEAR(num_frames_dropped, | |
| 1518 kDefaultFramerateFps - (kDefaultFramerateFps * 2 / 3), | |
| 1519 kErrorMargin); | |
| 1520 | |
| 1521 // Trigger CPU overuse, reduce framerate by 2/3 again. | |
| 1522 vie_encoder_->TriggerCpuOveruse(); | |
| 1523 num_frames_dropped = 0; | |
| 1524 for (int i = 0; i < kDefaultFramerateFps; ++i) { | |
| 1525 timestamp_ms += kFrameIntervalMs; | |
| 1526 fake_clock.AdvanceTimeMicros(kFrameIntervalMs * 1000); | |
| 1527 video_source_.IncomingCapturedFrame( | |
| 1528 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1529 if (!sink_.WaitForFrame(kFrameTimeoutMs)) { | |
| 1530 ++num_frames_dropped; | |
| 1531 } else { | |
| 1532 sink_.CheckLastFrameSizeMathces(kFrameWidth, kFrameHeight); | |
| 1533 } | |
| 1534 } | |
| 1535 EXPECT_NEAR(num_frames_dropped, | |
| 1536 kDefaultFramerateFps - (kDefaultFramerateFps * 4 / 9), | |
| 1537 kErrorMargin); | |
| 1538 | |
| 1539 // Go back up one step. | |
| 1540 vie_encoder_->TriggerCpuNormalUsage(); | |
| 1541 num_frames_dropped = 0; | |
| 1542 for (int i = 0; i < kDefaultFramerateFps; ++i) { | |
| 1543 timestamp_ms += kFrameIntervalMs; | |
| 1544 fake_clock.AdvanceTimeMicros(kFrameIntervalMs * 1000); | |
| 1545 video_source_.IncomingCapturedFrame( | |
| 1546 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1547 if (!sink_.WaitForFrame(kFrameTimeoutMs)) { | |
| 1548 ++num_frames_dropped; | |
| 1549 } else { | |
| 1550 sink_.CheckLastFrameSizeMathces(kFrameWidth, kFrameHeight); | |
| 1551 } | |
| 1552 } | |
| 1553 EXPECT_NEAR(num_frames_dropped, | |
| 1554 kDefaultFramerateFps - (kDefaultFramerateFps * 2 / 3), | |
| 1555 kErrorMargin); | |
| 1556 | |
| 1557 // Go back up to original mode. | |
| 1558 vie_encoder_->TriggerCpuNormalUsage(); | |
| 1559 num_frames_dropped = 0; | |
| 1560 for (int i = 0; i < kDefaultFramerateFps; ++i) { | |
| 1561 timestamp_ms += kFrameIntervalMs; | |
| 1562 fake_clock.AdvanceTimeMicros(kFrameIntervalMs * 1000); | |
| 1563 video_source_.IncomingCapturedFrame( | |
| 1564 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1565 if (!sink_.WaitForFrame(kFrameTimeoutMs)) { | |
| 1566 ++num_frames_dropped; | |
| 1567 } else { | |
| 1568 sink_.CheckLastFrameSizeMathces(kFrameWidth, kFrameHeight); | |
| 1569 } | |
| 1570 } | |
| 1571 EXPECT_NEAR(num_frames_dropped, 0, kErrorMargin); | |
| 1572 | |
| 1573 vie_encoder_->Stop(); | |
| 1574 } | |
| 1575 | |
| 1576 TEST_F(ViEEncoderTest, DoesntAdaptDownPastMinFramerate) { | |
| 1577 const int kFramerateFps = 5; | |
| 1578 const int kFrameIntervalMs = rtc::kNumMillisecsPerSec / kFramerateFps; | |
| 1579 const int kMinFpsFrameInterval = rtc::kNumMillisecsPerSec / kMinFramerateFps; | |
| 1580 const int kFrameWidth = 1280; | |
| 1581 const int kFrameHeight = 720; | |
| 1582 | |
| 1583 rtc::ScopedFakeClock fake_clock; | |
| 1584 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | |
| 1585 vie_encoder_->SetSource( | |
| 1586 &video_source_, | |
| 1587 VideoSendStream::DegradationPreference::kMaintainResolution); | |
| 1588 video_source_.set_adaptation_enabled(true); | |
| 1589 | |
| 1590 fake_clock.SetTimeMicros(kFrameIntervalMs * 1000); | |
| 1591 int64_t timestamp_ms = kFrameIntervalMs; | |
| 1592 | |
| 1593 // Trigger overuse as much as we can. | |
| 1594 for (int i = 0; i < ViEEncoder::kMaxCpuResolutionDowngrades; ++i) { | |
| 1595 // Insert frames to get a new fps estimate... | |
| 1596 for (int j = 0; j < kFramerateFps; ++j) { | |
| 1597 video_source_.IncomingCapturedFrame( | |
| 1598 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1599 timestamp_ms += kFrameIntervalMs; | |
| 1600 fake_clock.AdvanceTimeMicros(kFrameIntervalMs * 1000); | |
| 1601 } | |
| 1602 // ...and then try to adapt again. | |
| 1603 vie_encoder_->TriggerCpuOveruse(); | |
| 1604 } | |
| 1605 | |
| 1606 // Drain any frame in the pipeline. | |
| 1607 sink_.WaitForFrame(kDefaultTimeoutMs); | |
| 1608 | |
| 1609 // Insert frames at min fps, all should go through. | |
| 1610 for (int i = 0; i < 10; ++i) { | |
| 1611 timestamp_ms += kMinFpsFrameInterval; | |
| 1612 fake_clock.AdvanceTimeMicros(kMinFpsFrameInterval * 1000); | |
| 1613 video_source_.IncomingCapturedFrame( | |
| 1614 CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight)); | |
| 1615 sink_.WaitForEncodedFrame(timestamp_ms); | |
| 1616 } | |
| 1617 vie_encoder_->Stop(); | |
| 1618 } | |
| 1619 } // namespace webrtc | 1290 } // namespace webrtc |
| OLD | NEW |