1 /*
2 * Copyright (c) 2014 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 "media/engine/simulcast_encoder_adapter.h"
12
13 #include <array>
14 #include <memory>
15 #include <vector>
16
17 #include "api/test/create_simulcast_test_fixture.h"
18 #include "api/test/simulcast_test_fixture.h"
19 #include "api/test/video/function_video_decoder_factory.h"
20 #include "api/test/video/function_video_encoder_factory.h"
21 #include "api/video_codecs/sdp_video_format.h"
22 #include "api/video_codecs/video_encoder.h"
23 #include "api/video_codecs/video_encoder_factory.h"
24 #include "common_video/include/video_frame_buffer.h"
25 #include "media/base/media_constants.h"
26 #include "media/engine/internal_encoder_factory.h"
27 #include "modules/video_coding/codecs/vp8/include/vp8.h"
28 #include "modules/video_coding/include/video_codec_interface.h"
29 #include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
30 #include "rtc_base/checks.h"
31 #include "test/gmock.h"
32 #include "test/gtest.h"
33
34 using ::testing::_;
35 using ::testing::Return;
36 using EncoderInfo = webrtc::VideoEncoder::EncoderInfo;
37 using FramerateFractions =
38 absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>;
39
40 namespace webrtc {
41 namespace test {
42
43 namespace {
44
45 constexpr int kDefaultWidth = 1280;
46 constexpr int kDefaultHeight = 720;
47
48 const VideoEncoder::Capabilities kCapabilities(false);
49 const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200);
50
CreateSpecificSimulcastTestFixture(VideoEncoderFactory * internal_encoder_factory)51 std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
52 VideoEncoderFactory* internal_encoder_factory) {
53 std::unique_ptr<VideoEncoderFactory> encoder_factory =
54 std::make_unique<FunctionVideoEncoderFactory>(
55 [internal_encoder_factory]() {
56 return std::make_unique<SimulcastEncoderAdapter>(
57 internal_encoder_factory,
58 SdpVideoFormat(cricket::kVp8CodecName));
59 });
60 std::unique_ptr<VideoDecoderFactory> decoder_factory =
61 std::make_unique<FunctionVideoDecoderFactory>(
62 []() { return VP8Decoder::Create(); });
63 return CreateSimulcastTestFixture(std::move(encoder_factory),
64 std::move(decoder_factory),
65 SdpVideoFormat(cricket::kVp8CodecName));
66 }
67 } // namespace
68
TEST(SimulcastEncoderAdapterSimulcastTest,TestKeyFrameRequestsOnAllStreams)69 TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
70 InternalEncoderFactory internal_encoder_factory;
71 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
72 fixture->TestKeyFrameRequestsOnAllStreams();
73 }
74
TEST(SimulcastEncoderAdapterSimulcastTest,TestPaddingAllStreams)75 TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
76 InternalEncoderFactory internal_encoder_factory;
77 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
78 fixture->TestPaddingAllStreams();
79 }
80
TEST(SimulcastEncoderAdapterSimulcastTest,TestPaddingTwoStreams)81 TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
82 InternalEncoderFactory internal_encoder_factory;
83 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
84 fixture->TestPaddingTwoStreams();
85 }
86
TEST(SimulcastEncoderAdapterSimulcastTest,TestPaddingTwoStreamsOneMaxedOut)87 TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
88 InternalEncoderFactory internal_encoder_factory;
89 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
90 fixture->TestPaddingTwoStreamsOneMaxedOut();
91 }
92
TEST(SimulcastEncoderAdapterSimulcastTest,TestPaddingOneStream)93 TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
94 InternalEncoderFactory internal_encoder_factory;
95 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
96 fixture->TestPaddingOneStream();
97 }
98
TEST(SimulcastEncoderAdapterSimulcastTest,TestPaddingOneStreamTwoMaxedOut)99 TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
100 InternalEncoderFactory internal_encoder_factory;
101 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
102 fixture->TestPaddingOneStreamTwoMaxedOut();
103 }
104
TEST(SimulcastEncoderAdapterSimulcastTest,TestSendAllStreams)105 TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
106 InternalEncoderFactory internal_encoder_factory;
107 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
108 fixture->TestSendAllStreams();
109 }
110
TEST(SimulcastEncoderAdapterSimulcastTest,TestDisablingStreams)111 TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
112 InternalEncoderFactory internal_encoder_factory;
113 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
114 fixture->TestDisablingStreams();
115 }
116
TEST(SimulcastEncoderAdapterSimulcastTest,TestActiveStreams)117 TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
118 InternalEncoderFactory internal_encoder_factory;
119 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
120 fixture->TestActiveStreams();
121 }
122
TEST(SimulcastEncoderAdapterSimulcastTest,TestSwitchingToOneStream)123 TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
124 InternalEncoderFactory internal_encoder_factory;
125 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
126 fixture->TestSwitchingToOneStream();
127 }
128
TEST(SimulcastEncoderAdapterSimulcastTest,TestSwitchingToOneOddStream)129 TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
130 InternalEncoderFactory internal_encoder_factory;
131 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
132 fixture->TestSwitchingToOneOddStream();
133 }
134
TEST(SimulcastEncoderAdapterSimulcastTest,TestStrideEncodeDecode)135 TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
136 InternalEncoderFactory internal_encoder_factory;
137 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
138 fixture->TestStrideEncodeDecode();
139 }
140
TEST(SimulcastEncoderAdapterSimulcastTest,TestSpatioTemporalLayers333PatternEncoder)141 TEST(SimulcastEncoderAdapterSimulcastTest,
142 TestSpatioTemporalLayers333PatternEncoder) {
143 InternalEncoderFactory internal_encoder_factory;
144 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
145 fixture->TestSpatioTemporalLayers333PatternEncoder();
146 }
147
TEST(SimulcastEncoderAdapterSimulcastTest,TestSpatioTemporalLayers321PatternEncoder)148 TEST(SimulcastEncoderAdapterSimulcastTest,
149 TestSpatioTemporalLayers321PatternEncoder) {
150 InternalEncoderFactory internal_encoder_factory;
151 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
152 fixture->TestSpatioTemporalLayers321PatternEncoder();
153 }
154
TEST(SimulcastEncoderAdapterSimulcastTest,TestDecodeWidthHeightSet)155 TEST(SimulcastEncoderAdapterSimulcastTest, TestDecodeWidthHeightSet) {
156 InternalEncoderFactory internal_encoder_factory;
157 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
158 fixture->TestDecodeWidthHeightSet();
159 }
160
161 class MockVideoEncoder;
162
163 class MockVideoEncoderFactory : public VideoEncoderFactory {
164 public:
165 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
166
167 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
168 const SdpVideoFormat& format) override;
169
170 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
171
172 const std::vector<MockVideoEncoder*>& encoders() const;
173 void SetEncoderNames(const std::vector<const char*>& encoder_names);
174 void set_init_encode_return_value(int32_t value);
set_requested_resolution_alignments(std::vector<int> requested_resolution_alignments)175 void set_requested_resolution_alignments(
176 std::vector<int> requested_resolution_alignments) {
177 requested_resolution_alignments_ = requested_resolution_alignments;
178 }
set_supports_simulcast(bool supports_simulcast)179 void set_supports_simulcast(bool supports_simulcast) {
180 supports_simulcast_ = supports_simulcast;
181 }
182
183 void DestroyVideoEncoder(VideoEncoder* encoder);
184
185 private:
186 int32_t init_encode_return_value_ = 0;
187 std::vector<MockVideoEncoder*> encoders_;
188 std::vector<const char*> encoder_names_;
189 // Keep number of entries in sync with |kMaxSimulcastStreams|.
190 std::vector<int> requested_resolution_alignments_ = {1, 1, 1};
191 bool supports_simulcast_ = false;
192 };
193
194 class MockVideoEncoder : public VideoEncoder {
195 public:
MockVideoEncoder(MockVideoEncoderFactory * factory)196 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
197 : factory_(factory),
198 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
199 video_format_("unknown"),
200 callback_(nullptr) {}
201
202 MOCK_METHOD(void,
203 SetFecControllerOverride,
204 (FecControllerOverride * fec_controller_override),
205 (override));
206
InitEncode(const VideoCodec * codecSettings,const VideoEncoder::Settings & settings)207 int32_t InitEncode(const VideoCodec* codecSettings,
208 const VideoEncoder::Settings& settings) override {
209 codec_ = *codecSettings;
210 return init_encode_return_value_;
211 }
212
213 MOCK_METHOD(int32_t,
214 Encode,
215 (const VideoFrame& inputImage,
216 const std::vector<VideoFrameType>* frame_types),
217 (override));
218
RegisterEncodeCompleteCallback(EncodedImageCallback * callback)219 int32_t RegisterEncodeCompleteCallback(
220 EncodedImageCallback* callback) override {
221 callback_ = callback;
222 return 0;
223 }
224
225 MOCK_METHOD(int32_t, Release, (), (override));
226
SetRates(const RateControlParameters & parameters)227 void SetRates(const RateControlParameters& parameters) {
228 last_set_rates_ = parameters;
229 }
230
GetEncoderInfo() const231 EncoderInfo GetEncoderInfo() const override {
232 EncoderInfo info;
233 info.supports_native_handle = supports_native_handle_;
234 info.implementation_name = implementation_name_;
235 info.scaling_settings = scaling_settings_;
236 info.requested_resolution_alignment = requested_resolution_alignment_;
237 info.has_trusted_rate_controller = has_trusted_rate_controller_;
238 info.is_hardware_accelerated = is_hardware_accelerated_;
239 info.has_internal_source = has_internal_source_;
240 info.fps_allocation[0] = fps_allocation_;
241 info.supports_simulcast = supports_simulcast_;
242 return info;
243 }
244
~MockVideoEncoder()245 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
246
codec() const247 const VideoCodec& codec() const { return codec_; }
248
SendEncodedImage(int width,int height)249 void SendEncodedImage(int width, int height) {
250 // Sends a fake image of the given width/height.
251 EncodedImage image;
252 image._encodedWidth = width;
253 image._encodedHeight = height;
254 CodecSpecificInfo codec_specific_info;
255 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
256 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
257 }
258
set_supports_native_handle(bool enabled)259 void set_supports_native_handle(bool enabled) {
260 supports_native_handle_ = enabled;
261 }
262
set_implementation_name(const std::string & name)263 void set_implementation_name(const std::string& name) {
264 implementation_name_ = name;
265 }
266
set_init_encode_return_value(int32_t value)267 void set_init_encode_return_value(int32_t value) {
268 init_encode_return_value_ = value;
269 }
270
set_scaling_settings(const VideoEncoder::ScalingSettings & settings)271 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
272 scaling_settings_ = settings;
273 }
274
set_requested_resolution_alignment(int requested_resolution_alignment)275 void set_requested_resolution_alignment(int requested_resolution_alignment) {
276 requested_resolution_alignment_ = requested_resolution_alignment;
277 }
278
set_has_trusted_rate_controller(bool trusted)279 void set_has_trusted_rate_controller(bool trusted) {
280 has_trusted_rate_controller_ = trusted;
281 }
282
set_is_hardware_accelerated(bool is_hardware_accelerated)283 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
284 is_hardware_accelerated_ = is_hardware_accelerated;
285 }
286
set_has_internal_source(bool has_internal_source)287 void set_has_internal_source(bool has_internal_source) {
288 has_internal_source_ = has_internal_source;
289 }
290
set_fps_allocation(const FramerateFractions & fps_allocation)291 void set_fps_allocation(const FramerateFractions& fps_allocation) {
292 fps_allocation_ = fps_allocation;
293 }
294
last_set_rates() const295 RateControlParameters last_set_rates() const { return last_set_rates_; }
296
set_supports_simulcast(bool supports_simulcast)297 void set_supports_simulcast(bool supports_simulcast) {
298 supports_simulcast_ = supports_simulcast;
299 }
300
set_video_format(const SdpVideoFormat & video_format)301 void set_video_format(const SdpVideoFormat& video_format) {
302 video_format_ = video_format;
303 }
304
supports_simulcast() const305 bool supports_simulcast() const { return supports_simulcast_; }
306
video_format() const307 SdpVideoFormat video_format() const { return video_format_; }
308
309 private:
310 MockVideoEncoderFactory* const factory_;
311 bool supports_native_handle_ = false;
312 std::string implementation_name_ = "unknown";
313 VideoEncoder::ScalingSettings scaling_settings_;
314 int requested_resolution_alignment_ = 1;
315 bool has_trusted_rate_controller_ = false;
316 bool is_hardware_accelerated_ = false;
317 bool has_internal_source_ = false;
318 int32_t init_encode_return_value_ = 0;
319 VideoEncoder::RateControlParameters last_set_rates_;
320 FramerateFractions fps_allocation_;
321 bool supports_simulcast_ = false;
322 SdpVideoFormat video_format_;
323
324 VideoCodec codec_;
325 EncodedImageCallback* callback_;
326 };
327
GetSupportedFormats() const328 std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
329 const {
330 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
331 return formats;
332 }
333
CreateVideoEncoder(const SdpVideoFormat & format)334 std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
335 const SdpVideoFormat& format) {
336 auto encoder = std::make_unique<::testing::NiceMock<MockVideoEncoder>>(this);
337 encoder->set_init_encode_return_value(init_encode_return_value_);
338 const char* encoder_name = encoder_names_.empty()
339 ? "codec_implementation_name"
340 : encoder_names_[encoders_.size()];
341 encoder->set_implementation_name(encoder_name);
342 RTC_CHECK_LT(encoders_.size(), requested_resolution_alignments_.size());
343 encoder->set_requested_resolution_alignment(
344 requested_resolution_alignments_[encoders_.size()]);
345 encoder->set_supports_simulcast(supports_simulcast_);
346 encoder->set_video_format(format);
347 encoders_.push_back(encoder.get());
348 return encoder;
349 }
350
DestroyVideoEncoder(VideoEncoder * encoder)351 void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
352 for (size_t i = 0; i < encoders_.size(); ++i) {
353 if (encoders_[i] == encoder) {
354 encoders_.erase(encoders_.begin() + i);
355 break;
356 }
357 }
358 }
359
QueryVideoEncoder(const SdpVideoFormat & format) const360 VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
361 const SdpVideoFormat& format) const {
362 return CodecInfo();
363 }
364
encoders() const365 const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
366 const {
367 return encoders_;
368 }
SetEncoderNames(const std::vector<const char * > & encoder_names)369 void MockVideoEncoderFactory::SetEncoderNames(
370 const std::vector<const char*>& encoder_names) {
371 encoder_names_ = encoder_names;
372 }
set_init_encode_return_value(int32_t value)373 void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
374 init_encode_return_value_ = value;
375 }
376
377 class TestSimulcastEncoderAdapterFakeHelper {
378 public:
TestSimulcastEncoderAdapterFakeHelper(bool use_fallback_factory,const SdpVideoFormat & video_format)379 explicit TestSimulcastEncoderAdapterFakeHelper(
380 bool use_fallback_factory,
381 const SdpVideoFormat& video_format)
382 : primary_factory_(new MockVideoEncoderFactory()),
383 fallback_factory_(use_fallback_factory ? new MockVideoEncoderFactory()
384 : nullptr),
385 video_format_(video_format) {}
386
387 // Can only be called once as the SimulcastEncoderAdapter will take the
388 // ownership of |factory_|.
CreateMockEncoderAdapter()389 VideoEncoder* CreateMockEncoderAdapter() {
390 return new SimulcastEncoderAdapter(primary_factory_.get(),
391 fallback_factory_.get(), video_format_);
392 }
393
factory()394 MockVideoEncoderFactory* factory() { return primary_factory_.get(); }
fallback_factory()395 MockVideoEncoderFactory* fallback_factory() {
396 return fallback_factory_.get();
397 }
398
399 private:
400 std::unique_ptr<MockVideoEncoderFactory> primary_factory_;
401 std::unique_ptr<MockVideoEncoderFactory> fallback_factory_;
402 SdpVideoFormat video_format_;
403 };
404
405 static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
406
407 class TestSimulcastEncoderAdapterFake : public ::testing::Test,
408 public EncodedImageCallback {
409 public:
TestSimulcastEncoderAdapterFake()410 TestSimulcastEncoderAdapterFake()
411 : last_encoded_image_width_(-1),
412 last_encoded_image_height_(-1),
413 last_encoded_image_simulcast_index_(-1),
414 use_fallback_factory_(false) {}
415
~TestSimulcastEncoderAdapterFake()416 virtual ~TestSimulcastEncoderAdapterFake() {
417 if (adapter_) {
418 adapter_->Release();
419 }
420 }
421
SetUp()422 void SetUp() override {
423 helper_ = std::make_unique<TestSimulcastEncoderAdapterFakeHelper>(
424 use_fallback_factory_, SdpVideoFormat("VP8", sdp_video_parameters_));
425 adapter_.reset(helper_->CreateMockEncoderAdapter());
426 last_encoded_image_width_ = -1;
427 last_encoded_image_height_ = -1;
428 last_encoded_image_simulcast_index_ = -1;
429 }
430
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)431 Result OnEncodedImage(const EncodedImage& encoded_image,
432 const CodecSpecificInfo* codec_specific_info,
433 const RTPFragmentationHeader* fragmentation) override {
434 last_encoded_image_width_ = encoded_image._encodedWidth;
435 last_encoded_image_height_ = encoded_image._encodedHeight;
436 last_encoded_image_simulcast_index_ =
437 encoded_image.SpatialIndex().value_or(-1);
438
439 return Result(Result::OK, encoded_image.Timestamp());
440 }
441
GetLastEncodedImageInfo(int * out_width,int * out_height,int * out_simulcast_index)442 bool GetLastEncodedImageInfo(int* out_width,
443 int* out_height,
444 int* out_simulcast_index) {
445 if (last_encoded_image_width_ == -1) {
446 return false;
447 }
448 *out_width = last_encoded_image_width_;
449 *out_height = last_encoded_image_height_;
450 *out_simulcast_index = last_encoded_image_simulcast_index_;
451 return true;
452 }
453
SetupCodec()454 void SetupCodec() {
455 SimulcastTestFixtureImpl::DefaultSettings(
456 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
457 kVideoCodecVP8);
458 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
459 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
460 adapter_->RegisterEncodeCompleteCallback(this);
461 }
462
VerifyCodec(const VideoCodec & ref,int stream_index)463 void VerifyCodec(const VideoCodec& ref, int stream_index) {
464 const VideoCodec& target =
465 helper_->factory()->encoders()[stream_index]->codec();
466 EXPECT_EQ(ref.codecType, target.codecType);
467 EXPECT_EQ(ref.plType, target.plType);
468 EXPECT_EQ(ref.width, target.width);
469 EXPECT_EQ(ref.height, target.height);
470 EXPECT_EQ(ref.startBitrate, target.startBitrate);
471 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
472 EXPECT_EQ(ref.minBitrate, target.minBitrate);
473 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
474 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
475 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
476 target.VP8().numberOfTemporalLayers);
477 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
478 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
479 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
480 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
481 EXPECT_EQ(ref.qpMax, target.qpMax);
482 EXPECT_EQ(0, target.numberOfSimulcastStreams);
483 EXPECT_EQ(ref.mode, target.mode);
484
485 // No need to compare simulcastStream as numberOfSimulcastStreams should
486 // always be 0.
487 }
488
InitRefCodec(int stream_index,VideoCodec * ref_codec,bool reverse_layer_order=false)489 void InitRefCodec(int stream_index,
490 VideoCodec* ref_codec,
491 bool reverse_layer_order = false) {
492 *ref_codec = codec_;
493 ref_codec->VP8()->numberOfTemporalLayers =
494 kTestTemporalLayerProfile[reverse_layer_order ? 2 - stream_index
495 : stream_index];
496 ref_codec->width = codec_.simulcastStream[stream_index].width;
497 ref_codec->height = codec_.simulcastStream[stream_index].height;
498 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
499 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
500 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
501 }
502
VerifyCodecSettings()503 void VerifyCodecSettings() {
504 EXPECT_EQ(3u, helper_->factory()->encoders().size());
505 VideoCodec ref_codec;
506
507 // stream 0, the lowest resolution stream.
508 InitRefCodec(0, &ref_codec);
509 ref_codec.qpMax = 45;
510 ref_codec.VP8()->complexity =
511 webrtc::VideoCodecComplexity::kComplexityHigher;
512 ref_codec.VP8()->denoisingOn = false;
513 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
514 VerifyCodec(ref_codec, 0);
515
516 // stream 1
517 InitRefCodec(1, &ref_codec);
518 ref_codec.VP8()->denoisingOn = false;
519 // The start bitrate (300kbit) minus what we have for the lower layers
520 // (100kbit).
521 ref_codec.startBitrate = 200;
522 VerifyCodec(ref_codec, 1);
523
524 // stream 2, the biggest resolution stream.
525 InitRefCodec(2, &ref_codec);
526 // We don't have enough bits to send this, so the adapter should have
527 // configured it to use the min bitrate for this layer (600kbit) but turn
528 // off sending.
529 ref_codec.startBitrate = 600;
530 VerifyCodec(ref_codec, 2);
531 }
532
533 protected:
534 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
535 std::unique_ptr<VideoEncoder> adapter_;
536 VideoCodec codec_;
537 int last_encoded_image_width_;
538 int last_encoded_image_height_;
539 int last_encoded_image_simulcast_index_;
540 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
541 bool use_fallback_factory_;
542 SdpVideoFormat::Parameters sdp_video_parameters_;
543 };
544
TEST_F(TestSimulcastEncoderAdapterFake,InitEncode)545 TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
546 SetupCodec();
547 VerifyCodecSettings();
548 }
549
TEST_F(TestSimulcastEncoderAdapterFake,ReleaseWithoutInitEncode)550 TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
551 EXPECT_EQ(0, adapter_->Release());
552 }
553
TEST_F(TestSimulcastEncoderAdapterFake,Reinit)554 TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
555 SetupCodec();
556 EXPECT_EQ(0, adapter_->Release());
557
558 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
559 }
560
TEST_F(TestSimulcastEncoderAdapterFake,EncodedCallbackForDifferentEncoders)561 TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
562 SetupCodec();
563
564 // Set bitrates so that we send all layers.
565 adapter_->SetRates(VideoEncoder::RateControlParameters(
566 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
567 30.0));
568
569 // At this point, the simulcast encoder adapter should have 3 streams: HD,
570 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
571 // resolutions, to test that the adapter forwards on the correct resolution
572 // and simulcast index values, going only off the encoder that generates the
573 // image.
574 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
575 ASSERT_EQ(3u, encoders.size());
576 encoders[0]->SendEncodedImage(1152, 704);
577 int width;
578 int height;
579 int simulcast_index;
580 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
581 EXPECT_EQ(1152, width);
582 EXPECT_EQ(704, height);
583 EXPECT_EQ(0, simulcast_index);
584
585 encoders[1]->SendEncodedImage(300, 620);
586 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
587 EXPECT_EQ(300, width);
588 EXPECT_EQ(620, height);
589 EXPECT_EQ(1, simulcast_index);
590
591 encoders[2]->SendEncodedImage(120, 240);
592 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
593 EXPECT_EQ(120, width);
594 EXPECT_EQ(240, height);
595 EXPECT_EQ(2, simulcast_index);
596 }
597
598 // This test verifies that the underlying encoders are reused, when the adapter
599 // is reinited with different number of simulcast streams. It further checks
600 // that the allocated encoders are reused in the same order as before, starting
601 // with the lowest stream.
TEST_F(TestSimulcastEncoderAdapterFake,ReusesEncodersInOrder)602 TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
603 // Set up common settings for three streams.
604 SimulcastTestFixtureImpl::DefaultSettings(
605 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
606 kVideoCodecVP8);
607 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
608 adapter_->RegisterEncodeCompleteCallback(this);
609 const uint32_t target_bitrate =
610 1000 * (codec_.simulcastStream[0].targetBitrate +
611 codec_.simulcastStream[1].targetBitrate +
612 codec_.simulcastStream[2].minBitrate);
613
614 // Input data.
615 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
616 VideoFrame input_frame = VideoFrame::Builder()
617 .set_video_frame_buffer(buffer)
618 .set_timestamp_rtp(100)
619 .set_timestamp_ms(1000)
620 .set_rotation(kVideoRotation_180)
621 .build();
622 std::vector<VideoFrameType> frame_types;
623
624 // Encode with three streams.
625 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
626 VerifyCodecSettings();
627 adapter_->SetRates(VideoEncoder::RateControlParameters(
628 rate_allocator_->Allocate(
629 VideoBitrateAllocationParameters(target_bitrate, 30)),
630 30.0));
631
632 std::vector<MockVideoEncoder*> original_encoders =
633 helper_->factory()->encoders();
634 ASSERT_EQ(3u, original_encoders.size());
635 EXPECT_CALL(*original_encoders[0], Encode(_, _))
636 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
637 EXPECT_CALL(*original_encoders[1], Encode(_, _))
638 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
639 EXPECT_CALL(*original_encoders[2], Encode(_, _))
640 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
641 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
642 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
643 EXPECT_CALL(*original_encoders[0], Release())
644 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
645 EXPECT_CALL(*original_encoders[1], Release())
646 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
647 EXPECT_CALL(*original_encoders[2], Release())
648 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
649 EXPECT_EQ(0, adapter_->Release());
650
651 // Encode with two streams.
652 codec_.width /= 2;
653 codec_.height /= 2;
654 codec_.numberOfSimulcastStreams = 2;
655 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
656 adapter_->SetRates(VideoEncoder::RateControlParameters(
657 rate_allocator_->Allocate(
658 VideoBitrateAllocationParameters(target_bitrate, 30)),
659 30.0));
660 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
661 ASSERT_EQ(2u, new_encoders.size());
662 ASSERT_EQ(original_encoders[0], new_encoders[0]);
663 EXPECT_CALL(*original_encoders[0], Encode(_, _))
664 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
665 ASSERT_EQ(original_encoders[1], new_encoders[1]);
666 EXPECT_CALL(*original_encoders[1], Encode(_, _))
667 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
668 frame_types.resize(2, VideoFrameType::kVideoFrameKey);
669 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
670 EXPECT_CALL(*original_encoders[0], Release())
671 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
672 EXPECT_CALL(*original_encoders[1], Release())
673 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
674 EXPECT_EQ(0, adapter_->Release());
675
676 // Encode with single stream.
677 codec_.width /= 2;
678 codec_.height /= 2;
679 codec_.numberOfSimulcastStreams = 1;
680 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
681 adapter_->SetRates(VideoEncoder::RateControlParameters(
682 rate_allocator_->Allocate(
683 VideoBitrateAllocationParameters(target_bitrate, 30)),
684 30.0));
685 new_encoders = helper_->factory()->encoders();
686 ASSERT_EQ(1u, new_encoders.size());
687 ASSERT_EQ(original_encoders[0], new_encoders[0]);
688 EXPECT_CALL(*original_encoders[0], Encode(_, _))
689 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
690 frame_types.resize(1, VideoFrameType::kVideoFrameKey);
691 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
692 EXPECT_CALL(*original_encoders[0], Release())
693 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
694 EXPECT_EQ(0, adapter_->Release());
695
696 // Encode with three streams, again.
697 codec_.width *= 4;
698 codec_.height *= 4;
699 codec_.numberOfSimulcastStreams = 3;
700 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
701 adapter_->SetRates(VideoEncoder::RateControlParameters(
702 rate_allocator_->Allocate(
703 VideoBitrateAllocationParameters(target_bitrate, 30)),
704 30.0));
705 new_encoders = helper_->factory()->encoders();
706 ASSERT_EQ(3u, new_encoders.size());
707 // The first encoder is reused.
708 ASSERT_EQ(original_encoders[0], new_encoders[0]);
709 EXPECT_CALL(*original_encoders[0], Encode(_, _))
710 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
711 // The second and third encoders are new.
712 EXPECT_CALL(*new_encoders[1], Encode(_, _))
713 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
714 EXPECT_CALL(*new_encoders[2], Encode(_, _))
715 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
716 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
717 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
718 EXPECT_CALL(*original_encoders[0], Release())
719 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
720 EXPECT_CALL(*new_encoders[1], Release())
721 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
722 EXPECT_CALL(*new_encoders[2], Release())
723 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
724 EXPECT_EQ(0, adapter_->Release());
725 }
726
TEST_F(TestSimulcastEncoderAdapterFake,DoesNotLeakEncoders)727 TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
728 SetupCodec();
729 VerifyCodecSettings();
730
731 EXPECT_EQ(3u, helper_->factory()->encoders().size());
732
733 // The adapter should destroy all encoders it has allocated. Since
734 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
735 // lsan to find leaks here.
736 EXPECT_EQ(0, adapter_->Release());
737 adapter_.reset();
738 }
739
740 // This test verifies that an adapter reinit with the same codec settings as
741 // before does not change the underlying encoder codec settings.
TEST_F(TestSimulcastEncoderAdapterFake,ReinitDoesNotReorderEncoderSettings)742 TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
743 SetupCodec();
744 VerifyCodecSettings();
745
746 // Capture current codec settings.
747 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
748 ASSERT_EQ(3u, encoders.size());
749 std::array<VideoCodec, 3> codecs_before;
750 for (int i = 0; i < 3; ++i) {
751 codecs_before[i] = encoders[i]->codec();
752 }
753
754 // Reinitialize and verify that the new codec settings are the same.
755 EXPECT_EQ(0, adapter_->Release());
756 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
757 for (int i = 0; i < 3; ++i) {
758 const VideoCodec& codec_before = codecs_before[i];
759 const VideoCodec& codec_after = encoders[i]->codec();
760
761 // webrtc::VideoCodec does not implement operator==.
762 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
763 EXPECT_EQ(codec_before.plType, codec_after.plType);
764 EXPECT_EQ(codec_before.width, codec_after.width);
765 EXPECT_EQ(codec_before.height, codec_after.height);
766 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
767 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
768 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
769 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
770 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
771 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
772 codec_after.numberOfSimulcastStreams);
773 EXPECT_EQ(codec_before.mode, codec_after.mode);
774 EXPECT_EQ(codec_before.expect_encode_from_texture,
775 codec_after.expect_encode_from_texture);
776 }
777 }
778
779 // This test is similar to the one above, except that it tests the simulcastIdx
780 // from the CodecSpecificInfo that is connected to an encoded frame. The
781 // PayloadRouter demuxes the incoming encoded frames on different RTP modules
782 // using the simulcastIdx, so it's important that there is no corresponding
783 // encoder reordering in between adapter reinits as this would lead to PictureID
784 // discontinuities.
TEST_F(TestSimulcastEncoderAdapterFake,ReinitDoesNotReorderFrameSimulcastIdx)785 TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
786 SetupCodec();
787 adapter_->SetRates(VideoEncoder::RateControlParameters(
788 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
789 30.0));
790 VerifyCodecSettings();
791
792 // Send frames on all streams.
793 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
794 ASSERT_EQ(3u, encoders.size());
795 encoders[0]->SendEncodedImage(1152, 704);
796 int width;
797 int height;
798 int simulcast_index;
799 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
800 EXPECT_EQ(0, simulcast_index);
801
802 encoders[1]->SendEncodedImage(300, 620);
803 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
804 EXPECT_EQ(1, simulcast_index);
805
806 encoders[2]->SendEncodedImage(120, 240);
807 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
808 EXPECT_EQ(2, simulcast_index);
809
810 // Reinitialize.
811 EXPECT_EQ(0, adapter_->Release());
812 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
813 adapter_->SetRates(VideoEncoder::RateControlParameters(
814 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
815 30.0));
816
817 // Verify that the same encoder sends out frames on the same simulcast index.
818 encoders[0]->SendEncodedImage(1152, 704);
819 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
820 EXPECT_EQ(0, simulcast_index);
821
822 encoders[1]->SendEncodedImage(300, 620);
823 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
824 EXPECT_EQ(1, simulcast_index);
825
826 encoders[2]->SendEncodedImage(120, 240);
827 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
828 EXPECT_EQ(2, simulcast_index);
829 }
830
TEST_F(TestSimulcastEncoderAdapterFake,SupportsNativeHandleForSingleStreams)831 TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
832 SimulcastTestFixtureImpl::DefaultSettings(
833 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
834 kVideoCodecVP8);
835 codec_.numberOfSimulcastStreams = 1;
836 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
837 adapter_->RegisterEncodeCompleteCallback(this);
838 ASSERT_EQ(1u, helper_->factory()->encoders().size());
839 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
840 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
841 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
842 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
843 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
844 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
845 }
846
TEST_F(TestSimulcastEncoderAdapterFake,SetRatesUnderMinBitrate)847 TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
848 SimulcastTestFixtureImpl::DefaultSettings(
849 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
850 kVideoCodecVP8);
851 codec_.minBitrate = 50;
852 codec_.numberOfSimulcastStreams = 1;
853 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
854 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
855
856 // Above min should be respected.
857 VideoBitrateAllocation target_bitrate = rate_allocator_->Allocate(
858 VideoBitrateAllocationParameters(codec_.minBitrate * 1000, 30));
859 adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
860 EXPECT_EQ(target_bitrate,
861 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
862
863 // Below min but non-zero should be replaced with the min bitrate.
864 VideoBitrateAllocation too_low_bitrate = rate_allocator_->Allocate(
865 VideoBitrateAllocationParameters((codec_.minBitrate - 1) * 1000, 30));
866 adapter_->SetRates(
867 VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
868 EXPECT_EQ(target_bitrate,
869 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
870
871 // Zero should be passed on as is, since it means "pause".
872 adapter_->SetRates(
873 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
874 EXPECT_EQ(VideoBitrateAllocation(),
875 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
876 }
877
TEST_F(TestSimulcastEncoderAdapterFake,SupportsImplementationName)878 TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
879 EXPECT_EQ("SimulcastEncoderAdapter",
880 adapter_->GetEncoderInfo().implementation_name);
881 SimulcastTestFixtureImpl::DefaultSettings(
882 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
883 kVideoCodecVP8);
884 std::vector<const char*> encoder_names;
885 encoder_names.push_back("codec1");
886 encoder_names.push_back("codec2");
887 encoder_names.push_back("codec3");
888 helper_->factory()->SetEncoderNames(encoder_names);
889 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
890 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
891 adapter_->GetEncoderInfo().implementation_name);
892
893 // Single streams should not expose "SimulcastEncoderAdapter" in name.
894 EXPECT_EQ(0, adapter_->Release());
895 codec_.numberOfSimulcastStreams = 1;
896 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
897 adapter_->RegisterEncodeCompleteCallback(this);
898 ASSERT_EQ(1u, helper_->factory()->encoders().size());
899 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
900 }
901
TEST_F(TestSimulcastEncoderAdapterFake,RuntimeEncoderInfoUpdate)902 TEST_F(TestSimulcastEncoderAdapterFake, RuntimeEncoderInfoUpdate) {
903 SimulcastTestFixtureImpl::DefaultSettings(
904 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
905 kVideoCodecVP8);
906 std::vector<const char*> encoder_names;
907 encoder_names.push_back("codec1");
908 encoder_names.push_back("codec2");
909 encoder_names.push_back("codec3");
910 helper_->factory()->SetEncoderNames(encoder_names);
911 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
912 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
913 adapter_->GetEncoderInfo().implementation_name);
914
915 // Change name of first encoder to indicate it has done a fallback to another
916 // implementation.
917 helper_->factory()->encoders().front()->set_implementation_name("fallback1");
918 EXPECT_EQ("SimulcastEncoderAdapter (fallback1, codec2, codec3)",
919 adapter_->GetEncoderInfo().implementation_name);
920 }
921
TEST_F(TestSimulcastEncoderAdapterFake,SupportsNativeHandleForMultipleStreams)922 TEST_F(TestSimulcastEncoderAdapterFake,
923 SupportsNativeHandleForMultipleStreams) {
924 SimulcastTestFixtureImpl::DefaultSettings(
925 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
926 kVideoCodecVP8);
927 codec_.numberOfSimulcastStreams = 3;
928 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
929 adapter_->RegisterEncodeCompleteCallback(this);
930 ASSERT_EQ(3u, helper_->factory()->encoders().size());
931 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
932 encoder->set_supports_native_handle(true);
933 // As long as one encoder supports native handle, it's enabled.
934 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
935 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
936 // Once none do, then the adapter claims no support.
937 helper_->factory()->encoders()[1]->set_supports_native_handle(false);
938 helper_->factory()->encoders()[2]->set_supports_native_handle(false);
939 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
940 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
941 }
942
943 // TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
944 class FakeNativeBufferI420 : public VideoFrameBuffer {
945 public:
FakeNativeBufferI420(int width,int height,bool allow_to_i420)946 FakeNativeBufferI420(int width, int height, bool allow_to_i420)
947 : width_(width), height_(height), allow_to_i420_(allow_to_i420) {}
948
type() const949 Type type() const override { return Type::kNative; }
width() const950 int width() const override { return width_; }
height() const951 int height() const override { return height_; }
952
ToI420()953 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
954 if (allow_to_i420_) {
955 return I420Buffer::Create(width_, height_);
956 } else {
957 RTC_NOTREACHED();
958 }
959 return nullptr;
960 }
961
962 private:
963 const int width_;
964 const int height_;
965 const bool allow_to_i420_;
966 };
967
TEST_F(TestSimulcastEncoderAdapterFake,NativeHandleForwardingForMultipleStreams)968 TEST_F(TestSimulcastEncoderAdapterFake,
969 NativeHandleForwardingForMultipleStreams) {
970 SimulcastTestFixtureImpl::DefaultSettings(
971 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
972 kVideoCodecVP8);
973 codec_.numberOfSimulcastStreams = 3;
974 // High start bitrate, so all streams are enabled.
975 codec_.startBitrate = 3000;
976 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
977 adapter_->RegisterEncodeCompleteCallback(this);
978 ASSERT_EQ(3u, helper_->factory()->encoders().size());
979 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
980 encoder->set_supports_native_handle(true);
981 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
982 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
983
984 rtc::scoped_refptr<VideoFrameBuffer> buffer(
985 new rtc::RefCountedObject<FakeNativeBufferI420>(1280, 720,
986 /*allow_to_i420=*/false));
987 VideoFrame input_frame = VideoFrame::Builder()
988 .set_video_frame_buffer(buffer)
989 .set_timestamp_rtp(100)
990 .set_timestamp_ms(1000)
991 .set_rotation(kVideoRotation_180)
992 .build();
993 // Expect calls with the given video frame verbatim, since it's a texture
994 // frame and can't otherwise be modified/resized.
995 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
996 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _)).Times(1);
997 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
998 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
999 }
1000
TEST_F(TestSimulcastEncoderAdapterFake,NativeHandleForwardingOnlyIfSupported)1001 TEST_F(TestSimulcastEncoderAdapterFake, NativeHandleForwardingOnlyIfSupported) {
1002 SimulcastTestFixtureImpl::DefaultSettings(
1003 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1004 kVideoCodecVP8);
1005 codec_.numberOfSimulcastStreams = 3;
1006 // High start bitrate, so all streams are enabled.
1007 codec_.startBitrate = 3000;
1008 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1009 adapter_->RegisterEncodeCompleteCallback(this);
1010 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1011
1012 // QVGA encoders has fallen back to software.
1013 auto& encoders = helper_->factory()->encoders();
1014 encoders[0]->set_supports_native_handle(false);
1015 encoders[1]->set_supports_native_handle(true);
1016 encoders[2]->set_supports_native_handle(true);
1017
1018 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1019 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
1020
1021 rtc::scoped_refptr<VideoFrameBuffer> buffer(
1022 new rtc::RefCountedObject<FakeNativeBufferI420>(1280, 720,
1023 /*allow_to_i420=*/true));
1024 VideoFrame input_frame = VideoFrame::Builder()
1025 .set_video_frame_buffer(buffer)
1026 .set_timestamp_rtp(100)
1027 .set_timestamp_ms(1000)
1028 .set_rotation(kVideoRotation_180)
1029 .build();
1030 // Expect calls with the given video frame verbatim, since it's a texture
1031 // frame and can't otherwise be modified/resized, but only on the two
1032 // streams supporting it...
1033 EXPECT_CALL(*encoders[1], Encode(::testing::Ref(input_frame), _)).Times(1);
1034 EXPECT_CALL(*encoders[2], Encode(::testing::Ref(input_frame), _)).Times(1);
1035 // ...the lowest one gets a software buffer.
1036 EXPECT_CALL(*encoders[0], Encode)
1037 .WillOnce([&](const VideoFrame& frame,
1038 const std::vector<VideoFrameType>* frame_types) {
1039 EXPECT_EQ(frame.video_frame_buffer()->type(),
1040 VideoFrameBuffer::Type::kI420);
1041 return 0;
1042 });
1043 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
1044 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1045 }
1046
TEST_F(TestSimulcastEncoderAdapterFake,TestFailureReturnCodesFromEncodeCalls)1047 TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
1048 SimulcastTestFixtureImpl::DefaultSettings(
1049 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1050 kVideoCodecVP8);
1051 codec_.numberOfSimulcastStreams = 3;
1052 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1053 adapter_->RegisterEncodeCompleteCallback(this);
1054 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1055 // Tell the 2nd encoder to request software fallback.
1056 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _))
1057 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
1058
1059 // Send a fake frame and assert the return is software fallback.
1060 rtc::scoped_refptr<I420Buffer> input_buffer =
1061 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
1062 input_buffer->InitializeData();
1063 VideoFrame input_frame = VideoFrame::Builder()
1064 .set_video_frame_buffer(input_buffer)
1065 .set_timestamp_rtp(0)
1066 .set_timestamp_us(0)
1067 .set_rotation(kVideoRotation_0)
1068 .build();
1069 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
1070 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
1071 adapter_->Encode(input_frame, &frame_types));
1072 }
1073
TEST_F(TestSimulcastEncoderAdapterFake,TestInitFailureCleansUpEncoders)1074 TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
1075 SimulcastTestFixtureImpl::DefaultSettings(
1076 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1077 kVideoCodecVP8);
1078 codec_.numberOfSimulcastStreams = 3;
1079 helper_->factory()->set_init_encode_return_value(
1080 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1081 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
1082 adapter_->InitEncode(&codec_, kSettings));
1083 EXPECT_TRUE(helper_->factory()->encoders().empty());
1084 }
1085
TEST_F(TestSimulcastEncoderAdapterFake,DoesNotAlterMaxQpForScreenshare)1086 TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
1087 const int kHighMaxQp = 56;
1088 const int kLowMaxQp = 46;
1089
1090 SimulcastTestFixtureImpl::DefaultSettings(
1091 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1092 kVideoCodecVP8);
1093 codec_.numberOfSimulcastStreams = 3;
1094 codec_.simulcastStream[0].qpMax = kHighMaxQp;
1095 codec_.mode = VideoCodecMode::kScreensharing;
1096
1097 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1098 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1099
1100 // Just check the lowest stream, which is the one that where the adapter
1101 // might alter the max qp setting.
1102 VideoCodec ref_codec;
1103 InitRefCodec(0, &ref_codec);
1104 ref_codec.qpMax = kHighMaxQp;
1105 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1106 ref_codec.VP8()->denoisingOn = false;
1107 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1108 VerifyCodec(ref_codec, 0);
1109
1110 // Change the max qp and try again.
1111 codec_.simulcastStream[0].qpMax = kLowMaxQp;
1112 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1113 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1114 ref_codec.qpMax = kLowMaxQp;
1115 VerifyCodec(ref_codec, 0);
1116 }
1117
TEST_F(TestSimulcastEncoderAdapterFake,DoesNotAlterMaxQpForScreenshareReversedLayer)1118 TEST_F(TestSimulcastEncoderAdapterFake,
1119 DoesNotAlterMaxQpForScreenshareReversedLayer) {
1120 const int kHighMaxQp = 56;
1121 const int kLowMaxQp = 46;
1122
1123 SimulcastTestFixtureImpl::DefaultSettings(
1124 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1125 kVideoCodecVP8, true /* reverse_layer_order */);
1126 codec_.numberOfSimulcastStreams = 3;
1127 codec_.simulcastStream[2].qpMax = kHighMaxQp;
1128 codec_.mode = VideoCodecMode::kScreensharing;
1129
1130 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1131 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1132
1133 // Just check the lowest stream, which is the one that where the adapter
1134 // might alter the max qp setting.
1135 VideoCodec ref_codec;
1136 InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
1137 ref_codec.qpMax = kHighMaxQp;
1138 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1139 ref_codec.VP8()->denoisingOn = false;
1140 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1141 VerifyCodec(ref_codec, 2);
1142
1143 // Change the max qp and try again.
1144 codec_.simulcastStream[2].qpMax = kLowMaxQp;
1145 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1146 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1147 ref_codec.qpMax = kLowMaxQp;
1148 VerifyCodec(ref_codec, 2);
1149 }
1150
TEST_F(TestSimulcastEncoderAdapterFake,ActivatesCorrectStreamsInInitEncode)1151 TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
1152 // Set up common settings for three streams.
1153 SimulcastTestFixtureImpl::DefaultSettings(
1154 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1155 kVideoCodecVP8);
1156 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1157 adapter_->RegisterEncodeCompleteCallback(this);
1158
1159 // Only enough start bitrate for the lowest stream.
1160 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1161 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1162 codec_.simulcastStream[1].minBitrate - 1;
1163
1164 // Input data.
1165 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
1166 VideoFrame input_frame = VideoFrame::Builder()
1167 .set_video_frame_buffer(buffer)
1168 .set_timestamp_rtp(100)
1169 .set_timestamp_ms(1000)
1170 .set_rotation(kVideoRotation_180)
1171 .build();
1172
1173 // Encode with three streams.
1174 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1175 std::vector<MockVideoEncoder*> original_encoders =
1176 helper_->factory()->encoders();
1177 ASSERT_EQ(3u, original_encoders.size());
1178 // Only first encoder will be active and called.
1179 EXPECT_CALL(*original_encoders[0], Encode(_, _))
1180 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1181 EXPECT_CALL(*original_encoders[1], Encode(_, _)).Times(0);
1182 EXPECT_CALL(*original_encoders[2], Encode(_, _)).Times(0);
1183
1184 std::vector<VideoFrameType> frame_types;
1185 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
1186 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1187 }
1188
TEST_F(TestSimulcastEncoderAdapterFake,TrustedRateControl)1189 TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
1190 // Set up common settings for three streams.
1191 SimulcastTestFixtureImpl::DefaultSettings(
1192 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1193 kVideoCodecVP8);
1194 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1195 adapter_->RegisterEncodeCompleteCallback(this);
1196
1197 // Only enough start bitrate for the lowest stream.
1198 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1199 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1200 codec_.simulcastStream[1].minBitrate - 1;
1201
1202 // Input data.
1203 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
1204 VideoFrame input_frame = VideoFrame::Builder()
1205 .set_video_frame_buffer(buffer)
1206 .set_timestamp_rtp(100)
1207 .set_timestamp_ms(1000)
1208 .set_rotation(kVideoRotation_180)
1209 .build();
1210
1211 // No encoder trusted, so simulcast adapter should not be either.
1212 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1213 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1214
1215 // Encode with three streams.
1216 std::vector<MockVideoEncoder*> original_encoders =
1217 helper_->factory()->encoders();
1218
1219 // All encoders are trusted, so simulcast adapter should be too.
1220 original_encoders[0]->set_has_trusted_rate_controller(true);
1221 original_encoders[1]->set_has_trusted_rate_controller(true);
1222 original_encoders[2]->set_has_trusted_rate_controller(true);
1223 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1224 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1225
1226 // One encoder not trusted, so simulcast adapter should not be either.
1227 original_encoders[2]->set_has_trusted_rate_controller(false);
1228 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1229 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1230
1231 // No encoder trusted, so simulcast adapter should not be either.
1232 original_encoders[0]->set_has_trusted_rate_controller(false);
1233 original_encoders[1]->set_has_trusted_rate_controller(false);
1234 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1235 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1236 }
1237
TEST_F(TestSimulcastEncoderAdapterFake,ReportsHardwareAccelerated)1238 TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1239 SimulcastTestFixtureImpl::DefaultSettings(
1240 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1241 kVideoCodecVP8);
1242 codec_.numberOfSimulcastStreams = 3;
1243 adapter_->RegisterEncodeCompleteCallback(this);
1244 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1245 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1246
1247 // None of the encoders uses HW support, so simulcast adapter reports false.
1248 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1249 encoder->set_is_hardware_accelerated(false);
1250 }
1251 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1252 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1253
1254 // One encoder uses HW support, so simulcast adapter reports true.
1255 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
1256 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1257 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1258 }
1259
TEST_F(TestSimulcastEncoderAdapterFake,ReportsLeastCommonMultipleOfRequestedResolutionAlignments)1260 TEST_F(TestSimulcastEncoderAdapterFake,
1261 ReportsLeastCommonMultipleOfRequestedResolutionAlignments) {
1262 SimulcastTestFixtureImpl::DefaultSettings(
1263 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1264 kVideoCodecVP8);
1265 codec_.numberOfSimulcastStreams = 3;
1266 helper_->factory()->set_requested_resolution_alignments({2, 4, 7});
1267 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1268
1269 EXPECT_EQ(adapter_->GetEncoderInfo().requested_resolution_alignment, 28);
1270 }
1271
TEST_F(TestSimulcastEncoderAdapterFake,ReportsInternalSource)1272 TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1273 SimulcastTestFixtureImpl::DefaultSettings(
1274 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1275 kVideoCodecVP8);
1276 codec_.numberOfSimulcastStreams = 3;
1277 adapter_->RegisterEncodeCompleteCallback(this);
1278 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1279 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1280
1281 // All encoders have internal source, simulcast adapter reports true.
1282 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1283 encoder->set_has_internal_source(true);
1284 }
1285 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1286 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1287
1288 // One encoder does not have internal source, simulcast adapter reports false.
1289 helper_->factory()->encoders()[2]->set_has_internal_source(false);
1290 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1291 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1292 }
1293
TEST_F(TestSimulcastEncoderAdapterFake,ReportsFpsAllocation)1294 TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
1295 SimulcastTestFixtureImpl::DefaultSettings(
1296 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1297 kVideoCodecVP8);
1298 codec_.numberOfSimulcastStreams = 3;
1299 adapter_->RegisterEncodeCompleteCallback(this);
1300 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1301 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1302
1303 // Combination of three different supported mode:
1304 // Simulcast stream 0 has undefined fps behavior.
1305 // Simulcast stream 1 has three temporal layers.
1306 // Simulcast stream 2 has 1 temporal layer.
1307 FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
1308 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 4);
1309 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 2);
1310 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction);
1311 expected_fps_allocation[2].push_back(EncoderInfo::kMaxFramerateFraction);
1312
1313 // All encoders have internal source, simulcast adapter reports true.
1314 for (size_t i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
1315 MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
1316 encoder->set_fps_allocation(expected_fps_allocation[i]);
1317 }
1318 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1319 EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
1320 ::testing::ElementsAreArray(expected_fps_allocation));
1321 }
1322
TEST_F(TestSimulcastEncoderAdapterFake,SetRateDistributesBandwithAllocation)1323 TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
1324 SimulcastTestFixtureImpl::DefaultSettings(
1325 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1326 kVideoCodecVP8);
1327 codec_.numberOfSimulcastStreams = 3;
1328 const DataRate target_bitrate =
1329 DataRate::KilobitsPerSec(codec_.simulcastStream[0].targetBitrate +
1330 codec_.simulcastStream[1].targetBitrate +
1331 codec_.simulcastStream[2].minBitrate);
1332 const DataRate bandwidth_allocation =
1333 target_bitrate + DataRate::KilobitsPerSec(600);
1334
1335 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1336 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1337 adapter_->RegisterEncodeCompleteCallback(this);
1338
1339 // Set bitrates so that we send all layers.
1340 adapter_->SetRates(VideoEncoder::RateControlParameters(
1341 rate_allocator_->Allocate(
1342 VideoBitrateAllocationParameters(target_bitrate.bps(), 30)),
1343 30.0, bandwidth_allocation));
1344
1345 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1346
1347 ASSERT_EQ(3u, encoders.size());
1348
1349 for (size_t i = 0; i < 3; ++i) {
1350 const uint32_t layer_bitrate_bps =
1351 (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
1352 ? codec_.simulcastStream[i].targetBitrate
1353 : codec_.simulcastStream[i].minBitrate) *
1354 1000;
1355 EXPECT_EQ(layer_bitrate_bps,
1356 encoders[i]->last_set_rates().bitrate.get_sum_bps())
1357 << i;
1358 EXPECT_EQ(
1359 (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
1360 encoders[i]->last_set_rates().bandwidth_allocation.bps())
1361 << i;
1362 }
1363 }
1364
TEST_F(TestSimulcastEncoderAdapterFake,CanSetZeroBitrateWithHeadroom)1365 TEST_F(TestSimulcastEncoderAdapterFake, CanSetZeroBitrateWithHeadroom) {
1366 SimulcastTestFixtureImpl::DefaultSettings(
1367 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1368 kVideoCodecVP8);
1369 codec_.numberOfSimulcastStreams = 3;
1370
1371 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1372 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1373 adapter_->RegisterEncodeCompleteCallback(this);
1374
1375 // Set allocated bitrate to 0, but keep (network) bandwidth allocation.
1376 VideoEncoder::RateControlParameters rate_params;
1377 rate_params.framerate_fps = 30;
1378 rate_params.bandwidth_allocation = DataRate::KilobitsPerSec(600);
1379
1380 adapter_->SetRates(rate_params);
1381
1382 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1383
1384 ASSERT_EQ(3u, encoders.size());
1385 for (size_t i = 0; i < 3; ++i) {
1386 EXPECT_EQ(0u, encoders[i]->last_set_rates().bitrate.get_sum_bps());
1387 }
1388 }
1389
TEST_F(TestSimulcastEncoderAdapterFake,SupportsSimulcast)1390 TEST_F(TestSimulcastEncoderAdapterFake, SupportsSimulcast) {
1391 SimulcastTestFixtureImpl::DefaultSettings(
1392 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1393 kVideoCodecVP8);
1394 codec_.numberOfSimulcastStreams = 3;
1395
1396 // Indicate that mock encoders internally support simulcast.
1397 helper_->factory()->set_supports_simulcast(true);
1398 adapter_->RegisterEncodeCompleteCallback(this);
1399 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1400
1401 // Only one encoder should have been produced.
1402 ASSERT_EQ(1u, helper_->factory()->encoders().size());
1403
1404 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
1405 VideoFrame input_frame = VideoFrame::Builder()
1406 .set_video_frame_buffer(buffer)
1407 .set_timestamp_rtp(100)
1408 .set_timestamp_ms(1000)
1409 .set_rotation(kVideoRotation_180)
1410 .build();
1411 EXPECT_CALL(*helper_->factory()->encoders()[0], Encode)
1412 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1413 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
1414 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1415 }
1416
TEST_F(TestSimulcastEncoderAdapterFake,PassesSdpVideoFormatToEncoder)1417 TEST_F(TestSimulcastEncoderAdapterFake, PassesSdpVideoFormatToEncoder) {
1418 sdp_video_parameters_ = {{"test_param", "test_value"}};
1419 SetUp();
1420 SetupCodec();
1421 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1422 ASSERT_GT(encoders.size(), 0u);
1423 EXPECT_EQ(encoders[0]->video_format(),
1424 SdpVideoFormat("VP8", sdp_video_parameters_));
1425 }
1426
TEST_F(TestSimulcastEncoderAdapterFake,SupportsFallback)1427 TEST_F(TestSimulcastEncoderAdapterFake, SupportsFallback) {
1428 // Enable support for fallback encoder factory and re-setup.
1429 use_fallback_factory_ = true;
1430 SetUp();
1431
1432 SetupCodec();
1433
1434 // Make sure we have bitrate for all layers.
1435 DataRate max_bitrate = DataRate::Zero();
1436 for (int i = 0; i < 3; ++i) {
1437 max_bitrate +=
1438 DataRate::KilobitsPerSec(codec_.simulcastStream[i].maxBitrate);
1439 }
1440 const auto rate_settings = VideoEncoder::RateControlParameters(
1441 rate_allocator_->Allocate(
1442 VideoBitrateAllocationParameters(max_bitrate.bps(), 30)),
1443 30.0, max_bitrate);
1444 adapter_->SetRates(rate_settings);
1445
1446 std::vector<MockVideoEncoder*> primary_encoders =
1447 helper_->factory()->encoders();
1448 std::vector<MockVideoEncoder*> fallback_encoders =
1449 helper_->fallback_factory()->encoders();
1450
1451 ASSERT_EQ(3u, primary_encoders.size());
1452 ASSERT_EQ(3u, fallback_encoders.size());
1453
1454 // Create frame to test with.
1455 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
1456 VideoFrame input_frame = VideoFrame::Builder()
1457 .set_video_frame_buffer(buffer)
1458 .set_timestamp_rtp(100)
1459 .set_timestamp_ms(1000)
1460 .set_rotation(kVideoRotation_180)
1461 .build();
1462 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
1463
1464 // All primary encoders used.
1465 for (auto codec : primary_encoders) {
1466 EXPECT_CALL(*codec, Encode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1467 }
1468 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1469
1470 // Trigger fallback on first encoder.
1471 primary_encoders[0]->set_init_encode_return_value(
1472 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1473 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1474 adapter_->SetRates(rate_settings);
1475 EXPECT_CALL(*fallback_encoders[0], Encode)
1476 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1477 EXPECT_CALL(*primary_encoders[1], Encode)
1478 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1479 EXPECT_CALL(*primary_encoders[2], Encode)
1480 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1481 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1482
1483 // Trigger fallback on all encoder.
1484 primary_encoders[1]->set_init_encode_return_value(
1485 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1486 primary_encoders[2]->set_init_encode_return_value(
1487 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1488 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1489 adapter_->SetRates(rate_settings);
1490 EXPECT_CALL(*fallback_encoders[0], Encode)
1491 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1492 EXPECT_CALL(*fallback_encoders[1], Encode)
1493 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1494 EXPECT_CALL(*fallback_encoders[2], Encode)
1495 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1496 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1497
1498 // Return to primary encoders on all streams.
1499 for (int i = 0; i < 3; ++i) {
1500 primary_encoders[i]->set_init_encode_return_value(WEBRTC_VIDEO_CODEC_OK);
1501 }
1502 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1503 adapter_->SetRates(rate_settings);
1504 for (auto codec : primary_encoders) {
1505 EXPECT_CALL(*codec, Encode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1506 }
1507 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1508 }
1509
TEST_F(TestSimulcastEncoderAdapterFake,SupportsPerSimulcastLayerMaxFramerate)1510 TEST_F(TestSimulcastEncoderAdapterFake, SupportsPerSimulcastLayerMaxFramerate) {
1511 SimulcastTestFixtureImpl::DefaultSettings(
1512 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1513 kVideoCodecVP8);
1514 codec_.numberOfSimulcastStreams = 3;
1515 codec_.simulcastStream[0].maxFramerate = 60;
1516 codec_.simulcastStream[1].maxFramerate = 30;
1517 codec_.simulcastStream[2].maxFramerate = 10;
1518
1519 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1520 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1521 EXPECT_EQ(60u, helper_->factory()->encoders()[0]->codec().maxFramerate);
1522 EXPECT_EQ(30u, helper_->factory()->encoders()[1]->codec().maxFramerate);
1523 EXPECT_EQ(10u, helper_->factory()->encoders()[2]->codec().maxFramerate);
1524 }
1525
1526 } // namespace test
1527 } // namespace webrtc
1528