blob: 8397365557a8c8819e15547d3bae81c6e58f6286 [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"
Elad Alon11dfff02019-06-10 19:10:29 +020021#include "api/video_codecs/video_encoder.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010022#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "common_video/include/video_frame_buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "media/base/media_constants.h"
25#include "media/engine/internal_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "media/engine/simulcast_encoder_adapter.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020027#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/video_coding/include/video_codec_interface.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020029#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020031#include "test/gtest.h"
32
33using ::testing::_;
34using ::testing::Return;
Erik Språngdbdd8392019-01-17 15:27:50 +010035using EncoderInfo = webrtc::VideoEncoder::EncoderInfo;
36using FramerateFractions =
37 absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000038
39namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020040namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000041
Rasmus Brandt0cedc052018-05-31 12:53:00 +020042namespace {
philipelcce46fc2015-12-21 03:04:49 -080043
Rasmus Brandt0cedc052018-05-31 12:53:00 +020044constexpr int kDefaultWidth = 1280;
45constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070046
Elad Alon11dfff02019-06-10 19:10:29 +020047const VideoEncoder::Capabilities kCapabilities(false);
48const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200);
49
Rasmus Brandt0cedc052018-05-31 12:53:00 +020050std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
51 VideoEncoderFactory* internal_encoder_factory) {
52 std::unique_ptr<VideoEncoderFactory> encoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020053 absl::make_unique<FunctionVideoEncoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020054 [internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +020055 return absl::make_unique<SimulcastEncoderAdapter>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020056 internal_encoder_factory,
57 SdpVideoFormat(cricket::kVp8CodecName));
58 });
59 std::unique_ptr<VideoDecoderFactory> decoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020060 absl::make_unique<FunctionVideoDecoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020061 []() { return VP8Decoder::Create(); });
62 return CreateSimulcastTestFixture(std::move(encoder_factory),
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020063 std::move(decoder_factory),
64 SdpVideoFormat(cricket::kVp8CodecName));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000065}
Rasmus Brandt0cedc052018-05-31 12:53:00 +020066} // namespace
67
68TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
69 InternalEncoderFactory internal_encoder_factory;
70 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
71 fixture->TestKeyFrameRequestsOnAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000072}
73
Rasmus Brandt0cedc052018-05-31 12:53:00 +020074TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
75 InternalEncoderFactory internal_encoder_factory;
76 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
77 fixture->TestPaddingAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000078}
79
Rasmus Brandt0cedc052018-05-31 12:53:00 +020080TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
81 InternalEncoderFactory internal_encoder_factory;
82 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
83 fixture->TestPaddingTwoStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000084}
85
Rasmus Brandt0cedc052018-05-31 12:53:00 +020086TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
87 InternalEncoderFactory internal_encoder_factory;
88 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
89 fixture->TestPaddingTwoStreamsOneMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000090}
91
Rasmus Brandt0cedc052018-05-31 12:53:00 +020092TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
93 InternalEncoderFactory internal_encoder_factory;
94 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
95 fixture->TestPaddingOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000096}
97
Rasmus Brandt0cedc052018-05-31 12:53:00 +020098TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
99 InternalEncoderFactory internal_encoder_factory;
100 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
101 fixture->TestPaddingOneStreamTwoMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000102}
103
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200104TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
105 InternalEncoderFactory internal_encoder_factory;
106 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
107 fixture->TestSendAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000108}
109
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200110TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
111 InternalEncoderFactory internal_encoder_factory;
112 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
113 fixture->TestDisablingStreams();
Seth Hampson46e31ba2018-01-18 10:39:54 -0800114}
115
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200116TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
117 InternalEncoderFactory internal_encoder_factory;
118 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
119 fixture->TestActiveStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000120}
121
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200122TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
123 InternalEncoderFactory internal_encoder_factory;
124 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
125 fixture->TestSwitchingToOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000126}
127
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200128TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
129 InternalEncoderFactory internal_encoder_factory;
130 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
131 fixture->TestSwitchingToOneOddStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000132}
133
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200134TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
135 InternalEncoderFactory internal_encoder_factory;
136 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
137 fixture->TestStrideEncodeDecode();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000138}
139
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200140TEST(SimulcastEncoderAdapterSimulcastTest,
141 TestSpatioTemporalLayers333PatternEncoder) {
142 InternalEncoderFactory internal_encoder_factory;
143 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
144 fixture->TestSpatioTemporalLayers333PatternEncoder();
145}
146
147TEST(SimulcastEncoderAdapterSimulcastTest,
148 TestSpatioTemporalLayers321PatternEncoder) {
149 InternalEncoderFactory internal_encoder_factory;
150 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
151 fixture->TestSpatioTemporalLayers321PatternEncoder();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000152}
153
Per Kjellander841c9122018-10-04 18:40:28 +0200154TEST(SimulcastEncoderAdapterSimulcastTest, TestDecodeWidthHeightSet) {
155 InternalEncoderFactory internal_encoder_factory;
156 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
157 fixture->TestDecodeWidthHeightSet();
158}
159
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100160class MockVideoEncoder;
161
162class MockVideoEncoderFactory : public VideoEncoderFactory {
163 public:
164 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
165
166 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
167 const SdpVideoFormat& format) override;
168
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000169 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
170
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100171 const std::vector<MockVideoEncoder*>& encoders() const;
172 void SetEncoderNames(const std::vector<const char*>& encoder_names);
173 void set_init_encode_return_value(int32_t value);
174
175 void DestroyVideoEncoder(VideoEncoder* encoder);
176
177 private:
178 int32_t init_encode_return_value_ = 0;
179 std::vector<MockVideoEncoder*> encoders_;
180 std::vector<const char*> encoder_names_;
181};
182
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000183class MockVideoEncoder : public VideoEncoder {
184 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100185 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng75de46a2018-11-07 14:53:32 +0100186 : factory_(factory),
187 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
188 callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100189
nisseef8b61e2016-04-29 06:09:15 -0700190 // TODO(nisse): Valid overrides commented out, because the gmock
191 // methods don't use any override declarations, and we want to avoid
192 // warnings from -Winconsistent-missing-override. See
193 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000194 int32_t InitEncode(const VideoCodec* codecSettings,
195 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700196 size_t maxPayloadSize) /* override */ {
Elad Alon11dfff02019-06-10 19:10:29 +0200197 RTC_NOTREACHED();
198 return WEBRTC_VIDEO_CODEC_ERROR;
199 }
200 int32_t InitEncode(const VideoCodec* codecSettings,
201 const VideoEncoder::Settings& settings) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000202 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800203 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000204 }
205
Niels Möllerb859b322019-03-07 12:40:01 +0100206 MOCK_METHOD2(
noahricfe3654d2016-07-01 09:05:54 -0700207 Encode,
208 int32_t(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +0100209 const std::vector<VideoFrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000210
pbos65e15ba2015-10-15 10:52:15 -0700211 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700212 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700213 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000214 return 0;
215 }
216
brandtr5e171752017-05-23 03:32:16 -0700217 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000218
Erik Språng16cb8f52019-04-12 13:59:09 +0200219 void SetRates(const RateControlParameters& parameters) {
220 last_set_rates_ = parameters;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000221 }
222
Erik Språng9b5b0702018-11-01 14:52:30 +0100223 EncoderInfo GetEncoderInfo() const override {
224 EncoderInfo info;
225 info.supports_native_handle = supports_native_handle_;
226 info.implementation_name = implementation_name_;
Erik Språng75de46a2018-11-07 14:53:32 +0100227 info.scaling_settings = scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100228 info.has_trusted_rate_controller = has_trusted_rate_controller_;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100229 info.is_hardware_accelerated = is_hardware_accelerated_;
230 info.has_internal_source = has_internal_source_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100231 info.fps_allocation[0] = fps_allocation_;
Erik Språng9b5b0702018-11-01 14:52:30 +0100232 return info;
nisseef8b61e2016-04-29 06:09:15 -0700233 }
pbos65e15ba2015-10-15 10:52:15 -0700234
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100235 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000236
237 const VideoCodec& codec() const { return codec_; }
238
Noah Richards41ee1ea2015-04-15 09:24:26 -0700239 void SendEncodedImage(int width, int height) {
240 // Sends a fake image of the given width/height.
241 EncodedImage image;
242 image._encodedWidth = width;
243 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700244 CodecSpecificInfo codec_specific_info;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200245 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700246 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700247 }
248
pbos65e15ba2015-10-15 10:52:15 -0700249 void set_supports_native_handle(bool enabled) {
250 supports_native_handle_ = enabled;
251 }
noahrice5ba75a2016-12-12 13:08:27 -0800252
Erik Språng9b5b0702018-11-01 14:52:30 +0100253 void set_implementation_name(const std::string& name) {
254 implementation_name_ = name;
255 }
256
noahrice5ba75a2016-12-12 13:08:27 -0800257 void set_init_encode_return_value(int32_t value) {
258 init_encode_return_value_ = value;
259 }
260
Erik Språng75de46a2018-11-07 14:53:32 +0100261 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
262 scaling_settings_ = settings;
263 }
264
Erik Språngd3438aa2018-11-08 16:56:43 +0100265 void set_has_trusted_rate_controller(bool trusted) {
266 has_trusted_rate_controller_ = trusted;
267 }
268
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100269 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
270 is_hardware_accelerated_ = is_hardware_accelerated;
271 }
272
273 void set_has_internal_source(bool has_internal_source) {
274 has_internal_source_ = has_internal_source;
275 }
276
Erik Språngdbdd8392019-01-17 15:27:50 +0100277 void set_fps_allocation(const FramerateFractions& fps_allocation) {
278 fps_allocation_ = fps_allocation;
279 }
280
Erik Språng16cb8f52019-04-12 13:59:09 +0200281 RateControlParameters last_set_rates() const { return last_set_rates_; }
pbos65e15ba2015-10-15 10:52:15 -0700282
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000283 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100284 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700285 bool supports_native_handle_ = false;
Erik Språng9b5b0702018-11-01 14:52:30 +0100286 std::string implementation_name_ = "unknown";
Erik Språng75de46a2018-11-07 14:53:32 +0100287 VideoEncoder::ScalingSettings scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100288 bool has_trusted_rate_controller_ = false;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100289 bool is_hardware_accelerated_ = false;
290 bool has_internal_source_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800291 int32_t init_encode_return_value_ = 0;
Erik Språng16cb8f52019-04-12 13:59:09 +0200292 VideoEncoder::RateControlParameters last_set_rates_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100293 FramerateFractions fps_allocation_;
noahricfac0ff02016-09-09 10:27:15 -0700294
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000295 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700296 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000297};
298
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100299std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
300 const {
301 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
302 return formats;
303}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000304
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100305std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
306 const SdpVideoFormat& format) {
307 std::unique_ptr<MockVideoEncoder> encoder(
308 new ::testing::NiceMock<MockVideoEncoder>(this));
309 encoder->set_init_encode_return_value(init_encode_return_value_);
310 const char* encoder_name = encoder_names_.empty()
311 ? "codec_implementation_name"
312 : encoder_names_[encoders_.size()];
Erik Språng9b5b0702018-11-01 14:52:30 +0100313 encoder->set_implementation_name(encoder_name);
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100314 encoders_.push_back(encoder.get());
315 return encoder;
316}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000317
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100318void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
319 for (size_t i = 0; i < encoders_.size(); ++i) {
320 if (encoders_[i] == encoder) {
321 encoders_.erase(encoders_.begin() + i);
322 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000323 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000324 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100325}
Zhi Huangaea84f52017-11-16 18:46:27 +0000326
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000327VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
328 const SdpVideoFormat& format) const {
329 return CodecInfo();
330}
331
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100332const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
333 const {
334 return encoders_;
335}
336void MockVideoEncoderFactory::SetEncoderNames(
337 const std::vector<const char*>& encoder_names) {
338 encoder_names_ = encoder_names;
339}
340void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
341 init_encode_return_value_ = value;
342}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000343
344class TestSimulcastEncoderAdapterFakeHelper {
345 public:
346 TestSimulcastEncoderAdapterFakeHelper()
347 : factory_(new MockVideoEncoderFactory()) {}
348
349 // Can only be called once as the SimulcastEncoderAdapter will take the
350 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200351 VideoEncoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200352 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000353 }
354
magjed6cc25612017-07-10 03:26:36 -0700355 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000356
357 private:
magjed6cc25612017-07-10 03:26:36 -0700358 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000359};
360
361static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
362
Noah Richards41ee1ea2015-04-15 09:24:26 -0700363class TestSimulcastEncoderAdapterFake : public ::testing::Test,
364 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000365 public:
366 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700367 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
368 adapter_(helper_->CreateMockEncoderAdapter()),
369 last_encoded_image_width_(-1),
370 last_encoded_image_height_(-1),
371 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700372 virtual ~TestSimulcastEncoderAdapterFake() {
373 if (adapter_) {
374 adapter_->Release();
375 }
376 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000377
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700378 Result OnEncodedImage(const EncodedImage& encoded_image,
379 const CodecSpecificInfo* codec_specific_info,
380 const RTPFragmentationHeader* fragmentation) override {
381 last_encoded_image_width_ = encoded_image._encodedWidth;
382 last_encoded_image_height_ = encoded_image._encodedHeight;
Niels Möllerd3b8c632018-08-27 15:33:42 +0200383 last_encoded_image_simulcast_index_ =
384 encoded_image.SpatialIndex().value_or(-1);
385
Niels Möller72bc8d62018-09-12 10:03:51 +0200386 return Result(Result::OK, encoded_image.Timestamp());
Noah Richards41ee1ea2015-04-15 09:24:26 -0700387 }
388
389 bool GetLastEncodedImageInfo(int* out_width,
390 int* out_height,
391 int* out_simulcast_index) {
392 if (last_encoded_image_width_ == -1) {
393 return false;
394 }
395 *out_width = last_encoded_image_width_;
396 *out_height = last_encoded_image_height_;
397 *out_simulcast_index = last_encoded_image_simulcast_index_;
398 return true;
399 }
400
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000401 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200402 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200403 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
404 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100405 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon11dfff02019-06-10 19:10:29 +0200406 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700407 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000408 }
409
410 void VerifyCodec(const VideoCodec& ref, int stream_index) {
411 const VideoCodec& target =
412 helper_->factory()->encoders()[stream_index]->codec();
413 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000414 EXPECT_EQ(ref.plType, target.plType);
415 EXPECT_EQ(ref.width, target.width);
416 EXPECT_EQ(ref.height, target.height);
417 EXPECT_EQ(ref.startBitrate, target.startBitrate);
418 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
419 EXPECT_EQ(ref.minBitrate, target.minBitrate);
420 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700421 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700422 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
423 target.VP8().numberOfTemporalLayers);
424 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700425 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
426 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
427 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000428 EXPECT_EQ(ref.qpMax, target.qpMax);
429 EXPECT_EQ(0, target.numberOfSimulcastStreams);
430 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000431
432 // No need to compare simulcastStream as numberOfSimulcastStreams should
433 // always be 0.
434 }
435
Florent Castelli1b761ca2019-01-21 14:33:02 +0100436 void InitRefCodec(int stream_index,
437 VideoCodec* ref_codec,
438 bool reverse_layer_order = false) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000439 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700440 ref_codec->VP8()->numberOfTemporalLayers =
Florent Castelli1b761ca2019-01-21 14:33:02 +0100441 kTestTemporalLayerProfile[reverse_layer_order ? 2 - stream_index
442 : stream_index];
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000443 ref_codec->width = codec_.simulcastStream[stream_index].width;
444 ref_codec->height = codec_.simulcastStream[stream_index].height;
445 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
446 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
447 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
448 }
449
450 void VerifyCodecSettings() {
451 EXPECT_EQ(3u, helper_->factory()->encoders().size());
452 VideoCodec ref_codec;
453
454 // stream 0, the lowest resolution stream.
455 InitRefCodec(0, &ref_codec);
456 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200457 ref_codec.VP8()->complexity =
458 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700459 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000460 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
461 VerifyCodec(ref_codec, 0);
462
463 // stream 1
464 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700465 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700466 // The start bitrate (300kbit) minus what we have for the lower layers
467 // (100kbit).
468 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000469 VerifyCodec(ref_codec, 1);
470
471 // stream 2, the biggest resolution stream.
472 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700473 // We don't have enough bits to send this, so the adapter should have
474 // configured it to use the min bitrate for this layer (600kbit) but turn
475 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000476 ref_codec.startBitrate = 600;
477 VerifyCodec(ref_codec, 2);
478 }
479
480 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800481 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200482 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000483 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700484 int last_encoded_image_width_;
485 int last_encoded_image_height_;
486 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100487 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000488};
489
490TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
491 SetupCodec();
492 VerifyCodecSettings();
493}
494
brandtr5e171752017-05-23 03:32:16 -0700495TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
496 EXPECT_EQ(0, adapter_->Release());
497}
498
499TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
500 SetupCodec();
501 EXPECT_EQ(0, adapter_->Release());
502
Elad Alon11dfff02019-06-10 19:10:29 +0200503 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700504}
505
Noah Richards41ee1ea2015-04-15 09:24:26 -0700506TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
507 SetupCodec();
508
Peter Boström5d0379d2015-10-06 14:04:51 +0200509 // Set bitrates so that we send all layers.
Erik Språng16cb8f52019-04-12 13:59:09 +0200510 adapter_->SetRates(VideoEncoder::RateControlParameters(
511 rate_allocator_->GetAllocation(1200, 30), 30.0));
Peter Boström5d0379d2015-10-06 14:04:51 +0200512
Noah Richards41ee1ea2015-04-15 09:24:26 -0700513 // At this point, the simulcast encoder adapter should have 3 streams: HD,
514 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
515 // resolutions, to test that the adapter forwards on the correct resolution
516 // and simulcast index values, going only off the encoder that generates the
517 // image.
brandtr5e171752017-05-23 03:32:16 -0700518 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
519 ASSERT_EQ(3u, encoders.size());
520 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700521 int width;
522 int height;
523 int simulcast_index;
524 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
525 EXPECT_EQ(1152, width);
526 EXPECT_EQ(704, height);
527 EXPECT_EQ(0, simulcast_index);
528
brandtr5e171752017-05-23 03:32:16 -0700529 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700530 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
531 EXPECT_EQ(300, width);
532 EXPECT_EQ(620, height);
533 EXPECT_EQ(1, simulcast_index);
534
brandtr5e171752017-05-23 03:32:16 -0700535 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700536 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
537 EXPECT_EQ(120, width);
538 EXPECT_EQ(240, height);
539 EXPECT_EQ(2, simulcast_index);
540}
541
brandtr5e171752017-05-23 03:32:16 -0700542// This test verifies that the underlying encoders are reused, when the adapter
543// is reinited with different number of simulcast streams. It further checks
544// that the allocated encoders are reused in the same order as before, starting
545// with the lowest stream.
546TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
547 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200548 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200549 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
550 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100551 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700552 adapter_->RegisterEncodeCompleteCallback(this);
Erik Språng7d687b12018-09-12 17:04:10 +0200553 const uint32_t target_bitrate =
554 1000 * (codec_.simulcastStream[0].targetBitrate +
555 codec_.simulcastStream[1].targetBitrate +
556 codec_.simulcastStream[2].minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700557
558 // Input data.
559 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100560 VideoFrame input_frame = VideoFrame::Builder()
561 .set_video_frame_buffer(buffer)
562 .set_timestamp_rtp(100)
563 .set_timestamp_ms(1000)
564 .set_rotation(kVideoRotation_180)
565 .build();
Niels Möller87e2d782019-03-07 10:18:23 +0100566 std::vector<VideoFrameType> frame_types;
brandtr5e171752017-05-23 03:32:16 -0700567
568 // Encode with three streams.
Elad Alon11dfff02019-06-10 19:10:29 +0200569 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700570 VerifyCodecSettings();
Erik Språng16cb8f52019-04-12 13:59:09 +0200571 adapter_->SetRates(VideoEncoder::RateControlParameters(
572 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
Erik Språng7d687b12018-09-12 17:04:10 +0200573
brandtr5e171752017-05-23 03:32:16 -0700574 std::vector<MockVideoEncoder*> original_encoders =
575 helper_->factory()->encoders();
576 ASSERT_EQ(3u, original_encoders.size());
Niels Möllerb859b322019-03-07 12:40:01 +0100577 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700578 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100579 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700580 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100581 EXPECT_CALL(*original_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700582 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100583 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100584 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700585 EXPECT_CALL(*original_encoders[0], Release())
586 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
587 EXPECT_CALL(*original_encoders[1], Release())
588 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
589 EXPECT_CALL(*original_encoders[2], Release())
590 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
591 EXPECT_EQ(0, adapter_->Release());
592
593 // Encode with two streams.
594 codec_.width /= 2;
595 codec_.height /= 2;
596 codec_.numberOfSimulcastStreams = 2;
Elad Alon11dfff02019-06-10 19:10:29 +0200597 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200598 adapter_->SetRates(VideoEncoder::RateControlParameters(
599 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700600 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
601 ASSERT_EQ(2u, new_encoders.size());
602 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100603 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700604 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
605 ASSERT_EQ(original_encoders[1], new_encoders[1]);
Niels Möllerb859b322019-03-07 12:40:01 +0100606 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700607 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100608 frame_types.resize(2, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100609 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700610 EXPECT_CALL(*original_encoders[0], Release())
611 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
612 EXPECT_CALL(*original_encoders[1], Release())
613 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
614 EXPECT_EQ(0, adapter_->Release());
615
616 // Encode with single stream.
617 codec_.width /= 2;
618 codec_.height /= 2;
619 codec_.numberOfSimulcastStreams = 1;
Elad Alon11dfff02019-06-10 19:10:29 +0200620 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200621 adapter_->SetRates(VideoEncoder::RateControlParameters(
622 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700623 new_encoders = helper_->factory()->encoders();
624 ASSERT_EQ(1u, new_encoders.size());
625 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100626 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700627 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100628 frame_types.resize(1, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100629 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700630 EXPECT_CALL(*original_encoders[0], Release())
631 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
632 EXPECT_EQ(0, adapter_->Release());
633
634 // Encode with three streams, again.
635 codec_.width *= 4;
636 codec_.height *= 4;
637 codec_.numberOfSimulcastStreams = 3;
Elad Alon11dfff02019-06-10 19:10:29 +0200638 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200639 adapter_->SetRates(VideoEncoder::RateControlParameters(
640 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700641 new_encoders = helper_->factory()->encoders();
642 ASSERT_EQ(3u, new_encoders.size());
643 // The first encoder is reused.
644 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100645 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700646 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
647 // The second and third encoders are new.
Niels Möllerb859b322019-03-07 12:40:01 +0100648 EXPECT_CALL(*new_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700649 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100650 EXPECT_CALL(*new_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700651 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100652 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100653 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700654 EXPECT_CALL(*original_encoders[0], Release())
655 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
656 EXPECT_CALL(*new_encoders[1], Release())
657 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
658 EXPECT_CALL(*new_encoders[2], Release())
659 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
660 EXPECT_EQ(0, adapter_->Release());
661}
662
663TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
664 SetupCodec();
665 VerifyCodecSettings();
666
667 EXPECT_EQ(3u, helper_->factory()->encoders().size());
668
669 // The adapter should destroy all encoders it has allocated. Since
670 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
671 // lsan to find leaks here.
672 EXPECT_EQ(0, adapter_->Release());
673 adapter_.reset();
674}
675
676// This test verifies that an adapter reinit with the same codec settings as
677// before does not change the underlying encoder codec settings.
678TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
679 SetupCodec();
680 VerifyCodecSettings();
681
682 // Capture current codec settings.
683 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
684 ASSERT_EQ(3u, encoders.size());
685 std::array<VideoCodec, 3> codecs_before;
686 for (int i = 0; i < 3; ++i) {
687 codecs_before[i] = encoders[i]->codec();
688 }
689
690 // Reinitialize and verify that the new codec settings are the same.
691 EXPECT_EQ(0, adapter_->Release());
Elad Alon11dfff02019-06-10 19:10:29 +0200692 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700693 for (int i = 0; i < 3; ++i) {
694 const VideoCodec& codec_before = codecs_before[i];
695 const VideoCodec& codec_after = encoders[i]->codec();
696
697 // webrtc::VideoCodec does not implement operator==.
698 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
699 EXPECT_EQ(codec_before.plType, codec_after.plType);
700 EXPECT_EQ(codec_before.width, codec_after.width);
701 EXPECT_EQ(codec_before.height, codec_after.height);
702 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
703 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
704 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700705 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
706 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
707 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
708 codec_after.numberOfSimulcastStreams);
709 EXPECT_EQ(codec_before.mode, codec_after.mode);
710 EXPECT_EQ(codec_before.expect_encode_from_texture,
711 codec_after.expect_encode_from_texture);
712 }
713}
714
715// This test is similar to the one above, except that it tests the simulcastIdx
716// from the CodecSpecificInfo that is connected to an encoded frame. The
717// PayloadRouter demuxes the incoming encoded frames on different RTP modules
718// using the simulcastIdx, so it's important that there is no corresponding
719// encoder reordering in between adapter reinits as this would lead to PictureID
720// discontinuities.
721TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
722 SetupCodec();
Erik Språng16cb8f52019-04-12 13:59:09 +0200723 adapter_->SetRates(VideoEncoder::RateControlParameters(
724 rate_allocator_->GetAllocation(1200, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700725 VerifyCodecSettings();
726
727 // Send frames on all streams.
728 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
729 ASSERT_EQ(3u, encoders.size());
730 encoders[0]->SendEncodedImage(1152, 704);
731 int width;
732 int height;
733 int simulcast_index;
734 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
735 EXPECT_EQ(0, simulcast_index);
736
737 encoders[1]->SendEncodedImage(300, 620);
738 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
739 EXPECT_EQ(1, simulcast_index);
740
741 encoders[2]->SendEncodedImage(120, 240);
742 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
743 EXPECT_EQ(2, simulcast_index);
744
745 // Reinitialize.
746 EXPECT_EQ(0, adapter_->Release());
Elad Alon11dfff02019-06-10 19:10:29 +0200747 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200748 adapter_->SetRates(VideoEncoder::RateControlParameters(
749 rate_allocator_->GetAllocation(1200, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700750
751 // Verify that the same encoder sends out frames on the same simulcast index.
752 encoders[0]->SendEncodedImage(1152, 704);
753 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
754 EXPECT_EQ(0, simulcast_index);
755
756 encoders[1]->SendEncodedImage(300, 620);
757 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
758 EXPECT_EQ(1, simulcast_index);
759
760 encoders[2]->SendEncodedImage(120, 240);
761 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
762 EXPECT_EQ(2, simulcast_index);
763}
764
pbos65e15ba2015-10-15 10:52:15 -0700765TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200766 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200767 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
768 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700769 codec_.numberOfSimulcastStreams = 1;
Elad Alon11dfff02019-06-10 19:10:29 +0200770 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700771 adapter_->RegisterEncodeCompleteCallback(this);
772 ASSERT_EQ(1u, helper_->factory()->encoders().size());
773 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon11dfff02019-06-10 19:10:29 +0200774 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200775 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700776 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Elad Alon11dfff02019-06-10 19:10:29 +0200777 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200778 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700779}
780
noahricfac0ff02016-09-09 10:27:15 -0700781TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200782 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200783 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
784 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700785 codec_.minBitrate = 50;
786 codec_.numberOfSimulcastStreams = 1;
Elad Alon11dfff02019-06-10 19:10:29 +0200787 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng82fad3d2018-03-21 09:57:23 +0100788 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700789
790 // Above min should be respected.
Erik Språng566124a2018-04-23 12:32:22 +0200791 VideoBitrateAllocation target_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100792 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
Erik Språng16cb8f52019-04-12 13:59:09 +0200793 adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100794 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200795 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700796
797 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng566124a2018-04-23 12:32:22 +0200798 VideoBitrateAllocation too_low_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100799 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
Erik Språng16cb8f52019-04-12 13:59:09 +0200800 adapter_->SetRates(
801 VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100802 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200803 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700804
805 // Zero should be passed on as is, since it means "pause".
Erik Språng16cb8f52019-04-12 13:59:09 +0200806 adapter_->SetRates(
807 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
Erik Språng566124a2018-04-23 12:32:22 +0200808 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng16cb8f52019-04-12 13:59:09 +0200809 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700810}
811
Peter Boströma5dec162016-01-20 15:53:55 +0100812TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
Erik Språnge2fd86a2018-10-24 11:32:39 +0200813 EXPECT_EQ("SimulcastEncoderAdapter",
814 adapter_->GetEncoderInfo().implementation_name);
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200815 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200816 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
817 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100818 std::vector<const char*> encoder_names;
819 encoder_names.push_back("codec1");
820 encoder_names.push_back("codec2");
821 encoder_names.push_back("codec3");
822 helper_->factory()->SetEncoderNames(encoder_names);
Elad Alon11dfff02019-06-10 19:10:29 +0200823 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200824 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
825 adapter_->GetEncoderInfo().implementation_name);
Peter Boströmd53c3892016-03-30 17:03:52 +0200826
827 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700828 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200829 codec_.numberOfSimulcastStreams = 1;
Elad Alon11dfff02019-06-10 19:10:29 +0200830 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Peter Boströmd53c3892016-03-30 17:03:52 +0200831 adapter_->RegisterEncodeCompleteCallback(this);
832 ASSERT_EQ(1u, helper_->factory()->encoders().size());
Erik Språnge2fd86a2018-10-24 11:32:39 +0200833 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
Peter Boströma5dec162016-01-20 15:53:55 +0100834}
835
pbos65e15ba2015-10-15 10:52:15 -0700836TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700837 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200838 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200839 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
840 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700841 codec_.numberOfSimulcastStreams = 3;
Elad Alon11dfff02019-06-10 19:10:29 +0200842 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700843 adapter_->RegisterEncodeCompleteCallback(this);
844 ASSERT_EQ(3u, helper_->factory()->encoders().size());
845 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
846 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700847 // If one encoder doesn't support it, then overall support is disabled.
848 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språnge2fd86a2018-10-24 11:32:39 +0200849 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700850 // Once all do, then the adapter claims support.
851 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon11dfff02019-06-10 19:10:29 +0200852 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200853 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700854}
855
nisseaf916892017-01-10 07:44:26 -0800856// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200857class FakeNativeBufferNoI420 : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700858 public:
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200859 FakeNativeBufferNoI420(int width, int height)
860 : width_(width), height_(height) {}
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000861
862 Type type() const override { return Type::kNative; }
863 int width() const override { return width_; }
864 int height() const override { return height_; }
865
866 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700867 RTC_NOTREACHED();
868 return nullptr;
869 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000870
871 private:
872 const int width_;
873 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700874};
875
876TEST_F(TestSimulcastEncoderAdapterFake,
877 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200878 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200879 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
880 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700881 codec_.numberOfSimulcastStreams = 3;
882 // High start bitrate, so all streams are enabled.
883 codec_.startBitrate = 3000;
Elad Alon11dfff02019-06-10 19:10:29 +0200884 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahricfe3654d2016-07-01 09:05:54 -0700885 adapter_->RegisterEncodeCompleteCallback(this);
886 ASSERT_EQ(3u, helper_->factory()->encoders().size());
887 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
888 encoder->set_supports_native_handle(true);
Elad Alon11dfff02019-06-10 19:10:29 +0200889 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200890 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700891
892 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200893 new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100894 VideoFrame input_frame = VideoFrame::Builder()
895 .set_video_frame_buffer(buffer)
896 .set_timestamp_rtp(100)
897 .set_timestamp_ms(1000)
898 .set_rotation(kVideoRotation_180)
899 .build();
noahricfe3654d2016-07-01 09:05:54 -0700900 // Expect calls with the given video frame verbatim, since it's a texture
901 // frame and can't otherwise be modified/resized.
902 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
Niels Möllerb859b322019-03-07 12:40:01 +0100903 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _)).Times(1);
Niels Möller8f7ce222019-03-21 15:43:58 +0100904 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100905 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700906}
907
noahric57779102016-05-25 06:48:46 -0700908TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200909 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200910 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
911 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700912 codec_.numberOfSimulcastStreams = 3;
Elad Alon11dfff02019-06-10 19:10:29 +0200913 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahric57779102016-05-25 06:48:46 -0700914 adapter_->RegisterEncodeCompleteCallback(this);
915 ASSERT_EQ(3u, helper_->factory()->encoders().size());
916 // Tell the 2nd encoder to request software fallback.
Niels Möllerb859b322019-03-07 12:40:01 +0100917 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _))
noahricfe3654d2016-07-01 09:05:54 -0700918 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700919
920 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000921 rtc::scoped_refptr<I420Buffer> input_buffer =
922 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700923 input_buffer->InitializeData();
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100924 VideoFrame input_frame = VideoFrame::Builder()
925 .set_video_frame_buffer(input_buffer)
926 .set_timestamp_rtp(0)
927 .set_timestamp_us(0)
928 .set_rotation(kVideoRotation_0)
929 .build();
Niels Möller8f7ce222019-03-21 15:43:58 +0100930 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
noahric57779102016-05-25 06:48:46 -0700931 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Niels Möllerc8d2e732019-03-06 12:00:33 +0100932 adapter_->Encode(input_frame, &frame_types));
noahric57779102016-05-25 06:48:46 -0700933}
934
noahrice5ba75a2016-12-12 13:08:27 -0800935TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200936 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200937 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
938 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800939 codec_.numberOfSimulcastStreams = 3;
940 helper_->factory()->set_init_encode_return_value(
941 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
942 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Elad Alon11dfff02019-06-10 19:10:29 +0200943 adapter_->InitEncode(&codec_, kSettings));
noahrice5ba75a2016-12-12 13:08:27 -0800944 EXPECT_TRUE(helper_->factory()->encoders().empty());
945}
946
Erik Språng8d2995b2018-08-09 11:18:17 +0200947TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
948 const int kHighMaxQp = 56;
949 const int kLowMaxQp = 46;
950
951 SimulcastTestFixtureImpl::DefaultSettings(
952 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
953 kVideoCodecVP8);
954 codec_.numberOfSimulcastStreams = 3;
955 codec_.simulcastStream[0].qpMax = kHighMaxQp;
956 codec_.mode = VideoCodecMode::kScreensharing;
957
Elad Alon11dfff02019-06-10 19:10:29 +0200958 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200959 EXPECT_EQ(3u, helper_->factory()->encoders().size());
960
961 // Just check the lowest stream, which is the one that where the adapter
962 // might alter the max qp setting.
963 VideoCodec ref_codec;
964 InitRefCodec(0, &ref_codec);
965 ref_codec.qpMax = kHighMaxQp;
966 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
967 ref_codec.VP8()->denoisingOn = false;
968 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
969 VerifyCodec(ref_codec, 0);
970
971 // Change the max qp and try again.
972 codec_.simulcastStream[0].qpMax = kLowMaxQp;
Elad Alon11dfff02019-06-10 19:10:29 +0200973 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200974 EXPECT_EQ(3u, helper_->factory()->encoders().size());
975 ref_codec.qpMax = kLowMaxQp;
976 VerifyCodec(ref_codec, 0);
977}
Erik Språng7d687b12018-09-12 17:04:10 +0200978
Florent Castelli1b761ca2019-01-21 14:33:02 +0100979TEST_F(TestSimulcastEncoderAdapterFake,
980 DoesNotAlterMaxQpForScreenshareReversedLayer) {
981 const int kHighMaxQp = 56;
982 const int kLowMaxQp = 46;
983
984 SimulcastTestFixtureImpl::DefaultSettings(
985 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
986 kVideoCodecVP8, true /* reverse_layer_order */);
987 codec_.numberOfSimulcastStreams = 3;
988 codec_.simulcastStream[2].qpMax = kHighMaxQp;
989 codec_.mode = VideoCodecMode::kScreensharing;
990
Elad Alon11dfff02019-06-10 19:10:29 +0200991 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +0100992 EXPECT_EQ(3u, helper_->factory()->encoders().size());
993
994 // Just check the lowest stream, which is the one that where the adapter
995 // might alter the max qp setting.
996 VideoCodec ref_codec;
997 InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
998 ref_codec.qpMax = kHighMaxQp;
999 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1000 ref_codec.VP8()->denoisingOn = false;
1001 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1002 VerifyCodec(ref_codec, 2);
1003
1004 // Change the max qp and try again.
1005 codec_.simulcastStream[2].qpMax = kLowMaxQp;
Elad Alon11dfff02019-06-10 19:10:29 +02001006 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001007 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1008 ref_codec.qpMax = kLowMaxQp;
1009 VerifyCodec(ref_codec, 2);
1010}
1011
Erik Språng7d687b12018-09-12 17:04:10 +02001012TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
1013 // Set up common settings for three streams.
1014 SimulcastTestFixtureImpl::DefaultSettings(
1015 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1016 kVideoCodecVP8);
1017 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1018 adapter_->RegisterEncodeCompleteCallback(this);
1019
1020 // Only enough start bitrate for the lowest stream.
1021 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1022 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1023 codec_.simulcastStream[1].minBitrate - 1;
1024
1025 // Input data.
1026 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001027 VideoFrame input_frame = VideoFrame::Builder()
1028 .set_video_frame_buffer(buffer)
1029 .set_timestamp_rtp(100)
1030 .set_timestamp_ms(1000)
1031 .set_rotation(kVideoRotation_180)
1032 .build();
Erik Språng7d687b12018-09-12 17:04:10 +02001033
1034 // Encode with three streams.
Elad Alon11dfff02019-06-10 19:10:29 +02001035 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng7d687b12018-09-12 17:04:10 +02001036 std::vector<MockVideoEncoder*> original_encoders =
1037 helper_->factory()->encoders();
1038 ASSERT_EQ(3u, original_encoders.size());
1039 // Only first encoder will be active and called.
Niels Möllerb859b322019-03-07 12:40:01 +01001040 EXPECT_CALL(*original_encoders[0], Encode(_, _))
Erik Språng7d687b12018-09-12 17:04:10 +02001041 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +01001042 EXPECT_CALL(*original_encoders[1], Encode(_, _)).Times(0);
1043 EXPECT_CALL(*original_encoders[2], Encode(_, _)).Times(0);
Erik Språng7d687b12018-09-12 17:04:10 +02001044
Niels Möller87e2d782019-03-07 10:18:23 +01001045 std::vector<VideoFrameType> frame_types;
Niels Möller8f7ce222019-03-21 15:43:58 +01001046 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +01001047 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
Erik Språng7d687b12018-09-12 17:04:10 +02001048}
Erik Språngd3438aa2018-11-08 16:56:43 +01001049
1050TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
1051 // Set up common settings for three streams.
1052 SimulcastTestFixtureImpl::DefaultSettings(
1053 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1054 kVideoCodecVP8);
1055 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1056 adapter_->RegisterEncodeCompleteCallback(this);
1057
1058 // Only enough start bitrate for the lowest stream.
1059 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1060 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1061 codec_.simulcastStream[1].minBitrate - 1;
1062
1063 // Input data.
1064 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001065 VideoFrame input_frame = VideoFrame::Builder()
1066 .set_video_frame_buffer(buffer)
1067 .set_timestamp_rtp(100)
1068 .set_timestamp_ms(1000)
1069 .set_rotation(kVideoRotation_180)
1070 .build();
Erik Språngd3438aa2018-11-08 16:56:43 +01001071
1072 // No encoder trusted, so simulcast adapter should not be either.
Elad Alon11dfff02019-06-10 19:10:29 +02001073 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001074 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1075
1076 // Encode with three streams.
1077 std::vector<MockVideoEncoder*> original_encoders =
1078 helper_->factory()->encoders();
1079
1080 // All encoders are trusted, so simulcast adapter should be too.
1081 original_encoders[0]->set_has_trusted_rate_controller(true);
1082 original_encoders[1]->set_has_trusted_rate_controller(true);
1083 original_encoders[2]->set_has_trusted_rate_controller(true);
Elad Alon11dfff02019-06-10 19:10:29 +02001084 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001085 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1086
1087 // One encoder not trusted, so simulcast adapter should not be either.
1088 original_encoders[2]->set_has_trusted_rate_controller(false);
Elad Alon11dfff02019-06-10 19:10:29 +02001089 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001090 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1091
1092 // No encoder trusted, so simulcast adapter should not be either.
1093 original_encoders[0]->set_has_trusted_rate_controller(false);
1094 original_encoders[1]->set_has_trusted_rate_controller(false);
Elad Alon11dfff02019-06-10 19:10:29 +02001095 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001096 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1097}
1098
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001099TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1100 SimulcastTestFixtureImpl::DefaultSettings(
1101 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1102 kVideoCodecVP8);
1103 codec_.numberOfSimulcastStreams = 3;
1104 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon11dfff02019-06-10 19:10:29 +02001105 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001106 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1107
1108 // None of the encoders uses HW support, so simulcast adapter reports false.
1109 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1110 encoder->set_is_hardware_accelerated(false);
1111 }
Elad Alon11dfff02019-06-10 19:10:29 +02001112 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001113 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1114
1115 // One encoder uses HW support, so simulcast adapter reports true.
1116 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
Elad Alon11dfff02019-06-10 19:10:29 +02001117 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001118 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1119}
1120
1121TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1122 SimulcastTestFixtureImpl::DefaultSettings(
1123 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1124 kVideoCodecVP8);
1125 codec_.numberOfSimulcastStreams = 3;
1126 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon11dfff02019-06-10 19:10:29 +02001127 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001128 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1129
1130 // All encoders have internal source, simulcast adapter reports true.
1131 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1132 encoder->set_has_internal_source(true);
1133 }
Elad Alon11dfff02019-06-10 19:10:29 +02001134 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001135 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1136
1137 // One encoder does not have internal source, simulcast adapter reports false.
1138 helper_->factory()->encoders()[2]->set_has_internal_source(false);
Elad Alon11dfff02019-06-10 19:10:29 +02001139 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001140 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1141}
1142
Erik Språngdbdd8392019-01-17 15:27:50 +01001143TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
1144 SimulcastTestFixtureImpl::DefaultSettings(
1145 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1146 kVideoCodecVP8);
1147 codec_.numberOfSimulcastStreams = 3;
1148 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon11dfff02019-06-10 19:10:29 +02001149 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001150 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1151
1152 // Combination of three different supported mode:
1153 // Simulcast stream 0 has undefined fps behavior.
1154 // Simulcast stream 1 has three temporal layers.
1155 // Simulcast stream 2 has 1 temporal layer.
1156 FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
1157 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 4);
1158 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 2);
1159 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction);
1160 expected_fps_allocation[2].push_back(EncoderInfo::kMaxFramerateFraction);
1161
1162 // All encoders have internal source, simulcast adapter reports true.
1163 for (size_t i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
1164 MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
1165 encoder->set_fps_allocation(expected_fps_allocation[i]);
1166 }
Elad Alon11dfff02019-06-10 19:10:29 +02001167 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001168 EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
1169 ::testing::ElementsAreArray(expected_fps_allocation));
1170}
1171
Erik Språng16cb8f52019-04-12 13:59:09 +02001172TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
1173 SimulcastTestFixtureImpl::DefaultSettings(
1174 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1175 kVideoCodecVP8);
1176 codec_.numberOfSimulcastStreams = 3;
1177 const DataRate target_bitrate =
1178 DataRate::kbps(codec_.simulcastStream[0].targetBitrate +
1179 codec_.simulcastStream[1].targetBitrate +
1180 codec_.simulcastStream[2].minBitrate);
1181 const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
1182
1183 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon11dfff02019-06-10 19:10:29 +02001184 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +02001185 adapter_->RegisterEncodeCompleteCallback(this);
1186
1187 // Set bitrates so that we send all layers.
1188 adapter_->SetRates(VideoEncoder::RateControlParameters(
1189 rate_allocator_->GetAllocation(target_bitrate.bps(), 30), 30.0,
1190 bandwidth_allocation));
1191
1192 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1193
1194 ASSERT_EQ(3u, encoders.size());
1195
1196 for (size_t i = 0; i < 3; ++i) {
1197 const uint32_t layer_bitrate_bps =
1198 (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
1199 ? codec_.simulcastStream[i].targetBitrate
1200 : codec_.simulcastStream[i].minBitrate) *
1201 1000;
1202 EXPECT_EQ(layer_bitrate_bps,
1203 encoders[i]->last_set_rates().bitrate.get_sum_bps())
1204 << i;
1205 EXPECT_EQ(
1206 (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
1207 encoders[i]->last_set_rates().bandwidth_allocation.bps())
1208 << i;
1209 }
1210}
1211
Rasmus Brandt0cedc052018-05-31 12:53:00 +02001212} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001213} // namespace webrtc