blob: 53f12a3732ca0d9a157d0477561f321fd83f9906 [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"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020022#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/video_coding/include/video_codec_interface.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020024#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010025#include "rtc_base/ptr_util.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020026#include "test/function_video_decoder_factory.h"
27#include "test/function_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020029#include "test/gtest.h"
30
31using ::testing::_;
32using ::testing::Return;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000033
34namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020035namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000036
Rasmus Brandt0cedc052018-05-31 12:53:00 +020037namespace {
philipelcce46fc2015-12-21 03:04:49 -080038
Rasmus Brandt0cedc052018-05-31 12:53:00 +020039constexpr int kDefaultWidth = 1280;
40constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070041
Rasmus Brandt0cedc052018-05-31 12:53:00 +020042std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
43 VideoEncoderFactory* internal_encoder_factory) {
44 std::unique_ptr<VideoEncoderFactory> encoder_factory =
45 rtc::MakeUnique<FunctionVideoEncoderFactory>(
46 [internal_encoder_factory]() {
47 return rtc::MakeUnique<SimulcastEncoderAdapter>(
48 internal_encoder_factory,
49 SdpVideoFormat(cricket::kVp8CodecName));
50 });
51 std::unique_ptr<VideoDecoderFactory> decoder_factory =
52 rtc::MakeUnique<FunctionVideoDecoderFactory>(
53 []() { return VP8Decoder::Create(); });
54 return CreateSimulcastTestFixture(std::move(encoder_factory),
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020055 std::move(decoder_factory),
56 SdpVideoFormat(cricket::kVp8CodecName));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000057}
58
Rasmus Brandt0cedc052018-05-31 12:53:00 +020059} // namespace
60
61TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
62 InternalEncoderFactory internal_encoder_factory;
63 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
64 fixture->TestKeyFrameRequestsOnAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000065}
66
Rasmus Brandt0cedc052018-05-31 12:53:00 +020067TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
68 InternalEncoderFactory internal_encoder_factory;
69 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
70 fixture->TestPaddingAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000071}
72
Rasmus Brandt0cedc052018-05-31 12:53:00 +020073TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
74 InternalEncoderFactory internal_encoder_factory;
75 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
76 fixture->TestPaddingTwoStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000077}
78
Rasmus Brandt0cedc052018-05-31 12:53:00 +020079TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
80 InternalEncoderFactory internal_encoder_factory;
81 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
82 fixture->TestPaddingTwoStreamsOneMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000083}
84
Rasmus Brandt0cedc052018-05-31 12:53:00 +020085TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
86 InternalEncoderFactory internal_encoder_factory;
87 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
88 fixture->TestPaddingOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000089}
90
Rasmus Brandt0cedc052018-05-31 12:53:00 +020091TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
92 InternalEncoderFactory internal_encoder_factory;
93 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
94 fixture->TestPaddingOneStreamTwoMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000095}
96
Rasmus Brandt0cedc052018-05-31 12:53:00 +020097TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
98 InternalEncoderFactory internal_encoder_factory;
99 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
100 fixture->TestSendAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000101}
102
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200103TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
104 InternalEncoderFactory internal_encoder_factory;
105 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
106 fixture->TestDisablingStreams();
Seth Hampson46e31ba2018-01-18 10:39:54 -0800107}
108
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200109TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
110 InternalEncoderFactory internal_encoder_factory;
111 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
112 fixture->TestActiveStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000113}
114
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200115TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
116 InternalEncoderFactory internal_encoder_factory;
117 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
118 fixture->TestSwitchingToOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000119}
120
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200121TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
122 InternalEncoderFactory internal_encoder_factory;
123 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
124 fixture->TestSwitchingToOneOddStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000125}
126
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200127TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
128 InternalEncoderFactory internal_encoder_factory;
129 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
130 fixture->TestStrideEncodeDecode();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000131}
132
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200133TEST(SimulcastEncoderAdapterSimulcastTest,
134 TestSpatioTemporalLayers333PatternEncoder) {
135 InternalEncoderFactory internal_encoder_factory;
136 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
137 fixture->TestSpatioTemporalLayers333PatternEncoder();
138}
139
140TEST(SimulcastEncoderAdapterSimulcastTest,
141 TestSpatioTemporalLayers321PatternEncoder) {
142 InternalEncoderFactory internal_encoder_factory;
143 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
144 fixture->TestSpatioTemporalLayers321PatternEncoder();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000145}
146
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100147class MockVideoEncoder;
148
149class MockVideoEncoderFactory : public VideoEncoderFactory {
150 public:
151 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
152
153 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
154 const SdpVideoFormat& format) override;
155
156 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
157
158 const std::vector<MockVideoEncoder*>& encoders() const;
159 void SetEncoderNames(const std::vector<const char*>& encoder_names);
160 void set_init_encode_return_value(int32_t value);
161
162 void DestroyVideoEncoder(VideoEncoder* encoder);
163
164 private:
165 int32_t init_encode_return_value_ = 0;
166 std::vector<MockVideoEncoder*> encoders_;
167 std::vector<const char*> encoder_names_;
168};
169
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000170class MockVideoEncoder : public VideoEncoder {
171 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100172 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng82fad3d2018-03-21 09:57:23 +0100173 : factory_(factory), callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100174
nisseef8b61e2016-04-29 06:09:15 -0700175 // TODO(nisse): Valid overrides commented out, because the gmock
176 // methods don't use any override declarations, and we want to avoid
177 // warnings from -Winconsistent-missing-override. See
178 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000179 int32_t InitEncode(const VideoCodec* codecSettings,
180 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700181 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000182 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800183 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000184 }
185
noahricfe3654d2016-07-01 09:05:54 -0700186 MOCK_METHOD3(
187 Encode,
188 int32_t(const VideoFrame& inputImage,
189 const CodecSpecificInfo* codecSpecificInfo,
190 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000191
pbos65e15ba2015-10-15 10:52:15 -0700192 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700193 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700194 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000195 return 0;
196 }
197
brandtr5e171752017-05-23 03:32:16 -0700198 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000199
Erik Språng566124a2018-04-23 12:32:22 +0200200 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
Erik Språng08127a92016-11-16 16:41:30 +0100201 uint32_t framerate) {
202 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000203 return 0;
204 }
205
philipelcce46fc2015-12-21 03:04:49 -0800206 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000207
nisseef8b61e2016-04-29 06:09:15 -0700208 bool SupportsNativeHandle() const /* override */ {
209 return supports_native_handle_;
210 }
pbos65e15ba2015-10-15 10:52:15 -0700211
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100212 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000213
214 const VideoCodec& codec() const { return codec_; }
215
Noah Richards41ee1ea2015-04-15 09:24:26 -0700216 void SendEncodedImage(int width, int height) {
217 // Sends a fake image of the given width/height.
218 EncodedImage image;
219 image._encodedWidth = width;
220 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700221 CodecSpecificInfo codec_specific_info;
222 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200223 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700224 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700225 }
226
pbos65e15ba2015-10-15 10:52:15 -0700227 void set_supports_native_handle(bool enabled) {
228 supports_native_handle_ = enabled;
229 }
noahrice5ba75a2016-12-12 13:08:27 -0800230
231 void set_init_encode_return_value(int32_t value) {
232 init_encode_return_value_ = value;
233 }
234
Erik Språng566124a2018-04-23 12:32:22 +0200235 VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700236
Peter Boströma5dec162016-01-20 15:53:55 +0100237 MOCK_CONST_METHOD0(ImplementationName, const char*());
238
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000239 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100240 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700241 bool supports_native_handle_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800242 int32_t init_encode_return_value_ = 0;
Erik Språng566124a2018-04-23 12:32:22 +0200243 VideoBitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700244
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000245 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700246 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000247};
248
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100249std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
250 const {
251 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
252 return formats;
253}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000254
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100255std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
256 const SdpVideoFormat& format) {
257 std::unique_ptr<MockVideoEncoder> encoder(
258 new ::testing::NiceMock<MockVideoEncoder>(this));
259 encoder->set_init_encode_return_value(init_encode_return_value_);
260 const char* encoder_name = encoder_names_.empty()
261 ? "codec_implementation_name"
262 : encoder_names_[encoders_.size()];
263 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
264 encoders_.push_back(encoder.get());
265 return encoder;
266}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000267
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100268void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
269 for (size_t i = 0; i < encoders_.size(); ++i) {
270 if (encoders_[i] == encoder) {
271 encoders_.erase(encoders_.begin() + i);
272 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000273 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000274 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100275}
Zhi Huangaea84f52017-11-16 18:46:27 +0000276
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100277VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
278 const SdpVideoFormat& format) const {
279 return CodecInfo();
280}
Zhi Huangaea84f52017-11-16 18:46:27 +0000281
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100282const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
283 const {
284 return encoders_;
285}
286void MockVideoEncoderFactory::SetEncoderNames(
287 const std::vector<const char*>& encoder_names) {
288 encoder_names_ = encoder_names;
289}
290void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
291 init_encode_return_value_ = value;
292}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000293
294class TestSimulcastEncoderAdapterFakeHelper {
295 public:
296 TestSimulcastEncoderAdapterFakeHelper()
297 : factory_(new MockVideoEncoderFactory()) {}
298
299 // Can only be called once as the SimulcastEncoderAdapter will take the
300 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200301 VideoEncoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200302 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000303 }
304
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000305 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000306 EXPECT_TRUE(!factory_->encoders().empty());
307 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
308 EXPECT_CALL(*factory_->encoders()[i],
philipelcce46fc2015-12-21 03:04:49 -0800309 SetChannelParameters(packetLoss, rtt))
310 .Times(1);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000311 }
312 }
313
magjed6cc25612017-07-10 03:26:36 -0700314 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000315
316 private:
magjed6cc25612017-07-10 03:26:36 -0700317 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000318};
319
320static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
321
Noah Richards41ee1ea2015-04-15 09:24:26 -0700322class TestSimulcastEncoderAdapterFake : public ::testing::Test,
323 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000324 public:
325 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700326 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
327 adapter_(helper_->CreateMockEncoderAdapter()),
328 last_encoded_image_width_(-1),
329 last_encoded_image_height_(-1),
330 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700331 virtual ~TestSimulcastEncoderAdapterFake() {
332 if (adapter_) {
333 adapter_->Release();
334 }
335 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000336
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700337 Result OnEncodedImage(const EncodedImage& encoded_image,
338 const CodecSpecificInfo* codec_specific_info,
339 const RTPFragmentationHeader* fragmentation) override {
340 last_encoded_image_width_ = encoded_image._encodedWidth;
341 last_encoded_image_height_ = encoded_image._encodedHeight;
342 if (codec_specific_info) {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700343 last_encoded_image_simulcast_index_ =
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700344 codec_specific_info->codecSpecific.VP8.simulcastIdx;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700345 }
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700346 return Result(Result::OK, encoded_image._timeStamp);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700347 }
348
349 bool GetLastEncodedImageInfo(int* out_width,
350 int* out_height,
351 int* out_simulcast_index) {
352 if (last_encoded_image_width_ == -1) {
353 return false;
354 }
355 *out_width = last_encoded_image_width_;
356 *out_height = last_encoded_image_height_;
357 *out_simulcast_index = last_encoded_image_simulcast_index_;
358 return true;
359 }
360
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000361 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200362 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200363 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
364 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100365 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000366 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700367 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000368 }
369
370 void VerifyCodec(const VideoCodec& ref, int stream_index) {
371 const VideoCodec& target =
372 helper_->factory()->encoders()[stream_index]->codec();
373 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000374 EXPECT_EQ(ref.plType, target.plType);
375 EXPECT_EQ(ref.width, target.width);
376 EXPECT_EQ(ref.height, target.height);
377 EXPECT_EQ(ref.startBitrate, target.startBitrate);
378 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
379 EXPECT_EQ(ref.minBitrate, target.minBitrate);
380 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700381 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700382 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
383 target.VP8().numberOfTemporalLayers);
384 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700385 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
386 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
387 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000388 EXPECT_EQ(ref.qpMax, target.qpMax);
389 EXPECT_EQ(0, target.numberOfSimulcastStreams);
390 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000391
392 // No need to compare simulcastStream as numberOfSimulcastStreams should
393 // always be 0.
394 }
395
396 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
397 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700398 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000399 kTestTemporalLayerProfile[stream_index];
400 ref_codec->width = codec_.simulcastStream[stream_index].width;
401 ref_codec->height = codec_.simulcastStream[stream_index].height;
402 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
403 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
404 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
405 }
406
407 void VerifyCodecSettings() {
408 EXPECT_EQ(3u, helper_->factory()->encoders().size());
409 VideoCodec ref_codec;
410
411 // stream 0, the lowest resolution stream.
412 InitRefCodec(0, &ref_codec);
413 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200414 ref_codec.VP8()->complexity =
415 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700416 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000417 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
418 VerifyCodec(ref_codec, 0);
419
420 // stream 1
421 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700422 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700423 // The start bitrate (300kbit) minus what we have for the lower layers
424 // (100kbit).
425 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000426 VerifyCodec(ref_codec, 1);
427
428 // stream 2, the biggest resolution stream.
429 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700430 // We don't have enough bits to send this, so the adapter should have
431 // configured it to use the min bitrate for this layer (600kbit) but turn
432 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000433 ref_codec.startBitrate = 600;
434 VerifyCodec(ref_codec, 2);
435 }
436
437 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800438 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200439 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000440 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700441 int last_encoded_image_width_;
442 int last_encoded_image_height_;
443 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100444 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000445};
446
447TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
448 SetupCodec();
449 VerifyCodecSettings();
450}
451
brandtr5e171752017-05-23 03:32:16 -0700452TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
453 EXPECT_EQ(0, adapter_->Release());
454}
455
456TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
457 SetupCodec();
458 EXPECT_EQ(0, adapter_->Release());
459
460 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
461}
462
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000463TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
464 SetupCodec();
465 const uint32_t packetLoss = 5;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000466 const int64_t rtt = 30;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000467 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
468 adapter_->SetChannelParameters(packetLoss, rtt);
469}
470
Noah Richards41ee1ea2015-04-15 09:24:26 -0700471TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
472 SetupCodec();
473
Peter Boström5d0379d2015-10-06 14:04:51 +0200474 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100475 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200476
Noah Richards41ee1ea2015-04-15 09:24:26 -0700477 // At this point, the simulcast encoder adapter should have 3 streams: HD,
478 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
479 // resolutions, to test that the adapter forwards on the correct resolution
480 // and simulcast index values, going only off the encoder that generates the
481 // image.
brandtr5e171752017-05-23 03:32:16 -0700482 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
483 ASSERT_EQ(3u, encoders.size());
484 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700485 int width;
486 int height;
487 int simulcast_index;
488 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
489 EXPECT_EQ(1152, width);
490 EXPECT_EQ(704, height);
491 EXPECT_EQ(0, simulcast_index);
492
brandtr5e171752017-05-23 03:32:16 -0700493 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700494 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
495 EXPECT_EQ(300, width);
496 EXPECT_EQ(620, height);
497 EXPECT_EQ(1, simulcast_index);
498
brandtr5e171752017-05-23 03:32:16 -0700499 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700500 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
501 EXPECT_EQ(120, width);
502 EXPECT_EQ(240, height);
503 EXPECT_EQ(2, simulcast_index);
504}
505
brandtr5e171752017-05-23 03:32:16 -0700506// This test verifies that the underlying encoders are reused, when the adapter
507// is reinited with different number of simulcast streams. It further checks
508// that the allocated encoders are reused in the same order as before, starting
509// with the lowest stream.
510TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
511 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200512 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200513 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
514 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100515 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700516 adapter_->RegisterEncodeCompleteCallback(this);
517
518 // Input data.
519 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
520 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
521 std::vector<FrameType> frame_types;
522
523 // Encode with three streams.
524 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
525 VerifyCodecSettings();
526 std::vector<MockVideoEncoder*> original_encoders =
527 helper_->factory()->encoders();
528 ASSERT_EQ(3u, original_encoders.size());
529 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
530 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
531 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
532 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
533 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
534 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
535 frame_types.resize(3, kVideoFrameKey);
536 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
537 EXPECT_CALL(*original_encoders[0], Release())
538 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
539 EXPECT_CALL(*original_encoders[1], Release())
540 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
541 EXPECT_CALL(*original_encoders[2], Release())
542 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
543 EXPECT_EQ(0, adapter_->Release());
544
545 // Encode with two streams.
546 codec_.width /= 2;
547 codec_.height /= 2;
548 codec_.numberOfSimulcastStreams = 2;
549 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
550 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
551 ASSERT_EQ(2u, new_encoders.size());
552 ASSERT_EQ(original_encoders[0], new_encoders[0]);
553 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
554 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
555 ASSERT_EQ(original_encoders[1], new_encoders[1]);
556 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
557 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
558 frame_types.resize(2, kVideoFrameKey);
559 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
560 EXPECT_CALL(*original_encoders[0], Release())
561 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
562 EXPECT_CALL(*original_encoders[1], Release())
563 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
564 EXPECT_EQ(0, adapter_->Release());
565
566 // Encode with single stream.
567 codec_.width /= 2;
568 codec_.height /= 2;
569 codec_.numberOfSimulcastStreams = 1;
570 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
571 new_encoders = helper_->factory()->encoders();
572 ASSERT_EQ(1u, new_encoders.size());
573 ASSERT_EQ(original_encoders[0], new_encoders[0]);
574 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
575 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
576 frame_types.resize(1, kVideoFrameKey);
577 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
578 EXPECT_CALL(*original_encoders[0], Release())
579 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
580 EXPECT_EQ(0, adapter_->Release());
581
582 // Encode with three streams, again.
583 codec_.width *= 4;
584 codec_.height *= 4;
585 codec_.numberOfSimulcastStreams = 3;
586 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
587 new_encoders = helper_->factory()->encoders();
588 ASSERT_EQ(3u, new_encoders.size());
589 // The first encoder is reused.
590 ASSERT_EQ(original_encoders[0], new_encoders[0]);
591 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
592 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
593 // The second and third encoders are new.
594 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
595 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
596 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
597 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
598 frame_types.resize(3, kVideoFrameKey);
599 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
600 EXPECT_CALL(*original_encoders[0], Release())
601 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
602 EXPECT_CALL(*new_encoders[1], Release())
603 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
604 EXPECT_CALL(*new_encoders[2], Release())
605 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
606 EXPECT_EQ(0, adapter_->Release());
607}
608
609TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
610 SetupCodec();
611 VerifyCodecSettings();
612
613 EXPECT_EQ(3u, helper_->factory()->encoders().size());
614
615 // The adapter should destroy all encoders it has allocated. Since
616 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
617 // lsan to find leaks here.
618 EXPECT_EQ(0, adapter_->Release());
619 adapter_.reset();
620}
621
622// This test verifies that an adapter reinit with the same codec settings as
623// before does not change the underlying encoder codec settings.
624TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
625 SetupCodec();
626 VerifyCodecSettings();
627
628 // Capture current codec settings.
629 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
630 ASSERT_EQ(3u, encoders.size());
631 std::array<VideoCodec, 3> codecs_before;
632 for (int i = 0; i < 3; ++i) {
633 codecs_before[i] = encoders[i]->codec();
634 }
635
636 // Reinitialize and verify that the new codec settings are the same.
637 EXPECT_EQ(0, adapter_->Release());
638 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
639 for (int i = 0; i < 3; ++i) {
640 const VideoCodec& codec_before = codecs_before[i];
641 const VideoCodec& codec_after = encoders[i]->codec();
642
643 // webrtc::VideoCodec does not implement operator==.
644 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
645 EXPECT_EQ(codec_before.plType, codec_after.plType);
646 EXPECT_EQ(codec_before.width, codec_after.width);
647 EXPECT_EQ(codec_before.height, codec_after.height);
648 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
649 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
650 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
651 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
652 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
653 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
654 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
655 codec_after.numberOfSimulcastStreams);
656 EXPECT_EQ(codec_before.mode, codec_after.mode);
657 EXPECT_EQ(codec_before.expect_encode_from_texture,
658 codec_after.expect_encode_from_texture);
659 }
660}
661
662// This test is similar to the one above, except that it tests the simulcastIdx
663// from the CodecSpecificInfo that is connected to an encoded frame. The
664// PayloadRouter demuxes the incoming encoded frames on different RTP modules
665// using the simulcastIdx, so it's important that there is no corresponding
666// encoder reordering in between adapter reinits as this would lead to PictureID
667// discontinuities.
668TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
669 SetupCodec();
670 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
671 VerifyCodecSettings();
672
673 // Send frames on all streams.
674 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
675 ASSERT_EQ(3u, encoders.size());
676 encoders[0]->SendEncodedImage(1152, 704);
677 int width;
678 int height;
679 int simulcast_index;
680 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
681 EXPECT_EQ(0, simulcast_index);
682
683 encoders[1]->SendEncodedImage(300, 620);
684 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
685 EXPECT_EQ(1, simulcast_index);
686
687 encoders[2]->SendEncodedImage(120, 240);
688 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
689 EXPECT_EQ(2, simulcast_index);
690
691 // Reinitialize.
692 EXPECT_EQ(0, adapter_->Release());
693 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
694 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
695
696 // Verify that the same encoder sends out frames on the same simulcast index.
697 encoders[0]->SendEncodedImage(1152, 704);
698 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
699 EXPECT_EQ(0, simulcast_index);
700
701 encoders[1]->SendEncodedImage(300, 620);
702 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
703 EXPECT_EQ(1, simulcast_index);
704
705 encoders[2]->SendEncodedImage(120, 240);
706 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
707 EXPECT_EQ(2, simulcast_index);
708}
709
pbos65e15ba2015-10-15 10:52:15 -0700710TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200711 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200712 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
713 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700714 codec_.numberOfSimulcastStreams = 1;
715 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
716 adapter_->RegisterEncodeCompleteCallback(this);
717 ASSERT_EQ(1u, helper_->factory()->encoders().size());
718 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
719 EXPECT_TRUE(adapter_->SupportsNativeHandle());
720 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
721 EXPECT_FALSE(adapter_->SupportsNativeHandle());
722}
723
noahricfac0ff02016-09-09 10:27:15 -0700724TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200725 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200726 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
727 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700728 codec_.minBitrate = 50;
729 codec_.numberOfSimulcastStreams = 1;
730 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng82fad3d2018-03-21 09:57:23 +0100731 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700732
733 // Above min should be respected.
Erik Språng566124a2018-04-23 12:32:22 +0200734 VideoBitrateAllocation target_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100735 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
736 adapter_->SetRateAllocation(target_bitrate, 30);
737 EXPECT_EQ(target_bitrate,
738 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700739
740 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng566124a2018-04-23 12:32:22 +0200741 VideoBitrateAllocation too_low_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100742 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
743 adapter_->SetRateAllocation(too_low_bitrate, 30);
744 EXPECT_EQ(target_bitrate,
745 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700746
747 // Zero should be passed on as is, since it means "pause".
Erik Språng566124a2018-04-23 12:32:22 +0200748 adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
749 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng08127a92016-11-16 16:41:30 +0100750 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700751}
752
Peter Boströma5dec162016-01-20 15:53:55 +0100753TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
754 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200755 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200756 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
757 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100758 std::vector<const char*> encoder_names;
759 encoder_names.push_back("codec1");
760 encoder_names.push_back("codec2");
761 encoder_names.push_back("codec3");
762 helper_->factory()->SetEncoderNames(encoder_names);
763 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
764 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
765 adapter_->ImplementationName());
Peter Boströmd53c3892016-03-30 17:03:52 +0200766
767 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700768 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200769 codec_.numberOfSimulcastStreams = 1;
770 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
771 adapter_->RegisterEncodeCompleteCallback(this);
772 ASSERT_EQ(1u, helper_->factory()->encoders().size());
773 EXPECT_STREQ("codec1", adapter_->ImplementationName());
Peter Boströma5dec162016-01-20 15:53:55 +0100774}
775
pbos65e15ba2015-10-15 10:52:15 -0700776TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700777 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200778 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200779 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
780 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700781 codec_.numberOfSimulcastStreams = 3;
782 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
783 adapter_->RegisterEncodeCompleteCallback(this);
784 ASSERT_EQ(3u, helper_->factory()->encoders().size());
785 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
786 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700787 // If one encoder doesn't support it, then overall support is disabled.
788 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
pbos65e15ba2015-10-15 10:52:15 -0700789 EXPECT_FALSE(adapter_->SupportsNativeHandle());
noahricfe3654d2016-07-01 09:05:54 -0700790 // Once all do, then the adapter claims support.
791 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
792 EXPECT_TRUE(adapter_->SupportsNativeHandle());
793}
794
nisseaf916892017-01-10 07:44:26 -0800795// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000796class FakeNativeBuffer : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700797 public:
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000798 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
799
800 Type type() const override { return Type::kNative; }
801 int width() const override { return width_; }
802 int height() const override { return height_; }
803
804 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700805 RTC_NOTREACHED();
806 return nullptr;
807 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000808
809 private:
810 const int width_;
811 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700812};
813
814TEST_F(TestSimulcastEncoderAdapterFake,
815 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200816 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200817 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
818 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700819 codec_.numberOfSimulcastStreams = 3;
820 // High start bitrate, so all streams are enabled.
821 codec_.startBitrate = 3000;
822 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
823 adapter_->RegisterEncodeCompleteCallback(this);
824 ASSERT_EQ(3u, helper_->factory()->encoders().size());
825 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
826 encoder->set_supports_native_handle(true);
827 EXPECT_TRUE(adapter_->SupportsNativeHandle());
828
829 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000830 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
noahricfe3654d2016-07-01 09:05:54 -0700831 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
832 // Expect calls with the given video frame verbatim, since it's a texture
833 // frame and can't otherwise be modified/resized.
834 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
835 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
836 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700837 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700838}
839
noahric57779102016-05-25 06:48:46 -0700840TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200841 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200842 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
843 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700844 codec_.numberOfSimulcastStreams = 3;
845 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
846 adapter_->RegisterEncodeCompleteCallback(this);
847 ASSERT_EQ(3u, helper_->factory()->encoders().size());
848 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700849 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
850 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700851
852 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000853 rtc::scoped_refptr<I420Buffer> input_buffer =
854 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700855 input_buffer->InitializeData();
856 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
noahric57779102016-05-25 06:48:46 -0700857 std::vector<FrameType> frame_types(3, kVideoFrameKey);
858 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
859 adapter_->Encode(input_frame, nullptr, &frame_types));
860}
861
noahrice5ba75a2016-12-12 13:08:27 -0800862TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200863 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200864 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
865 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800866 codec_.numberOfSimulcastStreams = 3;
867 helper_->factory()->set_init_encode_return_value(
868 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
869 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
870 adapter_->InitEncode(&codec_, 1, 1200));
871 EXPECT_TRUE(helper_->factory()->encoders().empty());
872}
873
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200874} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000875} // namespace webrtc