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