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