| 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 |
| 11 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" | 11 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" |
| 12 | 12 |
| 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/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" | 16 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" |
| 17 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 17 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
| 18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 19 #include "webrtc/modules/video_coding/include/video_error_codes.h" | 19 #include "webrtc/modules/video_coding/include/video_error_codes.h" |
| 20 #include "webrtc/rtc_base/checks.h" | 20 #include "webrtc/rtc_base/checks.h" |
| 21 #include "webrtc/rtc_base/fakeclock.h" |
| 22 #include "webrtc/test/field_trial.h" |
| 21 #include "webrtc/test/gtest.h" | 23 #include "webrtc/test/gtest.h" |
| 22 | 24 |
| 23 namespace webrtc { | 25 namespace webrtc { |
| 24 | 26 namespace { |
| 25 const int kWidth = 320; | 27 const int kWidth = 320; |
| 26 const int kHeight = 240; | 28 const int kHeight = 240; |
| 29 const int kNumCores = 2; |
| 30 const uint32_t kFramerate = 30; |
| 27 const size_t kMaxPayloadSize = 800; | 31 const size_t kMaxPayloadSize = 800; |
| 32 } // namespace |
| 28 | 33 |
| 29 class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { | 34 class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { |
| 30 protected: | 35 protected: |
| 31 VideoEncoderSoftwareFallbackWrapperTest() | 36 VideoEncoderSoftwareFallbackWrapperTest() |
| 32 : fallback_wrapper_(cricket::VideoCodec("VP8"), &fake_encoder_) {} | 37 : VideoEncoderSoftwareFallbackWrapperTest("") {} |
| 38 explicit VideoEncoderSoftwareFallbackWrapperTest( |
| 39 const std::string& field_trials) |
| 40 : override_field_trials_(field_trials), |
| 41 fallback_wrapper_(cricket::VideoCodec("VP8"), &fake_encoder_) {} |
| 33 | 42 |
| 34 class CountingFakeEncoder : public VideoEncoder { | 43 class CountingFakeEncoder : public VideoEncoder { |
| 35 public: | 44 public: |
| 36 int32_t InitEncode(const VideoCodec* codec_settings, | 45 int32_t InitEncode(const VideoCodec* codec_settings, |
| 37 int32_t number_of_cores, | 46 int32_t number_of_cores, |
| 38 size_t max_payload_size) override { | 47 size_t max_payload_size) override { |
| 39 ++init_encode_count_; | 48 ++init_encode_count_; |
| 40 return init_encode_return_code_; | 49 return init_encode_return_code_; |
| 41 } | 50 } |
| 42 int32_t Encode(const VideoFrame& frame, | 51 int32_t Encode(const VideoFrame& frame, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 70 } | 79 } |
| 71 | 80 |
| 72 int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation, | 81 int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation, |
| 73 uint32_t framerate) override { | 82 uint32_t framerate) override { |
| 74 ++set_rates_count_; | 83 ++set_rates_count_; |
| 75 return WEBRTC_VIDEO_CODEC_OK; | 84 return WEBRTC_VIDEO_CODEC_OK; |
| 76 } | 85 } |
| 77 | 86 |
| 78 bool SupportsNativeHandle() const override { | 87 bool SupportsNativeHandle() const override { |
| 79 ++supports_native_handle_count_; | 88 ++supports_native_handle_count_; |
| 80 return false; | 89 return supports_native_handle_; |
| 81 } | 90 } |
| 82 | 91 |
| 83 const char* ImplementationName() const override { | 92 const char* ImplementationName() const override { |
| 84 return "fake-encoder"; | 93 return "fake-encoder"; |
| 85 } | 94 } |
| 86 | 95 |
| 87 int init_encode_count_ = 0; | 96 int init_encode_count_ = 0; |
| 88 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; | 97 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; |
| 89 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; | 98 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK; |
| 90 int encode_count_ = 0; | 99 int encode_count_ = 0; |
| 91 EncodedImageCallback* encode_complete_callback_ = nullptr; | 100 EncodedImageCallback* encode_complete_callback_ = nullptr; |
| 92 int release_count_ = 0; | 101 int release_count_ = 0; |
| 93 int set_channel_parameters_count_ = 0; | 102 int set_channel_parameters_count_ = 0; |
| 94 int set_rates_count_ = 0; | 103 int set_rates_count_ = 0; |
| 95 mutable int supports_native_handle_count_ = 0; | 104 mutable int supports_native_handle_count_ = 0; |
| 105 bool supports_native_handle_ = false; |
| 96 }; | 106 }; |
| 97 | 107 |
| 98 class FakeEncodedImageCallback : public EncodedImageCallback { | 108 class FakeEncodedImageCallback : public EncodedImageCallback { |
| 99 public: | 109 public: |
| 100 Result OnEncodedImage( | 110 Result OnEncodedImage( |
| 101 const EncodedImage& encoded_image, | 111 const EncodedImage& encoded_image, |
| 102 const CodecSpecificInfo* codec_specific_info, | 112 const CodecSpecificInfo* codec_specific_info, |
| 103 const RTPFragmentationHeader* fragmentation) override { | 113 const RTPFragmentationHeader* fragmentation) override { |
| 104 ++callback_count_; | 114 ++callback_count_; |
| 105 last_codec_name_ = codec_specific_info->codec_name; | 115 last_codec_name_ = codec_specific_info->codec_name; |
| 106 return Result(Result::OK, callback_count_); | 116 return Result(Result::OK, callback_count_); |
| 107 } | 117 } |
| 108 int callback_count_ = 0; | 118 int callback_count_ = 0; |
| 109 std::string last_codec_name_; | 119 std::string last_codec_name_; |
| 110 }; | 120 }; |
| 111 | 121 |
| 112 void UtilizeFallbackEncoder(); | 122 void UtilizeFallbackEncoder(); |
| 113 void FallbackFromEncodeRequest(); | 123 void FallbackFromEncodeRequest(); |
| 114 void EncodeFrame(); | 124 void EncodeFrame(); |
| 125 void EncodeFrame(int expected_ret); |
| 115 void CheckLastEncoderName(const char* expected_name) { | 126 void CheckLastEncoderName(const char* expected_name) { |
| 116 EXPECT_STREQ(expected_name, callback_.last_codec_name_.c_str()); | 127 EXPECT_STREQ(expected_name, callback_.last_codec_name_.c_str()); |
| 117 } | 128 } |
| 118 | 129 |
| 130 test::ScopedFieldTrials override_field_trials_; |
| 119 FakeEncodedImageCallback callback_; | 131 FakeEncodedImageCallback callback_; |
| 120 CountingFakeEncoder fake_encoder_; | 132 CountingFakeEncoder fake_encoder_; |
| 121 VideoEncoderSoftwareFallbackWrapper fallback_wrapper_; | 133 VideoEncoderSoftwareFallbackWrapper fallback_wrapper_; |
| 122 VideoCodec codec_ = {}; | 134 VideoCodec codec_ = {}; |
| 123 std::unique_ptr<VideoFrame> frame_; | 135 std::unique_ptr<VideoFrame> frame_; |
| 124 std::unique_ptr<SimulcastRateAllocator> rate_allocator_; | 136 std::unique_ptr<SimulcastRateAllocator> rate_allocator_; |
| 125 }; | 137 }; |
| 126 | 138 |
| 127 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() { | 139 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() { |
| 140 EncodeFrame(WEBRTC_VIDEO_CODEC_OK); |
| 141 } |
| 142 |
| 143 void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame(int expected_ret) { |
| 128 rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create(kWidth, kHeight); | 144 rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create(kWidth, kHeight); |
| 129 I420Buffer::SetBlack(buffer); | 145 I420Buffer::SetBlack(buffer); |
| 130 std::vector<FrameType> types(1, kVideoFrameKey); | 146 std::vector<FrameType> types(1, kVideoFrameKey); |
| 131 | 147 |
| 132 frame_.reset(new VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); | 148 frame_.reset(new VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0)); |
| 133 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 149 EXPECT_EQ(expected_ret, fallback_wrapper_.Encode(*frame_, nullptr, &types)); |
| 134 fallback_wrapper_.Encode(*frame_, nullptr, &types)); | |
| 135 } | 150 } |
| 136 | 151 |
| 137 void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { | 152 void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() { |
| 138 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); | 153 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
| 139 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_); | 154 EXPECT_EQ(&callback_, fake_encoder_.encode_complete_callback_); |
| 140 | 155 |
| 141 // Register with failing fake encoder. Should succeed with VP8 fallback. | 156 // Register with failing fake encoder. Should succeed with VP8 fallback. |
| 142 codec_.codecType = kVideoCodecVP8; | 157 codec_.codecType = kVideoCodecVP8; |
| 143 codec_.maxFramerate = 30; | 158 codec_.maxFramerate = kFramerate; |
| 144 codec_.width = kWidth; | 159 codec_.width = kWidth; |
| 145 codec_.height = kHeight; | 160 codec_.height = kHeight; |
| 146 codec_.VP8()->numberOfTemporalLayers = 1; | 161 codec_.VP8()->numberOfTemporalLayers = 1; |
| 147 std::unique_ptr<TemporalLayersFactory> tl_factory( | 162 std::unique_ptr<TemporalLayersFactory> tl_factory( |
| 148 new TemporalLayersFactory()); | 163 new TemporalLayersFactory()); |
| 149 codec_.VP8()->tl_factory = tl_factory.get(); | 164 codec_.VP8()->tl_factory = tl_factory.get(); |
| 150 rate_allocator_.reset( | 165 rate_allocator_.reset( |
| 151 new SimulcastRateAllocator(codec_, std::move(tl_factory))); | 166 new SimulcastRateAllocator(codec_, std::move(tl_factory))); |
| 152 | 167 |
| 153 fake_encoder_.init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; | 168 fake_encoder_.init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; |
| 154 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 169 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 155 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize)); | 170 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 156 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 171 EXPECT_EQ( |
| 157 fallback_wrapper_.SetRateAllocation( | 172 WEBRTC_VIDEO_CODEC_OK, |
| 158 rate_allocator_->GetAllocation(300000, 30), 30)); | 173 fallback_wrapper_.SetRateAllocation( |
| 174 rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); |
| 159 | 175 |
| 160 int callback_count = callback_.callback_count_; | 176 int callback_count = callback_.callback_count_; |
| 161 int encode_count = fake_encoder_.encode_count_; | 177 int encode_count = fake_encoder_.encode_count_; |
| 162 EncodeFrame(); | 178 EncodeFrame(); |
| 163 EXPECT_EQ(encode_count, fake_encoder_.encode_count_); | 179 EXPECT_EQ(encode_count, fake_encoder_.encode_count_); |
| 164 EXPECT_EQ(callback_count + 1, callback_.callback_count_); | 180 EXPECT_EQ(callback_count + 1, callback_.callback_count_); |
| 165 } | 181 } |
| 166 | 182 |
| 167 void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { | 183 void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() { |
| 168 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); | 184 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
| 169 codec_.codecType = kVideoCodecVP8; | 185 codec_.codecType = kVideoCodecVP8; |
| 170 codec_.maxFramerate = 30; | 186 codec_.maxFramerate = kFramerate; |
| 171 codec_.width = kWidth; | 187 codec_.width = kWidth; |
| 172 codec_.height = kHeight; | 188 codec_.height = kHeight; |
| 173 codec_.VP8()->numberOfTemporalLayers = 1; | 189 codec_.VP8()->numberOfTemporalLayers = 1; |
| 174 std::unique_ptr<TemporalLayersFactory> tl_factory( | 190 std::unique_ptr<TemporalLayersFactory> tl_factory( |
| 175 new TemporalLayersFactory()); | 191 new TemporalLayersFactory()); |
| 176 codec_.VP8()->tl_factory = tl_factory.get(); | 192 codec_.VP8()->tl_factory = tl_factory.get(); |
| 177 rate_allocator_.reset( | 193 rate_allocator_.reset( |
| 178 new SimulcastRateAllocator(codec_, std::move(tl_factory))); | 194 new SimulcastRateAllocator(codec_, std::move(tl_factory))); |
| 179 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize); | 195 fallback_wrapper_.InitEncode(&codec_, 2, kMaxPayloadSize); |
| 180 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 196 EXPECT_EQ( |
| 181 fallback_wrapper_.SetRateAllocation( | 197 WEBRTC_VIDEO_CODEC_OK, |
| 182 rate_allocator_->GetAllocation(300000, 30), 30)); | 198 fallback_wrapper_.SetRateAllocation( |
| 199 rate_allocator_->GetAllocation(300000, kFramerate), kFramerate)); |
| 183 EXPECT_EQ(1, fake_encoder_.init_encode_count_); | 200 EXPECT_EQ(1, fake_encoder_.init_encode_count_); |
| 184 | 201 |
| 185 // Have the non-fallback encoder request a software fallback. | 202 // Have the non-fallback encoder request a software fallback. |
| 186 fake_encoder_.encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; | 203 fake_encoder_.encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; |
| 187 int callback_count = callback_.callback_count_; | 204 int callback_count = callback_.callback_count_; |
| 188 int encode_count = fake_encoder_.encode_count_; | 205 int encode_count = fake_encoder_.encode_count_; |
| 189 EncodeFrame(); | 206 EncodeFrame(); |
| 190 // Single encode request, which returned failure. | 207 // Single encode request, which returned failure. |
| 191 EXPECT_EQ(encode_count + 1, fake_encoder_.encode_count_); | 208 EXPECT_EQ(encode_count + 1, fake_encoder_.encode_count_); |
| 192 EXPECT_EQ(callback_count + 1, callback_.callback_count_); | 209 EXPECT_EQ(callback_count + 1, callback_.callback_count_); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 SupportsNativeHandleNotForwardedDuringFallback) { | 294 SupportsNativeHandleNotForwardedDuringFallback) { |
| 278 UtilizeFallbackEncoder(); | 295 UtilizeFallbackEncoder(); |
| 279 fallback_wrapper_.SupportsNativeHandle(); | 296 fallback_wrapper_.SupportsNativeHandle(); |
| 280 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); | 297 EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_); |
| 281 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); | 298 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
| 282 } | 299 } |
| 283 | 300 |
| 284 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) { | 301 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) { |
| 285 VideoCodec codec = {}; | 302 VideoCodec codec = {}; |
| 286 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); | 303 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
| 287 fallback_wrapper_.InitEncode(&codec, 2, kMaxPayloadSize); | 304 fallback_wrapper_.InitEncode(&codec, kNumCores, kMaxPayloadSize); |
| 288 EncodeFrame(); | 305 EncodeFrame(); |
| 289 CheckLastEncoderName("fake-encoder"); | 306 CheckLastEncoderName("fake-encoder"); |
| 290 } | 307 } |
| 291 | 308 |
| 292 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, | 309 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, |
| 293 ReportsFallbackImplementationName) { | 310 ReportsFallbackImplementationName) { |
| 294 UtilizeFallbackEncoder(); | 311 UtilizeFallbackEncoder(); |
| 295 // Hard coded expected value since libvpx is the software implementation name | 312 // Hard coded expected value since libvpx is the software implementation name |
| 296 // for VP8. Change accordingly if the underlying implementation does. | 313 // for VP8. Change accordingly if the underlying implementation does. |
| 297 CheckLastEncoderName("libvpx"); | 314 CheckLastEncoderName("libvpx"); |
| 298 } | 315 } |
| 299 | 316 |
| 317 namespace { |
| 318 const int kLowKbps = 220; |
| 319 const int kHighKbps = 300; |
| 320 const int kMinLowDurationMs = 4000; |
| 321 const std::string kFieldTrial = "WebRTC-VP8-Forced-Fallback-Encoder"; |
| 322 } // namespace |
| 323 |
| 324 class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest { |
| 325 public: |
| 326 ForcedFallbackTest(const std::string& field_trials) |
| 327 : VideoEncoderSoftwareFallbackWrapperTest(field_trials) {} |
| 328 |
| 329 ~ForcedFallbackTest() override {} |
| 330 |
| 331 protected: |
| 332 void SetUp() override { |
| 333 clock_.SetTimeMicros(1234); |
| 334 ConfigureVp8Codec(); |
| 335 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.InitEncode( |
| 336 &codec_, kNumCores, kMaxPayloadSize)); |
| 337 EXPECT_EQ(1, fake_encoder_.init_encode_count_); |
| 338 } |
| 339 |
| 340 void TearDown() override { |
| 341 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release()); |
| 342 } |
| 343 |
| 344 void ConfigureVp8Codec() { |
| 345 fallback_wrapper_.RegisterEncodeCompleteCallback(&callback_); |
| 346 std::unique_ptr<TemporalLayersFactory> tl_factory( |
| 347 new TemporalLayersFactory()); |
| 348 codec_.codecType = kVideoCodecVP8; |
| 349 codec_.maxFramerate = kFramerate; |
| 350 codec_.width = kWidth; |
| 351 codec_.height = kHeight; |
| 352 codec_.VP8()->numberOfTemporalLayers = 1; |
| 353 codec_.VP8()->tl_factory = tl_factory.get(); |
| 354 rate_allocator_.reset( |
| 355 new SimulcastRateAllocator(codec_, std::move(tl_factory))); |
| 356 } |
| 357 |
| 358 void SetRateAllocation(uint32_t bitrate_kbps) { |
| 359 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.SetRateAllocation( |
| 360 rate_allocator_->GetAllocation( |
| 361 bitrate_kbps * 1000, kFramerate), |
| 362 kFramerate)); |
| 363 } |
| 364 |
| 365 void EncodeFrameAndVerifyLastName(const char* expected_name) { |
| 366 EncodeFrameAndVerifyLastName(expected_name, WEBRTC_VIDEO_CODEC_OK); |
| 367 } |
| 368 |
| 369 void EncodeFrameAndVerifyLastName(const char* expected_name, |
| 370 int expected_ret) { |
| 371 EncodeFrame(expected_ret); |
| 372 CheckLastEncoderName(expected_name); |
| 373 } |
| 374 |
| 375 rtc::ScopedFakeClock clock_; |
| 376 }; |
| 377 |
| 378 class ForcedFallbackTestEnabled : public ForcedFallbackTest { |
| 379 public: |
| 380 ForcedFallbackTestEnabled() |
| 381 : ForcedFallbackTest(kFieldTrial + "/Enabled-" + |
| 382 std::to_string(kLowKbps) + "," + |
| 383 std::to_string(kHighKbps) + "," + |
| 384 std::to_string(kMinLowDurationMs) + "/") {} |
| 385 }; |
| 386 |
| 387 class ForcedFallbackTestDisabled : public ForcedFallbackTest { |
| 388 public: |
| 389 ForcedFallbackTestDisabled() |
| 390 : ForcedFallbackTest(kFieldTrial + "/Disabled/") {} |
| 391 }; |
| 392 |
| 393 TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) { |
| 394 // Bitrate at low threshold. |
| 395 SetRateAllocation(kLowKbps); |
| 396 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 397 // Duration passed, expect no fallback. |
| 398 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 399 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 400 } |
| 401 |
| 402 TEST_F(ForcedFallbackTestEnabled, FallbackIfAtLowLimit) { |
| 403 // Bitrate at low threshold. |
| 404 SetRateAllocation(kLowKbps); |
| 405 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 406 // Duration passed, expect fallback. |
| 407 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 408 EncodeFrameAndVerifyLastName("libvpx"); |
| 409 } |
| 410 |
| 411 TEST_F(ForcedFallbackTestEnabled, NoFallbackIfNotAtLowLimit) { |
| 412 // Bitrate above low threshold. |
| 413 SetRateAllocation(kLowKbps + 1); |
| 414 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 415 // Duration passed, expect no fallback. |
| 416 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 417 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 418 } |
| 419 |
| 420 TEST_F(ForcedFallbackTestEnabled, NoFallbackIfResolutionIsTooLarge) { |
| 421 // Resolution above max pixels. |
| 422 codec_.width += 1; |
| 423 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 424 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 425 // Bitrate at low threshold. |
| 426 SetRateAllocation(kLowKbps); |
| 427 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 428 // Duration passed, expect no fallback. |
| 429 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 430 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 431 } |
| 432 |
| 433 TEST_F(ForcedFallbackTestEnabled, FallbackIfMinDurationPassed) { |
| 434 // Bitrate at low threshold. |
| 435 SetRateAllocation(kLowKbps); |
| 436 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 437 // Duration not passed, expect no fallback. |
| 438 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs - 1)); |
| 439 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 440 // Duration passed, expect fallback. |
| 441 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); |
| 442 EncodeFrameAndVerifyLastName("libvpx"); |
| 443 } |
| 444 |
| 445 TEST_F(ForcedFallbackTestEnabled, FallbackStartTimeResetIfAboveLowLimit) { |
| 446 // Bitrate at low threshold, start time set. |
| 447 SetRateAllocation(kLowKbps); |
| 448 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 449 // Duration not passed, expect no fallback. |
| 450 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs - 1)); |
| 451 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 452 |
| 453 // Bitrate above low threshold, start time reset. |
| 454 SetRateAllocation(kLowKbps + 1); |
| 455 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); |
| 456 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 457 |
| 458 // Bitrate at low threshold, start time set. |
| 459 SetRateAllocation(kLowKbps); |
| 460 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 461 // Duration not passed, expect no fallback. |
| 462 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs - 1)); |
| 463 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 464 // Duration passed, expect fallback. |
| 465 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); |
| 466 EncodeFrameAndVerifyLastName("libvpx"); |
| 467 } |
| 468 |
| 469 TEST_F(ForcedFallbackTestEnabled, FallbackEndsIfAtHighLimit) { |
| 470 // Bitrate at low threshold. |
| 471 SetRateAllocation(kLowKbps); |
| 472 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 473 // Duration passed, expect fallback. |
| 474 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 475 EncodeFrameAndVerifyLastName("libvpx"); |
| 476 // Bitrate below high threshold, expect fallback. |
| 477 SetRateAllocation(kHighKbps - 1); |
| 478 EncodeFrameAndVerifyLastName("libvpx"); |
| 479 // Bitrate at high threshold, expect fallback ended. |
| 480 SetRateAllocation(kHighKbps); |
| 481 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 482 } |
| 483 |
| 484 TEST_F(ForcedFallbackTestEnabled, MultipleStartEndFallback) { |
| 485 const int kNumRuns = 5; |
| 486 for (int i = 0; i < kNumRuns; ++i) { |
| 487 // Bitrate at low threshold. |
| 488 SetRateAllocation(kLowKbps); |
| 489 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 490 // Duration passed, expect fallback. |
| 491 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 492 EncodeFrameAndVerifyLastName("libvpx"); |
| 493 // Bitrate at high threshold, expect fallback ended. |
| 494 SetRateAllocation(kHighKbps); |
| 495 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 496 } |
| 497 } |
| 498 |
| 499 TEST_F(ForcedFallbackTestEnabled, DropsFirstNonNativeFrameAfterFallbackEnds) { |
| 500 fake_encoder_.supports_native_handle_ = true; |
| 501 |
| 502 // Bitrate at low threshold. |
| 503 SetRateAllocation(kLowKbps); |
| 504 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 505 // Duration passed, expect fallback. |
| 506 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 507 EncodeFrameAndVerifyLastName("libvpx"); |
| 508 // Bitrate at high threshold, fallback should be ended but first non-native |
| 509 // frame dropped (i.e. frame not encoded). |
| 510 SetRateAllocation(kHighKbps); |
| 511 EncodeFrameAndVerifyLastName("libvpx", WEBRTC_VIDEO_CODEC_ERROR); |
| 512 // Next frame should be encoded. |
| 513 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 514 } |
| 515 |
| 516 TEST_F(ForcedFallbackTestEnabled, FallbackIsKeptWhenInitEncodeIsCalled) { |
| 517 // Bitrate below low threshold. |
| 518 SetRateAllocation(kLowKbps - 1); |
| 519 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 520 // Duration passed, expect fallback. |
| 521 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 522 EncodeFrameAndVerifyLastName("libvpx"); |
| 523 |
| 524 // Re-initialize encoder, still expect fallback. |
| 525 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 526 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 527 EXPECT_EQ(1, fake_encoder_.init_encode_count_); // No change. |
| 528 SetRateAllocation(kLowKbps); |
| 529 EncodeFrameAndVerifyLastName("libvpx"); |
| 530 } |
| 531 |
| 532 TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedWhenResolutionIsTooLarge) { |
| 533 // Bitrate below low threshold. |
| 534 SetRateAllocation(kLowKbps - 1); |
| 535 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 536 // Duration passed, expect fallback. |
| 537 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 538 EncodeFrameAndVerifyLastName("libvpx"); |
| 539 |
| 540 // Re-initialize encoder with a larger resolution, expect no fallback. |
| 541 codec_.width += 1; |
| 542 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 543 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 544 EXPECT_EQ(2, fake_encoder_.init_encode_count_); |
| 545 SetRateAllocation(kLowKbps); |
| 546 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 547 } |
| 548 |
| 549 TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedForNonValidSettings) { |
| 550 // Bitrate below low threshold. |
| 551 SetRateAllocation(kLowKbps - 1); |
| 552 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 553 // Duration passed, expect fallback. |
| 554 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 555 EncodeFrameAndVerifyLastName("libvpx"); |
| 556 |
| 557 // Re-initialize encoder with invalid setting, expect no fallback. |
| 558 codec_.VP8()->numberOfTemporalLayers = 2; |
| 559 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 560 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 561 EXPECT_EQ(2, fake_encoder_.init_encode_count_); |
| 562 SetRateAllocation(kLowKbps); |
| 563 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 564 |
| 565 // Re-initialize encoder with valid setting but fallback disabled from now on. |
| 566 codec_.VP8()->numberOfTemporalLayers = 1; |
| 567 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 568 fallback_wrapper_.InitEncode(&codec_, kNumCores, kMaxPayloadSize)); |
| 569 EXPECT_EQ(3, fake_encoder_.init_encode_count_); |
| 570 // Bitrate at low threshold. |
| 571 SetRateAllocation(kLowKbps); |
| 572 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 573 // Duration passed, expect no fallback. |
| 574 clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(kMinLowDurationMs)); |
| 575 EncodeFrameAndVerifyLastName("fake-encoder"); |
| 576 } |
| 577 |
| 300 } // namespace webrtc | 578 } // namespace webrtc |
| OLD | NEW |