blob: a26c0c366f8ace09a11f94013b933aaacec4bd29 [file] [log] [blame]
Peter Boström4d71ede2015-05-19 21:09:351/*
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
Jonas Olssona4d87372019-07-05 17:08:3311#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
12
Yves Gerey3e707812018-11-28 15:47:4913#include <stddef.h>
14#include <stdint.h>
Jonas Olssona4d87372019-07-05 17:08:3315
Yves Gerey3e707812018-11-28 15:47:4916#include <memory>
17#include <string>
18#include <vector>
Peter Boström4d71ede2015-05-19 21:09:3519
Yves Gerey3e707812018-11-28 15:47:4920#include "absl/types/optional.h"
Elad Alon8f01c4e2019-06-28 13:19:4321#include "api/fec_controller_override.h"
Mirko Bonadeid9708072019-01-25 19:26:4822#include "api/scoped_refptr.h"
Erik Språngd3438aa2018-11-08 15:56:4323#include "api/test/mock_video_encoder.h"
Yves Gerey3e707812018-11-28 15:47:4924#include "api/video/encoded_image.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3125#include "api/video/i420_buffer.h"
Erik Språng7fd0a282018-05-22 13:37:2326#include "api/video/video_bitrate_allocation.h"
Yves Gerey3e707812018-11-28 15:47:4927#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"
Yves Gerey3e707812018-11-28 15:47:4932#include "modules/include/module_common_types.h"
Magnus Jedvertee92d622017-11-13 14:26:1733#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3134#include "modules/video_coding/include/video_codec_interface.h"
35#include "modules/video_coding/include/video_error_codes.h"
Sergio Garcia Murillo43800f92018-06-21 14:16:3836#include "modules/video_coding/utility/simulcast_rate_allocator.h"
Steve Anton10542f22019-01-11 17:11:0037#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3138#include "test/field_trial.h"
Erik Språngd3438aa2018-11-08 15:56:4339#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3140#include "test/gtest.h"
Peter Boström4d71ede2015-05-19 21:09:3541
42namespace webrtc {
Erik Språngd3438aa2018-11-08 15:56:4343using ::testing::Return;
44
asapersson22c76c42017-08-16 07:53:5945namespace {
noahricb1ce6632015-10-22 06:54:5146const int kWidth = 320;
47const int kHeight = 240;
asapersson22c76c42017-08-16 07:53:5948const int kNumCores = 2;
49const uint32_t kFramerate = 30;
Peter Boström4d71ede2015-05-19 21:09:3550const size_t kMaxPayloadSize = 800;
asapersson142fcc92017-08-17 15:58:5451const int kDefaultMinPixelsPerFrame = 320 * 180;
Åsa Persson45bbc8a2017-11-13 09:16:4752const int kLowThreshold = 10;
53const int kHighThreshold = 20;
Erik Språngd3438aa2018-11-08 15:56:4354
Elad Alon370f93a2019-06-11 12:57:5755const VideoEncoder::Capabilities kCapabilities(false);
56const VideoEncoder::Settings kSettings(kCapabilities,
57 kNumCores,
58 kMaxPayloadSize);
59
Mirta Dvornicic897a9912018-11-30 12:12:2160VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
61 bool trusted_rate_controller) {
Erik Språngd3438aa2018-11-08 15:56:4362 VideoEncoder::EncoderInfo info;
63 info.has_trusted_rate_controller = trusted_rate_controller;
64 return info;
65}
Mirta Dvornicic897a9912018-11-30 12:12:2166
67VideoEncoder::EncoderInfo GetEncoderInfoWithHardwareAccelerated(
68 bool hardware_accelerated) {
69 VideoEncoder::EncoderInfo info;
70 info.is_hardware_accelerated = hardware_accelerated;
71 return info;
72}
73
74VideoEncoder::EncoderInfo GetEncoderInfoWithInternalSource(
75 bool internal_source) {
76 VideoEncoder::EncoderInfo info;
77 info.has_internal_source = internal_source;
78 return info;
79}
asapersson22c76c42017-08-16 07:53:5980} // namespace
Peter Boström4d71ede2015-05-19 21:09:3581
82class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
83 protected:
84 VideoEncoderSoftwareFallbackWrapperTest()
asapersson22c76c42017-08-16 07:53:5985 : VideoEncoderSoftwareFallbackWrapperTest("") {}
86 explicit VideoEncoderSoftwareFallbackWrapperTest(
87 const std::string& field_trials)
88 : override_field_trials_(field_trials),
magjedf52d34d2017-08-29 07:58:5289 fake_encoder_(new CountingFakeEncoder()),
Anders Carlssondd3e0ab2018-06-12 09:15:5690 fallback_wrapper_(CreateVideoEncoderSoftwareFallbackWrapper(
91 std::unique_ptr<VideoEncoder>(VP8Encoder::Create()),
92 std::unique_ptr<VideoEncoder>(fake_encoder_))) {}
Peter Boström4d71ede2015-05-19 21:09:3593
94 class CountingFakeEncoder : public VideoEncoder {
95 public:
Elad Alon8f01c4e2019-06-28 13:19:4396 void SetFecControllerOverride(
97 FecControllerOverride* fec_controller_override) override {
98 // Ignored.
99 }
100
Peter Boström4d71ede2015-05-19 21:09:35101 int32_t InitEncode(const VideoCodec* codec_settings,
Elad Alon370f93a2019-06-11 12:57:57102 const VideoEncoder::Settings& settings) override {
Peter Boström4d71ede2015-05-19 21:09:35103 ++init_encode_count_;
104 return init_encode_return_code_;
105 }
Elad Alon370f93a2019-06-11 12:57:57106
Miguel Casas-Sanchez47650702015-05-30 00:21:40107 int32_t Encode(const VideoFrame& frame,
Niels Möller87e2d782019-03-07 09:18:23108 const std::vector<VideoFrameType>* frame_types) override {
Peter Boström4d71ede2015-05-19 21:09:35109 ++encode_count_;
perkj275afc52016-09-01 07:21:16110 if (encode_complete_callback_ &&
111 encode_return_code_ == WEBRTC_VIDEO_CODEC_OK) {
Erik Språnge2fd86a72018-10-24 09:32:39112 encode_complete_callback_->OnEncodedImage(EncodedImage(), nullptr,
perkj275afc52016-09-01 07:21:16113 nullptr);
114 }
noahricb1ce6632015-10-22 06:54:51115 return encode_return_code_;
Peter Boström4d71ede2015-05-19 21:09:35116 }
117
118 int32_t RegisterEncodeCompleteCallback(
119 EncodedImageCallback* callback) override {
120 encode_complete_callback_ = callback;
121 return WEBRTC_VIDEO_CODEC_OK;
122 }
123
124 int32_t Release() override {
125 ++release_count_;
126 return WEBRTC_VIDEO_CODEC_OK;
127 }
128
Erik Språng16cb8f52019-04-12 11:59:09129 void SetRates(const RateControlParameters& parameters) override {
Peter Boström4d71ede2015-05-19 21:09:35130 ++set_rates_count_;
Peter Boström4d71ede2015-05-19 21:09:35131 }
132
Erik Språnge2fd86a72018-10-24 09:32:39133 EncoderInfo GetEncoderInfo() const override {
Peter Boströmeb66e802015-06-05 09:08:03134 ++supports_native_handle_count_;
Erik Språngff7020a2018-11-06 14:32:48135 EncoderInfo info;
136 info.scaling_settings = ScalingSettings(kLowThreshold, kHighThreshold);
137 info.supports_native_handle = supports_native_handle_;
138 info.implementation_name = "fake-encoder";
139 return info;
asapersson142fcc92017-08-17 15:58:54140 }
141
Peter Boström4d71ede2015-05-19 21:09:35142 int init_encode_count_ = 0;
143 int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
noahricb1ce6632015-10-22 06:54:51144 int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
Peter Boström4d71ede2015-05-19 21:09:35145 int encode_count_ = 0;
146 EncodedImageCallback* encode_complete_callback_ = nullptr;
147 int release_count_ = 0;
Peter Boström4d71ede2015-05-19 21:09:35148 int set_rates_count_ = 0;
Peter Boströmeb66e802015-06-05 09:08:03149 mutable int supports_native_handle_count_ = 0;
asapersson22c76c42017-08-16 07:53:59150 bool supports_native_handle_ = false;
Peter Boström4d71ede2015-05-19 21:09:35151 };
152
153 class FakeEncodedImageCallback : public EncodedImageCallback {
154 public:
Sergey Ulanov525df3f2016-08-03 00:46:41155 Result OnEncodedImage(
156 const EncodedImage& encoded_image,
157 const CodecSpecificInfo* codec_specific_info,
158 const RTPFragmentationHeader* fragmentation) override {
159 ++callback_count_;
160 return Result(Result::OK, callback_count_);
Peter Boström4d71ede2015-05-19 21:09:35161 }
162 int callback_count_ = 0;
163 };
164
165 void UtilizeFallbackEncoder();
noahricb1ce6632015-10-22 06:54:51166 void FallbackFromEncodeRequest();
167 void EncodeFrame();
asapersson22c76c42017-08-16 07:53:59168 void EncodeFrame(int expected_ret);
perkj275afc52016-09-01 07:21:16169 void CheckLastEncoderName(const char* expected_name) {
Erik Språnge2fd86a72018-10-24 09:32:39170 EXPECT_EQ(expected_name,
171 fallback_wrapper_->GetEncoderInfo().implementation_name);
perkj275afc52016-09-01 07:21:16172 }
Peter Boström4d71ede2015-05-19 21:09:35173
asapersson22c76c42017-08-16 07:53:59174 test::ScopedFieldTrials override_field_trials_;
Peter Boström4d71ede2015-05-19 21:09:35175 FakeEncodedImageCallback callback_;
magjedf52d34d2017-08-29 07:58:52176 // |fake_encoder_| is owned and released by |fallback_wrapper_|.
177 CountingFakeEncoder* fake_encoder_;
Anders Carlssondd3e0ab2018-06-12 09:15:56178 std::unique_ptr<VideoEncoder> fallback_wrapper_;
Peter Boström4d71ede2015-05-19 21:09:35179 VideoCodec codec_ = {};
nisse64ec8f82016-09-27 07:17:25180 std::unique_ptr<VideoFrame> frame_;
Erik Språng08127a92016-11-16 15:41:30181 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
Peter Boström4d71ede2015-05-19 21:09:35182};
183
noahricb1ce6632015-10-22 06:54:51184void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame() {
asapersson22c76c42017-08-16 07:53:59185 EncodeFrame(WEBRTC_VIDEO_CODEC_OK);
186}
187
188void VideoEncoderSoftwareFallbackWrapperTest::EncodeFrame(int expected_ret) {
asapersson142fcc92017-08-17 15:58:54189 rtc::scoped_refptr<I420Buffer> buffer =
190 I420Buffer::Create(codec_.width, codec_.height);
nisseaf916892017-01-10 15:44:26191 I420Buffer::SetBlack(buffer);
Niels Möller8f7ce222019-03-21 14:43:58192 std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
nisse64ec8f82016-09-27 07:17:25193
Artem Titov1ebfb6a2019-01-03 22:49:37194 frame_ =
Mirko Bonadei317a1f02019-09-17 15:06:18195 std::make_unique<VideoFrame>(VideoFrame::Builder()
196 .set_video_frame_buffer(buffer)
197 .set_rotation(webrtc::kVideoRotation_0)
198 .set_timestamp_us(0)
199 .build());
Niels Möllerc8d2e732019-03-06 11:00:33200 EXPECT_EQ(expected_ret, fallback_wrapper_->Encode(*frame_, &types));
noahricb1ce6632015-10-22 06:54:51201}
202
Peter Boström4d71ede2015-05-19 21:09:35203void VideoEncoderSoftwareFallbackWrapperTest::UtilizeFallbackEncoder() {
Anders Carlssondd3e0ab2018-06-12 09:15:56204 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
magjedf52d34d2017-08-29 07:58:52205 EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
Peter Boström4d71ede2015-05-19 21:09:35206
207 // Register with failing fake encoder. Should succeed with VP8 fallback.
208 codec_.codecType = kVideoCodecVP8;
asapersson22c76c42017-08-16 07:53:59209 codec_.maxFramerate = kFramerate;
Peter Boström4d71ede2015-05-19 21:09:35210 codec_.width = kWidth;
211 codec_.height = kHeight;
Erik Språng08127a92016-11-16 15:41:30212 codec_.VP8()->numberOfTemporalLayers = 1;
Erik Språng82fad3d2018-03-21 08:57:23213 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Erik Språng08127a92016-11-16 15:41:30214
magjedf52d34d2017-08-29 07:58:52215 fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
Peter Boström4d71ede2015-05-19 21:09:35216 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
Elad Alon370f93a2019-06-11 12:57:57217 fallback_wrapper_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 11:59:09218 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 13:16:28219 rate_allocator_->Allocate(
220 VideoBitrateAllocationParameters(300000, kFramerate)),
221 kFramerate));
Peter Boström4d71ede2015-05-19 21:09:35222
noahricb1ce6632015-10-22 06:54:51223 int callback_count = callback_.callback_count_;
magjedf52d34d2017-08-29 07:58:52224 int encode_count = fake_encoder_->encode_count_;
noahricb1ce6632015-10-22 06:54:51225 EncodeFrame();
magjedf52d34d2017-08-29 07:58:52226 EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
noahricb1ce6632015-10-22 06:54:51227 EXPECT_EQ(callback_count + 1, callback_.callback_count_);
228}
Peter Boström4d71ede2015-05-19 21:09:35229
noahricb1ce6632015-10-22 06:54:51230void VideoEncoderSoftwareFallbackWrapperTest::FallbackFromEncodeRequest() {
Anders Carlssondd3e0ab2018-06-12 09:15:56231 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
noahricb1ce6632015-10-22 06:54:51232 codec_.codecType = kVideoCodecVP8;
asapersson22c76c42017-08-16 07:53:59233 codec_.maxFramerate = kFramerate;
noahricb1ce6632015-10-22 06:54:51234 codec_.width = kWidth;
235 codec_.height = kHeight;
Erik Språng08127a92016-11-16 15:41:30236 codec_.VP8()->numberOfTemporalLayers = 1;
Erik Språng82fad3d2018-03-21 08:57:23237 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 12:57:57238 fallback_wrapper_->InitEncode(&codec_, kSettings);
Erik Språng16cb8f52019-04-12 11:59:09239 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 13:16:28240 rate_allocator_->Allocate(
241 VideoBitrateAllocationParameters(300000, kFramerate)),
242 kFramerate));
magjedf52d34d2017-08-29 07:58:52243 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
noahricb1ce6632015-10-22 06:54:51244
245 // Have the non-fallback encoder request a software fallback.
magjedf52d34d2017-08-29 07:58:52246 fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
noahricb1ce6632015-10-22 06:54:51247 int callback_count = callback_.callback_count_;
magjedf52d34d2017-08-29 07:58:52248 int encode_count = fake_encoder_->encode_count_;
noahricb1ce6632015-10-22 06:54:51249 EncodeFrame();
250 // Single encode request, which returned failure.
magjedf52d34d2017-08-29 07:58:52251 EXPECT_EQ(encode_count + 1, fake_encoder_->encode_count_);
noahricb1ce6632015-10-22 06:54:51252 EXPECT_EQ(callback_count + 1, callback_.callback_count_);
Peter Boström4d71ede2015-05-19 21:09:35253}
254
255TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
256 VideoCodec codec = {};
Elad Alon370f93a2019-06-11 12:57:57257 fallback_wrapper_->InitEncode(&codec, kSettings);
magjedf52d34d2017-08-29 07:58:52258 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
Peter Boström4d71ede2015-05-19 21:09:35259}
260
noahricb1ce6632015-10-22 06:54:51261TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
262 FallbackFromEncodeRequest();
263 // After fallback, further encodes shouldn't hit the fake encoder.
magjedf52d34d2017-08-29 07:58:52264 int encode_count = fake_encoder_->encode_count_;
noahricb1ce6632015-10-22 06:54:51265 EncodeFrame();
magjedf52d34d2017-08-29 07:58:52266 EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
noahricb1ce6632015-10-22 06:54:51267}
268
Peter Boström4d71ede2015-05-19 21:09:35269TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
270 UtilizeFallbackEncoder();
Anders Carlssondd3e0ab2018-06-12 09:15:56271 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
Peter Boström4d71ede2015-05-19 21:09:35272}
273
274TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
noahricb1ce6632015-10-22 06:54:51275 InternalEncoderReleasedDuringFallback) {
magjedf52d34d2017-08-29 07:58:52276 EXPECT_EQ(0, fake_encoder_->release_count_);
noahricb1ce6632015-10-22 06:54:51277 UtilizeFallbackEncoder();
magjedf52d34d2017-08-29 07:58:52278 EXPECT_EQ(1, fake_encoder_->release_count_);
Anders Carlssondd3e0ab2018-06-12 09:15:56279 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
noahricb1ce6632015-10-22 06:54:51280 // No extra release when the fallback is released.
magjedf52d34d2017-08-29 07:58:52281 EXPECT_EQ(1, fake_encoder_->release_count_);
Peter Boström4d71ede2015-05-19 21:09:35282}
283
284TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
285 InternalEncoderNotEncodingDuringFallback) {
286 UtilizeFallbackEncoder();
magjedf52d34d2017-08-29 07:58:52287 int encode_count = fake_encoder_->encode_count_;
noahricb1ce6632015-10-22 06:54:51288 EncodeFrame();
magjedf52d34d2017-08-29 07:58:52289 EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
Peter Boström4d71ede2015-05-19 21:09:35290
Anders Carlssondd3e0ab2018-06-12 09:15:56291 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
Peter Boström4d71ede2015-05-19 21:09:35292}
293
294TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
295 CanRegisterCallbackWhileUsingFallbackEncoder) {
296 UtilizeFallbackEncoder();
297 // Registering an encode-complete callback should still work when fallback
298 // encoder is being used.
299 FakeEncodedImageCallback callback2;
Anders Carlssondd3e0ab2018-06-12 09:15:56300 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback2);
magjedf52d34d2017-08-29 07:58:52301 EXPECT_EQ(&callback2, fake_encoder_->encode_complete_callback_);
Peter Boström4d71ede2015-05-19 21:09:35302
303 // Encoding a frame using the fallback should arrive at the new callback.
Niels Möller8f7ce222019-03-21 14:43:58304 std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
nisse64ec8f82016-09-27 07:17:25305 frame_->set_timestamp(frame_->timestamp() + 1000);
Niels Möllerc8d2e732019-03-06 11:00:33306 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
Peter Boström4d71ede2015-05-19 21:09:35307
Anders Carlssondd3e0ab2018-06-12 09:15:56308 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
Peter Boström4d71ede2015-05-19 21:09:35309}
310
311TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
Peter Boström4d71ede2015-05-19 21:09:35312 SetRatesForwardedDuringFallback) {
313 UtilizeFallbackEncoder();
magjedf52d34d2017-08-29 07:58:52314 EXPECT_EQ(1, fake_encoder_->set_rates_count_);
Erik Språng16cb8f52019-04-12 11:59:09315 fallback_wrapper_->SetRates(
316 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 1));
magjedf52d34d2017-08-29 07:58:52317 EXPECT_EQ(2, fake_encoder_->set_rates_count_);
Anders Carlssondd3e0ab2018-06-12 09:15:56318 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
Peter Boström4d71ede2015-05-19 21:09:35319}
320
321TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
Peter Boströmeb66e802015-06-05 09:08:03322 SupportsNativeHandleForwardedWithoutFallback) {
Erik Språnge2fd86a72018-10-24 09:32:39323 fallback_wrapper_->GetEncoderInfo();
magjedf52d34d2017-08-29 07:58:52324 EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_);
Peter Boströmeb66e802015-06-05 09:08:03325}
326
327TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
328 SupportsNativeHandleNotForwardedDuringFallback) {
Erik Språnge2fd86a72018-10-24 09:32:39329 // Fake encoder signals support for native handle, default (libvpx) does not.
330 fake_encoder_->supports_native_handle_ = true;
331 EXPECT_TRUE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
Peter Boströmeb66e802015-06-05 09:08:03332 UtilizeFallbackEncoder();
Erik Språnge2fd86a72018-10-24 09:32:39333 EXPECT_FALSE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
334 // Both times, both encoders are queried.
335 EXPECT_EQ(2, fake_encoder_->supports_native_handle_count_);
Anders Carlssondd3e0ab2018-06-12 09:15:56336 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
Peter Boströmeb66e802015-06-05 09:08:03337}
338
perkj275afc52016-09-01 07:21:16339TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) {
asapersson142fcc92017-08-17 15:58:54340 codec_.width = kWidth;
341 codec_.height = kHeight;
Anders Carlssondd3e0ab2018-06-12 09:15:56342 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
Elad Alon370f93a2019-06-11 12:57:57343 fallback_wrapper_->InitEncode(&codec_, kSettings);
perkj275afc52016-09-01 07:21:16344 EncodeFrame();
345 CheckLastEncoderName("fake-encoder");
346}
347
Peter Boströmb7d9a972015-12-18 15:01:11348TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
349 ReportsFallbackImplementationName) {
350 UtilizeFallbackEncoder();
351 // Hard coded expected value since libvpx is the software implementation name
352 // for VP8. Change accordingly if the underlying implementation does.
perkj275afc52016-09-01 07:21:16353 CheckLastEncoderName("libvpx");
Peter Boströmb7d9a972015-12-18 15:01:11354}
355
asapersson22c76c42017-08-16 07:53:59356namespace {
Åsa Persson45bbc8a2017-11-13 09:16:47357const int kBitrateKbps = 200;
asapersson142fcc92017-08-17 15:58:54358const int kMinPixelsPerFrame = 1;
Åsa Persson45bbc8a2017-11-13 09:16:47359const char kFieldTrial[] = "WebRTC-VP8-Forced-Fallback-Encoder-v2";
asapersson22c76c42017-08-16 07:53:59360} // namespace
361
362class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTest {
363 public:
Steve Antone78bcb92017-10-31 16:53:08364 explicit ForcedFallbackTest(const std::string& field_trials)
asapersson22c76c42017-08-16 07:53:59365 : VideoEncoderSoftwareFallbackWrapperTest(field_trials) {}
366
367 ~ForcedFallbackTest() override {}
368
369 protected:
370 void SetUp() override {
Sebastian Jansson40889f32019-04-17 10:11:20371 clock_.SetTime(Timestamp::us(1234));
asapersson22c76c42017-08-16 07:53:59372 ConfigureVp8Codec();
asapersson22c76c42017-08-16 07:53:59373 }
374
375 void TearDown() override {
Anders Carlssondd3e0ab2018-06-12 09:15:56376 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
asapersson22c76c42017-08-16 07:53:59377 }
378
379 void ConfigureVp8Codec() {
Anders Carlssondd3e0ab2018-06-12 09:15:56380 fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
asapersson22c76c42017-08-16 07:53:59381 codec_.codecType = kVideoCodecVP8;
382 codec_.maxFramerate = kFramerate;
383 codec_.width = kWidth;
384 codec_.height = kHeight;
385 codec_.VP8()->numberOfTemporalLayers = 1;
asapersson142fcc92017-08-17 15:58:54386 codec_.VP8()->automaticResizeOn = true;
387 codec_.VP8()->frameDroppingOn = true;
Erik Språng82fad3d2018-03-21 08:57:23388 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
asapersson22c76c42017-08-16 07:53:59389 }
390
Åsa Persson45bbc8a2017-11-13 09:16:47391 void InitEncode(int width, int height) {
392 codec_.width = width;
393 codec_.height = height;
Elad Alon370f93a2019-06-11 12:57:57394 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
395 fallback_wrapper_->InitEncode(&codec_, kSettings));
Åsa Persson45bbc8a2017-11-13 09:16:47396 SetRateAllocation(kBitrateKbps);
397 }
398
asapersson22c76c42017-08-16 07:53:59399 void SetRateAllocation(uint32_t bitrate_kbps) {
Erik Språng16cb8f52019-04-12 11:59:09400 fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 13:16:28401 rate_allocator_->Allocate(
402 VideoBitrateAllocationParameters(bitrate_kbps * 1000, kFramerate)),
Erik Språng16cb8f52019-04-12 11:59:09403 kFramerate));
asapersson22c76c42017-08-16 07:53:59404 }
405
406 void EncodeFrameAndVerifyLastName(const char* expected_name) {
407 EncodeFrameAndVerifyLastName(expected_name, WEBRTC_VIDEO_CODEC_OK);
408 }
409
410 void EncodeFrameAndVerifyLastName(const char* expected_name,
411 int expected_ret) {
412 EncodeFrame(expected_ret);
413 CheckLastEncoderName(expected_name);
414 }
415
416 rtc::ScopedFakeClock clock_;
417};
418
419class ForcedFallbackTestEnabled : public ForcedFallbackTest {
420 public:
421 ForcedFallbackTestEnabled()
Steve Antone78bcb92017-10-31 16:53:08422 : ForcedFallbackTest(std::string(kFieldTrial) + "/Enabled-" +
Åsa Persson45bbc8a2017-11-13 09:16:47423 std::to_string(kMinPixelsPerFrame) + "," +
424 std::to_string(kWidth * kHeight) + ",30000/") {}
asapersson22c76c42017-08-16 07:53:59425};
426
427class ForcedFallbackTestDisabled : public ForcedFallbackTest {
428 public:
429 ForcedFallbackTestDisabled()
Steve Antone78bcb92017-10-31 16:53:08430 : ForcedFallbackTest(std::string(kFieldTrial) + "/Disabled/") {}
asapersson22c76c42017-08-16 07:53:59431};
432
433TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) {
Åsa Persson45bbc8a2017-11-13 09:16:47434 // Resolution above max threshold.
435 InitEncode(kWidth + 1, kHeight);
436 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59437 EncodeFrameAndVerifyLastName("fake-encoder");
Åsa Persson45bbc8a2017-11-13 09:16:47438
439 // Resolution at max threshold.
440 InitEncode(kWidth, kHeight);
asapersson22c76c42017-08-16 07:53:59441 EncodeFrameAndVerifyLastName("fake-encoder");
442}
443
Åsa Persson45bbc8a2017-11-13 09:16:47444TEST_F(ForcedFallbackTestEnabled, FallbackIfAtMaxResolutionLimit) {
445 // Resolution above max threshold.
446 InitEncode(kWidth + 1, kHeight);
447 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59448 EncodeFrameAndVerifyLastName("fake-encoder");
Åsa Persson45bbc8a2017-11-13 09:16:47449
450 // Resolution at max threshold.
451 InitEncode(kWidth, kHeight);
asapersson22c76c42017-08-16 07:53:59452 EncodeFrameAndVerifyLastName("libvpx");
453}
454
Åsa Persson45bbc8a2017-11-13 09:16:47455TEST_F(ForcedFallbackTestEnabled, FallbackIsKeptWhenInitEncodeIsCalled) {
456 // Resolution above max threshold.
457 InitEncode(kWidth + 1, kHeight);
458 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59459 EncodeFrameAndVerifyLastName("fake-encoder");
asapersson22c76c42017-08-16 07:53:59460
Åsa Persson45bbc8a2017-11-13 09:16:47461 // Resolution at max threshold.
462 InitEncode(kWidth, kHeight);
463 EncodeFrameAndVerifyLastName("libvpx");
asapersson22c76c42017-08-16 07:53:59464
Åsa Persson45bbc8a2017-11-13 09:16:47465 // Re-initialize encoder, still expect fallback.
466 InitEncode(kWidth / 2, kHeight / 2);
467 EXPECT_EQ(1, fake_encoder_->init_encode_count_); // No change.
asapersson22c76c42017-08-16 07:53:59468 EncodeFrameAndVerifyLastName("libvpx");
469}
470
Åsa Persson45bbc8a2017-11-13 09:16:47471TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedWhenResolutionIsTooLarge) {
472 // Resolution above max threshold.
473 InitEncode(kWidth + 1, kHeight);
474 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59475 EncodeFrameAndVerifyLastName("fake-encoder");
476
Åsa Persson45bbc8a2017-11-13 09:16:47477 // Resolution at max threshold.
478 InitEncode(kWidth, kHeight);
asapersson22c76c42017-08-16 07:53:59479 EncodeFrameAndVerifyLastName("libvpx");
Åsa Persson45bbc8a2017-11-13 09:16:47480
481 // Re-initialize encoder with a larger resolution, expect no fallback.
482 InitEncode(kWidth + 1, kHeight);
483 EXPECT_EQ(2, fake_encoder_->init_encode_count_);
484 EncodeFrameAndVerifyLastName("fake-encoder");
asapersson22c76c42017-08-16 07:53:59485}
486
Åsa Persson45bbc8a2017-11-13 09:16:47487TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedForNonValidSettings) {
488 // Resolution at max threshold.
489 InitEncode(kWidth, kHeight);
490 EncodeFrameAndVerifyLastName("libvpx");
491
492 // Re-initialize encoder with invalid setting, expect no fallback.
493 codec_.VP8()->numberOfTemporalLayers = 2;
494 InitEncode(kWidth, kHeight);
495 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59496 EncodeFrameAndVerifyLastName("fake-encoder");
Åsa Persson45bbc8a2017-11-13 09:16:47497
498 // Re-initialize encoder with valid setting but fallback disabled from now on.
499 codec_.VP8()->numberOfTemporalLayers = 1;
500 InitEncode(kWidth, kHeight);
501 EXPECT_EQ(2, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59502 EncodeFrameAndVerifyLastName("fake-encoder");
503}
504
505TEST_F(ForcedFallbackTestEnabled, MultipleStartEndFallback) {
506 const int kNumRuns = 5;
Åsa Persson45bbc8a2017-11-13 09:16:47507 for (int i = 1; i <= kNumRuns; ++i) {
508 // Resolution at max threshold.
509 InitEncode(kWidth, kHeight);
asapersson22c76c42017-08-16 07:53:59510 EncodeFrameAndVerifyLastName("libvpx");
Åsa Persson45bbc8a2017-11-13 09:16:47511 // Resolution above max threshold.
512 InitEncode(kWidth + 1, kHeight);
513 EXPECT_EQ(i, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59514 EncodeFrameAndVerifyLastName("fake-encoder");
515 }
516}
517
Åsa Persson45bbc8a2017-11-13 09:16:47518TEST_F(ForcedFallbackTestDisabled, GetScaleSettings) {
519 // Resolution above max threshold.
520 InitEncode(kWidth + 1, kHeight);
521 EXPECT_EQ(1, fake_encoder_->init_encode_count_);
asapersson22c76c42017-08-16 07:53:59522 EncodeFrameAndVerifyLastName("fake-encoder");
523
asapersson142fcc92017-08-17 15:58:54524 // Default min pixels per frame should be used.
Erik Språnge2fd86a72018-10-24 09:32:39525 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
Niels Möller225c787c2018-02-22 14:03:53526 EXPECT_TRUE(settings.thresholds.has_value());
asapersson142fcc92017-08-17 15:58:54527 EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
528}
529
Åsa Persson45bbc8a2017-11-13 09:16:47530TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithNoFallback) {
531 // Resolution above max threshold.
532 InitEncode(kWidth + 1, kHeight);
asapersson142fcc92017-08-17 15:58:54533 EncodeFrameAndVerifyLastName("fake-encoder");
Åsa Persson45bbc8a2017-11-13 09:16:47534
535 // Configured min pixels per frame should be used.
Erik Språnge2fd86a72018-10-24 09:32:39536 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
Åsa Persson45bbc8a2017-11-13 09:16:47537 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
538 ASSERT_TRUE(settings.thresholds);
539 EXPECT_EQ(kLowThreshold, settings.thresholds->low);
540 EXPECT_EQ(kHighThreshold, settings.thresholds->high);
541}
542
543TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) {
544 // Resolution at max threshold.
545 InitEncode(kWidth, kHeight);
asapersson142fcc92017-08-17 15:58:54546 EncodeFrameAndVerifyLastName("libvpx");
Åsa Persson45bbc8a2017-11-13 09:16:47547
asapersson142fcc92017-08-17 15:58:54548 // Configured min pixels per frame should be used.
Erik Språnge2fd86a72018-10-24 09:32:39549 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
Niels Möller225c787c2018-02-22 14:03:53550 EXPECT_TRUE(settings.thresholds.has_value());
asapersson142fcc92017-08-17 15:58:54551 EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
552}
553
Åsa Persson45bbc8a2017-11-13 09:16:47554TEST_F(ForcedFallbackTestEnabled, ScalingDisabledIfResizeOff) {
555 // Resolution at max threshold.
556 codec_.VP8()->automaticResizeOn = false;
557 InitEncode(kWidth, kHeight);
asapersson142fcc92017-08-17 15:58:54558 EncodeFrameAndVerifyLastName("libvpx");
559
Åsa Persson45bbc8a2017-11-13 09:16:47560 // Should be disabled for automatic resize off.
Erik Språnge2fd86a72018-10-24 09:32:39561 const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
Niels Möller225c787c2018-02-22 14:03:53562 EXPECT_FALSE(settings.thresholds.has_value());
asapersson142fcc92017-08-17 15:58:54563}
564
Erik Språngd3438aa2018-11-08 15:56:43565TEST(SoftwareFallbackEncoderTest, BothRateControllersNotTrusted) {
Mirko Bonadei6a489f22019-04-09 13:11:12566 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
567 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
Erik Språngd3438aa2018-11-08 15:56:43568
569 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21570 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
Erik Språngd3438aa2018-11-08 15:56:43571 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21572 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
Erik Språngd3438aa2018-11-08 15:56:43573
574 std::unique_ptr<VideoEncoder> wrapper =
575 CreateVideoEncoderSoftwareFallbackWrapper(
576 std::unique_ptr<VideoEncoder>(sw_encoder),
577 std::unique_ptr<VideoEncoder>(hw_encoder));
578 EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
579}
580
581TEST(SoftwareFallbackEncoderTest, SwRateControllerTrusted) {
Mirko Bonadei6a489f22019-04-09 13:11:12582 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
583 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
Erik Språngd3438aa2018-11-08 15:56:43584 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21585 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
Erik Språngd3438aa2018-11-08 15:56:43586 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21587 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
Erik Språngd3438aa2018-11-08 15:56:43588
589 std::unique_ptr<VideoEncoder> wrapper =
590 CreateVideoEncoderSoftwareFallbackWrapper(
591 std::unique_ptr<VideoEncoder>(sw_encoder),
592 std::unique_ptr<VideoEncoder>(hw_encoder));
593 EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
594}
595
596TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) {
Mirko Bonadei6a489f22019-04-09 13:11:12597 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
598 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
Erik Språngd3438aa2018-11-08 15:56:43599 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21600 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
Erik Språngd3438aa2018-11-08 15:56:43601 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21602 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
Erik Språngd3438aa2018-11-08 15:56:43603
604 std::unique_ptr<VideoEncoder> wrapper =
605 CreateVideoEncoderSoftwareFallbackWrapper(
606 std::unique_ptr<VideoEncoder>(sw_encoder),
607 std::unique_ptr<VideoEncoder>(hw_encoder));
608 EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
609
Elad Alon370f93a2019-06-11 12:57:57610 VideoCodec codec_ = {};
611 wrapper->InitEncode(&codec_, kSettings);
612
Erik Språngd3438aa2018-11-08 15:56:43613 // Trigger fallback to software.
614 EXPECT_CALL(*hw_encoder, Encode)
615 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
Ilya Nikolaevskiy6aca0b72019-02-13 10:55:57616 VideoFrame frame = VideoFrame::Builder()
617 .set_video_frame_buffer(I420Buffer::Create(100, 100))
618 .build();
Niels Möllerc8d2e732019-03-06 11:00:33619 wrapper->Encode(frame, nullptr);
Erik Språngd3438aa2018-11-08 15:56:43620
621 EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
622}
623
624TEST(SoftwareFallbackEncoderTest, BothRateControllersTrusted) {
Mirko Bonadei6a489f22019-04-09 13:11:12625 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
626 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
Erik Språngd3438aa2018-11-08 15:56:43627 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21628 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
Erik Språngd3438aa2018-11-08 15:56:43629 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
Mirta Dvornicic897a9912018-11-30 12:12:21630 .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
Erik Språngd3438aa2018-11-08 15:56:43631
632 std::unique_ptr<VideoEncoder> wrapper =
633 CreateVideoEncoderSoftwareFallbackWrapper(
634 std::unique_ptr<VideoEncoder>(sw_encoder),
635 std::unique_ptr<VideoEncoder>(hw_encoder));
636 EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
637}
638
Mirta Dvornicic897a9912018-11-30 12:12:21639TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) {
Mirko Bonadei6a489f22019-04-09 13:11:12640 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
641 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
Mirta Dvornicic897a9912018-11-30 12:12:21642 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
643 .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(false)));
644 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
645 .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(true)));
646
647 std::unique_ptr<VideoEncoder> wrapper =
648 CreateVideoEncoderSoftwareFallbackWrapper(
649 std::unique_ptr<VideoEncoder>(sw_encoder),
650 std::unique_ptr<VideoEncoder>(hw_encoder));
651 EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);
652
Elad Alon370f93a2019-06-11 12:57:57653 VideoCodec codec_ = {};
654 wrapper->InitEncode(&codec_, kSettings);
655
Mirta Dvornicic897a9912018-11-30 12:12:21656 // Trigger fallback to software.
657 EXPECT_CALL(*hw_encoder, Encode)
658 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
Ilya Nikolaevskiy6aca0b72019-02-13 10:55:57659 VideoFrame frame = VideoFrame::Builder()
660 .set_video_frame_buffer(I420Buffer::Create(100, 100))
661 .build();
Niels Möllerc8d2e732019-03-06 11:00:33662 wrapper->Encode(frame, nullptr);
Mirta Dvornicic897a9912018-11-30 12:12:21663 EXPECT_FALSE(wrapper->GetEncoderInfo().is_hardware_accelerated);
664}
665
666TEST(SoftwareFallbackEncoderTest, ReportsInternalSource) {
Mirko Bonadei6a489f22019-04-09 13:11:12667 auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
668 auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
Mirta Dvornicic897a9912018-11-30 12:12:21669 EXPECT_CALL(*sw_encoder, GetEncoderInfo())
670 .WillRepeatedly(Return(GetEncoderInfoWithInternalSource(false)));
671 EXPECT_CALL(*hw_encoder, GetEncoderInfo())
672 .WillRepeatedly(Return(GetEncoderInfoWithInternalSource(true)));
673
674 std::unique_ptr<VideoEncoder> wrapper =
675 CreateVideoEncoderSoftwareFallbackWrapper(
676 std::unique_ptr<VideoEncoder>(sw_encoder),
677 std::unique_ptr<VideoEncoder>(hw_encoder));
678 EXPECT_TRUE(wrapper->GetEncoderInfo().has_internal_source);
679
Elad Alon370f93a2019-06-11 12:57:57680 VideoCodec codec_ = {};
681 wrapper->InitEncode(&codec_, kSettings);
682
Mirta Dvornicic897a9912018-11-30 12:12:21683 // Trigger fallback to software.
684 EXPECT_CALL(*hw_encoder, Encode)
685 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
Ilya Nikolaevskiy6aca0b72019-02-13 10:55:57686 VideoFrame frame = VideoFrame::Builder()
687 .set_video_frame_buffer(I420Buffer::Create(100, 100))
688 .build();
Niels Möllerc8d2e732019-03-06 11:00:33689 wrapper->Encode(frame, nullptr);
Mirta Dvornicic897a9912018-11-30 12:12:21690 EXPECT_FALSE(wrapper->GetEncoderInfo().has_internal_source);
691}
692
Peter Boström4d71ede2015-05-19 21:09:35693} // namespace webrtc