Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2150)

Side by Side Diff: webrtc/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc

Issue 2988963002: Add support for a forced software encoder fallback. (Closed)
Patch Set: fix comment Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698