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