blob: 741e3fced0db818231afe643c4f16fbce974454f [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
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#include "absl/memory/memory.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020016#include "api/test/create_simulcast_test_fixture.h"
17#include "api/test/simulcast_test_fixture.h"
Danil Chapovalov99b71df2018-10-26 15:57:48 +020018#include "api/test/video/function_video_decoder_factory.h"
19#include "api/test/video/function_video_encoder_factory.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010020#include "api/video_codecs/sdp_video_format.h"
21#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "common_video/include/video_frame_buffer.h"
Jonathan Yu9a5da492018-10-19 00:51:18 -070023#include "media/base/mediaconstants.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010024#include "media/engine/internalencoderfactory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "media/engine/simulcast_encoder_adapter.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020026#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/video_coding/include/video_codec_interface.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020028#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020030#include "test/gtest.h"
31
32using ::testing::_;
33using ::testing::Return;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000034
35namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020036namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000037
Rasmus Brandt0cedc052018-05-31 12:53:00 +020038namespace {
philipelcce46fc2015-12-21 03:04:49 -080039
Rasmus Brandt0cedc052018-05-31 12:53:00 +020040constexpr int kDefaultWidth = 1280;
41constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070042
Rasmus Brandt0cedc052018-05-31 12:53:00 +020043std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
44 VideoEncoderFactory* internal_encoder_factory) {
45 std::unique_ptr<VideoEncoderFactory> encoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020046 absl::make_unique<FunctionVideoEncoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020047 [internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +020048 return absl::make_unique<SimulcastEncoderAdapter>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020049 internal_encoder_factory,
50 SdpVideoFormat(cricket::kVp8CodecName));
51 });
52 std::unique_ptr<VideoDecoderFactory> decoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020053 absl::make_unique<FunctionVideoDecoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020054 []() { return VP8Decoder::Create(); });
55 return CreateSimulcastTestFixture(std::move(encoder_factory),
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020056 std::move(decoder_factory),
57 SdpVideoFormat(cricket::kVp8CodecName));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000058}
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
Per Kjellander841c9122018-10-04 18:40:28 +0200147TEST(SimulcastEncoderAdapterSimulcastTest, TestDecodeWidthHeightSet) {
148 InternalEncoderFactory internal_encoder_factory;
149 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
150 fixture->TestDecodeWidthHeightSet();
151}
152
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100153class MockVideoEncoder;
154
155class MockVideoEncoderFactory : public VideoEncoderFactory {
156 public:
157 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
158
159 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
160 const SdpVideoFormat& format) override;
161
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000162 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
163
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100164 const std::vector<MockVideoEncoder*>& encoders() const;
165 void SetEncoderNames(const std::vector<const char*>& encoder_names);
166 void set_init_encode_return_value(int32_t value);
167
168 void DestroyVideoEncoder(VideoEncoder* encoder);
169
170 private:
171 int32_t init_encode_return_value_ = 0;
172 std::vector<MockVideoEncoder*> encoders_;
173 std::vector<const char*> encoder_names_;
174};
175
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000176class MockVideoEncoder : public VideoEncoder {
177 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100178 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng75de46a2018-11-07 14:53:32 +0100179 : factory_(factory),
180 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
181 callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100182
nisseef8b61e2016-04-29 06:09:15 -0700183 // TODO(nisse): Valid overrides commented out, because the gmock
184 // methods don't use any override declarations, and we want to avoid
185 // warnings from -Winconsistent-missing-override. See
186 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000187 int32_t InitEncode(const VideoCodec* codecSettings,
188 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700189 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000190 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800191 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000192 }
193
noahricfe3654d2016-07-01 09:05:54 -0700194 MOCK_METHOD3(
195 Encode,
196 int32_t(const VideoFrame& inputImage,
197 const CodecSpecificInfo* codecSpecificInfo,
198 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000199
pbos65e15ba2015-10-15 10:52:15 -0700200 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700201 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700202 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000203 return 0;
204 }
205
brandtr5e171752017-05-23 03:32:16 -0700206 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000207
Erik Språng566124a2018-04-23 12:32:22 +0200208 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
Erik Språng08127a92016-11-16 16:41:30 +0100209 uint32_t framerate) {
210 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000211 return 0;
212 }
213
Erik Språng9b5b0702018-11-01 14:52:30 +0100214 EncoderInfo GetEncoderInfo() const override {
215 EncoderInfo info;
216 info.supports_native_handle = supports_native_handle_;
217 info.implementation_name = implementation_name_;
Erik Språng75de46a2018-11-07 14:53:32 +0100218 info.scaling_settings = scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100219 info.has_trusted_rate_controller = has_trusted_rate_controller_;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100220 info.is_hardware_accelerated = is_hardware_accelerated_;
221 info.has_internal_source = has_internal_source_;
Erik Språng9b5b0702018-11-01 14:52:30 +0100222 return info;
nisseef8b61e2016-04-29 06:09:15 -0700223 }
pbos65e15ba2015-10-15 10:52:15 -0700224
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100225 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000226
227 const VideoCodec& codec() const { return codec_; }
228
Noah Richards41ee1ea2015-04-15 09:24:26 -0700229 void SendEncodedImage(int width, int height) {
230 // Sends a fake image of the given width/height.
231 EncodedImage image;
232 image._encodedWidth = width;
233 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700234 CodecSpecificInfo codec_specific_info;
235 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200236 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700237 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700238 }
239
pbos65e15ba2015-10-15 10:52:15 -0700240 void set_supports_native_handle(bool enabled) {
241 supports_native_handle_ = enabled;
242 }
noahrice5ba75a2016-12-12 13:08:27 -0800243
Erik Språng9b5b0702018-11-01 14:52:30 +0100244 void set_implementation_name(const std::string& name) {
245 implementation_name_ = name;
246 }
247
noahrice5ba75a2016-12-12 13:08:27 -0800248 void set_init_encode_return_value(int32_t value) {
249 init_encode_return_value_ = value;
250 }
251
Erik Språng75de46a2018-11-07 14:53:32 +0100252 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
253 scaling_settings_ = settings;
254 }
255
Erik Språngd3438aa2018-11-08 16:56:43 +0100256 void set_has_trusted_rate_controller(bool trusted) {
257 has_trusted_rate_controller_ = trusted;
258 }
259
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100260 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
261 is_hardware_accelerated_ = is_hardware_accelerated;
262 }
263
264 void set_has_internal_source(bool has_internal_source) {
265 has_internal_source_ = has_internal_source;
266 }
267
Erik Språng566124a2018-04-23 12:32:22 +0200268 VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700269
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000270 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100271 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700272 bool supports_native_handle_ = false;
Erik Språng9b5b0702018-11-01 14:52:30 +0100273 std::string implementation_name_ = "unknown";
Erik Språng75de46a2018-11-07 14:53:32 +0100274 VideoEncoder::ScalingSettings scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100275 bool has_trusted_rate_controller_ = false;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100276 bool is_hardware_accelerated_ = false;
277 bool has_internal_source_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800278 int32_t init_encode_return_value_ = 0;
Erik Språng566124a2018-04-23 12:32:22 +0200279 VideoBitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700280
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000281 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700282 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000283};
284
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100285std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
286 const {
287 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
288 return formats;
289}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000290
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100291std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
292 const SdpVideoFormat& format) {
293 std::unique_ptr<MockVideoEncoder> encoder(
294 new ::testing::NiceMock<MockVideoEncoder>(this));
295 encoder->set_init_encode_return_value(init_encode_return_value_);
296 const char* encoder_name = encoder_names_.empty()
297 ? "codec_implementation_name"
298 : encoder_names_[encoders_.size()];
Erik Språng9b5b0702018-11-01 14:52:30 +0100299 encoder->set_implementation_name(encoder_name);
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100300 encoders_.push_back(encoder.get());
301 return encoder;
302}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000303
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100304void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
305 for (size_t i = 0; i < encoders_.size(); ++i) {
306 if (encoders_[i] == encoder) {
307 encoders_.erase(encoders_.begin() + i);
308 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000309 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000310 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100311}
Zhi Huangaea84f52017-11-16 18:46:27 +0000312
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000313VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
314 const SdpVideoFormat& format) const {
315 return CodecInfo();
316}
317
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100318const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
319 const {
320 return encoders_;
321}
322void MockVideoEncoderFactory::SetEncoderNames(
323 const std::vector<const char*>& encoder_names) {
324 encoder_names_ = encoder_names;
325}
326void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
327 init_encode_return_value_ = value;
328}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000329
330class TestSimulcastEncoderAdapterFakeHelper {
331 public:
332 TestSimulcastEncoderAdapterFakeHelper()
333 : factory_(new MockVideoEncoderFactory()) {}
334
335 // Can only be called once as the SimulcastEncoderAdapter will take the
336 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200337 VideoEncoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200338 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000339 }
340
magjed6cc25612017-07-10 03:26:36 -0700341 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000342
343 private:
magjed6cc25612017-07-10 03:26:36 -0700344 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000345};
346
347static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
348
Noah Richards41ee1ea2015-04-15 09:24:26 -0700349class TestSimulcastEncoderAdapterFake : public ::testing::Test,
350 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000351 public:
352 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700353 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
354 adapter_(helper_->CreateMockEncoderAdapter()),
355 last_encoded_image_width_(-1),
356 last_encoded_image_height_(-1),
357 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700358 virtual ~TestSimulcastEncoderAdapterFake() {
359 if (adapter_) {
360 adapter_->Release();
361 }
362 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000363
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700364 Result OnEncodedImage(const EncodedImage& encoded_image,
365 const CodecSpecificInfo* codec_specific_info,
366 const RTPFragmentationHeader* fragmentation) override {
367 last_encoded_image_width_ = encoded_image._encodedWidth;
368 last_encoded_image_height_ = encoded_image._encodedHeight;
Niels Möllerd3b8c632018-08-27 15:33:42 +0200369 last_encoded_image_simulcast_index_ =
370 encoded_image.SpatialIndex().value_or(-1);
371
Niels Möller72bc8d62018-09-12 10:03:51 +0200372 return Result(Result::OK, encoded_image.Timestamp());
Noah Richards41ee1ea2015-04-15 09:24:26 -0700373 }
374
375 bool GetLastEncodedImageInfo(int* out_width,
376 int* out_height,
377 int* out_simulcast_index) {
378 if (last_encoded_image_width_ == -1) {
379 return false;
380 }
381 *out_width = last_encoded_image_width_;
382 *out_height = last_encoded_image_height_;
383 *out_simulcast_index = last_encoded_image_simulcast_index_;
384 return true;
385 }
386
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000387 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200388 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200389 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
390 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100391 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000392 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700393 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000394 }
395
396 void VerifyCodec(const VideoCodec& ref, int stream_index) {
397 const VideoCodec& target =
398 helper_->factory()->encoders()[stream_index]->codec();
399 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000400 EXPECT_EQ(ref.plType, target.plType);
401 EXPECT_EQ(ref.width, target.width);
402 EXPECT_EQ(ref.height, target.height);
403 EXPECT_EQ(ref.startBitrate, target.startBitrate);
404 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
405 EXPECT_EQ(ref.minBitrate, target.minBitrate);
406 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700407 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700408 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
409 target.VP8().numberOfTemporalLayers);
410 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700411 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
412 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
413 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000414 EXPECT_EQ(ref.qpMax, target.qpMax);
415 EXPECT_EQ(0, target.numberOfSimulcastStreams);
416 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000417
418 // No need to compare simulcastStream as numberOfSimulcastStreams should
419 // always be 0.
420 }
421
422 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
423 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700424 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000425 kTestTemporalLayerProfile[stream_index];
426 ref_codec->width = codec_.simulcastStream[stream_index].width;
427 ref_codec->height = codec_.simulcastStream[stream_index].height;
428 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
429 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
430 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
431 }
432
433 void VerifyCodecSettings() {
434 EXPECT_EQ(3u, helper_->factory()->encoders().size());
435 VideoCodec ref_codec;
436
437 // stream 0, the lowest resolution stream.
438 InitRefCodec(0, &ref_codec);
439 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200440 ref_codec.VP8()->complexity =
441 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700442 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000443 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
444 VerifyCodec(ref_codec, 0);
445
446 // stream 1
447 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700448 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700449 // The start bitrate (300kbit) minus what we have for the lower layers
450 // (100kbit).
451 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000452 VerifyCodec(ref_codec, 1);
453
454 // stream 2, the biggest resolution stream.
455 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700456 // We don't have enough bits to send this, so the adapter should have
457 // configured it to use the min bitrate for this layer (600kbit) but turn
458 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000459 ref_codec.startBitrate = 600;
460 VerifyCodec(ref_codec, 2);
461 }
462
463 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800464 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200465 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000466 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700467 int last_encoded_image_width_;
468 int last_encoded_image_height_;
469 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100470 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000471};
472
473TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
474 SetupCodec();
475 VerifyCodecSettings();
476}
477
brandtr5e171752017-05-23 03:32:16 -0700478TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
479 EXPECT_EQ(0, adapter_->Release());
480}
481
482TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
483 SetupCodec();
484 EXPECT_EQ(0, adapter_->Release());
485
486 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
487}
488
Noah Richards41ee1ea2015-04-15 09:24:26 -0700489TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
490 SetupCodec();
491
Peter Boström5d0379d2015-10-06 14:04:51 +0200492 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100493 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200494
Noah Richards41ee1ea2015-04-15 09:24:26 -0700495 // At this point, the simulcast encoder adapter should have 3 streams: HD,
496 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
497 // resolutions, to test that the adapter forwards on the correct resolution
498 // and simulcast index values, going only off the encoder that generates the
499 // image.
brandtr5e171752017-05-23 03:32:16 -0700500 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
501 ASSERT_EQ(3u, encoders.size());
502 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700503 int width;
504 int height;
505 int simulcast_index;
506 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
507 EXPECT_EQ(1152, width);
508 EXPECT_EQ(704, height);
509 EXPECT_EQ(0, simulcast_index);
510
brandtr5e171752017-05-23 03:32:16 -0700511 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700512 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
513 EXPECT_EQ(300, width);
514 EXPECT_EQ(620, height);
515 EXPECT_EQ(1, simulcast_index);
516
brandtr5e171752017-05-23 03:32:16 -0700517 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700518 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
519 EXPECT_EQ(120, width);
520 EXPECT_EQ(240, height);
521 EXPECT_EQ(2, simulcast_index);
522}
523
brandtr5e171752017-05-23 03:32:16 -0700524// This test verifies that the underlying encoders are reused, when the adapter
525// is reinited with different number of simulcast streams. It further checks
526// that the allocated encoders are reused in the same order as before, starting
527// with the lowest stream.
528TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
529 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200530 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200531 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
532 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100533 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700534 adapter_->RegisterEncodeCompleteCallback(this);
Erik Språng7d687b12018-09-12 17:04:10 +0200535 const uint32_t target_bitrate =
536 1000 * (codec_.simulcastStream[0].targetBitrate +
537 codec_.simulcastStream[1].targetBitrate +
538 codec_.simulcastStream[2].minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700539
540 // Input data.
541 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100542 VideoFrame input_frame = VideoFrame::Builder()
543 .set_video_frame_buffer(buffer)
544 .set_timestamp_rtp(100)
545 .set_timestamp_ms(1000)
546 .set_rotation(kVideoRotation_180)
547 .build();
brandtr5e171752017-05-23 03:32:16 -0700548 std::vector<FrameType> frame_types;
549
550 // Encode with three streams.
551 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
552 VerifyCodecSettings();
Erik Språng7d687b12018-09-12 17:04:10 +0200553 adapter_->SetRateAllocation(
554 rate_allocator_->GetAllocation(target_bitrate, 30), 30);
555
brandtr5e171752017-05-23 03:32:16 -0700556 std::vector<MockVideoEncoder*> original_encoders =
557 helper_->factory()->encoders();
558 ASSERT_EQ(3u, original_encoders.size());
559 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
560 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
561 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
562 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
563 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
564 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
565 frame_types.resize(3, kVideoFrameKey);
566 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
567 EXPECT_CALL(*original_encoders[0], Release())
568 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
569 EXPECT_CALL(*original_encoders[1], Release())
570 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
571 EXPECT_CALL(*original_encoders[2], Release())
572 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
573 EXPECT_EQ(0, adapter_->Release());
574
575 // Encode with two streams.
576 codec_.width /= 2;
577 codec_.height /= 2;
578 codec_.numberOfSimulcastStreams = 2;
579 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng7d687b12018-09-12 17:04:10 +0200580 adapter_->SetRateAllocation(
581 rate_allocator_->GetAllocation(target_bitrate, 30), 30);
brandtr5e171752017-05-23 03:32:16 -0700582 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
583 ASSERT_EQ(2u, new_encoders.size());
584 ASSERT_EQ(original_encoders[0], new_encoders[0]);
585 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
586 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
587 ASSERT_EQ(original_encoders[1], new_encoders[1]);
588 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
589 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
590 frame_types.resize(2, kVideoFrameKey);
591 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
592 EXPECT_CALL(*original_encoders[0], Release())
593 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
594 EXPECT_CALL(*original_encoders[1], Release())
595 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
596 EXPECT_EQ(0, adapter_->Release());
597
598 // Encode with single stream.
599 codec_.width /= 2;
600 codec_.height /= 2;
601 codec_.numberOfSimulcastStreams = 1;
602 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng7d687b12018-09-12 17:04:10 +0200603 adapter_->SetRateAllocation(
604 rate_allocator_->GetAllocation(target_bitrate, 30), 30);
brandtr5e171752017-05-23 03:32:16 -0700605 new_encoders = helper_->factory()->encoders();
606 ASSERT_EQ(1u, new_encoders.size());
607 ASSERT_EQ(original_encoders[0], new_encoders[0]);
608 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
609 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
610 frame_types.resize(1, kVideoFrameKey);
611 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
612 EXPECT_CALL(*original_encoders[0], Release())
613 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
614 EXPECT_EQ(0, adapter_->Release());
615
616 // Encode with three streams, again.
617 codec_.width *= 4;
618 codec_.height *= 4;
619 codec_.numberOfSimulcastStreams = 3;
620 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng7d687b12018-09-12 17:04:10 +0200621 adapter_->SetRateAllocation(
622 rate_allocator_->GetAllocation(target_bitrate, 30), 30);
brandtr5e171752017-05-23 03:32:16 -0700623 new_encoders = helper_->factory()->encoders();
624 ASSERT_EQ(3u, new_encoders.size());
625 // The first encoder is reused.
626 ASSERT_EQ(original_encoders[0], new_encoders[0]);
627 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
628 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
629 // The second and third encoders are new.
630 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
631 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
632 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
633 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
634 frame_types.resize(3, kVideoFrameKey);
635 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
636 EXPECT_CALL(*original_encoders[0], Release())
637 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
638 EXPECT_CALL(*new_encoders[1], Release())
639 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
640 EXPECT_CALL(*new_encoders[2], Release())
641 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
642 EXPECT_EQ(0, adapter_->Release());
643}
644
645TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
646 SetupCodec();
647 VerifyCodecSettings();
648
649 EXPECT_EQ(3u, helper_->factory()->encoders().size());
650
651 // The adapter should destroy all encoders it has allocated. Since
652 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
653 // lsan to find leaks here.
654 EXPECT_EQ(0, adapter_->Release());
655 adapter_.reset();
656}
657
658// This test verifies that an adapter reinit with the same codec settings as
659// before does not change the underlying encoder codec settings.
660TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
661 SetupCodec();
662 VerifyCodecSettings();
663
664 // Capture current codec settings.
665 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
666 ASSERT_EQ(3u, encoders.size());
667 std::array<VideoCodec, 3> codecs_before;
668 for (int i = 0; i < 3; ++i) {
669 codecs_before[i] = encoders[i]->codec();
670 }
671
672 // Reinitialize and verify that the new codec settings are the same.
673 EXPECT_EQ(0, adapter_->Release());
674 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
675 for (int i = 0; i < 3; ++i) {
676 const VideoCodec& codec_before = codecs_before[i];
677 const VideoCodec& codec_after = encoders[i]->codec();
678
679 // webrtc::VideoCodec does not implement operator==.
680 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
681 EXPECT_EQ(codec_before.plType, codec_after.plType);
682 EXPECT_EQ(codec_before.width, codec_after.width);
683 EXPECT_EQ(codec_before.height, codec_after.height);
684 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
685 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
686 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700687 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
688 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
689 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
690 codec_after.numberOfSimulcastStreams);
691 EXPECT_EQ(codec_before.mode, codec_after.mode);
692 EXPECT_EQ(codec_before.expect_encode_from_texture,
693 codec_after.expect_encode_from_texture);
694 }
695}
696
697// This test is similar to the one above, except that it tests the simulcastIdx
698// from the CodecSpecificInfo that is connected to an encoded frame. The
699// PayloadRouter demuxes the incoming encoded frames on different RTP modules
700// using the simulcastIdx, so it's important that there is no corresponding
701// encoder reordering in between adapter reinits as this would lead to PictureID
702// discontinuities.
703TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
704 SetupCodec();
705 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
706 VerifyCodecSettings();
707
708 // Send frames on all streams.
709 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
710 ASSERT_EQ(3u, encoders.size());
711 encoders[0]->SendEncodedImage(1152, 704);
712 int width;
713 int height;
714 int simulcast_index;
715 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
716 EXPECT_EQ(0, simulcast_index);
717
718 encoders[1]->SendEncodedImage(300, 620);
719 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
720 EXPECT_EQ(1, simulcast_index);
721
722 encoders[2]->SendEncodedImage(120, 240);
723 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
724 EXPECT_EQ(2, simulcast_index);
725
726 // Reinitialize.
727 EXPECT_EQ(0, adapter_->Release());
728 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
729 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
730
731 // Verify that the same encoder sends out frames on the same simulcast index.
732 encoders[0]->SendEncodedImage(1152, 704);
733 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
734 EXPECT_EQ(0, simulcast_index);
735
736 encoders[1]->SendEncodedImage(300, 620);
737 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
738 EXPECT_EQ(1, simulcast_index);
739
740 encoders[2]->SendEncodedImage(120, 240);
741 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
742 EXPECT_EQ(2, simulcast_index);
743}
744
pbos65e15ba2015-10-15 10:52:15 -0700745TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200746 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200747 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
748 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700749 codec_.numberOfSimulcastStreams = 1;
750 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
751 adapter_->RegisterEncodeCompleteCallback(this);
752 ASSERT_EQ(1u, helper_->factory()->encoders().size());
753 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Erik Språng75de46a2018-11-07 14:53:32 +0100754 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200755 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700756 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språng75de46a2018-11-07 14:53:32 +0100757 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200758 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700759}
760
noahricfac0ff02016-09-09 10:27:15 -0700761TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200762 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200763 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
764 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700765 codec_.minBitrate = 50;
766 codec_.numberOfSimulcastStreams = 1;
767 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng82fad3d2018-03-21 09:57:23 +0100768 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700769
770 // Above min should be respected.
Erik Språng566124a2018-04-23 12:32:22 +0200771 VideoBitrateAllocation target_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100772 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
773 adapter_->SetRateAllocation(target_bitrate, 30);
774 EXPECT_EQ(target_bitrate,
775 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700776
777 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng566124a2018-04-23 12:32:22 +0200778 VideoBitrateAllocation too_low_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100779 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
780 adapter_->SetRateAllocation(too_low_bitrate, 30);
781 EXPECT_EQ(target_bitrate,
782 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700783
784 // Zero should be passed on as is, since it means "pause".
Erik Språng566124a2018-04-23 12:32:22 +0200785 adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
786 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng08127a92016-11-16 16:41:30 +0100787 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700788}
789
Peter Boströma5dec162016-01-20 15:53:55 +0100790TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
Erik Språnge2fd86a2018-10-24 11:32:39 +0200791 EXPECT_EQ("SimulcastEncoderAdapter",
792 adapter_->GetEncoderInfo().implementation_name);
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200793 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200794 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
795 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100796 std::vector<const char*> encoder_names;
797 encoder_names.push_back("codec1");
798 encoder_names.push_back("codec2");
799 encoder_names.push_back("codec3");
800 helper_->factory()->SetEncoderNames(encoder_names);
801 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200802 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
803 adapter_->GetEncoderInfo().implementation_name);
Peter Boströmd53c3892016-03-30 17:03:52 +0200804
805 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700806 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200807 codec_.numberOfSimulcastStreams = 1;
808 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
809 adapter_->RegisterEncodeCompleteCallback(this);
810 ASSERT_EQ(1u, helper_->factory()->encoders().size());
Erik Språnge2fd86a2018-10-24 11:32:39 +0200811 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
Peter Boströma5dec162016-01-20 15:53:55 +0100812}
813
pbos65e15ba2015-10-15 10:52:15 -0700814TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700815 SupportsNativeHandleForMultipleStreams) {
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);
pbos65e15ba2015-10-15 10:52:15 -0700819 codec_.numberOfSimulcastStreams = 3;
820 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
821 adapter_->RegisterEncodeCompleteCallback(this);
822 ASSERT_EQ(3u, helper_->factory()->encoders().size());
823 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
824 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700825 // If one encoder doesn't support it, then overall support is disabled.
826 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språnge2fd86a2018-10-24 11:32:39 +0200827 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700828 // Once all do, then the adapter claims support.
829 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Erik Språng75de46a2018-11-07 14:53:32 +0100830 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200831 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700832}
833
nisseaf916892017-01-10 07:44:26 -0800834// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200835class FakeNativeBufferNoI420 : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700836 public:
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200837 FakeNativeBufferNoI420(int width, int height)
838 : width_(width), height_(height) {}
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000839
840 Type type() const override { return Type::kNative; }
841 int width() const override { return width_; }
842 int height() const override { return height_; }
843
844 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700845 RTC_NOTREACHED();
846 return nullptr;
847 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000848
849 private:
850 const int width_;
851 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700852};
853
854TEST_F(TestSimulcastEncoderAdapterFake,
855 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200856 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200857 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
858 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700859 codec_.numberOfSimulcastStreams = 3;
860 // High start bitrate, so all streams are enabled.
861 codec_.startBitrate = 3000;
862 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
863 adapter_->RegisterEncodeCompleteCallback(this);
864 ASSERT_EQ(3u, helper_->factory()->encoders().size());
865 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
866 encoder->set_supports_native_handle(true);
Erik Språng75de46a2018-11-07 14:53:32 +0100867 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200868 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700869
870 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200871 new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100872 VideoFrame input_frame = VideoFrame::Builder()
873 .set_video_frame_buffer(buffer)
874 .set_timestamp_rtp(100)
875 .set_timestamp_ms(1000)
876 .set_rotation(kVideoRotation_180)
877 .build();
noahricfe3654d2016-07-01 09:05:54 -0700878 // Expect calls with the given video frame verbatim, since it's a texture
879 // frame and can't otherwise be modified/resized.
880 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
881 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
882 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700883 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700884}
885
noahric57779102016-05-25 06:48:46 -0700886TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200887 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200888 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
889 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700890 codec_.numberOfSimulcastStreams = 3;
891 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
892 adapter_->RegisterEncodeCompleteCallback(this);
893 ASSERT_EQ(3u, helper_->factory()->encoders().size());
894 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700895 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
896 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700897
898 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000899 rtc::scoped_refptr<I420Buffer> input_buffer =
900 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700901 input_buffer->InitializeData();
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100902 VideoFrame input_frame = VideoFrame::Builder()
903 .set_video_frame_buffer(input_buffer)
904 .set_timestamp_rtp(0)
905 .set_timestamp_us(0)
906 .set_rotation(kVideoRotation_0)
907 .build();
noahric57779102016-05-25 06:48:46 -0700908 std::vector<FrameType> frame_types(3, kVideoFrameKey);
909 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
910 adapter_->Encode(input_frame, nullptr, &frame_types));
911}
912
noahrice5ba75a2016-12-12 13:08:27 -0800913TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200914 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200915 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
916 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800917 codec_.numberOfSimulcastStreams = 3;
918 helper_->factory()->set_init_encode_return_value(
919 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
920 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
921 adapter_->InitEncode(&codec_, 1, 1200));
922 EXPECT_TRUE(helper_->factory()->encoders().empty());
923}
924
Erik Språng8d2995b2018-08-09 11:18:17 +0200925TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
926 const int kHighMaxQp = 56;
927 const int kLowMaxQp = 46;
928
929 SimulcastTestFixtureImpl::DefaultSettings(
930 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
931 kVideoCodecVP8);
932 codec_.numberOfSimulcastStreams = 3;
933 codec_.simulcastStream[0].qpMax = kHighMaxQp;
934 codec_.mode = VideoCodecMode::kScreensharing;
935
936 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
937 EXPECT_EQ(3u, helper_->factory()->encoders().size());
938
939 // Just check the lowest stream, which is the one that where the adapter
940 // might alter the max qp setting.
941 VideoCodec ref_codec;
942 InitRefCodec(0, &ref_codec);
943 ref_codec.qpMax = kHighMaxQp;
944 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
945 ref_codec.VP8()->denoisingOn = false;
946 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
947 VerifyCodec(ref_codec, 0);
948
949 // Change the max qp and try again.
950 codec_.simulcastStream[0].qpMax = kLowMaxQp;
951 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
952 EXPECT_EQ(3u, helper_->factory()->encoders().size());
953 ref_codec.qpMax = kLowMaxQp;
954 VerifyCodec(ref_codec, 0);
955}
Erik Språng7d687b12018-09-12 17:04:10 +0200956
957TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
958 // Set up common settings for three streams.
959 SimulcastTestFixtureImpl::DefaultSettings(
960 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
961 kVideoCodecVP8);
962 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
963 adapter_->RegisterEncodeCompleteCallback(this);
964
965 // Only enough start bitrate for the lowest stream.
966 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
967 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
968 codec_.simulcastStream[1].minBitrate - 1;
969
970 // Input data.
971 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100972 VideoFrame input_frame = VideoFrame::Builder()
973 .set_video_frame_buffer(buffer)
974 .set_timestamp_rtp(100)
975 .set_timestamp_ms(1000)
976 .set_rotation(kVideoRotation_180)
977 .build();
Erik Språng7d687b12018-09-12 17:04:10 +0200978
979 // Encode with three streams.
980 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
981 std::vector<MockVideoEncoder*> original_encoders =
982 helper_->factory()->encoders();
983 ASSERT_EQ(3u, original_encoders.size());
984 // Only first encoder will be active and called.
985 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
986 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
987 EXPECT_CALL(*original_encoders[1], Encode(_, _, _)).Times(0);
988 EXPECT_CALL(*original_encoders[2], Encode(_, _, _)).Times(0);
989
990 std::vector<FrameType> frame_types;
991 frame_types.resize(3, kVideoFrameKey);
992 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
993}
Erik Språngd3438aa2018-11-08 16:56:43 +0100994
995TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
996 // Set up common settings for three streams.
997 SimulcastTestFixtureImpl::DefaultSettings(
998 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
999 kVideoCodecVP8);
1000 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1001 adapter_->RegisterEncodeCompleteCallback(this);
1002
1003 // Only enough start bitrate for the lowest stream.
1004 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1005 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1006 codec_.simulcastStream[1].minBitrate - 1;
1007
1008 // Input data.
1009 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001010 VideoFrame input_frame = VideoFrame::Builder()
1011 .set_video_frame_buffer(buffer)
1012 .set_timestamp_rtp(100)
1013 .set_timestamp_ms(1000)
1014 .set_rotation(kVideoRotation_180)
1015 .build();
Erik Språngd3438aa2018-11-08 16:56:43 +01001016
1017 // No encoder trusted, so simulcast adapter should not be either.
1018 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1019 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1020
1021 // Encode with three streams.
1022 std::vector<MockVideoEncoder*> original_encoders =
1023 helper_->factory()->encoders();
1024
1025 // All encoders are trusted, so simulcast adapter should be too.
1026 original_encoders[0]->set_has_trusted_rate_controller(true);
1027 original_encoders[1]->set_has_trusted_rate_controller(true);
1028 original_encoders[2]->set_has_trusted_rate_controller(true);
1029 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1030 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1031
1032 // One encoder not trusted, so simulcast adapter should not be either.
1033 original_encoders[2]->set_has_trusted_rate_controller(false);
1034 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1035 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1036
1037 // No encoder trusted, so simulcast adapter should not be either.
1038 original_encoders[0]->set_has_trusted_rate_controller(false);
1039 original_encoders[1]->set_has_trusted_rate_controller(false);
1040 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1041 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1042}
1043
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001044TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1045 SimulcastTestFixtureImpl::DefaultSettings(
1046 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1047 kVideoCodecVP8);
1048 codec_.numberOfSimulcastStreams = 3;
1049 adapter_->RegisterEncodeCompleteCallback(this);
1050 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1051 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1052
1053 // None of the encoders uses HW support, so simulcast adapter reports false.
1054 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1055 encoder->set_is_hardware_accelerated(false);
1056 }
1057 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1058 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1059
1060 // One encoder uses HW support, so simulcast adapter reports true.
1061 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
1062 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1063 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1064}
1065
1066TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1067 SimulcastTestFixtureImpl::DefaultSettings(
1068 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1069 kVideoCodecVP8);
1070 codec_.numberOfSimulcastStreams = 3;
1071 adapter_->RegisterEncodeCompleteCallback(this);
1072 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1073 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1074
1075 // All encoders have internal source, simulcast adapter reports true.
1076 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1077 encoder->set_has_internal_source(true);
1078 }
1079 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1080 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1081
1082 // One encoder does not have internal source, simulcast adapter reports false.
1083 helper_->factory()->encoders()[2]->set_has_internal_source(false);
1084 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
1085 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1086}
1087
Rasmus Brandt0cedc052018-05-31 12:53:00 +02001088} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001089} // namespace webrtc