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