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