1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
12
13 #include <stddef.h>
14 #include <stdint.h>
15
16 #include <memory>
17 #include <string>
18 #include <vector>
19
20 #include "absl/types/optional.h"
21 #include "api/fec_controller_override.h"
22 #include "api/scoped_refptr.h"
23 #include "api/test/mock_video_encoder.h"
24 #include "api/video/encoded_image.h"
25 #include "api/video/i420_buffer.h"
26 #include "api/video/video_bitrate_allocation.h"
27 #include "api/video/video_frame.h"
28 #include "api/video/video_frame_buffer.h"
29 #include "api/video/video_rotation.h"
30 #include "api/video_codecs/video_codec.h"
31 #include "api/video_codecs/video_encoder.h"
32 #include "modules/video_coding/codecs/vp8/include/vp8.h"
33 #include "modules/video_coding/include/video_codec_interface.h"
34 #include "modules/video_coding/include/video_error_codes.h"
35 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
36 #include "rtc_base/fake_clock.h"
37 #include "test/fake_texture_frame.h"
38 #include "test/field_trial.h"
39 #include "test/gmock.h"
40 #include "test/gtest.h"
41
42 namespace webrtc {
43 using ::testing::_;
44 using ::testing::Return;
45
46 namespace {
47 const int kWidth = 320;
48 const int kHeight = 240;
49 const int kNumCores = 2;
50 const uint32_t kFramerate = 30;
51 const size_t kMaxPayloadSize = 800;
52 const int kLowThreshold = 10;
53 const int kHighThreshold = 20;
54
55 const VideoEncoder::Capabilities kCapabilities(false);
56 const VideoEncoder::Settings kSettings(kCapabilities,
57 kNumCores,
58 kMaxPayloadSize);
59
GetEncoderInfoWithTrustedRateController(bool trusted_rate_controller)60 VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
61 bool trusted_rate_controller) {
62 VideoEncoder::EncoderInfo info;
63 info.has_trusted_rate_controller = trusted_rate_controller;
64 return info;
65 }
66
GetEncoderInfoWithHardwareAccelerated(bool hardware_accelerated)67 VideoEncoder::EncoderInfo GetEncoderInfoWithHardwareAccelerated(
68 bool hardware_accelerated) {
69 VideoEncoder::EncoderInfo info;
70 info.is_hardware_accelerated = hardware_accelerated;
71 return info;
72 }
73
GetEncoderInfoWithInternalSource(bool internal_source)74 VideoEncoder::EncoderInfo GetEncoderInfoWithInternalSource(
75 bool internal_source) {
76 VideoEncoder::EncoderInfo info;
77 info.has_internal_source = internal_source;
78 return info;
79 }
80
81 class FakeEncodedImageCallback : public EncodedImageCallback {
82 public:
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info)83 Result OnEncodedImage(const EncodedImage& encoded_image,
84 const CodecSpecificInfo* codec_specific_info) override {
85 ++callback_count_;
86 return Result(Result::OK, callback_count_);
87 }
88 int callback_count_ = 0;
89 };
90 } // namespace
91
92 class VideoEncoderSoftwareFallbackWrapperTestBase : public ::testing::Test {
93 protected:
VideoEncoderSoftwareFallbackWrapperTestBase(const std::string & field_trials,std::unique_ptr<VideoEncoder> sw_encoder)94 VideoEncoderSoftwareFallbackWrapperTestBase(
95 const std::string& field_trials,
96 std::unique_ptr<VideoEncoder> sw_encoder)
97 : override_field_trials_(field_trials),
98 fake_encoder_(new CountingFakeEncoder()),
99 wrapper_initialized_(false),
100 fallback_wrapper_(CreateVideoEncoderSoftwareFallbackWrapper(
101 std::move(sw_encoder),
102 std::unique_ptr<VideoEncoder>(fake_encoder_),
103 false)) {}
104
105 class CountingFakeEncoder : public VideoEncoder {
106 public:
SetFecControllerOverride(FecControllerOverride * fec_controller_override)107 void SetFecControllerOverride(
108 FecControllerOverride* fec_controller_override) override {
109 // Ignored.
110 }
111
InitEncode(const VideoCodec * codec_settings,const VideoEncoder::Settings & settings)112 int32_t InitEncode(const VideoCodec* codec_settings,
113 const VideoEncoder::Settings& settings) override {
114 ++init_encode_count_;
115 return init_encode_return_code_;
116 }
117
Encode(const VideoFrame & frame,const std::vector<VideoFrameType> * frame_types)118 int32_t Encode(const VideoFrame& frame,
119 const std::vector<VideoFrameType>* frame_types) override {
120 ++encode_count_;
121 last_video_frame_ = frame;
122 if (encode_complete_callback_ &&
123 encode_return_code_ == WEBRTC_VIDEO_CODEC_OK) {
124 encode_complete_callback_->OnEncodedImage(EncodedImage(), nullptr);
125 }
126 return encode_return_code_;
127 }
128
RegisterEncodeCompleteCallback(EncodedImageCallback * callback)129 int32_t RegisterEncodeCompleteCallback(
130 EncodedImageCallback* callback) override {
131 encode_complete_callback_ = callback;
132 return WEBRTC_VIDEO_CODEC_OK;
133 }
134
Release()135 int32_t Release() override {
136 ++release_count_;
137 return WEBRTC_VIDEO_CODEC_OK;
138 }
139
SetRates(const RateControlParameters & parameters)140 void SetRates(const RateControlParameters& parameters) override {}
141
GetEncoderInfo() const142 EncoderInfo GetEncoderInfo() const override {
143 ++supports_native_handle_count_;
144 EncoderInfo info;
145 info.scaling_settings = ScalingSettings(kLowThreshold, kHighThreshold);
146 info.supports_native_handle = supports_native_handle_;
147 info.implementation_name = implementation_name_;
148 return info;
149 }
150
151 int init_encode_count_ = 0;
152 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
153 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
154 int encode_count_ = 0;
155 EncodedImageCallback* encode_complete_callback_ = nullptr;
156 int release_count_ = 0;
157 mutable int supports_native_handle_count_ = 0;
158 bool supports_native_handle_ = false;
159 std::string implementation_name_ = "fake-encoder";
160 absl::optional<VideoFrame> last_video_frame_;
161 };
162
163 void InitEncode();
164 void UtilizeFallbackEncoder();
165 void FallbackFromEncodeRequest();
166 void EncodeFrame();
167 void EncodeFrame(int expected_ret);
CheckLastEncoderName(const char * expected_name)168 void CheckLastEncoderName(const char* expected_name) {
169 EXPECT_EQ(expected_name,
170 fallback_wrapper_->GetEncoderInfo().implementation_name);
171 }
172
173 test::ScopedFieldTrials override_field_trials_;
174 FakeEncodedImageCallback callback_;
175 // |fake_encoder_| is owned and released by |fallback_wrapper_|.
176 CountingFakeEncoder* fake_encoder_;
177 CountingFakeEncoder* fake_sw_encoder_;
178 bool wrapper_initialized_;
179 std::unique_ptr<VideoEncoder> fallback_wrapper_;
180 VideoCodec codec_ = {};
181 std::unique_ptr<VideoFrame> frame_;
182 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
183 };
184
185 class VideoEncoderSoftwareFallbackWrapperTest
186 : public VideoEncoderSoftwareFallbackWrapperTestBase {
187 protected:
VideoEncoderSoftwareFallbackWrapperTest()188 VideoEncoderSoftwareFallbackWrapperTest()
189 : VideoEncoderSoftwareFallbackWrapperTest(new CountingFakeEncoder()) {}
VideoEncoderSoftwareFallbackWrapperTest(CountingFakeEncoder * fake_sw_encoder)190 explicit VideoEncoderSoftwareFallbackWrapperTest(
191 CountingFakeEncoder* fake_sw_encoder)
192 : VideoEncoderSoftwareFallbackWrapperTestBase(
193 "",
194 std::unique_ptr<VideoEncoder>(fake_sw_encoder)),
195 fake_sw_encoder_(fake_sw_encoder) {
196 fake_sw_encoder_->implementation_name_ = "fake_sw_encoder";
197 }
198
199 CountingFakeEncoder* fake_sw_encoder_;
200 };
201
EncodeFrame()202 void VideoEncoderSoftwareFallbackWrapperTestBase::EncodeFrame() {
203 EncodeFrame(WEBRTC_VIDEO_CODEC_OK);
204 }
205
EncodeFrame(int expected_ret)206 void VideoEncoderSoftwareFallbackWrapperTestBase::EncodeFrame(
207 int expected_ret) {
208 rtc::scoped_refptr<I420Buffer> buffer =
209 I420Buffer::Create(codec_.width, codec_.height);
210 I420Buffer::SetBlack(buffer);
211 std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
212
213 frame_ =
214 std::make_unique<VideoFrame>(VideoFrame::Builder()
215 .set_video_frame_buffer(buffer)
216 .set_rotation(webrtc::kVideoRotation_0)
217 .set_timestamp_us(0)
218 .build());
219 EXPECT_EQ(expected_ret, fallback_wrapper_->Encode(*frame_, &types));
220 }
221
InitEncode()222 void VideoEncoderSoftwareFallbackWrapperTestBase::InitEncode() {
223 if (!wrapper_initialized_) {
224 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
225 EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
226 }
227
228 // Register fake encoder as main.
229 codec_.codecType = kVideoCodecVP8;
230 codec_.maxFramerate = kFramerate;
231 codec_.width = kWidth;
232 codec_.height = kHeight;
233 codec_.VP8()->numberOfTemporalLayers = 1;
234 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
235
236 if (wrapper_initialized_) {
237 fallback_wrapper_->Release();
238 }
239
240 fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
241 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
242 fallback_wrapper_->InitEncode(&codec_, kSettings));
243
244 if (!wrapper_initialized_) {
245 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
246 rate_allocator_->Allocate(
247 VideoBitrateAllocationParameters(300000, kFramerate)),
248 kFramerate));
249 }
250 wrapper_initialized_ = true;
251 }
252
UtilizeFallbackEncoder()253 void VideoEncoderSoftwareFallbackWrapperTestBase::UtilizeFallbackEncoder() {
254 if (!wrapper_initialized_) {
255 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
256 EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
257 }
258
259 // Register with failing fake encoder. Should succeed with VP8 fallback.
260 codec_.codecType = kVideoCodecVP8;
261 codec_.maxFramerate = kFramerate;
262 codec_.width = kWidth;
263 codec_.height = kHeight;
264 codec_.VP8()->numberOfTemporalLayers = 1;
265 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
266
267 if (wrapper_initialized_) {
268 fallback_wrapper_->Release();
269 }
270
271 fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
272 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
273 fallback_wrapper_->InitEncode(&codec_, kSettings));
274 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
275 rate_allocator_->Allocate(
276 VideoBitrateAllocationParameters(300000, kFramerate)),
277 kFramerate));
278
279 int callback_count = callback_.callback_count_;
280 int encode_count = fake_encoder_->encode_count_;
281 EncodeFrame();
282 EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
283 EXPECT_EQ(callback_count + 1, callback_.callback_count_);
284 }
285
FallbackFromEncodeRequest()286 void VideoEncoderSoftwareFallbackWrapperTestBase::FallbackFromEncodeRequest() {
287 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
288 codec_.codecType = kVideoCodecVP8;
289 codec_.maxFramerate = kFramerate;
290 codec_.width = kWidth;
291 codec_.height = kHeight;
292 codec_.VP8()->numberOfTemporalLayers = 1;
293 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
294 if (wrapper_initialized_) {
295 fallback_wrapper_->Release();
296 }
297 fallback_wrapper_->InitEncode(&codec_, kSettings);
298 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
299 rate_allocator_->Allocate(
300 VideoBitrateAllocationParameters(300000, kFramerate)),
301 kFramerate));
302 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
303
304 // Have the non-fallback encoder request a software fallback.
305 fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
306 int callback_count = callback_.callback_count_;
307 int encode_count = fake_encoder_->encode_count_;
308 EncodeFrame();
309 // Single encode request, which returned failure.
310 EXPECT_EQ(encode_count + 1, fake_encoder_->encode_count_);
311 EXPECT_EQ(callback_count + 1, callback_.callback_count_);
312 }
313
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,InitializesEncoder)314 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
315 VideoCodec codec = {};
316 fallback_wrapper_->InitEncode(&codec, kSettings);
317 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
318 }
319
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,EncodeRequestsFallback)320 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
321 FallbackFromEncodeRequest();
322 // After fallback, further encodes shouldn't hit the fake encoder.
323 int encode_count = fake_encoder_->encode_count_;
324 EncodeFrame();
325 EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
326 }
327
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,CanUtilizeFallbackEncoder)328 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
329 UtilizeFallbackEncoder();
330 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
331 }
332
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,InternalEncoderReleasedDuringFallback)333 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
334 InternalEncoderReleasedDuringFallback) {
335 EXPECT_EQ(0, fake_encoder_->init_encode_count_);
336 EXPECT_EQ(0, fake_encoder_->release_count_);
337
338 InitEncode();
339
340 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
341 EXPECT_EQ(0, fake_encoder_->release_count_);
342
343 UtilizeFallbackEncoder();
344
345 // One successful InitEncode(), one failed.
346 EXPECT_EQ(2, fake_encoder_->init_encode_count_);
347 EXPECT_EQ(1, fake_encoder_->release_count_);
348
349 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
350
351 // No extra release when the fallback is released.
352 EXPECT_EQ(2, fake_encoder_->init_encode_count_);
353 EXPECT_EQ(1, fake_encoder_->release_count_);
354 }
355
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,InternalEncoderNotEncodingDuringFallback)356 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
357 InternalEncoderNotEncodingDuringFallback) {
358 UtilizeFallbackEncoder();
359 int encode_count = fake_encoder_->encode_count_;
360 EncodeFrame();
361 EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
362
363 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
364 }
365
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,CanRegisterCallbackWhileUsingFallbackEncoder)366 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
367 CanRegisterCallbackWhileUsingFallbackEncoder) {
368 InitEncode();
369 EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
370
371 UtilizeFallbackEncoder();
372
373 // Registering an encode-complete callback will now pass to the fallback
374 // instead of the main encoder.
375 FakeEncodedImageCallback callback2;
376 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback2);
377 EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
378
379 // Encoding a frame using the fallback should arrive at the new callback.
380 std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
381 frame_->set_timestamp(frame_->timestamp() + 1000);
382 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
383 EXPECT_EQ(callback2.callback_count_, 1);
384
385 // Re-initialize to use the main encoder, the new callback should be in use.
386 InitEncode();
387 EXPECT_EQ(&callback2, fake_encoder_->encode_complete_callback_);
388
389 frame_->set_timestamp(frame_->timestamp() + 2000);
390 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
391 EXPECT_EQ(callback2.callback_count_, 2);
392 }
393
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,SupportsNativeHandleForwardedWithoutFallback)394 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
395 SupportsNativeHandleForwardedWithoutFallback) {
396 fallback_wrapper_->GetEncoderInfo();
397 EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_);
398 }
399
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,SupportsNativeHandleNotForwardedDuringFallback)400 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
401 SupportsNativeHandleNotForwardedDuringFallback) {
402 // Fake encoder signals support for native handle, default (libvpx) does not.
403 fake_encoder_->supports_native_handle_ = true;
404 EXPECT_TRUE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
405 UtilizeFallbackEncoder();
406 EXPECT_FALSE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
407 // Both times, both encoders are queried.
408 EXPECT_EQ(2, fake_encoder_->supports_native_handle_count_);
409 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
410 }
411
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,ReportsImplementationName)412 TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) {
413 codec_.width = kWidth;
414 codec_.height = kHeight;
415 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
416 fallback_wrapper_->InitEncode(&codec_, kSettings);
417 EncodeFrame();
418 CheckLastEncoderName("fake-encoder");
419 }
420
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,ReportsFallbackImplementationName)421 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
422 ReportsFallbackImplementationName) {
423 UtilizeFallbackEncoder();
424 CheckLastEncoderName(fake_sw_encoder_->implementation_name_.c_str());
425 }
426
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,OnEncodeFallbackNativeFrameScaledIfFallbackDoesNotSupportNativeFrames)427 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
428 OnEncodeFallbackNativeFrameScaledIfFallbackDoesNotSupportNativeFrames) {
429 fake_encoder_->supports_native_handle_ = true;
430 fake_sw_encoder_->supports_native_handle_ = false;
431 InitEncode();
432 int width = codec_.width * 2;
433 int height = codec_.height * 2;
434 VideoFrame native_frame = test::FakeNativeBuffer::CreateFrame(
435 width, height, 0, 0, VideoRotation::kVideoRotation_0);
436 std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
437 fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
438
439 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
440 fallback_wrapper_->Encode(native_frame, &types));
441 EXPECT_EQ(1, fake_sw_encoder_->encode_count_);
442 ASSERT_TRUE(fake_sw_encoder_->last_video_frame_.has_value());
443 EXPECT_NE(VideoFrameBuffer::Type::kNative,
444 fake_sw_encoder_->last_video_frame_->video_frame_buffer()->type());
445 EXPECT_EQ(codec_.width, fake_sw_encoder_->last_video_frame_->width());
446 EXPECT_EQ(codec_.height, fake_sw_encoder_->last_video_frame_->height());
447 }
448
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,OnEncodeFallbackNativeFrameForwardedToFallbackIfItSupportsNativeFrames)449 TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
450 OnEncodeFallbackNativeFrameForwardedToFallbackIfItSupportsNativeFrames) {
451 fake_encoder_->supports_native_handle_ = true;
452 fake_sw_encoder_->supports_native_handle_ = true;
453 InitEncode();
454 int width = codec_.width * 2;
455 int height = codec_.height * 2;
456 VideoFrame native_frame = test::FakeNativeBuffer::CreateFrame(
457 width, height, 0, 0, VideoRotation::kVideoRotation_0);
458 std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
459 fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
460
461 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
462 fallback_wrapper_->Encode(native_frame, &types));
463 EXPECT_EQ(1, fake_sw_encoder_->encode_count_);
464 ASSERT_TRUE(fake_sw_encoder_->last_video_frame_.has_value());
465 EXPECT_EQ(VideoFrameBuffer::Type::kNative,
466 fake_sw_encoder_->last_video_frame_->video_frame_buffer()->type());
467 EXPECT_EQ(native_frame.width(), fake_sw_encoder_->last_video_frame_->width());
468 EXPECT_EQ(native_frame.height(),
469 fake_sw_encoder_->last_video_frame_->height());
470 }
471
472 namespace {
473 const int kBitrateKbps = 200;
474 const int kMinPixelsPerFrame = 1;
475 const char kFieldTrial[] = "WebRTC-VP8-Forced-Fallback-Encoder-v2";
476 } // namespace
477
478 class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTestBase {
479 public:
ForcedFallbackTest(const std::string & field_trials)480 explicit ForcedFallbackTest(const std::string& field_trials)
481 : VideoEncoderSoftwareFallbackWrapperTestBase(field_trials,
482 VP8Encoder::Create()) {}
483
~ForcedFallbackTest()484 ~ForcedFallbackTest() override {}
485
486 protected:
SetUp()487 void SetUp() override {
488 clock_.SetTime(Timestamp::Micros(1234));
489 ConfigureVp8Codec();
490 }
491
TearDown()492 void TearDown() override {
493 if (wrapper_initialized_) {
494 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
495 }
496 }
497
ConfigureVp8Codec()498 void ConfigureVp8Codec() {
499 codec_.codecType = kVideoCodecVP8;
500 codec_.maxFramerate = kFramerate;
501 codec_.width = kWidth;
502 codec_.height = kHeight;
503 codec_.VP8()->numberOfTemporalLayers = 1;
504 codec_.VP8()->automaticResizeOn = true;
505 codec_.VP8()->frameDroppingOn = true;
506 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
507 }
508
InitEncode(int width,int height)509 void InitEncode(int width, int height) {
510 codec_.width = width;
511 codec_.height = height;
512 if (wrapper_initialized_) {
513 fallback_wrapper_->Release();
514 }
515 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
516 fallback_wrapper_->InitEncode(&codec_, kSettings));
517 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
518 wrapper_initialized_ = true;
519 SetRateAllocation(kBitrateKbps);
520 }
521
SetRateAllocation(uint32_t bitrate_kbps)522 void SetRateAllocation(uint32_t bitrate_kbps) {
523 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
524 rate_allocator_->Allocate(
525 VideoBitrateAllocationParameters(bitrate_kbps * 1000, kFramerate)),
526 kFramerate));
527 }
528
EncodeFrameAndVerifyLastName(const char * expected_name)529 void EncodeFrameAndVerifyLastName(const char* expected_name) {
530 EncodeFrameAndVerifyLastName(expected_name, WEBRTC_VIDEO_CODEC_OK);
531 }
532
EncodeFrameAndVerifyLastName(const char * expected_name,int expected_ret)533 void EncodeFrameAndVerifyLastName(const char* expected_name,
534 int expected_ret) {
535 EncodeFrame(expected_ret);
536 CheckLastEncoderName(expected_name);
537 }
538
539 rtc::ScopedFakeClock clock_;
540 };
541
542 class ForcedFallbackTestEnabled : public ForcedFallbackTest {
543 public:
ForcedFallbackTestEnabled()544 ForcedFallbackTestEnabled()
545 : ForcedFallbackTest(std::string(kFieldTrial) + "/Enabled-" +
546 std::to_string(kMinPixelsPerFrame) + "," +
547 std::to_string(kWidth * kHeight) + ",30000/") {}
548 };
549
550 class ForcedFallbackTestDisabled : public ForcedFallbackTest {
551 public:
ForcedFallbackTestDisabled()552 ForcedFallbackTestDisabled()
553 : ForcedFallbackTest(std::string(kFieldTrial) + "/Disabled/") {}
554 };
555
TEST_F(ForcedFallbackTestDisabled,NoFallbackWithoutFieldTrial)556 TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) {
557 // Resolution above max threshold.
558 InitEncode(kWidth + 1, kHeight);
559 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
560 EncodeFrameAndVerifyLastName("fake-encoder");
561
562 // Resolution at max threshold.
563 InitEncode(kWidth, kHeight);
564 EncodeFrameAndVerifyLastName("fake-encoder");
565 }
566
TEST_F(ForcedFallbackTestEnabled,FallbackIfAtMaxResolutionLimit)567 TEST_F(ForcedFallbackTestEnabled, FallbackIfAtMaxResolutionLimit) {
568 // Resolution above max threshold.
569 InitEncode(kWidth + 1, kHeight);
570 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
571 EncodeFrameAndVerifyLastName("fake-encoder");
572
573 // Resolution at max threshold.
574 InitEncode(kWidth, kHeight);
575 EncodeFrameAndVerifyLastName("libvpx");
576 }
577
TEST_F(ForcedFallbackTestEnabled,FallbackIsKeptWhenInitEncodeIsCalled)578 TEST_F(ForcedFallbackTestEnabled, FallbackIsKeptWhenInitEncodeIsCalled) {
579 // Resolution above max threshold.
580 InitEncode(kWidth + 1, kHeight);
581 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
582 EncodeFrameAndVerifyLastName("fake-encoder");
583
584 // Resolution at max threshold.
585 InitEncode(kWidth, kHeight);
586 EncodeFrameAndVerifyLastName("libvpx");
587
588 // Re-initialize encoder, still expect fallback.
589 InitEncode(kWidth / 2, kHeight / 2);
590 EXPECT_EQ(1, fake_encoder_->init_encode_count_); // No change.
591 EncodeFrameAndVerifyLastName("libvpx");
592 }
593
TEST_F(ForcedFallbackTestEnabled,FallbackIsEndedWhenResolutionIsTooLarge)594 TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedWhenResolutionIsTooLarge) {
595 // Resolution above max threshold.
596 InitEncode(kWidth + 1, kHeight);
597 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
598 EncodeFrameAndVerifyLastName("fake-encoder");
599
600 // Resolution at max threshold.
601 InitEncode(kWidth, kHeight);
602 EncodeFrameAndVerifyLastName("libvpx");
603
604 // Re-initialize encoder with a larger resolution, expect no fallback.
605 InitEncode(kWidth + 1, kHeight);
606 EXPECT_EQ(2, fake_encoder_->init_encode_count_);
607 EncodeFrameAndVerifyLastName("fake-encoder");
608 }
609
TEST_F(ForcedFallbackTestEnabled,FallbackIsEndedForNonValidSettings)610 TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedForNonValidSettings) {
611 // Resolution at max threshold.
612 InitEncode(kWidth, kHeight);
613 EncodeFrameAndVerifyLastName("libvpx");
614
615 // Re-initialize encoder with invalid setting, expect no fallback.
616 codec_.numberOfSimulcastStreams = 2;
617 InitEncode(kWidth, kHeight);
618 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
619 EncodeFrameAndVerifyLastName("fake-encoder");
620
621 // Re-initialize encoder with valid setting.
622 codec_.numberOfSimulcastStreams = 1;
623 InitEncode(kWidth, kHeight);
624 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
625 EncodeFrameAndVerifyLastName("libvpx");
626 }
627
TEST_F(ForcedFallbackTestEnabled,MultipleStartEndFallback)628 TEST_F(ForcedFallbackTestEnabled, MultipleStartEndFallback) {
629 const int kNumRuns = 5;
630 for (int i = 1; i <= kNumRuns; ++i) {
631 // Resolution at max threshold.
632 InitEncode(kWidth, kHeight);
633 EncodeFrameAndVerifyLastName("libvpx");
634 // Resolution above max threshold.
635 InitEncode(kWidth + 1, kHeight);
636 EXPECT_EQ(i, fake_encoder_->init_encode_count_);
637 EncodeFrameAndVerifyLastName("fake-encoder");
638 }
639 }
640
TEST_F(ForcedFallbackTestDisabled,GetScaleSettings)641 TEST_F(ForcedFallbackTestDisabled, GetScaleSettings) {
642 // Resolution above max threshold.
643 InitEncode(kWidth + 1, kHeight);
644 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
645 EncodeFrameAndVerifyLastName("fake-encoder");
646
647 // Default min pixels per frame should be used.
648 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
649 EXPECT_TRUE(settings.thresholds.has_value());
650 EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
651 }
652
TEST_F(ForcedFallbackTestEnabled,GetScaleSettingsWithNoFallback)653 TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithNoFallback) {
654 // Resolution above max threshold.
655 InitEncode(kWidth + 1, kHeight);
656 EncodeFrameAndVerifyLastName("fake-encoder");
657
658 // Configured min pixels per frame should be used.
659 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
660 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
661 ASSERT_TRUE(settings.thresholds);
662 EXPECT_EQ(kLowThreshold, settings.thresholds->low);
663 EXPECT_EQ(kHighThreshold, settings.thresholds->high);
664 }
665
TEST_F(ForcedFallbackTestEnabled,GetScaleSettingsWithFallback)666 TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) {
667 // Resolution at max threshold.
668 InitEncode(kWidth, kHeight);
669 EncodeFrameAndVerifyLastName("libvpx");
670
671 // Configured min pixels per frame should be used.
672 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
673 EXPECT_TRUE(settings.thresholds.has_value());
674 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
675 }
676
TEST_F(ForcedFallbackTestEnabled,ScalingDisabledIfResizeOff)677 TEST_F(ForcedFallbackTestEnabled, ScalingDisabledIfResizeOff) {
678 // Resolution at max threshold.
679 codec_.VP8()->automaticResizeOn = false;
680 InitEncode(kWidth, kHeight);
681 EncodeFrameAndVerifyLastName("libvpx");
682
683 // Should be disabled for automatic resize off.
684 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
685 EXPECT_FALSE(settings.thresholds.has_value());
686 }
687
TEST(SoftwareFallbackEncoderTest,BothRateControllersNotTrusted)688 TEST(SoftwareFallbackEncoderTest, BothRateControllersNotTrusted) {
689 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
690 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
691
692 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
693 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
694 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
695 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
696
697 std::unique_ptr<VideoEncoder> wrapper =
698 CreateVideoEncoderSoftwareFallbackWrapper(
699 std::unique_ptr<VideoEncoder>(sw_encoder),
700 std::unique_ptr<VideoEncoder>(hw_encoder));
701 EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
702 }
703
TEST(SoftwareFallbackEncoderTest,SwRateControllerTrusted)704 TEST(SoftwareFallbackEncoderTest, SwRateControllerTrusted) {
705 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
706 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
707 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
708 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
709 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
710 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
711
712 std::unique_ptr<VideoEncoder> wrapper =
713 CreateVideoEncoderSoftwareFallbackWrapper(
714 std::unique_ptr<VideoEncoder>(sw_encoder),
715 std::unique_ptr<VideoEncoder>(hw_encoder));
716 EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
717 }
718
TEST(SoftwareFallbackEncoderTest,HwRateControllerTrusted)719 TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) {
720 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
721 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
722 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
723 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
724 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
725 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
726
727 std::unique_ptr<VideoEncoder> wrapper =
728 CreateVideoEncoderSoftwareFallbackWrapper(
729 std::unique_ptr<VideoEncoder>(sw_encoder),
730 std::unique_ptr<VideoEncoder>(hw_encoder));
731 EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
732
733 VideoCodec codec_ = {};
734 codec_.width = 100;
735 codec_.height = 100;
736 wrapper->InitEncode(&codec_, kSettings);
737
738 // Trigger fallback to software.
739 EXPECT_CALL(*hw_encoder, Encode)
740 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
741 VideoFrame frame = VideoFrame::Builder()
742 .set_video_frame_buffer(I420Buffer::Create(100, 100))
743 .build();
744 wrapper->Encode(frame, nullptr);
745
746 EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
747 }
748
TEST(SoftwareFallbackEncoderTest,BothRateControllersTrusted)749 TEST(SoftwareFallbackEncoderTest, BothRateControllersTrusted) {
750 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
751 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
752 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
753 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
754 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
755 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
756
757 std::unique_ptr<VideoEncoder> wrapper =
758 CreateVideoEncoderSoftwareFallbackWrapper(
759 std::unique_ptr<VideoEncoder>(sw_encoder),
760 std::unique_ptr<VideoEncoder>(hw_encoder));
761 EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
762 }
763
TEST(SoftwareFallbackEncoderTest,ReportsHardwareAccelerated)764 TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) {
765 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
766 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
767 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
768 .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(false)));
769 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
770 .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(true)));
771
772 std::unique_ptr<VideoEncoder> wrapper =
773 CreateVideoEncoderSoftwareFallbackWrapper(
774 std::unique_ptr<VideoEncoder>(sw_encoder),
775 std::unique_ptr<VideoEncoder>(hw_encoder));
776 EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);
777
778 VideoCodec codec_ = {};
779 codec_.width = 100;
780 codec_.height = 100;
781 wrapper->InitEncode(&codec_, kSettings);
782
783 // Trigger fallback to software.
784 EXPECT_CALL(*hw_encoder, Encode)
785 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
786 VideoFrame frame = VideoFrame::Builder()
787 .set_video_frame_buffer(I420Buffer::Create(100, 100))
788 .build();
789 wrapper->Encode(frame, nullptr);
790 EXPECT_FALSE(wrapper->GetEncoderInfo().is_hardware_accelerated);
791 }
792
TEST(SoftwareFallbackEncoderTest,ReportsInternalSource)793 TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) {
794 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
795 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
796 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
797 .WillRepeatedly(Return(GetEncoderInfoWithInternalSource(false)));
798 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
799 .WillRepeatedly(Return(GetEncoderInfoWithInternalSource(true)));
800
801 std::unique_ptr<VideoEncoder> wrapper =
802 CreateVideoEncoderSoftwareFallbackWrapper(
803 std::unique_ptr<VideoEncoder>(sw_encoder),
804 std::unique_ptr<VideoEncoder>(hw_encoder));
805 EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source);
806
807 VideoCodec codec_ = {};
808 codec_.width = 100;
809 codec_.height = 100;
810 wrapper->InitEncode(&codec_, kSettings);
811
812 // Trigger fallback to software.
813 EXPECT_CALL(*hw_encoder, Encode)
814 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
815 VideoFrame frame = VideoFrame::Builder()
816 .set_video_frame_buffer(I420Buffer::Create(100, 100))
817 .build();
818 wrapper->Encode(frame, nullptr);
819 EXPECT_FALSE(wrapper->GetEncoderInfo().has_internal_source);
820 }
821
822 class PreferTemporalLayersFallbackTest : public ::testing::Test {
823 public:
PreferTemporalLayersFallbackTest()824 PreferTemporalLayersFallbackTest() {}
SetUp()825 void SetUp() override {
826 sw_ = new ::testing::NiceMock<MockVideoEncoder>();
827 sw_info_.implementation_name = "sw";
828 EXPECT_CALL(*sw_, GetEncoderInfo).WillRepeatedly([&]() {
829 return sw_info_;
830 });
831 EXPECT_CALL(*sw_, InitEncode(_, _, _))
832 .WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));
833
834 hw_ = new ::testing::NiceMock<MockVideoEncoder>();
835 hw_info_.implementation_name = "hw";
836 EXPECT_CALL(*hw_, GetEncoderInfo()).WillRepeatedly([&]() {
837 return hw_info_;
838 });
839 EXPECT_CALL(*hw_, InitEncode(_, _, _))
840 .WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));
841
842 wrapper_ = CreateVideoEncoderSoftwareFallbackWrapper(
843 std::unique_ptr<VideoEncoder>(sw_), std::unique_ptr<VideoEncoder>(hw_),
844 /*prefer_temporal_support=*/true);
845
846 codec_settings.codecType = kVideoCodecVP8;
847 codec_settings.maxFramerate = kFramerate;
848 codec_settings.width = kWidth;
849 codec_settings.height = kHeight;
850 codec_settings.numberOfSimulcastStreams = 1;
851 codec_settings.VP8()->numberOfTemporalLayers = 1;
852 }
853
854 protected:
SetSupportsLayers(VideoEncoder::EncoderInfo * info,bool tl_enabled)855 void SetSupportsLayers(VideoEncoder::EncoderInfo* info, bool tl_enabled) {
856 int num_layers = 1;
857 if (tl_enabled) {
858 num_layers = codec_settings.VP8()->numberOfTemporalLayers;
859 }
860 SetNumLayers(info, num_layers);
861 }
862
SetNumLayers(VideoEncoder::EncoderInfo * info,int num_layers)863 void SetNumLayers(VideoEncoder::EncoderInfo* info, int num_layers) {
864 info->fps_allocation[0].clear();
865 for (int i = 0; i < num_layers; ++i) {
866 info->fps_allocation[0].push_back(
867 VideoEncoder::EncoderInfo::kMaxFramerateFraction >>
868 (num_layers - i - 1));
869 }
870 }
871
872 VideoCodec codec_settings;
873 ::testing::NiceMock<MockVideoEncoder>* sw_;
874 ::testing::NiceMock<MockVideoEncoder>* hw_;
875 VideoEncoder::EncoderInfo sw_info_;
876 VideoEncoder::EncoderInfo hw_info_;
877 std::unique_ptr<VideoEncoder> wrapper_;
878 };
879
TEST_F(PreferTemporalLayersFallbackTest,UsesMainWhenLayersNotUsed)880 TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenLayersNotUsed) {
881 codec_settings.VP8()->numberOfTemporalLayers = 1;
882 SetSupportsLayers(&hw_info_, true);
883 SetSupportsLayers(&sw_info_, true);
884 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
885 wrapper_->InitEncode(&codec_settings, kSettings));
886 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
887 }
888
TEST_F(PreferTemporalLayersFallbackTest,UsesMainWhenLayersSupported)889 TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenLayersSupported) {
890 codec_settings.VP8()->numberOfTemporalLayers = 2;
891 SetSupportsLayers(&hw_info_, true);
892 SetSupportsLayers(&sw_info_, true);
893 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
894 wrapper_->InitEncode(&codec_settings, kSettings));
895 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
896 }
897
TEST_F(PreferTemporalLayersFallbackTest,UsesFallbackWhenLayersNotSupportedOnMain)898 TEST_F(PreferTemporalLayersFallbackTest,
899 UsesFallbackWhenLayersNotSupportedOnMain) {
900 codec_settings.VP8()->numberOfTemporalLayers = 2;
901 SetSupportsLayers(&hw_info_, false);
902 SetSupportsLayers(&sw_info_, true);
903 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
904 wrapper_->InitEncode(&codec_settings, kSettings));
905 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
906 }
907
TEST_F(PreferTemporalLayersFallbackTest,UsesMainWhenNeitherSupportsTemporal)908 TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenNeitherSupportsTemporal) {
909 codec_settings.VP8()->numberOfTemporalLayers = 2;
910 SetSupportsLayers(&hw_info_, false);
911 SetSupportsLayers(&sw_info_, false);
912 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
913 wrapper_->InitEncode(&codec_settings, kSettings));
914 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
915 }
916
TEST_F(PreferTemporalLayersFallbackTest,UsesFallbackWhenLayersAreUndefined)917 TEST_F(PreferTemporalLayersFallbackTest, UsesFallbackWhenLayersAreUndefined) {
918 codec_settings.VP8()->numberOfTemporalLayers = 2;
919 SetNumLayers(&hw_info_, 1);
920 SetNumLayers(&sw_info_, 0);
921 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
922 wrapper_->InitEncode(&codec_settings, kSettings));
923 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
924 }
925
TEST_F(PreferTemporalLayersFallbackTest,PrimesEncoderOnSwitch)926 TEST_F(PreferTemporalLayersFallbackTest, PrimesEncoderOnSwitch) {
927 codec_settings.VP8()->numberOfTemporalLayers = 2;
928 // Both support temporal layers, will use main one.
929 SetSupportsLayers(&hw_info_, true);
930 SetSupportsLayers(&sw_info_, true);
931
932 // On first InitEncode most params have no state and will not be
933 // called to update.
934 EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
935 EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
936
937 EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
938 EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
939
940 EXPECT_CALL(*hw_, SetRates).Times(0);
941 EXPECT_CALL(*hw_, SetRates).Times(0);
942
943 EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
944 EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
945
946 EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
947 EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
948
949 EXPECT_CALL(*hw_, OnLossNotification).Times(0);
950 EXPECT_CALL(*sw_, OnLossNotification).Times(0);
951
952 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
953 wrapper_->InitEncode(&codec_settings, kSettings));
954 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
955
956 FakeEncodedImageCallback callback1;
957 class DummyFecControllerOverride : public FecControllerOverride {
958 public:
959 void SetFecAllowed(bool fec_allowed) override {}
960 };
961 DummyFecControllerOverride fec_controller_override1;
962 VideoEncoder::RateControlParameters rate_params1;
963 float packet_loss1 = 0.1;
964 int64_t rtt1 = 1;
965 VideoEncoder::LossNotification lntf1;
966
967 EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback(&callback1));
968 EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
969 wrapper_->RegisterEncodeCompleteCallback(&callback1);
970
971 EXPECT_CALL(*hw_, SetFecControllerOverride(&fec_controller_override1));
972 EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
973 wrapper_->SetFecControllerOverride(&fec_controller_override1);
974
975 EXPECT_CALL(*hw_, SetRates(rate_params1));
976 EXPECT_CALL(*sw_, SetRates).Times(0);
977 wrapper_->SetRates(rate_params1);
978
979 EXPECT_CALL(*hw_, OnPacketLossRateUpdate(packet_loss1));
980 EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
981 wrapper_->OnPacketLossRateUpdate(packet_loss1);
982
983 EXPECT_CALL(*hw_, OnRttUpdate(rtt1));
984 EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
985 wrapper_->OnRttUpdate(rtt1);
986
987 EXPECT_CALL(*hw_, OnLossNotification).Times(1);
988 EXPECT_CALL(*sw_, OnLossNotification).Times(0);
989 wrapper_->OnLossNotification(lntf1);
990
991 // Release and re-init, with fallback to software. This should trigger
992 // the software encoder to be primed with the current state.
993 wrapper_->Release();
994 EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback(&callback1));
995 EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
996
997 EXPECT_CALL(*sw_, SetFecControllerOverride(&fec_controller_override1));
998 EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
999
1000 // Rate control parameters are cleared on InitEncode.
1001 EXPECT_CALL(*sw_, SetRates).Times(0);
1002 EXPECT_CALL(*hw_, SetRates).Times(0);
1003
1004 EXPECT_CALL(*sw_, OnPacketLossRateUpdate(packet_loss1));
1005 EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
1006
1007 EXPECT_CALL(*sw_, OnRttUpdate(rtt1));
1008 EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
1009
1010 EXPECT_CALL(*sw_, OnLossNotification).Times(1);
1011 EXPECT_CALL(*hw_, OnLossNotification).Times(0);
1012
1013 SetSupportsLayers(&hw_info_, false);
1014 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
1015 wrapper_->InitEncode(&codec_settings, kSettings));
1016 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
1017
1018 // Update with all-new params for the software encoder.
1019 FakeEncodedImageCallback callback2;
1020 DummyFecControllerOverride fec_controller_override2;
1021 VideoEncoder::RateControlParameters rate_params2;
1022 float packet_loss2 = 0.2;
1023 int64_t rtt2 = 2;
1024 VideoEncoder::LossNotification lntf2;
1025
1026 EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback(&callback2));
1027 EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
1028 wrapper_->RegisterEncodeCompleteCallback(&callback2);
1029
1030 EXPECT_CALL(*sw_, SetFecControllerOverride(&fec_controller_override2));
1031 EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
1032 wrapper_->SetFecControllerOverride(&fec_controller_override2);
1033
1034 EXPECT_CALL(*sw_, SetRates(rate_params2));
1035 EXPECT_CALL(*hw_, SetRates).Times(0);
1036 wrapper_->SetRates(rate_params2);
1037
1038 EXPECT_CALL(*sw_, OnPacketLossRateUpdate(packet_loss2));
1039 EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
1040 wrapper_->OnPacketLossRateUpdate(packet_loss2);
1041
1042 EXPECT_CALL(*sw_, OnRttUpdate(rtt2));
1043 EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
1044 wrapper_->OnRttUpdate(rtt2);
1045
1046 EXPECT_CALL(*sw_, OnLossNotification).Times(1);
1047 EXPECT_CALL(*hw_, OnLossNotification).Times(0);
1048 wrapper_->OnLossNotification(lntf2);
1049
1050 // Release and re-init, back to main encoder. This should trigger
1051 // the main encoder to be primed with the current state.
1052 wrapper_->Release();
1053 EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback(&callback2));
1054 EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
1055
1056 EXPECT_CALL(*hw_, SetFecControllerOverride(&fec_controller_override2));
1057 EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
1058
1059 // Rate control parameters are cleared on InitEncode.
1060 EXPECT_CALL(*sw_, SetRates).Times(0);
1061 EXPECT_CALL(*hw_, SetRates).Times(0);
1062
1063 EXPECT_CALL(*hw_, OnPacketLossRateUpdate(packet_loss2));
1064 EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
1065
1066 EXPECT_CALL(*hw_, OnRttUpdate(rtt2));
1067 EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
1068
1069 EXPECT_CALL(*hw_, OnLossNotification).Times(1);
1070 EXPECT_CALL(*sw_, OnLossNotification).Times(0);
1071
1072 SetSupportsLayers(&hw_info_, true);
1073 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
1074 wrapper_->InitEncode(&codec_settings, kSettings));
1075 EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
1076 }
1077
1078 } // namespace webrtc
1079