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