OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "webrtc/test/field_trial.h" | 22 #include "webrtc/test/field_trial.h" |
23 #include "webrtc/test/gtest.h" | 23 #include "webrtc/test/gtest.h" |
24 | 24 |
25 namespace webrtc { | 25 namespace webrtc { |
26 namespace { | 26 namespace { |
27 const int kWidth = 320; | 27 const int kWidth = 320; |
28 const int kHeight = 240; | 28 const int kHeight = 240; |
29 const int kNumCores = 2; | 29 const int kNumCores = 2; |
30 const uint32_t kFramerate = 30; | 30 const uint32_t kFramerate = 30; |
31 const size_t kMaxPayloadSize = 800; | 31 const size_t kMaxPayloadSize = 800; |
| 32 const int kDefaultMinPixelsPerFrame = 320 * 180; |
32 } // namespace | 33 } // namespace |
33 | 34 |
34 class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { | 35 class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { |
35 protected: | 36 protected: |
36 VideoEncoderSoftwareFallbackWrapperTest() | 37 VideoEncoderSoftwareFallbackWrapperTest() |
37 : VideoEncoderSoftwareFallbackWrapperTest("") {} | 38 : VideoEncoderSoftwareFallbackWrapperTest("") {} |
38 explicit VideoEncoderSoftwareFallbackWrapperTest( | 39 explicit VideoEncoderSoftwareFallbackWrapperTest( |
39 const std::string& field_trials) | 40 const std::string& field_trials) |
40 : override_field_trials_(field_trials), | 41 : override_field_trials_(field_trials), |
41 fallback_wrapper_(cricket::VideoCodec("VP8"), &fake_encoder_) {} | 42 fallback_wrapper_(cricket::VideoCodec("VP8"), &fake_encoder_) {} |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 87 |
87 bool SupportsNativeHandle() const override { | 88 bool SupportsNativeHandle() const override { |
88 ++supports_native_handle_count_; | 89 ++supports_native_handle_count_; |
89 return supports_native_handle_; | 90 return supports_native_handle_; |
90 } | 91 } |
91 | 92 |
92 const char* ImplementationName() const override { | 93 const char* ImplementationName() const override { |
93 return "fake-encoder"; | 94 return "fake-encoder"; |
94 } | 95 } |
95 | 96 |
| 97 VideoEncoder::ScalingSettings GetScalingSettings() const override { |
| 98 return VideoEncoder::ScalingSettings(true); |
| 99 } |
| 100 |
96 int init_encode_count_ = 0; | 101 int init_encode_count_ = 0; |
97 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; | 102 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; |
98 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; | 103 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; |
99 int encode_count_ = 0; | 104 int encode_count_ = 0; |
100 EncodedImageCallback* encode_complete_callback_ = nullptr; | 105 EncodedImageCallback* encode_complete_callback_ = nullptr; |
101 int release_count_ = 0; | 106 int release_count_ = 0; |
102 int set_channel_parameters_count_ = 0; | 107 int set_channel_parameters_count_ = 0; |
103 int set_rates_count_ = 0; | 108 int set_rates_count_ = 0; |
104 mutable int supports_native_handle_count_ = 0; | 109 mutable int supports_native_handle_count_ = 0; |
105 bool supports_native_handle_ = false; | 110 bool supports_native_handle_ = false; |
(...skipping 28 matching lines...) Expand all Loading... |
134 VideoCodec codec_ = {}; | 139 VideoCodec codec_ = {}; |
135 std::unique_ptr<VideoFrame> frame_; | 140 std::unique_ptr<VideoFrame> frame_; |
136 std::unique_ptr<SimulcastRateAllocator> rate_allocator_; | 141 std::unique_ptr<SimulcastRateAllocator> rate_allocator_; |
137 }; | 142 }; |
138 | 143 |
139 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() { | 144 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() { |
140 EncodeFrame(WEBRTC_VIDEO_CODEC_OK); | 145 EncodeFrame(WEBRTC_VIDEO_CODEC_OK); |
141 } | 146 } |
142 | 147 |
143 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame(int expected_ret) { | 148 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame(int expected_ret) { |
144 rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create(kWidth, kHeight); | 149 rtc::scoped_refptr<I420Buffer> buffer = |
| 150 I420Buffer::Create(codec_.width, codec_.height); |
145 I420Buffer::SetBlack(buffer); | 151 I420Buffer::SetBlack(buffer); |
146 std::vector<FrameType> types(1, kVideoFrameKey); | 152 std::vector<FrameType> types(1, kVideoFrameKey); |
147 | 153 |
148 frame_.reset(new VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); | 154 frame_.reset(new VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); |
149 EXPECT_EQ(expected_ret, fallback_wrapper_.Encode(*frame_, nullptr, &types)); | 155 EXPECT_EQ(expected_ret, fallback_wrapper_.Encode(*frame_, nullptr, &types)); |
150 } | 156 } |
151 | 157 |
152 void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { | 158 void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { |
153 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); | 159 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
154 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_); | 160 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 298 |
293 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 299 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
294 SupportsNativeHandleNotForwardedDuringFallback) { | 300 SupportsNativeHandleNotForwardedDuringFallback) { |
295 UtilizeFallbackEncoder(); | 301 UtilizeFallbackEncoder(); |
296 fallback_wrapper_.SupportsNativeHandle(); | 302 fallback_wrapper_.SupportsNativeHandle(); |
297 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); | 303 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); |
298 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); | 304 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
299 } | 305 } |
300 | 306 |
301 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) { | 307 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) { |
302 VideoCodec codec = {}; | 308 codec_.width = kWidth; |
| 309 codec_.height = kHeight; |
303 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); | 310 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
304 fallback_wrapper_.InitEncode(&codec, kNumCores, kMaxPayloadSize); | 311 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize); |
305 EncodeFrame(); | 312 EncodeFrame(); |
306 CheckLastEncoderName("fake-encoder"); | 313 CheckLastEncoderName("fake-encoder"); |
307 } | 314 } |
308 | 315 |
309 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 316 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
310 ReportsFallbackImplementationName) { | 317 ReportsFallbackImplementationName) { |
311 UtilizeFallbackEncoder(); | 318 UtilizeFallbackEncoder(); |
312 // Hard coded expected value since libvpx is the software implementation name | 319 // Hard coded expected value since libvpx is the software implementation name |
313 // for VP8. Change accordingly if the underlying implementation does. | 320 // for VP8. Change accordingly if the underlying implementation does. |
314 CheckLastEncoderName("libvpx"); | 321 CheckLastEncoderName("libvpx"); |
315 } | 322 } |
316 | 323 |
317 namespace { | 324 namespace { |
318 const int kLowKbps = 220; | 325 const int kLowKbps = 220; |
319 const int kHighKbps = 300; | 326 const int kHighKbps = 300; |
320 const int kMinLowDurationMs = 4000; | 327 const int kMinLowDurationMs = 4000; |
| 328 const int kMinPixelsPerFrame = 1; |
| 329 const int kMinPixelsStop = 320 * 180; |
321 const std::string kFieldTrial = "WebRTC-VP8-Forced-Fallback-Encoder"; | 330 const std::string kFieldTrial = "WebRTC-VP8-Forced-Fallback-Encoder"; |
322 } // namespace | 331 } // namespace |
323 | 332 |
324 class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest { | 333 class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest { |
325 public: | 334 public: |
326 ForcedFallbackTest(const std::string& field_trials) | 335 ForcedFallbackTest(const std::string& field_trials) |
327 : VideoEncoderSoftwareFallbackWrapperTest(field_trials) {} | 336 : VideoEncoderSoftwareFallbackWrapperTest(field_trials) {} |
328 | 337 |
329 ~ForcedFallbackTest() override {} | 338 ~ForcedFallbackTest() override {} |
330 | 339 |
(...skipping 12 matching lines...) Expand all Loading... |
343 | 352 |
344 void ConfigureVp8Codec() { | 353 void ConfigureVp8Codec() { |
345 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); | 354 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
346 std::unique_ptr<TemporalLayersFactory> tl_factory( | 355 std::unique_ptr<TemporalLayersFactory> tl_factory( |
347 new TemporalLayersFactory()); | 356 new TemporalLayersFactory()); |
348 codec_.codecType = kVideoCodecVP8; | 357 codec_.codecType = kVideoCodecVP8; |
349 codec_.maxFramerate = kFramerate; | 358 codec_.maxFramerate = kFramerate; |
350 codec_.width = kWidth; | 359 codec_.width = kWidth; |
351 codec_.height = kHeight; | 360 codec_.height = kHeight; |
352 codec_.VP8()->numberOfTemporalLayers = 1; | 361 codec_.VP8()->numberOfTemporalLayers = 1; |
| 362 codec_.VP8()->automaticResizeOn = true; |
| 363 codec_.VP8()->frameDroppingOn = true; |
353 codec_.VP8()->tl_factory = tl_factory.get(); | 364 codec_.VP8()->tl_factory = tl_factory.get(); |
354 rate_allocator_.reset( | 365 rate_allocator_.reset( |
355 new SimulcastRateAllocator(codec_, std::move(tl_factory))); | 366 new SimulcastRateAllocator(codec_, std::move(tl_factory))); |
356 } | 367 } |
357 | 368 |
358 void SetRateAllocation(uint32_t bitrate_kbps) { | 369 void SetRateAllocation(uint32_t bitrate_kbps) { |
359 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRateAllocation( | 370 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRateAllocation( |
360 rate_allocator_->GetAllocation( | 371 rate_allocator_->GetAllocation( |
361 bitrate_kbps * 1000, kFramerate), | 372 bitrate_kbps * 1000, kFramerate), |
362 kFramerate)); | 373 kFramerate)); |
(...skipping 11 matching lines...) Expand all Loading... |
374 | 385 |
375 rtc::ScopedFakeClock clock_; | 386 rtc::ScopedFakeClock clock_; |
376 }; | 387 }; |
377 | 388 |
378 class ForcedFallbackTestEnabled : public ForcedFallbackTest { | 389 class ForcedFallbackTestEnabled : public ForcedFallbackTest { |
379 public: | 390 public: |
380 ForcedFallbackTestEnabled() | 391 ForcedFallbackTestEnabled() |
381 : ForcedFallbackTest(kFieldTrial + "/Enabled-" + | 392 : ForcedFallbackTest(kFieldTrial + "/Enabled-" + |
382 std::to_string(kLowKbps) + "," + | 393 std::to_string(kLowKbps) + "," + |
383 std::to_string(kHighKbps) + "," + | 394 std::to_string(kHighKbps) + "," + |
384 std::to_string(kMinLowDurationMs) + "/") {} | 395 std::to_string(kMinLowDurationMs) + "," + |
| 396 std::to_string(kMinPixelsPerFrame) + "/") {} |
385 }; | 397 }; |
386 | 398 |
387 class ForcedFallbackTestDisabled : public ForcedFallbackTest { | 399 class ForcedFallbackTestDisabled : public ForcedFallbackTest { |
388 public: | 400 public: |
389 ForcedFallbackTestDisabled() | 401 ForcedFallbackTestDisabled() |
390 : ForcedFallbackTest(kFieldTrial + "/Disabled/") {} | 402 : ForcedFallbackTest(kFieldTrial + "/Disabled/") {} |
391 }; | 403 }; |
392 | 404 |
393 TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) { | 405 TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) { |
394 // Bitrate at low threshold. | 406 // Bitrate at low threshold. |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); | 580 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
569 EXPECT_EQ(3, fake_encoder_.init_encode_count_); | 581 EXPECT_EQ(3, fake_encoder_.init_encode_count_); |
570 // Bitrate at low threshold. | 582 // Bitrate at low threshold. |
571 SetRateAllocation(kLowKbps); | 583 SetRateAllocation(kLowKbps); |
572 EncodeFrameAndVerifyLastName("fake-encoder"); | 584 EncodeFrameAndVerifyLastName("fake-encoder"); |
573 // Duration passed, expect no fallback. | 585 // Duration passed, expect no fallback. |
574 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); | 586 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
575 EncodeFrameAndVerifyLastName("fake-encoder"); | 587 EncodeFrameAndVerifyLastName("fake-encoder"); |
576 } | 588 } |
577 | 589 |
| 590 TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithoutFallback) { |
| 591 // Bitrate at low threshold. |
| 592 SetRateAllocation(kLowKbps); |
| 593 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 594 // Default min pixels per frame should be used. |
| 595 const auto settings = fallback_wrapper_.GetScalingSettings(); |
| 596 EXPECT_TRUE(settings.enabled); |
| 597 EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame); |
| 598 } |
| 599 |
| 600 TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) { |
| 601 // Bitrate at low threshold. |
| 602 SetRateAllocation(kLowKbps); |
| 603 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 604 // Duration passed, expect fallback. |
| 605 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 606 EncodeFrameAndVerifyLastName("libvpx"); |
| 607 // Configured min pixels per frame should be used. |
| 608 const auto settings = fallback_wrapper_.GetScalingSettings(); |
| 609 EXPECT_TRUE(settings.enabled); |
| 610 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame); |
| 611 } |
| 612 |
| 613 TEST_F(ForcedFallbackTestEnabled, FallbackIsKeptIfResolutionIsTooSmall) { |
| 614 // Bitrate at low threshold. |
| 615 SetRateAllocation(kLowKbps); |
| 616 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 617 // Duration passed, expect fallback. |
| 618 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 619 EncodeFrameAndVerifyLastName("libvpx"); |
| 620 |
| 621 // Re-initialize encoder with a resolution less than |kMinPixelsStop|. |
| 622 codec_.height = kMinPixelsStop / codec_.width - 1; |
| 623 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 624 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 625 EXPECT_EQ(1, fake_encoder_.init_encode_count_); // No change |
| 626 SetRateAllocation(kHighKbps - 1); |
| 627 EncodeFrameAndVerifyLastName("libvpx"); |
| 628 // Bitrate at high threshold but resolution too small for fallback to end. |
| 629 SetRateAllocation(kHighKbps); |
| 630 EncodeFrameAndVerifyLastName("libvpx"); |
| 631 |
| 632 // Re-initialize encoder with a resolution equal to |kMinPixelsStop|. |
| 633 codec_.height++; |
| 634 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 635 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 636 EXPECT_EQ(1, fake_encoder_.init_encode_count_); // No change |
| 637 SetRateAllocation(kHighKbps - 1); |
| 638 EncodeFrameAndVerifyLastName("libvpx"); |
| 639 // Bitrate at high threshold and resolution large enough for fallback to end. |
| 640 SetRateAllocation(kHighKbps); |
| 641 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 642 } |
| 643 |
578 } // namespace webrtc | 644 } // namespace webrtc |
OLD | NEW |