blob: 48767dc7546ff47462c4270dc1bb0a61df920751 [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/engine/simulcast_encoder_adapter.h"
12
brandtr5e171752017-05-23 03:32:16 -070013#include <array>
kwiberg3f55dea2016-02-29 05:51:59 -080014#include <memory>
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000015#include <vector>
16
Rasmus Brandt0cedc052018-05-31 12:53:00 +020017#include "api/test/create_simulcast_test_fixture.h"
18#include "api/test/simulcast_test_fixture.h"
Danil Chapovalov99b71df2018-10-26 15:57:48 +020019#include "api/test/video/function_video_decoder_factory.h"
20#include "api/test/video/function_video_encoder_factory.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010021#include "api/video_codecs/sdp_video_format.h"
Elad Alon370f93a2019-06-11 14:57:57 +020022#include "api/video_codecs/video_encoder.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010023#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "common_video/include/video_frame_buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "media/base/media_constants.h"
26#include "media/engine/internal_encoder_factory.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 Alon370f93a2019-06-11 14:57:57 +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 =
Mirko Bonadei317a1f02019-09-17 17:06:18 +020053 std::make_unique<FunctionVideoEncoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020054 [internal_encoder_factory]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020055 return std::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 =
Mirko Bonadei317a1f02019-09-17 17:06:18 +020060 std::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);
Erik Språngf4e0c292019-10-01 18:50:03 +0200174 void set_supports_simulcast(bool supports_simulcast) {
175 supports_simulcast_ = supports_simulcast;
176 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100177
178 void DestroyVideoEncoder(VideoEncoder* encoder);
179
180 private:
181 int32_t init_encode_return_value_ = 0;
182 std::vector<MockVideoEncoder*> encoders_;
183 std::vector<const char*> encoder_names_;
Erik Språngf4e0c292019-10-01 18:50:03 +0200184 bool supports_simulcast_ = false;
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100185};
186
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000187class MockVideoEncoder : public VideoEncoder {
188 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100189 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng75de46a2018-11-07 14:53:32 +0100190 : factory_(factory),
191 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
192 callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100193
Elad Alon8f01c4e2019-06-28 15:19:43 +0200194 MOCK_METHOD1(SetFecControllerOverride,
195 void(FecControllerOverride* fec_controller_override));
196
nisseef8b61e2016-04-29 06:09:15 -0700197 // TODO(nisse): Valid overrides commented out, because the gmock
198 // methods don't use any override declarations, and we want to avoid
199 // warnings from -Winconsistent-missing-override. See
200 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000201 int32_t InitEncode(const VideoCodec* codecSettings,
Elad Alona9952cb2019-06-11 19:03:16 +0200202 const VideoEncoder::Settings& settings) override {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000203 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800204 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000205 }
206
Niels Möllerb859b322019-03-07 12:40:01 +0100207 MOCK_METHOD2(
noahricfe3654d2016-07-01 09:05:54 -0700208 Encode,
209 int32_t(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +0100210 const std::vector<VideoFrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000211
pbos65e15ba2015-10-15 10:52:15 -0700212 int32_t RegisterEncodeCompleteCallback(
Elad Alona9952cb2019-06-11 19:03:16 +0200213 EncodedImageCallback* callback) override {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700214 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000215 return 0;
216 }
217
Elad Alona9952cb2019-06-11 19:03:16 +0200218 MOCK_METHOD0(Release, int32_t() /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000219
Erik Språng16cb8f52019-04-12 13:59:09 +0200220 void SetRates(const RateControlParameters& parameters) {
221 last_set_rates_ = parameters;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000222 }
223
Erik Språng9b5b0702018-11-01 14:52:30 +0100224 EncoderInfo GetEncoderInfo() const override {
225 EncoderInfo info;
226 info.supports_native_handle = supports_native_handle_;
227 info.implementation_name = implementation_name_;
Erik Språng75de46a2018-11-07 14:53:32 +0100228 info.scaling_settings = scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100229 info.has_trusted_rate_controller = has_trusted_rate_controller_;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100230 info.is_hardware_accelerated = is_hardware_accelerated_;
231 info.has_internal_source = has_internal_source_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100232 info.fps_allocation[0] = fps_allocation_;
Erik Språngf4e0c292019-10-01 18:50:03 +0200233 info.supports_simulcast = supports_simulcast_;
Erik Språng9b5b0702018-11-01 14:52:30 +0100234 return info;
nisseef8b61e2016-04-29 06:09:15 -0700235 }
pbos65e15ba2015-10-15 10:52:15 -0700236
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100237 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000238
239 const VideoCodec& codec() const { return codec_; }
240
Noah Richards41ee1ea2015-04-15 09:24:26 -0700241 void SendEncodedImage(int width, int height) {
242 // Sends a fake image of the given width/height.
243 EncodedImage image;
244 image._encodedWidth = width;
245 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700246 CodecSpecificInfo codec_specific_info;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200247 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700248 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700249 }
250
pbos65e15ba2015-10-15 10:52:15 -0700251 void set_supports_native_handle(bool enabled) {
252 supports_native_handle_ = enabled;
253 }
noahrice5ba75a2016-12-12 13:08:27 -0800254
Erik Språng9b5b0702018-11-01 14:52:30 +0100255 void set_implementation_name(const std::string& name) {
256 implementation_name_ = name;
257 }
258
noahrice5ba75a2016-12-12 13:08:27 -0800259 void set_init_encode_return_value(int32_t value) {
260 init_encode_return_value_ = value;
261 }
262
Erik Språng75de46a2018-11-07 14:53:32 +0100263 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
264 scaling_settings_ = settings;
265 }
266
Erik Språngd3438aa2018-11-08 16:56:43 +0100267 void set_has_trusted_rate_controller(bool trusted) {
268 has_trusted_rate_controller_ = trusted;
269 }
270
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100271 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
272 is_hardware_accelerated_ = is_hardware_accelerated;
273 }
274
275 void set_has_internal_source(bool has_internal_source) {
276 has_internal_source_ = has_internal_source;
277 }
278
Erik Språngdbdd8392019-01-17 15:27:50 +0100279 void set_fps_allocation(const FramerateFractions& fps_allocation) {
280 fps_allocation_ = fps_allocation;
281 }
282
Erik Språng16cb8f52019-04-12 13:59:09 +0200283 RateControlParameters last_set_rates() const { return last_set_rates_; }
pbos65e15ba2015-10-15 10:52:15 -0700284
Erik Språngf4e0c292019-10-01 18:50:03 +0200285 void set_supports_simulcast(bool supports_simulcast) {
286 supports_simulcast_ = supports_simulcast;
287 }
288
289 bool supports_simulcast() const { return supports_simulcast_; }
290
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000291 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100292 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700293 bool supports_native_handle_ = false;
Erik Språng9b5b0702018-11-01 14:52:30 +0100294 std::string implementation_name_ = "unknown";
Erik Språng75de46a2018-11-07 14:53:32 +0100295 VideoEncoder::ScalingSettings scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100296 bool has_trusted_rate_controller_ = false;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100297 bool is_hardware_accelerated_ = false;
298 bool has_internal_source_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800299 int32_t init_encode_return_value_ = 0;
Erik Språng16cb8f52019-04-12 13:59:09 +0200300 VideoEncoder::RateControlParameters last_set_rates_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100301 FramerateFractions fps_allocation_;
Erik Språngf4e0c292019-10-01 18:50:03 +0200302 bool supports_simulcast_ = false;
noahricfac0ff02016-09-09 10:27:15 -0700303
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000304 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700305 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000306};
307
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100308std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
309 const {
310 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
311 return formats;
312}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000313
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100314std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
315 const SdpVideoFormat& format) {
316 std::unique_ptr<MockVideoEncoder> encoder(
317 new ::testing::NiceMock<MockVideoEncoder>(this));
318 encoder->set_init_encode_return_value(init_encode_return_value_);
319 const char* encoder_name = encoder_names_.empty()
320 ? "codec_implementation_name"
321 : encoder_names_[encoders_.size()];
Erik Språng9b5b0702018-11-01 14:52:30 +0100322 encoder->set_implementation_name(encoder_name);
Erik Språngf4e0c292019-10-01 18:50:03 +0200323 encoder->set_supports_simulcast(supports_simulcast_);
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100324 encoders_.push_back(encoder.get());
325 return encoder;
326}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000327
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100328void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
329 for (size_t i = 0; i < encoders_.size(); ++i) {
330 if (encoders_[i] == encoder) {
331 encoders_.erase(encoders_.begin() + i);
332 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000333 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000334 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100335}
Zhi Huangaea84f52017-11-16 18:46:27 +0000336
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000337VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
338 const SdpVideoFormat& format) const {
339 return CodecInfo();
340}
341
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100342const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
343 const {
344 return encoders_;
345}
346void MockVideoEncoderFactory::SetEncoderNames(
347 const std::vector<const char*>& encoder_names) {
348 encoder_names_ = encoder_names;
349}
350void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
351 init_encode_return_value_ = value;
352}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000353
354class TestSimulcastEncoderAdapterFakeHelper {
355 public:
Erik Språngf4e0c292019-10-01 18:50:03 +0200356 explicit TestSimulcastEncoderAdapterFakeHelper(bool use_fallback_factory)
357 : primary_factory_(new MockVideoEncoderFactory()),
358 fallback_factory_(use_fallback_factory ? new MockVideoEncoderFactory()
359 : nullptr) {}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000360
361 // Can only be called once as the SimulcastEncoderAdapter will take the
362 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200363 VideoEncoder* CreateMockEncoderAdapter() {
Erik Språngf4e0c292019-10-01 18:50:03 +0200364 return new SimulcastEncoderAdapter(
365 primary_factory_.get(), fallback_factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000366 }
367
Erik Språngf4e0c292019-10-01 18:50:03 +0200368 MockVideoEncoderFactory* factory() { return primary_factory_.get(); }
369 MockVideoEncoderFactory* fallback_factory() {
370 return fallback_factory_.get();
371 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000372
373 private:
Erik Språngf4e0c292019-10-01 18:50:03 +0200374 std::unique_ptr<MockVideoEncoderFactory> primary_factory_;
375 std::unique_ptr<MockVideoEncoderFactory> fallback_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000376};
377
378static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
379
Noah Richards41ee1ea2015-04-15 09:24:26 -0700380class TestSimulcastEncoderAdapterFake : public ::testing::Test,
381 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000382 public:
383 TestSimulcastEncoderAdapterFake()
Erik Språngf4e0c292019-10-01 18:50:03 +0200384 : last_encoded_image_width_(-1),
Noah Richards41ee1ea2015-04-15 09:24:26 -0700385 last_encoded_image_height_(-1),
Erik Språngf4e0c292019-10-01 18:50:03 +0200386 last_encoded_image_simulcast_index_(-1),
387 use_fallback_factory_(false) {}
388
brandtr5e171752017-05-23 03:32:16 -0700389 virtual ~TestSimulcastEncoderAdapterFake() {
390 if (adapter_) {
391 adapter_->Release();
392 }
393 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000394
Erik Språngf4e0c292019-10-01 18:50:03 +0200395 void SetUp() override {
396 helper_ = std::make_unique<TestSimulcastEncoderAdapterFakeHelper>(
397 use_fallback_factory_);
398 adapter_.reset(helper_->CreateMockEncoderAdapter());
399 last_encoded_image_width_ = -1;
400 last_encoded_image_height_ = -1;
401 last_encoded_image_simulcast_index_ = -1;
402 }
403
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700404 Result OnEncodedImage(const EncodedImage& encoded_image,
405 const CodecSpecificInfo* codec_specific_info,
406 const RTPFragmentationHeader* fragmentation) override {
407 last_encoded_image_width_ = encoded_image._encodedWidth;
408 last_encoded_image_height_ = encoded_image._encodedHeight;
Niels Möllerd3b8c632018-08-27 15:33:42 +0200409 last_encoded_image_simulcast_index_ =
410 encoded_image.SpatialIndex().value_or(-1);
411
Niels Möller72bc8d62018-09-12 10:03:51 +0200412 return Result(Result::OK, encoded_image.Timestamp());
Noah Richards41ee1ea2015-04-15 09:24:26 -0700413 }
414
415 bool GetLastEncodedImageInfo(int* out_width,
416 int* out_height,
417 int* out_simulcast_index) {
418 if (last_encoded_image_width_ == -1) {
419 return false;
420 }
421 *out_width = last_encoded_image_width_;
422 *out_height = last_encoded_image_height_;
423 *out_simulcast_index = last_encoded_image_simulcast_index_;
424 return true;
425 }
426
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000427 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200428 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200429 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
430 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100431 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 14:57:57 +0200432 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700433 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000434 }
435
436 void VerifyCodec(const VideoCodec& ref, int stream_index) {
437 const VideoCodec& target =
438 helper_->factory()->encoders()[stream_index]->codec();
439 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000440 EXPECT_EQ(ref.plType, target.plType);
441 EXPECT_EQ(ref.width, target.width);
442 EXPECT_EQ(ref.height, target.height);
443 EXPECT_EQ(ref.startBitrate, target.startBitrate);
444 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
445 EXPECT_EQ(ref.minBitrate, target.minBitrate);
446 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700447 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700448 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
449 target.VP8().numberOfTemporalLayers);
450 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700451 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
452 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
453 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000454 EXPECT_EQ(ref.qpMax, target.qpMax);
455 EXPECT_EQ(0, target.numberOfSimulcastStreams);
456 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000457
458 // No need to compare simulcastStream as numberOfSimulcastStreams should
459 // always be 0.
460 }
461
Florent Castelli1b761ca2019-01-21 14:33:02 +0100462 void InitRefCodec(int stream_index,
463 VideoCodec* ref_codec,
464 bool reverse_layer_order = false) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000465 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700466 ref_codec->VP8()->numberOfTemporalLayers =
Florent Castelli1b761ca2019-01-21 14:33:02 +0100467 kTestTemporalLayerProfile[reverse_layer_order ? 2 - stream_index
468 : stream_index];
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000469 ref_codec->width = codec_.simulcastStream[stream_index].width;
470 ref_codec->height = codec_.simulcastStream[stream_index].height;
471 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
472 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
473 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
474 }
475
476 void VerifyCodecSettings() {
477 EXPECT_EQ(3u, helper_->factory()->encoders().size());
478 VideoCodec ref_codec;
479
480 // stream 0, the lowest resolution stream.
481 InitRefCodec(0, &ref_codec);
482 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200483 ref_codec.VP8()->complexity =
484 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700485 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000486 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
487 VerifyCodec(ref_codec, 0);
488
489 // stream 1
490 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700491 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700492 // The start bitrate (300kbit) minus what we have for the lower layers
493 // (100kbit).
494 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000495 VerifyCodec(ref_codec, 1);
496
497 // stream 2, the biggest resolution stream.
498 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700499 // We don't have enough bits to send this, so the adapter should have
500 // configured it to use the min bitrate for this layer (600kbit) but turn
501 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000502 ref_codec.startBitrate = 600;
503 VerifyCodec(ref_codec, 2);
504 }
505
506 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800507 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200508 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000509 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700510 int last_encoded_image_width_;
511 int last_encoded_image_height_;
512 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100513 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
Erik Språngf4e0c292019-10-01 18:50:03 +0200514 bool use_fallback_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000515};
516
517TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
518 SetupCodec();
519 VerifyCodecSettings();
520}
521
brandtr5e171752017-05-23 03:32:16 -0700522TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
523 EXPECT_EQ(0, adapter_->Release());
524}
525
526TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
527 SetupCodec();
528 EXPECT_EQ(0, adapter_->Release());
529
Elad Alon370f93a2019-06-11 14:57:57 +0200530 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700531}
532
Noah Richards41ee1ea2015-04-15 09:24:26 -0700533TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
534 SetupCodec();
535
Peter Boström5d0379d2015-10-06 14:04:51 +0200536 // Set bitrates so that we send all layers.
Erik Språng16cb8f52019-04-12 13:59:09 +0200537 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200538 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
539 30.0));
Peter Boström5d0379d2015-10-06 14:04:51 +0200540
Noah Richards41ee1ea2015-04-15 09:24:26 -0700541 // At this point, the simulcast encoder adapter should have 3 streams: HD,
542 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
543 // resolutions, to test that the adapter forwards on the correct resolution
544 // and simulcast index values, going only off the encoder that generates the
545 // image.
brandtr5e171752017-05-23 03:32:16 -0700546 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
547 ASSERT_EQ(3u, encoders.size());
548 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700549 int width;
550 int height;
551 int simulcast_index;
552 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
553 EXPECT_EQ(1152, width);
554 EXPECT_EQ(704, height);
555 EXPECT_EQ(0, simulcast_index);
556
brandtr5e171752017-05-23 03:32:16 -0700557 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700558 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
559 EXPECT_EQ(300, width);
560 EXPECT_EQ(620, height);
561 EXPECT_EQ(1, simulcast_index);
562
brandtr5e171752017-05-23 03:32:16 -0700563 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700564 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
565 EXPECT_EQ(120, width);
566 EXPECT_EQ(240, height);
567 EXPECT_EQ(2, simulcast_index);
568}
569
brandtr5e171752017-05-23 03:32:16 -0700570// This test verifies that the underlying encoders are reused, when the adapter
571// is reinited with different number of simulcast streams. It further checks
572// that the allocated encoders are reused in the same order as before, starting
573// with the lowest stream.
574TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
575 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200576 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200577 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
578 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100579 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700580 adapter_->RegisterEncodeCompleteCallback(this);
Erik Språng7d687b12018-09-12 17:04:10 +0200581 const uint32_t target_bitrate =
582 1000 * (codec_.simulcastStream[0].targetBitrate +
583 codec_.simulcastStream[1].targetBitrate +
584 codec_.simulcastStream[2].minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700585
586 // Input data.
587 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100588 VideoFrame input_frame = VideoFrame::Builder()
589 .set_video_frame_buffer(buffer)
590 .set_timestamp_rtp(100)
591 .set_timestamp_ms(1000)
592 .set_rotation(kVideoRotation_180)
593 .build();
Niels Möller87e2d782019-03-07 10:18:23 +0100594 std::vector<VideoFrameType> frame_types;
brandtr5e171752017-05-23 03:32:16 -0700595
596 // Encode with three streams.
Elad Alon370f93a2019-06-11 14:57:57 +0200597 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700598 VerifyCodecSettings();
Erik Språng16cb8f52019-04-12 13:59:09 +0200599 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200600 rate_allocator_->Allocate(
601 VideoBitrateAllocationParameters(target_bitrate, 30)),
602 30.0));
Erik Språng7d687b12018-09-12 17:04:10 +0200603
brandtr5e171752017-05-23 03:32:16 -0700604 std::vector<MockVideoEncoder*> original_encoders =
605 helper_->factory()->encoders();
606 ASSERT_EQ(3u, original_encoders.size());
Niels Möllerb859b322019-03-07 12:40:01 +0100607 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700608 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100609 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700610 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100611 EXPECT_CALL(*original_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700612 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100613 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100614 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700615 EXPECT_CALL(*original_encoders[0], Release())
616 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
617 EXPECT_CALL(*original_encoders[1], Release())
618 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
619 EXPECT_CALL(*original_encoders[2], Release())
620 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
621 EXPECT_EQ(0, adapter_->Release());
622
623 // Encode with two streams.
624 codec_.width /= 2;
625 codec_.height /= 2;
626 codec_.numberOfSimulcastStreams = 2;
Elad Alon370f93a2019-06-11 14:57:57 +0200627 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200628 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200629 rate_allocator_->Allocate(
630 VideoBitrateAllocationParameters(target_bitrate, 30)),
631 30.0));
brandtr5e171752017-05-23 03:32:16 -0700632 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
633 ASSERT_EQ(2u, new_encoders.size());
634 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100635 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700636 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
637 ASSERT_EQ(original_encoders[1], new_encoders[1]);
Niels Möllerb859b322019-03-07 12:40:01 +0100638 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700639 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100640 frame_types.resize(2, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100641 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700642 EXPECT_CALL(*original_encoders[0], Release())
643 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
644 EXPECT_CALL(*original_encoders[1], Release())
645 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
646 EXPECT_EQ(0, adapter_->Release());
647
648 // Encode with single stream.
649 codec_.width /= 2;
650 codec_.height /= 2;
651 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200652 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200653 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200654 rate_allocator_->Allocate(
655 VideoBitrateAllocationParameters(target_bitrate, 30)),
656 30.0));
brandtr5e171752017-05-23 03:32:16 -0700657 new_encoders = helper_->factory()->encoders();
658 ASSERT_EQ(1u, new_encoders.size());
659 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100660 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700661 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100662 frame_types.resize(1, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100663 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700664 EXPECT_CALL(*original_encoders[0], Release())
665 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
666 EXPECT_EQ(0, adapter_->Release());
667
668 // Encode with three streams, again.
669 codec_.width *= 4;
670 codec_.height *= 4;
671 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200672 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200673 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200674 rate_allocator_->Allocate(
675 VideoBitrateAllocationParameters(target_bitrate, 30)),
676 30.0));
brandtr5e171752017-05-23 03:32:16 -0700677 new_encoders = helper_->factory()->encoders();
678 ASSERT_EQ(3u, new_encoders.size());
679 // The first encoder is reused.
680 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100681 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700682 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
683 // The second and third encoders are new.
Niels Möllerb859b322019-03-07 12:40:01 +0100684 EXPECT_CALL(*new_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700685 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100686 EXPECT_CALL(*new_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700687 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100688 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100689 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700690 EXPECT_CALL(*original_encoders[0], Release())
691 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
692 EXPECT_CALL(*new_encoders[1], Release())
693 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
694 EXPECT_CALL(*new_encoders[2], Release())
695 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
696 EXPECT_EQ(0, adapter_->Release());
697}
698
699TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
700 SetupCodec();
701 VerifyCodecSettings();
702
703 EXPECT_EQ(3u, helper_->factory()->encoders().size());
704
705 // The adapter should destroy all encoders it has allocated. Since
706 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
707 // lsan to find leaks here.
708 EXPECT_EQ(0, adapter_->Release());
709 adapter_.reset();
710}
711
712// This test verifies that an adapter reinit with the same codec settings as
713// before does not change the underlying encoder codec settings.
714TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
715 SetupCodec();
716 VerifyCodecSettings();
717
718 // Capture current codec settings.
719 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
720 ASSERT_EQ(3u, encoders.size());
721 std::array<VideoCodec, 3> codecs_before;
722 for (int i = 0; i < 3; ++i) {
723 codecs_before[i] = encoders[i]->codec();
724 }
725
726 // Reinitialize and verify that the new codec settings are the same.
727 EXPECT_EQ(0, adapter_->Release());
Elad Alon370f93a2019-06-11 14:57:57 +0200728 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700729 for (int i = 0; i < 3; ++i) {
730 const VideoCodec& codec_before = codecs_before[i];
731 const VideoCodec& codec_after = encoders[i]->codec();
732
733 // webrtc::VideoCodec does not implement operator==.
734 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
735 EXPECT_EQ(codec_before.plType, codec_after.plType);
736 EXPECT_EQ(codec_before.width, codec_after.width);
737 EXPECT_EQ(codec_before.height, codec_after.height);
738 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
739 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
740 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700741 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
742 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
743 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
744 codec_after.numberOfSimulcastStreams);
745 EXPECT_EQ(codec_before.mode, codec_after.mode);
746 EXPECT_EQ(codec_before.expect_encode_from_texture,
747 codec_after.expect_encode_from_texture);
748 }
749}
750
751// This test is similar to the one above, except that it tests the simulcastIdx
752// from the CodecSpecificInfo that is connected to an encoded frame. The
753// PayloadRouter demuxes the incoming encoded frames on different RTP modules
754// using the simulcastIdx, so it's important that there is no corresponding
755// encoder reordering in between adapter reinits as this would lead to PictureID
756// discontinuities.
757TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
758 SetupCodec();
Erik Språng16cb8f52019-04-12 13:59:09 +0200759 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200760 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
761 30.0));
brandtr5e171752017-05-23 03:32:16 -0700762 VerifyCodecSettings();
763
764 // Send frames on all streams.
765 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
766 ASSERT_EQ(3u, encoders.size());
767 encoders[0]->SendEncodedImage(1152, 704);
768 int width;
769 int height;
770 int simulcast_index;
771 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
772 EXPECT_EQ(0, simulcast_index);
773
774 encoders[1]->SendEncodedImage(300, 620);
775 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
776 EXPECT_EQ(1, simulcast_index);
777
778 encoders[2]->SendEncodedImage(120, 240);
779 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
780 EXPECT_EQ(2, simulcast_index);
781
782 // Reinitialize.
783 EXPECT_EQ(0, adapter_->Release());
Elad Alon370f93a2019-06-11 14:57:57 +0200784 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200785 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200786 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
787 30.0));
brandtr5e171752017-05-23 03:32:16 -0700788
789 // Verify that the same encoder sends out frames on the same simulcast index.
790 encoders[0]->SendEncodedImage(1152, 704);
791 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
792 EXPECT_EQ(0, simulcast_index);
793
794 encoders[1]->SendEncodedImage(300, 620);
795 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
796 EXPECT_EQ(1, simulcast_index);
797
798 encoders[2]->SendEncodedImage(120, 240);
799 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
800 EXPECT_EQ(2, simulcast_index);
801}
802
pbos65e15ba2015-10-15 10:52:15 -0700803TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200804 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200805 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
806 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700807 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200808 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700809 adapter_->RegisterEncodeCompleteCallback(this);
810 ASSERT_EQ(1u, helper_->factory()->encoders().size());
811 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200812 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200813 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700814 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Elad Alon370f93a2019-06-11 14:57:57 +0200815 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200816 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700817}
818
noahricfac0ff02016-09-09 10:27:15 -0700819TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200820 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200821 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
822 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700823 codec_.minBitrate = 50;
824 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200825 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng82fad3d2018-03-21 09:57:23 +0100826 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700827
828 // Above min should be respected.
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200829 VideoBitrateAllocation target_bitrate = rate_allocator_->Allocate(
830 VideoBitrateAllocationParameters(codec_.minBitrate * 1000, 30));
Erik Språng16cb8f52019-04-12 13:59:09 +0200831 adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100832 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200833 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700834
835 // Below min but non-zero should be replaced with the min bitrate.
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200836 VideoBitrateAllocation too_low_bitrate = rate_allocator_->Allocate(
837 VideoBitrateAllocationParameters((codec_.minBitrate - 1) * 1000, 30));
Erik Språng16cb8f52019-04-12 13:59:09 +0200838 adapter_->SetRates(
839 VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100840 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200841 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700842
843 // Zero should be passed on as is, since it means "pause".
Erik Språng16cb8f52019-04-12 13:59:09 +0200844 adapter_->SetRates(
845 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
Erik Språng566124a2018-04-23 12:32:22 +0200846 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng16cb8f52019-04-12 13:59:09 +0200847 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700848}
849
Peter Boströma5dec162016-01-20 15:53:55 +0100850TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
Erik Språnge2fd86a2018-10-24 11:32:39 +0200851 EXPECT_EQ("SimulcastEncoderAdapter",
852 adapter_->GetEncoderInfo().implementation_name);
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200853 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200854 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
855 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100856 std::vector<const char*> encoder_names;
857 encoder_names.push_back("codec1");
858 encoder_names.push_back("codec2");
859 encoder_names.push_back("codec3");
860 helper_->factory()->SetEncoderNames(encoder_names);
Elad Alon370f93a2019-06-11 14:57:57 +0200861 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200862 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
863 adapter_->GetEncoderInfo().implementation_name);
Peter Boströmd53c3892016-03-30 17:03:52 +0200864
865 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700866 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200867 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200868 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Peter Boströmd53c3892016-03-30 17:03:52 +0200869 adapter_->RegisterEncodeCompleteCallback(this);
870 ASSERT_EQ(1u, helper_->factory()->encoders().size());
Erik Språnge2fd86a2018-10-24 11:32:39 +0200871 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
Peter Boströma5dec162016-01-20 15:53:55 +0100872}
873
pbos65e15ba2015-10-15 10:52:15 -0700874TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700875 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200876 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200877 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
878 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700879 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200880 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700881 adapter_->RegisterEncodeCompleteCallback(this);
882 ASSERT_EQ(3u, helper_->factory()->encoders().size());
883 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
884 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700885 // If one encoder doesn't support it, then overall support is disabled.
886 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språnge2fd86a2018-10-24 11:32:39 +0200887 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700888 // Once all do, then the adapter claims support.
889 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200890 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200891 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700892}
893
nisseaf916892017-01-10 07:44:26 -0800894// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200895class FakeNativeBufferNoI420 : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700896 public:
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200897 FakeNativeBufferNoI420(int width, int height)
898 : width_(width), height_(height) {}
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000899
900 Type type() const override { return Type::kNative; }
901 int width() const override { return width_; }
902 int height() const override { return height_; }
903
904 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700905 RTC_NOTREACHED();
906 return nullptr;
907 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000908
909 private:
910 const int width_;
911 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700912};
913
914TEST_F(TestSimulcastEncoderAdapterFake,
915 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200916 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200917 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
918 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700919 codec_.numberOfSimulcastStreams = 3;
920 // High start bitrate, so all streams are enabled.
921 codec_.startBitrate = 3000;
Elad Alon370f93a2019-06-11 14:57:57 +0200922 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahricfe3654d2016-07-01 09:05:54 -0700923 adapter_->RegisterEncodeCompleteCallback(this);
924 ASSERT_EQ(3u, helper_->factory()->encoders().size());
925 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
926 encoder->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200927 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200928 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700929
930 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200931 new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100932 VideoFrame input_frame = VideoFrame::Builder()
933 .set_video_frame_buffer(buffer)
934 .set_timestamp_rtp(100)
935 .set_timestamp_ms(1000)
936 .set_rotation(kVideoRotation_180)
937 .build();
noahricfe3654d2016-07-01 09:05:54 -0700938 // Expect calls with the given video frame verbatim, since it's a texture
939 // frame and can't otherwise be modified/resized.
940 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
Niels Möllerb859b322019-03-07 12:40:01 +0100941 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _)).Times(1);
Niels Möller8f7ce222019-03-21 15:43:58 +0100942 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100943 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700944}
945
noahric57779102016-05-25 06:48:46 -0700946TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200947 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200948 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
949 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700950 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200951 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahric57779102016-05-25 06:48:46 -0700952 adapter_->RegisterEncodeCompleteCallback(this);
953 ASSERT_EQ(3u, helper_->factory()->encoders().size());
954 // Tell the 2nd encoder to request software fallback.
Niels Möllerb859b322019-03-07 12:40:01 +0100955 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _))
noahricfe3654d2016-07-01 09:05:54 -0700956 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700957
958 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000959 rtc::scoped_refptr<I420Buffer> input_buffer =
960 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700961 input_buffer->InitializeData();
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100962 VideoFrame input_frame = VideoFrame::Builder()
963 .set_video_frame_buffer(input_buffer)
964 .set_timestamp_rtp(0)
965 .set_timestamp_us(0)
966 .set_rotation(kVideoRotation_0)
967 .build();
Niels Möller8f7ce222019-03-21 15:43:58 +0100968 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
noahric57779102016-05-25 06:48:46 -0700969 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Niels Möllerc8d2e732019-03-06 12:00:33 +0100970 adapter_->Encode(input_frame, &frame_types));
noahric57779102016-05-25 06:48:46 -0700971}
972
noahrice5ba75a2016-12-12 13:08:27 -0800973TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200974 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200975 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
976 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800977 codec_.numberOfSimulcastStreams = 3;
978 helper_->factory()->set_init_encode_return_value(
979 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
980 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Elad Alon370f93a2019-06-11 14:57:57 +0200981 adapter_->InitEncode(&codec_, kSettings));
noahrice5ba75a2016-12-12 13:08:27 -0800982 EXPECT_TRUE(helper_->factory()->encoders().empty());
983}
984
Erik Språng8d2995b2018-08-09 11:18:17 +0200985TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
986 const int kHighMaxQp = 56;
987 const int kLowMaxQp = 46;
988
989 SimulcastTestFixtureImpl::DefaultSettings(
990 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
991 kVideoCodecVP8);
992 codec_.numberOfSimulcastStreams = 3;
993 codec_.simulcastStream[0].qpMax = kHighMaxQp;
994 codec_.mode = VideoCodecMode::kScreensharing;
995
Elad Alon370f93a2019-06-11 14:57:57 +0200996 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200997 EXPECT_EQ(3u, helper_->factory()->encoders().size());
998
999 // Just check the lowest stream, which is the one that where the adapter
1000 // might alter the max qp setting.
1001 VideoCodec ref_codec;
1002 InitRefCodec(0, &ref_codec);
1003 ref_codec.qpMax = kHighMaxQp;
1004 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1005 ref_codec.VP8()->denoisingOn = false;
1006 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1007 VerifyCodec(ref_codec, 0);
1008
1009 // Change the max qp and try again.
1010 codec_.simulcastStream[0].qpMax = kLowMaxQp;
Elad Alon370f93a2019-06-11 14:57:57 +02001011 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +02001012 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1013 ref_codec.qpMax = kLowMaxQp;
1014 VerifyCodec(ref_codec, 0);
1015}
Erik Språng7d687b12018-09-12 17:04:10 +02001016
Florent Castelli1b761ca2019-01-21 14:33:02 +01001017TEST_F(TestSimulcastEncoderAdapterFake,
1018 DoesNotAlterMaxQpForScreenshareReversedLayer) {
1019 const int kHighMaxQp = 56;
1020 const int kLowMaxQp = 46;
1021
1022 SimulcastTestFixtureImpl::DefaultSettings(
1023 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1024 kVideoCodecVP8, true /* reverse_layer_order */);
1025 codec_.numberOfSimulcastStreams = 3;
1026 codec_.simulcastStream[2].qpMax = kHighMaxQp;
1027 codec_.mode = VideoCodecMode::kScreensharing;
1028
Elad Alon370f93a2019-06-11 14:57:57 +02001029 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001030 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1031
1032 // Just check the lowest stream, which is the one that where the adapter
1033 // might alter the max qp setting.
1034 VideoCodec ref_codec;
1035 InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
1036 ref_codec.qpMax = kHighMaxQp;
1037 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1038 ref_codec.VP8()->denoisingOn = false;
1039 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1040 VerifyCodec(ref_codec, 2);
1041
1042 // Change the max qp and try again.
1043 codec_.simulcastStream[2].qpMax = kLowMaxQp;
Elad Alon370f93a2019-06-11 14:57:57 +02001044 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001045 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1046 ref_codec.qpMax = kLowMaxQp;
1047 VerifyCodec(ref_codec, 2);
1048}
1049
Erik Språng7d687b12018-09-12 17:04:10 +02001050TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
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ång7d687b12018-09-12 17:04:10 +02001071
1072 // Encode with three streams.
Elad Alon370f93a2019-06-11 14:57:57 +02001073 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng7d687b12018-09-12 17:04:10 +02001074 std::vector<MockVideoEncoder*> original_encoders =
1075 helper_->factory()->encoders();
1076 ASSERT_EQ(3u, original_encoders.size());
1077 // Only first encoder will be active and called.
Niels Möllerb859b322019-03-07 12:40:01 +01001078 EXPECT_CALL(*original_encoders[0], Encode(_, _))
Erik Språng7d687b12018-09-12 17:04:10 +02001079 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +01001080 EXPECT_CALL(*original_encoders[1], Encode(_, _)).Times(0);
1081 EXPECT_CALL(*original_encoders[2], Encode(_, _)).Times(0);
Erik Språng7d687b12018-09-12 17:04:10 +02001082
Niels Möller87e2d782019-03-07 10:18:23 +01001083 std::vector<VideoFrameType> frame_types;
Niels Möller8f7ce222019-03-21 15:43:58 +01001084 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +01001085 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
Erik Språng7d687b12018-09-12 17:04:10 +02001086}
Erik Språngd3438aa2018-11-08 16:56:43 +01001087
1088TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
1089 // Set up common settings for three streams.
1090 SimulcastTestFixtureImpl::DefaultSettings(
1091 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1092 kVideoCodecVP8);
1093 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1094 adapter_->RegisterEncodeCompleteCallback(this);
1095
1096 // Only enough start bitrate for the lowest stream.
1097 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1098 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1099 codec_.simulcastStream[1].minBitrate - 1;
1100
1101 // Input data.
1102 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001103 VideoFrame input_frame = VideoFrame::Builder()
1104 .set_video_frame_buffer(buffer)
1105 .set_timestamp_rtp(100)
1106 .set_timestamp_ms(1000)
1107 .set_rotation(kVideoRotation_180)
1108 .build();
Erik Språngd3438aa2018-11-08 16:56:43 +01001109
1110 // No encoder trusted, so simulcast adapter should not be either.
Elad Alon370f93a2019-06-11 14:57:57 +02001111 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001112 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1113
1114 // Encode with three streams.
1115 std::vector<MockVideoEncoder*> original_encoders =
1116 helper_->factory()->encoders();
1117
1118 // All encoders are trusted, so simulcast adapter should be too.
1119 original_encoders[0]->set_has_trusted_rate_controller(true);
1120 original_encoders[1]->set_has_trusted_rate_controller(true);
1121 original_encoders[2]->set_has_trusted_rate_controller(true);
Elad Alon370f93a2019-06-11 14:57:57 +02001122 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001123 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1124
1125 // One encoder not trusted, so simulcast adapter should not be either.
1126 original_encoders[2]->set_has_trusted_rate_controller(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001127 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001128 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1129
1130 // No encoder trusted, so simulcast adapter should not be either.
1131 original_encoders[0]->set_has_trusted_rate_controller(false);
1132 original_encoders[1]->set_has_trusted_rate_controller(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001133 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001134 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1135}
1136
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001137TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1138 SimulcastTestFixtureImpl::DefaultSettings(
1139 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1140 kVideoCodecVP8);
1141 codec_.numberOfSimulcastStreams = 3;
1142 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001143 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001144 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1145
1146 // None of the encoders uses HW support, so simulcast adapter reports false.
1147 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1148 encoder->set_is_hardware_accelerated(false);
1149 }
Elad Alon370f93a2019-06-11 14:57:57 +02001150 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001151 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1152
1153 // One encoder uses HW support, so simulcast adapter reports true.
1154 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
Elad Alon370f93a2019-06-11 14:57:57 +02001155 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001156 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1157}
1158
1159TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1160 SimulcastTestFixtureImpl::DefaultSettings(
1161 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1162 kVideoCodecVP8);
1163 codec_.numberOfSimulcastStreams = 3;
1164 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001165 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001166 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1167
1168 // All encoders have internal source, simulcast adapter reports true.
1169 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1170 encoder->set_has_internal_source(true);
1171 }
Elad Alon370f93a2019-06-11 14:57:57 +02001172 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001173 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1174
1175 // One encoder does not have internal source, simulcast adapter reports false.
1176 helper_->factory()->encoders()[2]->set_has_internal_source(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001177 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001178 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1179}
1180
Erik Språngdbdd8392019-01-17 15:27:50 +01001181TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
1182 SimulcastTestFixtureImpl::DefaultSettings(
1183 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1184 kVideoCodecVP8);
1185 codec_.numberOfSimulcastStreams = 3;
1186 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001187 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001188 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1189
1190 // Combination of three different supported mode:
1191 // Simulcast stream 0 has undefined fps behavior.
1192 // Simulcast stream 1 has three temporal layers.
1193 // Simulcast stream 2 has 1 temporal layer.
1194 FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
1195 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 4);
1196 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 2);
1197 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction);
1198 expected_fps_allocation[2].push_back(EncoderInfo::kMaxFramerateFraction);
1199
1200 // All encoders have internal source, simulcast adapter reports true.
1201 for (size_t i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
1202 MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
1203 encoder->set_fps_allocation(expected_fps_allocation[i]);
1204 }
Elad Alon370f93a2019-06-11 14:57:57 +02001205 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001206 EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
1207 ::testing::ElementsAreArray(expected_fps_allocation));
1208}
1209
Erik Språng16cb8f52019-04-12 13:59:09 +02001210TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
1211 SimulcastTestFixtureImpl::DefaultSettings(
1212 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1213 kVideoCodecVP8);
1214 codec_.numberOfSimulcastStreams = 3;
1215 const DataRate target_bitrate =
1216 DataRate::kbps(codec_.simulcastStream[0].targetBitrate +
1217 codec_.simulcastStream[1].targetBitrate +
1218 codec_.simulcastStream[2].minBitrate);
1219 const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
1220
1221 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 14:57:57 +02001222 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +02001223 adapter_->RegisterEncodeCompleteCallback(this);
1224
1225 // Set bitrates so that we send all layers.
1226 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +02001227 rate_allocator_->Allocate(
1228 VideoBitrateAllocationParameters(target_bitrate.bps(), 30)),
1229 30.0, bandwidth_allocation));
Erik Språng16cb8f52019-04-12 13:59:09 +02001230
1231 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1232
1233 ASSERT_EQ(3u, encoders.size());
1234
1235 for (size_t i = 0; i < 3; ++i) {
1236 const uint32_t layer_bitrate_bps =
1237 (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
1238 ? codec_.simulcastStream[i].targetBitrate
1239 : codec_.simulcastStream[i].minBitrate) *
1240 1000;
1241 EXPECT_EQ(layer_bitrate_bps,
1242 encoders[i]->last_set_rates().bitrate.get_sum_bps())
1243 << i;
1244 EXPECT_EQ(
1245 (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
1246 encoders[i]->last_set_rates().bandwidth_allocation.bps())
1247 << i;
1248 }
1249}
1250
Erik Språngf4e0c292019-10-01 18:50:03 +02001251TEST_F(TestSimulcastEncoderAdapterFake, SupportsSimulcast) {
1252 SimulcastTestFixtureImpl::DefaultSettings(
1253 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1254 kVideoCodecVP8);
1255 codec_.numberOfSimulcastStreams = 3;
1256
1257 // Indicate that mock encoders internally support simulcast.
1258 helper_->factory()->set_supports_simulcast(true);
1259 adapter_->RegisterEncodeCompleteCallback(this);
1260 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1261
1262 // Only one encoder should have been produced.
1263 ASSERT_EQ(1u, helper_->factory()->encoders().size());
1264
1265 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
1266 VideoFrame input_frame = VideoFrame::Builder()
1267 .set_video_frame_buffer(buffer)
1268 .set_timestamp_rtp(100)
1269 .set_timestamp_ms(1000)
1270 .set_rotation(kVideoRotation_180)
1271 .build();
1272 EXPECT_CALL(*helper_->factory()->encoders()[0], Encode)
1273 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1274 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
1275 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1276}
1277
1278TEST_F(TestSimulcastEncoderAdapterFake, SupportsFallback) {
1279 // Enable support for fallback encoder factory and re-setup.
1280 use_fallback_factory_ = true;
1281 SetUp();
1282
1283 SetupCodec();
1284
1285 // Make sure we have bitrate for all layers.
1286 DataRate max_bitrate = DataRate::Zero();
1287 for (int i = 0; i < 3; ++i) {
1288 max_bitrate += DataRate::kbps(codec_.simulcastStream[i].maxBitrate);
1289 }
1290 const auto rate_settings = VideoEncoder::RateControlParameters(
1291 rate_allocator_->Allocate(
1292 VideoBitrateAllocationParameters(max_bitrate.bps(), 30)),
1293 30.0, max_bitrate);
1294 adapter_->SetRates(rate_settings);
1295
1296 std::vector<MockVideoEncoder*> primary_encoders =
1297 helper_->factory()->encoders();
1298 std::vector<MockVideoEncoder*> fallback_encoders =
1299 helper_->fallback_factory()->encoders();
1300
1301 ASSERT_EQ(3u, primary_encoders.size());
1302 ASSERT_EQ(3u, fallback_encoders.size());
1303
1304 // Create frame to test with.
1305 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
1306 VideoFrame input_frame = VideoFrame::Builder()
1307 .set_video_frame_buffer(buffer)
1308 .set_timestamp_rtp(100)
1309 .set_timestamp_ms(1000)
1310 .set_rotation(kVideoRotation_180)
1311 .build();
1312 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
1313
1314 // All primary encoders used.
1315 for (auto codec : primary_encoders) {
1316 EXPECT_CALL(*codec, Encode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1317 }
1318 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1319
1320 // Trigger fallback on first encoder.
1321 primary_encoders[0]->set_init_encode_return_value(
1322 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1323 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1324 adapter_->SetRates(rate_settings);
1325 EXPECT_CALL(*fallback_encoders[0], Encode)
1326 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1327 EXPECT_CALL(*primary_encoders[1], Encode)
1328 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1329 EXPECT_CALL(*primary_encoders[2], Encode)
1330 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1331 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1332
1333 // Trigger fallback on all encoder.
1334 primary_encoders[1]->set_init_encode_return_value(
1335 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1336 primary_encoders[2]->set_init_encode_return_value(
1337 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
1338 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1339 adapter_->SetRates(rate_settings);
1340 EXPECT_CALL(*fallback_encoders[0], Encode)
1341 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1342 EXPECT_CALL(*fallback_encoders[1], Encode)
1343 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1344 EXPECT_CALL(*fallback_encoders[2], Encode)
1345 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1346 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1347
1348 // Return to primary encoders on all streams.
1349 for (int i = 0; i < 3; ++i) {
1350 primary_encoders[i]->set_init_encode_return_value(WEBRTC_VIDEO_CODEC_OK);
1351 }
1352 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
1353 adapter_->SetRates(rate_settings);
1354 for (auto codec : primary_encoders) {
1355 EXPECT_CALL(*codec, Encode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
1356 }
1357 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
1358}
1359
Rasmus Brandt0cedc052018-05-31 12:53:00 +02001360} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001361} // namespace webrtc