blob: 9625b31d2332363d3c65b94525242a91c40c895a [file] [log] [blame]
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001/*
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
brandtr5e171752017-05-23 03:32:16 -070011#include <array>
kwiberg3f55dea2016-02-29 05:51:59 -080012#include <memory>
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000013#include <vector>
14
Rasmus Brandt0cedc052018-05-31 12:53:00 +020015#include "api/test/create_simulcast_test_fixture.h"
16#include "api/test/simulcast_test_fixture.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010017#include "api/video_codecs/sdp_video_format.h"
18#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "common_video/include/video_frame_buffer.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010020#include "media/engine/internalencoderfactory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "media/engine/simulcast_encoder_adapter.h"
Mirko Bonadei6f440ed2018-06-21 13:41:01 +000022#include "modules/video_coding/codecs/vp8/simulcast_test_fixture_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/video_coding/include/video_codec_interface.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010024#include "rtc_base/ptr_util.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020025#include "test/function_video_decoder_factory.h"
26#include "test/function_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020028#include "test/gtest.h"
29
30using ::testing::_;
31using ::testing::Return;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000032
33namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020034namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000035
Rasmus Brandt0cedc052018-05-31 12:53:00 +020036namespace {
philipelcce46fc2015-12-21 03:04:49 -080037
Rasmus Brandt0cedc052018-05-31 12:53:00 +020038constexpr int kDefaultWidth = 1280;
39constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070040
Rasmus Brandt0cedc052018-05-31 12:53:00 +020041std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
42 VideoEncoderFactory* internal_encoder_factory) {
43 std::unique_ptr<VideoEncoderFactory> encoder_factory =
44 rtc::MakeUnique<FunctionVideoEncoderFactory>(
45 [internal_encoder_factory]() {
46 return rtc::MakeUnique<SimulcastEncoderAdapter>(
47 internal_encoder_factory,
48 SdpVideoFormat(cricket::kVp8CodecName));
49 });
50 std::unique_ptr<VideoDecoderFactory> decoder_factory =
51 rtc::MakeUnique<FunctionVideoDecoderFactory>(
52 []() { return VP8Decoder::Create(); });
53 return CreateSimulcastTestFixture(std::move(encoder_factory),
Mirko Bonadei6f440ed2018-06-21 13:41:01 +000054 std::move(decoder_factory));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000055}
56
Rasmus Brandt0cedc052018-05-31 12:53:00 +020057} // namespace
58
59TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
60 InternalEncoderFactory internal_encoder_factory;
61 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
62 fixture->TestKeyFrameRequestsOnAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000063}
64
Rasmus Brandt0cedc052018-05-31 12:53:00 +020065TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
66 InternalEncoderFactory internal_encoder_factory;
67 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
68 fixture->TestPaddingAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000069}
70
Rasmus Brandt0cedc052018-05-31 12:53:00 +020071TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
72 InternalEncoderFactory internal_encoder_factory;
73 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
74 fixture->TestPaddingTwoStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000075}
76
Rasmus Brandt0cedc052018-05-31 12:53:00 +020077TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
78 InternalEncoderFactory internal_encoder_factory;
79 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
80 fixture->TestPaddingTwoStreamsOneMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000081}
82
Rasmus Brandt0cedc052018-05-31 12:53:00 +020083TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
84 InternalEncoderFactory internal_encoder_factory;
85 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
86 fixture->TestPaddingOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000087}
88
Rasmus Brandt0cedc052018-05-31 12:53:00 +020089TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
90 InternalEncoderFactory internal_encoder_factory;
91 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
92 fixture->TestPaddingOneStreamTwoMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000093}
94
Rasmus Brandt0cedc052018-05-31 12:53:00 +020095TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
96 InternalEncoderFactory internal_encoder_factory;
97 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
98 fixture->TestSendAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000099}
100
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200101TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
102 InternalEncoderFactory internal_encoder_factory;
103 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
104 fixture->TestDisablingStreams();
Seth Hampson46e31ba2018-01-18 10:39:54 -0800105}
106
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200107TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
108 InternalEncoderFactory internal_encoder_factory;
109 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
110 fixture->TestActiveStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000111}
112
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200113TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
114 InternalEncoderFactory internal_encoder_factory;
115 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
116 fixture->TestSwitchingToOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000117}
118
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200119TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
120 InternalEncoderFactory internal_encoder_factory;
121 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
122 fixture->TestSwitchingToOneOddStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000123}
124
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200125TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
126 InternalEncoderFactory internal_encoder_factory;
127 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
128 fixture->TestStrideEncodeDecode();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000129}
130
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200131TEST(SimulcastEncoderAdapterSimulcastTest,
132 TestSpatioTemporalLayers333PatternEncoder) {
133 InternalEncoderFactory internal_encoder_factory;
134 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
135 fixture->TestSpatioTemporalLayers333PatternEncoder();
136}
137
138TEST(SimulcastEncoderAdapterSimulcastTest,
139 TestSpatioTemporalLayers321PatternEncoder) {
140 InternalEncoderFactory internal_encoder_factory;
141 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
142 fixture->TestSpatioTemporalLayers321PatternEncoder();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000143}
144
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100145class MockVideoEncoder;
146
147class MockVideoEncoderFactory : public VideoEncoderFactory {
148 public:
149 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
150
151 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
152 const SdpVideoFormat& format) override;
153
154 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
155
156 const std::vector<MockVideoEncoder*>& encoders() const;
157 void SetEncoderNames(const std::vector<const char*>& encoder_names);
158 void set_init_encode_return_value(int32_t value);
159
160 void DestroyVideoEncoder(VideoEncoder* encoder);
161
162 private:
163 int32_t init_encode_return_value_ = 0;
164 std::vector<MockVideoEncoder*> encoders_;
165 std::vector<const char*> encoder_names_;
166};
167
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000168class MockVideoEncoder : public VideoEncoder {
169 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100170 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng82fad3d2018-03-21 09:57:23 +0100171 : factory_(factory), callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100172
nisseef8b61e2016-04-29 06:09:15 -0700173 // TODO(nisse): Valid overrides commented out, because the gmock
174 // methods don't use any override declarations, and we want to avoid
175 // warnings from -Winconsistent-missing-override. See
176 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000177 int32_t InitEncode(const VideoCodec* codecSettings,
178 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700179 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000180 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800181 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000182 }
183
noahricfe3654d2016-07-01 09:05:54 -0700184 MOCK_METHOD3(
185 Encode,
186 int32_t(const VideoFrame& inputImage,
187 const CodecSpecificInfo* codecSpecificInfo,
188 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000189
pbos65e15ba2015-10-15 10:52:15 -0700190 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700191 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700192 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000193 return 0;
194 }
195
brandtr5e171752017-05-23 03:32:16 -0700196 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000197
Erik Språng566124a2018-04-23 12:32:22 +0200198 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
Erik Språng08127a92016-11-16 16:41:30 +0100199 uint32_t framerate) {
200 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000201 return 0;
202 }
203
philipelcce46fc2015-12-21 03:04:49 -0800204 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000205
nisseef8b61e2016-04-29 06:09:15 -0700206 bool SupportsNativeHandle() const /* override */ {
207 return supports_native_handle_;
208 }
pbos65e15ba2015-10-15 10:52:15 -0700209
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100210 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000211
212 const VideoCodec& codec() const { return codec_; }
213
Noah Richards41ee1ea2015-04-15 09:24:26 -0700214 void SendEncodedImage(int width, int height) {
215 // Sends a fake image of the given width/height.
216 EncodedImage image;
217 image._encodedWidth = width;
218 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700219 CodecSpecificInfo codec_specific_info;
220 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
brandtr5e171752017-05-23 03:32:16 -0700221 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700222 }
223
pbos65e15ba2015-10-15 10:52:15 -0700224 void set_supports_native_handle(bool enabled) {
225 supports_native_handle_ = enabled;
226 }
noahrice5ba75a2016-12-12 13:08:27 -0800227
228 void set_init_encode_return_value(int32_t value) {
229 init_encode_return_value_ = value;
230 }
231
Erik Språng566124a2018-04-23 12:32:22 +0200232 VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700233
Peter Boströma5dec162016-01-20 15:53:55 +0100234 MOCK_CONST_METHOD0(ImplementationName, const char*());
235
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000236 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100237 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700238 bool supports_native_handle_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800239 int32_t init_encode_return_value_ = 0;
Erik Språng566124a2018-04-23 12:32:22 +0200240 VideoBitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700241
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000242 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700243 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000244};
245
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100246std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
247 const {
248 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
249 return formats;
250}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000251
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100252std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
253 const SdpVideoFormat& format) {
254 std::unique_ptr<MockVideoEncoder> encoder(
255 new ::testing::NiceMock<MockVideoEncoder>(this));
256 encoder->set_init_encode_return_value(init_encode_return_value_);
257 const char* encoder_name = encoder_names_.empty()
258 ? "codec_implementation_name"
259 : encoder_names_[encoders_.size()];
260 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
261 encoders_.push_back(encoder.get());
262 return encoder;
263}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000264
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100265void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
266 for (size_t i = 0; i < encoders_.size(); ++i) {
267 if (encoders_[i] == encoder) {
268 encoders_.erase(encoders_.begin() + i);
269 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000270 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000271 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100272}
Zhi Huangaea84f52017-11-16 18:46:27 +0000273
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100274VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
275 const SdpVideoFormat& format) const {
276 return CodecInfo();
277}
Zhi Huangaea84f52017-11-16 18:46:27 +0000278
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100279const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
280 const {
281 return encoders_;
282}
283void MockVideoEncoderFactory::SetEncoderNames(
284 const std::vector<const char*>& encoder_names) {
285 encoder_names_ = encoder_names;
286}
287void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
288 init_encode_return_value_ = value;
289}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000290
291class TestSimulcastEncoderAdapterFakeHelper {
292 public:
293 TestSimulcastEncoderAdapterFakeHelper()
294 : factory_(new MockVideoEncoderFactory()) {}
295
296 // Can only be called once as the SimulcastEncoderAdapter will take the
297 // ownership of |factory_|.
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000298 VP8Encoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200299 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000300 }
301
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000302 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000303 EXPECT_TRUE(!factory_->encoders().empty());
304 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
305 EXPECT_CALL(*factory_->encoders()[i],
philipelcce46fc2015-12-21 03:04:49 -0800306 SetChannelParameters(packetLoss, rtt))
307 .Times(1);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000308 }
309 }
310
magjed6cc25612017-07-10 03:26:36 -0700311 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000312
313 private:
magjed6cc25612017-07-10 03:26:36 -0700314 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000315};
316
317static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
318
Noah Richards41ee1ea2015-04-15 09:24:26 -0700319class TestSimulcastEncoderAdapterFake : public ::testing::Test,
320 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000321 public:
322 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700323 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
324 adapter_(helper_->CreateMockEncoderAdapter()),
325 last_encoded_image_width_(-1),
326 last_encoded_image_height_(-1),
327 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700328 virtual ~TestSimulcastEncoderAdapterFake() {
329 if (adapter_) {
330 adapter_->Release();
331 }
332 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000333
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700334 Result OnEncodedImage(const EncodedImage& encoded_image,
335 const CodecSpecificInfo* codec_specific_info,
336 const RTPFragmentationHeader* fragmentation) override {
337 last_encoded_image_width_ = encoded_image._encodedWidth;
338 last_encoded_image_height_ = encoded_image._encodedHeight;
339 if (codec_specific_info) {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700340 last_encoded_image_simulcast_index_ =
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700341 codec_specific_info->codecSpecific.VP8.simulcastIdx;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700342 }
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700343 return Result(Result::OK, encoded_image._timeStamp);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700344 }
345
346 bool GetLastEncodedImageInfo(int* out_width,
347 int* out_height,
348 int* out_simulcast_index) {
349 if (last_encoded_image_width_ == -1) {
350 return false;
351 }
352 *out_width = last_encoded_image_width_;
353 *out_height = last_encoded_image_height_;
354 *out_simulcast_index = last_encoded_image_simulcast_index_;
355 return true;
356 }
357
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000358 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200359 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000360 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng82fad3d2018-03-21 09:57:23 +0100361 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000362 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700363 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000364 }
365
366 void VerifyCodec(const VideoCodec& ref, int stream_index) {
367 const VideoCodec& target =
368 helper_->factory()->encoders()[stream_index]->codec();
369 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000370 EXPECT_EQ(ref.plType, target.plType);
371 EXPECT_EQ(ref.width, target.width);
372 EXPECT_EQ(ref.height, target.height);
373 EXPECT_EQ(ref.startBitrate, target.startBitrate);
374 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
375 EXPECT_EQ(ref.minBitrate, target.minBitrate);
376 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700377 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700378 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
379 target.VP8().numberOfTemporalLayers);
380 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700381 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
382 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
383 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000384 EXPECT_EQ(ref.qpMax, target.qpMax);
385 EXPECT_EQ(0, target.numberOfSimulcastStreams);
386 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000387
388 // No need to compare simulcastStream as numberOfSimulcastStreams should
389 // always be 0.
390 }
391
392 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
393 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700394 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000395 kTestTemporalLayerProfile[stream_index];
396 ref_codec->width = codec_.simulcastStream[stream_index].width;
397 ref_codec->height = codec_.simulcastStream[stream_index].height;
398 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
399 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
400 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
401 }
402
403 void VerifyCodecSettings() {
404 EXPECT_EQ(3u, helper_->factory()->encoders().size());
405 VideoCodec ref_codec;
406
407 // stream 0, the lowest resolution stream.
408 InitRefCodec(0, &ref_codec);
409 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200410 ref_codec.VP8()->complexity =
411 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700412 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000413 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
414 VerifyCodec(ref_codec, 0);
415
416 // stream 1
417 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700418 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700419 // The start bitrate (300kbit) minus what we have for the lower layers
420 // (100kbit).
421 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000422 VerifyCodec(ref_codec, 1);
423
424 // stream 2, the biggest resolution stream.
425 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700426 // We don't have enough bits to send this, so the adapter should have
427 // configured it to use the min bitrate for this layer (600kbit) but turn
428 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000429 ref_codec.startBitrate = 600;
430 VerifyCodec(ref_codec, 2);
431 }
432
433 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800434 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000435 std::unique_ptr<VP8Encoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000436 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700437 int last_encoded_image_width_;
438 int last_encoded_image_height_;
439 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100440 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000441};
442
443TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
444 SetupCodec();
445 VerifyCodecSettings();
446}
447
brandtr5e171752017-05-23 03:32:16 -0700448TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
449 EXPECT_EQ(0, adapter_->Release());
450}
451
452TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
453 SetupCodec();
454 EXPECT_EQ(0, adapter_->Release());
455
456 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
457}
458
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000459TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
460 SetupCodec();
461 const uint32_t packetLoss = 5;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000462 const int64_t rtt = 30;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000463 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
464 adapter_->SetChannelParameters(packetLoss, rtt);
465}
466
Noah Richards41ee1ea2015-04-15 09:24:26 -0700467TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
468 SetupCodec();
469
Peter Boström5d0379d2015-10-06 14:04:51 +0200470 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100471 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200472
Noah Richards41ee1ea2015-04-15 09:24:26 -0700473 // At this point, the simulcast encoder adapter should have 3 streams: HD,
474 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
475 // resolutions, to test that the adapter forwards on the correct resolution
476 // and simulcast index values, going only off the encoder that generates the
477 // image.
brandtr5e171752017-05-23 03:32:16 -0700478 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
479 ASSERT_EQ(3u, encoders.size());
480 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700481 int width;
482 int height;
483 int simulcast_index;
484 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
485 EXPECT_EQ(1152, width);
486 EXPECT_EQ(704, height);
487 EXPECT_EQ(0, simulcast_index);
488
brandtr5e171752017-05-23 03:32:16 -0700489 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700490 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
491 EXPECT_EQ(300, width);
492 EXPECT_EQ(620, height);
493 EXPECT_EQ(1, simulcast_index);
494
brandtr5e171752017-05-23 03:32:16 -0700495 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700496 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
497 EXPECT_EQ(120, width);
498 EXPECT_EQ(240, height);
499 EXPECT_EQ(2, simulcast_index);
500}
501
brandtr5e171752017-05-23 03:32:16 -0700502// This test verifies that the underlying encoders are reused, when the adapter
503// is reinited with different number of simulcast streams. It further checks
504// that the allocated encoders are reused in the same order as before, starting
505// with the lowest stream.
506TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
507 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200508 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000509 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng82fad3d2018-03-21 09:57:23 +0100510 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700511 adapter_->RegisterEncodeCompleteCallback(this);
512
513 // Input data.
514 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
515 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
516 std::vector<FrameType> frame_types;
517
518 // Encode with three streams.
519 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
520 VerifyCodecSettings();
521 std::vector<MockVideoEncoder*> original_encoders =
522 helper_->factory()->encoders();
523 ASSERT_EQ(3u, original_encoders.size());
524 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
525 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
526 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
527 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
528 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
529 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
530 frame_types.resize(3, kVideoFrameKey);
531 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
532 EXPECT_CALL(*original_encoders[0], Release())
533 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
534 EXPECT_CALL(*original_encoders[1], Release())
535 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
536 EXPECT_CALL(*original_encoders[2], Release())
537 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
538 EXPECT_EQ(0, adapter_->Release());
539
540 // Encode with two streams.
541 codec_.width /= 2;
542 codec_.height /= 2;
543 codec_.numberOfSimulcastStreams = 2;
544 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
545 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
546 ASSERT_EQ(2u, new_encoders.size());
547 ASSERT_EQ(original_encoders[0], new_encoders[0]);
548 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
549 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
550 ASSERT_EQ(original_encoders[1], new_encoders[1]);
551 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
552 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
553 frame_types.resize(2, kVideoFrameKey);
554 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
555 EXPECT_CALL(*original_encoders[0], Release())
556 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
557 EXPECT_CALL(*original_encoders[1], Release())
558 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
559 EXPECT_EQ(0, adapter_->Release());
560
561 // Encode with single stream.
562 codec_.width /= 2;
563 codec_.height /= 2;
564 codec_.numberOfSimulcastStreams = 1;
565 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
566 new_encoders = helper_->factory()->encoders();
567 ASSERT_EQ(1u, new_encoders.size());
568 ASSERT_EQ(original_encoders[0], new_encoders[0]);
569 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
570 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
571 frame_types.resize(1, kVideoFrameKey);
572 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
573 EXPECT_CALL(*original_encoders[0], Release())
574 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
575 EXPECT_EQ(0, adapter_->Release());
576
577 // Encode with three streams, again.
578 codec_.width *= 4;
579 codec_.height *= 4;
580 codec_.numberOfSimulcastStreams = 3;
581 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
582 new_encoders = helper_->factory()->encoders();
583 ASSERT_EQ(3u, new_encoders.size());
584 // The first encoder is reused.
585 ASSERT_EQ(original_encoders[0], new_encoders[0]);
586 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
587 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
588 // The second and third encoders are new.
589 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
590 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
591 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
592 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
593 frame_types.resize(3, kVideoFrameKey);
594 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
595 EXPECT_CALL(*original_encoders[0], Release())
596 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
597 EXPECT_CALL(*new_encoders[1], Release())
598 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
599 EXPECT_CALL(*new_encoders[2], Release())
600 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
601 EXPECT_EQ(0, adapter_->Release());
602}
603
604TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
605 SetupCodec();
606 VerifyCodecSettings();
607
608 EXPECT_EQ(3u, helper_->factory()->encoders().size());
609
610 // The adapter should destroy all encoders it has allocated. Since
611 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
612 // lsan to find leaks here.
613 EXPECT_EQ(0, adapter_->Release());
614 adapter_.reset();
615}
616
617// This test verifies that an adapter reinit with the same codec settings as
618// before does not change the underlying encoder codec settings.
619TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
620 SetupCodec();
621 VerifyCodecSettings();
622
623 // Capture current codec settings.
624 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
625 ASSERT_EQ(3u, encoders.size());
626 std::array<VideoCodec, 3> codecs_before;
627 for (int i = 0; i < 3; ++i) {
628 codecs_before[i] = encoders[i]->codec();
629 }
630
631 // Reinitialize and verify that the new codec settings are the same.
632 EXPECT_EQ(0, adapter_->Release());
633 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
634 for (int i = 0; i < 3; ++i) {
635 const VideoCodec& codec_before = codecs_before[i];
636 const VideoCodec& codec_after = encoders[i]->codec();
637
638 // webrtc::VideoCodec does not implement operator==.
639 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
640 EXPECT_EQ(codec_before.plType, codec_after.plType);
641 EXPECT_EQ(codec_before.width, codec_after.width);
642 EXPECT_EQ(codec_before.height, codec_after.height);
643 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
644 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
645 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
646 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
647 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
648 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
649 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
650 codec_after.numberOfSimulcastStreams);
651 EXPECT_EQ(codec_before.mode, codec_after.mode);
652 EXPECT_EQ(codec_before.expect_encode_from_texture,
653 codec_after.expect_encode_from_texture);
654 }
655}
656
657// This test is similar to the one above, except that it tests the simulcastIdx
658// from the CodecSpecificInfo that is connected to an encoded frame. The
659// PayloadRouter demuxes the incoming encoded frames on different RTP modules
660// using the simulcastIdx, so it's important that there is no corresponding
661// encoder reordering in between adapter reinits as this would lead to PictureID
662// discontinuities.
663TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
664 SetupCodec();
665 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
666 VerifyCodecSettings();
667
668 // Send frames on all streams.
669 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
670 ASSERT_EQ(3u, encoders.size());
671 encoders[0]->SendEncodedImage(1152, 704);
672 int width;
673 int height;
674 int simulcast_index;
675 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
676 EXPECT_EQ(0, simulcast_index);
677
678 encoders[1]->SendEncodedImage(300, 620);
679 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
680 EXPECT_EQ(1, simulcast_index);
681
682 encoders[2]->SendEncodedImage(120, 240);
683 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
684 EXPECT_EQ(2, simulcast_index);
685
686 // Reinitialize.
687 EXPECT_EQ(0, adapter_->Release());
688 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
689 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
690
691 // Verify that the same encoder sends out frames on the same simulcast index.
692 encoders[0]->SendEncodedImage(1152, 704);
693 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
694 EXPECT_EQ(0, simulcast_index);
695
696 encoders[1]->SendEncodedImage(300, 620);
697 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
698 EXPECT_EQ(1, simulcast_index);
699
700 encoders[2]->SendEncodedImage(120, 240);
701 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
702 EXPECT_EQ(2, simulcast_index);
703}
704
pbos65e15ba2015-10-15 10:52:15 -0700705TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200706 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000707 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
pbos65e15ba2015-10-15 10:52:15 -0700708 codec_.numberOfSimulcastStreams = 1;
709 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
710 adapter_->RegisterEncodeCompleteCallback(this);
711 ASSERT_EQ(1u, helper_->factory()->encoders().size());
712 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
713 EXPECT_TRUE(adapter_->SupportsNativeHandle());
714 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
715 EXPECT_FALSE(adapter_->SupportsNativeHandle());
716}
717
noahricfac0ff02016-09-09 10:27:15 -0700718TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200719 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000720 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
noahricfac0ff02016-09-09 10:27:15 -0700721 codec_.minBitrate = 50;
722 codec_.numberOfSimulcastStreams = 1;
723 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng82fad3d2018-03-21 09:57:23 +0100724 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700725
726 // Above min should be respected.
Erik Språng566124a2018-04-23 12:32:22 +0200727 VideoBitrateAllocation target_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100728 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
729 adapter_->SetRateAllocation(target_bitrate, 30);
730 EXPECT_EQ(target_bitrate,
731 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700732
733 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng566124a2018-04-23 12:32:22 +0200734 VideoBitrateAllocation too_low_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100735 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
736 adapter_->SetRateAllocation(too_low_bitrate, 30);
737 EXPECT_EQ(target_bitrate,
738 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700739
740 // Zero should be passed on as is, since it means "pause".
Erik Språng566124a2018-04-23 12:32:22 +0200741 adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
742 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng08127a92016-11-16 16:41:30 +0100743 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700744}
745
Peter Boströma5dec162016-01-20 15:53:55 +0100746TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
747 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200748 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000749 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Peter Boströma5dec162016-01-20 15:53:55 +0100750 std::vector<const char*> encoder_names;
751 encoder_names.push_back("codec1");
752 encoder_names.push_back("codec2");
753 encoder_names.push_back("codec3");
754 helper_->factory()->SetEncoderNames(encoder_names);
755 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
756 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
757 adapter_->ImplementationName());
Peter Boströmd53c3892016-03-30 17:03:52 +0200758
759 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700760 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200761 codec_.numberOfSimulcastStreams = 1;
762 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
763 adapter_->RegisterEncodeCompleteCallback(this);
764 ASSERT_EQ(1u, helper_->factory()->encoders().size());
765 EXPECT_STREQ("codec1", adapter_->ImplementationName());
Peter Boströma5dec162016-01-20 15:53:55 +0100766}
767
pbos65e15ba2015-10-15 10:52:15 -0700768TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700769 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200770 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000771 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
pbos65e15ba2015-10-15 10:52:15 -0700772 codec_.numberOfSimulcastStreams = 3;
773 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
774 adapter_->RegisterEncodeCompleteCallback(this);
775 ASSERT_EQ(3u, helper_->factory()->encoders().size());
776 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
777 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700778 // If one encoder doesn't support it, then overall support is disabled.
779 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
pbos65e15ba2015-10-15 10:52:15 -0700780 EXPECT_FALSE(adapter_->SupportsNativeHandle());
noahricfe3654d2016-07-01 09:05:54 -0700781 // Once all do, then the adapter claims support.
782 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
783 EXPECT_TRUE(adapter_->SupportsNativeHandle());
784}
785
nisseaf916892017-01-10 07:44:26 -0800786// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000787class FakeNativeBuffer : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700788 public:
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000789 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
790
791 Type type() const override { return Type::kNative; }
792 int width() const override { return width_; }
793 int height() const override { return height_; }
794
795 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700796 RTC_NOTREACHED();
797 return nullptr;
798 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000799
800 private:
801 const int width_;
802 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700803};
804
805TEST_F(TestSimulcastEncoderAdapterFake,
806 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200807 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000808 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
noahricfe3654d2016-07-01 09:05:54 -0700809 codec_.numberOfSimulcastStreams = 3;
810 // High start bitrate, so all streams are enabled.
811 codec_.startBitrate = 3000;
812 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
813 adapter_->RegisterEncodeCompleteCallback(this);
814 ASSERT_EQ(3u, helper_->factory()->encoders().size());
815 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
816 encoder->set_supports_native_handle(true);
817 EXPECT_TRUE(adapter_->SupportsNativeHandle());
818
819 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000820 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
noahricfe3654d2016-07-01 09:05:54 -0700821 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
822 // Expect calls with the given video frame verbatim, since it's a texture
823 // frame and can't otherwise be modified/resized.
824 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
825 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
826 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700827 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700828}
829
noahric57779102016-05-25 06:48:46 -0700830TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200831 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000832 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
noahric57779102016-05-25 06:48:46 -0700833 codec_.numberOfSimulcastStreams = 3;
834 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
835 adapter_->RegisterEncodeCompleteCallback(this);
836 ASSERT_EQ(3u, helper_->factory()->encoders().size());
837 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700838 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
839 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700840
841 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000842 rtc::scoped_refptr<I420Buffer> input_buffer =
843 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700844 input_buffer->InitializeData();
845 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
noahric57779102016-05-25 06:48:46 -0700846 std::vector<FrameType> frame_types(3, kVideoFrameKey);
847 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
848 adapter_->Encode(input_frame, nullptr, &frame_types));
849}
850
noahrice5ba75a2016-12-12 13:08:27 -0800851TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200852 SimulcastTestFixtureImpl::DefaultSettings(
Mirko Bonadei6f440ed2018-06-21 13:41:01 +0000853 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
noahrice5ba75a2016-12-12 13:08:27 -0800854 codec_.numberOfSimulcastStreams = 3;
855 helper_->factory()->set_init_encode_return_value(
856 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
857 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
858 adapter_->InitEncode(&codec_, 1, 1200));
859 EXPECT_TRUE(helper_->factory()->encoders().empty());
860}
861
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200862} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000863} // namespace webrtc