blob: 1bab49af8a67bdd2e06fe28b3255910b1e1a8530 [file] [log] [blame]
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001/*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
brandtr5e171752017-05-23 03:32:16 -070011#include <array>
kwiberg3f55dea2016-02-29 05:51:59 -080012#include <memory>
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000013#include <vector>
14
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#include "absl/memory/memory.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020016#include "api/test/create_simulcast_test_fixture.h"
17#include "api/test/simulcast_test_fixture.h"
Danil Chapovalov99b71df2018-10-26 15:57:48 +020018#include "api/test/video/function_video_decoder_factory.h"
19#include "api/test/video/function_video_encoder_factory.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010020#include "api/video_codecs/sdp_video_format.h"
21#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "common_video/include/video_frame_buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "media/base/media_constants.h"
24#include "media/engine/internal_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "media/engine/simulcast_encoder_adapter.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020026#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "modules/video_coding/include/video_codec_interface.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020028#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020030#include "test/gtest.h"
31
32using ::testing::_;
33using ::testing::Return;
Erik Språngdbdd8392019-01-17 15:27:50 +010034using EncoderInfo = webrtc::VideoEncoder::EncoderInfo;
35using FramerateFractions =
36 absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000037
38namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020039namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000040
Rasmus Brandt0cedc052018-05-31 12:53:00 +020041namespace {
philipelcce46fc2015-12-21 03:04:49 -080042
Rasmus Brandt0cedc052018-05-31 12:53:00 +020043constexpr int kDefaultWidth = 1280;
44constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070045
Rasmus Brandt0cedc052018-05-31 12:53:00 +020046std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
47 VideoEncoderFactory* internal_encoder_factory) {
48 std::unique_ptr<VideoEncoderFactory> encoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020049 absl::make_unique<FunctionVideoEncoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020050 [internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +020051 return absl::make_unique<SimulcastEncoderAdapter>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020052 internal_encoder_factory,
53 SdpVideoFormat(cricket::kVp8CodecName));
54 });
55 std::unique_ptr<VideoDecoderFactory> decoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020056 absl::make_unique<FunctionVideoDecoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020057 []() { return VP8Decoder::Create(); });
58 return CreateSimulcastTestFixture(std::move(encoder_factory),
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020059 std::move(decoder_factory),
60 SdpVideoFormat(cricket::kVp8CodecName));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000061}
Rasmus Brandt0cedc052018-05-31 12:53:00 +020062} // namespace
63
64TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
65 InternalEncoderFactory internal_encoder_factory;
66 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
67 fixture->TestKeyFrameRequestsOnAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000068}
69
Rasmus Brandt0cedc052018-05-31 12:53:00 +020070TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
71 InternalEncoderFactory internal_encoder_factory;
72 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
73 fixture->TestPaddingAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000074}
75
Rasmus Brandt0cedc052018-05-31 12:53:00 +020076TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
77 InternalEncoderFactory internal_encoder_factory;
78 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
79 fixture->TestPaddingTwoStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000080}
81
Rasmus Brandt0cedc052018-05-31 12:53:00 +020082TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
83 InternalEncoderFactory internal_encoder_factory;
84 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
85 fixture->TestPaddingTwoStreamsOneMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000086}
87
Rasmus Brandt0cedc052018-05-31 12:53:00 +020088TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
89 InternalEncoderFactory internal_encoder_factory;
90 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
91 fixture->TestPaddingOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000092}
93
Rasmus Brandt0cedc052018-05-31 12:53:00 +020094TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
95 InternalEncoderFactory internal_encoder_factory;
96 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
97 fixture->TestPaddingOneStreamTwoMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000098}
99
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200100TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
101 InternalEncoderFactory internal_encoder_factory;
102 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
103 fixture->TestSendAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000104}
105
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200106TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
107 InternalEncoderFactory internal_encoder_factory;
108 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
109 fixture->TestDisablingStreams();
Seth Hampson46e31ba2018-01-18 10:39:54 -0800110}
111
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200112TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
113 InternalEncoderFactory internal_encoder_factory;
114 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
115 fixture->TestActiveStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000116}
117
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200118TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
119 InternalEncoderFactory internal_encoder_factory;
120 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
121 fixture->TestSwitchingToOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000122}
123
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200124TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
125 InternalEncoderFactory internal_encoder_factory;
126 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
127 fixture->TestSwitchingToOneOddStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000128}
129
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200130TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
131 InternalEncoderFactory internal_encoder_factory;
132 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
133 fixture->TestStrideEncodeDecode();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000134}
135
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200136TEST(SimulcastEncoderAdapterSimulcastTest,
137 TestSpatioTemporalLayers333PatternEncoder) {
138 InternalEncoderFactory internal_encoder_factory;
139 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
140 fixture->TestSpatioTemporalLayers333PatternEncoder();
141}
142
143TEST(SimulcastEncoderAdapterSimulcastTest,
144 TestSpatioTemporalLayers321PatternEncoder) {
145 InternalEncoderFactory internal_encoder_factory;
146 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
147 fixture->TestSpatioTemporalLayers321PatternEncoder();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000148}
149
Per Kjellander841c9122018-10-04 18:40:28 +0200150TEST(SimulcastEncoderAdapterSimulcastTest, TestDecodeWidthHeightSet) {
151 InternalEncoderFactory internal_encoder_factory;
152 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
153 fixture->TestDecodeWidthHeightSet();
154}
155
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100156class MockVideoEncoder;
157
158class MockVideoEncoderFactory : public VideoEncoderFactory {
159 public:
160 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
161
162 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
163 const SdpVideoFormat& format) override;
164
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000165 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
166
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100167 const std::vector<MockVideoEncoder*>& encoders() const;
168 void SetEncoderNames(const std::vector<const char*>& encoder_names);
169 void set_init_encode_return_value(int32_t value);
170
171 void DestroyVideoEncoder(VideoEncoder* encoder);
172
173 private:
174 int32_t init_encode_return_value_ = 0;
175 std::vector<MockVideoEncoder*> encoders_;
176 std::vector<const char*> encoder_names_;
177};
178
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000179class MockVideoEncoder : public VideoEncoder {
180 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100181 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng75de46a2018-11-07 14:53:32 +0100182 : factory_(factory),
183 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
184 callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100185
nisseef8b61e2016-04-29 06:09:15 -0700186 // TODO(nisse): Valid overrides commented out, because the gmock
187 // methods don't use any override declarations, and we want to avoid
188 // warnings from -Winconsistent-missing-override. See
189 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000190 int32_t InitEncode(const VideoCodec* codecSettings,
191 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700192 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000193 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800194 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000195 }
196
Niels Möllerb859b322019-03-07 12:40:01 +0100197 MOCK_METHOD2(
noahricfe3654d2016-07-01 09:05:54 -0700198 Encode,
199 int32_t(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +0100200 const std::vector<VideoFrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000201
pbos65e15ba2015-10-15 10:52:15 -0700202 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700203 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700204 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000205 return 0;
206 }
207
brandtr5e171752017-05-23 03:32:16 -0700208 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000209
Erik Språng16cb8f52019-04-12 13:59:09 +0200210 void SetRates(const RateControlParameters& parameters) {
211 last_set_rates_ = parameters;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000212 }
213
Erik Språng9b5b0702018-11-01 14:52:30 +0100214 EncoderInfo GetEncoderInfo() const override {
215 EncoderInfo info;
216 info.supports_native_handle = supports_native_handle_;
217 info.implementation_name = implementation_name_;
Erik Språng75de46a2018-11-07 14:53:32 +0100218 info.scaling_settings = scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100219 info.has_trusted_rate_controller = has_trusted_rate_controller_;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100220 info.is_hardware_accelerated = is_hardware_accelerated_;
221 info.has_internal_source = has_internal_source_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100222 info.fps_allocation[0] = fps_allocation_;
Erik Språng9b5b0702018-11-01 14:52:30 +0100223 return info;
nisseef8b61e2016-04-29 06:09:15 -0700224 }
pbos65e15ba2015-10-15 10:52:15 -0700225
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100226 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000227
228 const VideoCodec& codec() const { return codec_; }
229
Noah Richards41ee1ea2015-04-15 09:24:26 -0700230 void SendEncodedImage(int width, int height) {
231 // Sends a fake image of the given width/height.
232 EncodedImage image;
233 image._encodedWidth = width;
234 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700235 CodecSpecificInfo codec_specific_info;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200236 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700237 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700238 }
239
pbos65e15ba2015-10-15 10:52:15 -0700240 void set_supports_native_handle(bool enabled) {
241 supports_native_handle_ = enabled;
242 }
noahrice5ba75a2016-12-12 13:08:27 -0800243
Erik Språng9b5b0702018-11-01 14:52:30 +0100244 void set_implementation_name(const std::string& name) {
245 implementation_name_ = name;
246 }
247
noahrice5ba75a2016-12-12 13:08:27 -0800248 void set_init_encode_return_value(int32_t value) {
249 init_encode_return_value_ = value;
250 }
251
Erik Språng75de46a2018-11-07 14:53:32 +0100252 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
253 scaling_settings_ = settings;
254 }
255
Erik Språngd3438aa2018-11-08 16:56:43 +0100256 void set_has_trusted_rate_controller(bool trusted) {
257 has_trusted_rate_controller_ = trusted;
258 }
259
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100260 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
261 is_hardware_accelerated_ = is_hardware_accelerated;
262 }
263
264 void set_has_internal_source(bool has_internal_source) {
265 has_internal_source_ = has_internal_source;
266 }
267
Erik Språngdbdd8392019-01-17 15:27:50 +0100268 void set_fps_allocation(const FramerateFractions& fps_allocation) {
269 fps_allocation_ = fps_allocation;
270 }
271
Erik Språng16cb8f52019-04-12 13:59:09 +0200272 RateControlParameters last_set_rates() const { return last_set_rates_; }
pbos65e15ba2015-10-15 10:52:15 -0700273
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000274 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100275 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700276 bool supports_native_handle_ = false;
Erik Språng9b5b0702018-11-01 14:52:30 +0100277 std::string implementation_name_ = "unknown";
Erik Språng75de46a2018-11-07 14:53:32 +0100278 VideoEncoder::ScalingSettings scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100279 bool has_trusted_rate_controller_ = false;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100280 bool is_hardware_accelerated_ = false;
281 bool has_internal_source_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800282 int32_t init_encode_return_value_ = 0;
Erik Språng16cb8f52019-04-12 13:59:09 +0200283 VideoEncoder::RateControlParameters last_set_rates_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100284 FramerateFractions fps_allocation_;
noahricfac0ff02016-09-09 10:27:15 -0700285
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000286 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700287 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000288};
289
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100290std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
291 const {
292 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
293 return formats;
294}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000295
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100296std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
297 const SdpVideoFormat& format) {
298 std::unique_ptr<MockVideoEncoder> encoder(
299 new ::testing::NiceMock<MockVideoEncoder>(this));
300 encoder->set_init_encode_return_value(init_encode_return_value_);
301 const char* encoder_name = encoder_names_.empty()
302 ? "codec_implementation_name"
303 : encoder_names_[encoders_.size()];
Erik Språng9b5b0702018-11-01 14:52:30 +0100304 encoder->set_implementation_name(encoder_name);
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100305 encoders_.push_back(encoder.get());
306 return encoder;
307}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000308
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100309void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
310 for (size_t i = 0; i < encoders_.size(); ++i) {
311 if (encoders_[i] == encoder) {
312 encoders_.erase(encoders_.begin() + i);
313 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000314 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000315 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100316}
Zhi Huangaea84f52017-11-16 18:46:27 +0000317
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000318VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
319 const SdpVideoFormat& format) const {
320 return CodecInfo();
321}
322
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100323const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
324 const {
325 return encoders_;
326}
327void MockVideoEncoderFactory::SetEncoderNames(
328 const std::vector<const char*>& encoder_names) {
329 encoder_names_ = encoder_names;
330}
331void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
332 init_encode_return_value_ = value;
333}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000334
335class TestSimulcastEncoderAdapterFakeHelper {
336 public:
337 TestSimulcastEncoderAdapterFakeHelper()
338 : factory_(new MockVideoEncoderFactory()) {}
339
340 // Can only be called once as the SimulcastEncoderAdapter will take the
341 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200342 VideoEncoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200343 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000344 }
345
magjed6cc25612017-07-10 03:26:36 -0700346 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000347
348 private:
magjed6cc25612017-07-10 03:26:36 -0700349 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000350};
351
352static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
353
Noah Richards41ee1ea2015-04-15 09:24:26 -0700354class TestSimulcastEncoderAdapterFake : public ::testing::Test,
355 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000356 public:
357 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700358 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
359 adapter_(helper_->CreateMockEncoderAdapter()),
360 last_encoded_image_width_(-1),
361 last_encoded_image_height_(-1),
362 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700363 virtual ~TestSimulcastEncoderAdapterFake() {
364 if (adapter_) {
365 adapter_->Release();
366 }
367 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000368
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700369 Result OnEncodedImage(const EncodedImage& encoded_image,
370 const CodecSpecificInfo* codec_specific_info,
371 const RTPFragmentationHeader* fragmentation) override {
372 last_encoded_image_width_ = encoded_image._encodedWidth;
373 last_encoded_image_height_ = encoded_image._encodedHeight;
Niels Möllerd3b8c632018-08-27 15:33:42 +0200374 last_encoded_image_simulcast_index_ =
375 encoded_image.SpatialIndex().value_or(-1);
376
Niels Möller72bc8d62018-09-12 10:03:51 +0200377 return Result(Result::OK, encoded_image.Timestamp());
Noah Richards41ee1ea2015-04-15 09:24:26 -0700378 }
379
380 bool GetLastEncodedImageInfo(int* out_width,
381 int* out_height,
382 int* out_simulcast_index) {
383 if (last_encoded_image_width_ == -1) {
384 return false;
385 }
386 *out_width = last_encoded_image_width_;
387 *out_height = last_encoded_image_height_;
388 *out_simulcast_index = last_encoded_image_simulcast_index_;
389 return true;
390 }
391
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000392 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200393 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200394 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
395 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100396 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Philip Eliasson49d661a2019-06-11 11:55:47 +0000397 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700398 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000399 }
400
401 void VerifyCodec(const VideoCodec& ref, int stream_index) {
402 const VideoCodec& target =
403 helper_->factory()->encoders()[stream_index]->codec();
404 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000405 EXPECT_EQ(ref.plType, target.plType);
406 EXPECT_EQ(ref.width, target.width);
407 EXPECT_EQ(ref.height, target.height);
408 EXPECT_EQ(ref.startBitrate, target.startBitrate);
409 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
410 EXPECT_EQ(ref.minBitrate, target.minBitrate);
411 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700412 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700413 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
414 target.VP8().numberOfTemporalLayers);
415 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700416 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
417 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
418 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000419 EXPECT_EQ(ref.qpMax, target.qpMax);
420 EXPECT_EQ(0, target.numberOfSimulcastStreams);
421 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000422
423 // No need to compare simulcastStream as numberOfSimulcastStreams should
424 // always be 0.
425 }
426
Florent Castelli1b761ca2019-01-21 14:33:02 +0100427 void InitRefCodec(int stream_index,
428 VideoCodec* ref_codec,
429 bool reverse_layer_order = false) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000430 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700431 ref_codec->VP8()->numberOfTemporalLayers =
Florent Castelli1b761ca2019-01-21 14:33:02 +0100432 kTestTemporalLayerProfile[reverse_layer_order ? 2 - stream_index
433 : stream_index];
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000434 ref_codec->width = codec_.simulcastStream[stream_index].width;
435 ref_codec->height = codec_.simulcastStream[stream_index].height;
436 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
437 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
438 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
439 }
440
441 void VerifyCodecSettings() {
442 EXPECT_EQ(3u, helper_->factory()->encoders().size());
443 VideoCodec ref_codec;
444
445 // stream 0, the lowest resolution stream.
446 InitRefCodec(0, &ref_codec);
447 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200448 ref_codec.VP8()->complexity =
449 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700450 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000451 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
452 VerifyCodec(ref_codec, 0);
453
454 // stream 1
455 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700456 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700457 // The start bitrate (300kbit) minus what we have for the lower layers
458 // (100kbit).
459 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000460 VerifyCodec(ref_codec, 1);
461
462 // stream 2, the biggest resolution stream.
463 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700464 // We don't have enough bits to send this, so the adapter should have
465 // configured it to use the min bitrate for this layer (600kbit) but turn
466 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000467 ref_codec.startBitrate = 600;
468 VerifyCodec(ref_codec, 2);
469 }
470
471 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800472 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200473 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000474 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700475 int last_encoded_image_width_;
476 int last_encoded_image_height_;
477 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100478 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000479};
480
481TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
482 SetupCodec();
483 VerifyCodecSettings();
484}
485
brandtr5e171752017-05-23 03:32:16 -0700486TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
487 EXPECT_EQ(0, adapter_->Release());
488}
489
490TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
491 SetupCodec();
492 EXPECT_EQ(0, adapter_->Release());
493
Philip Eliasson49d661a2019-06-11 11:55:47 +0000494 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
brandtr5e171752017-05-23 03:32:16 -0700495}
496
Noah Richards41ee1ea2015-04-15 09:24:26 -0700497TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
498 SetupCodec();
499
Peter Boström5d0379d2015-10-06 14:04:51 +0200500 // Set bitrates so that we send all layers.
Erik Språng16cb8f52019-04-12 13:59:09 +0200501 adapter_->SetRates(VideoEncoder::RateControlParameters(
502 rate_allocator_->GetAllocation(1200, 30), 30.0));
Peter Boström5d0379d2015-10-06 14:04:51 +0200503
Noah Richards41ee1ea2015-04-15 09:24:26 -0700504 // At this point, the simulcast encoder adapter should have 3 streams: HD,
505 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
506 // resolutions, to test that the adapter forwards on the correct resolution
507 // and simulcast index values, going only off the encoder that generates the
508 // image.
brandtr5e171752017-05-23 03:32:16 -0700509 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
510 ASSERT_EQ(3u, encoders.size());
511 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700512 int width;
513 int height;
514 int simulcast_index;
515 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
516 EXPECT_EQ(1152, width);
517 EXPECT_EQ(704, height);
518 EXPECT_EQ(0, simulcast_index);
519
brandtr5e171752017-05-23 03:32:16 -0700520 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700521 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
522 EXPECT_EQ(300, width);
523 EXPECT_EQ(620, height);
524 EXPECT_EQ(1, simulcast_index);
525
brandtr5e171752017-05-23 03:32:16 -0700526 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700527 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
528 EXPECT_EQ(120, width);
529 EXPECT_EQ(240, height);
530 EXPECT_EQ(2, simulcast_index);
531}
532
brandtr5e171752017-05-23 03:32:16 -0700533// This test verifies that the underlying encoders are reused, when the adapter
534// is reinited with different number of simulcast streams. It further checks
535// that the allocated encoders are reused in the same order as before, starting
536// with the lowest stream.
537TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
538 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200539 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200540 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
541 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100542 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700543 adapter_->RegisterEncodeCompleteCallback(this);
Erik Språng7d687b12018-09-12 17:04:10 +0200544 const uint32_t target_bitrate =
545 1000 * (codec_.simulcastStream[0].targetBitrate +
546 codec_.simulcastStream[1].targetBitrate +
547 codec_.simulcastStream[2].minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700548
549 // Input data.
550 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100551 VideoFrame input_frame = VideoFrame::Builder()
552 .set_video_frame_buffer(buffer)
553 .set_timestamp_rtp(100)
554 .set_timestamp_ms(1000)
555 .set_rotation(kVideoRotation_180)
556 .build();
Niels Möller87e2d782019-03-07 10:18:23 +0100557 std::vector<VideoFrameType> frame_types;
brandtr5e171752017-05-23 03:32:16 -0700558
559 // Encode with three streams.
Philip Eliasson49d661a2019-06-11 11:55:47 +0000560 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
brandtr5e171752017-05-23 03:32:16 -0700561 VerifyCodecSettings();
Erik Språng16cb8f52019-04-12 13:59:09 +0200562 adapter_->SetRates(VideoEncoder::RateControlParameters(
563 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
Erik Språng7d687b12018-09-12 17:04:10 +0200564
brandtr5e171752017-05-23 03:32:16 -0700565 std::vector<MockVideoEncoder*> original_encoders =
566 helper_->factory()->encoders();
567 ASSERT_EQ(3u, original_encoders.size());
Niels Möllerb859b322019-03-07 12:40:01 +0100568 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700569 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100570 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700571 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100572 EXPECT_CALL(*original_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700573 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100574 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100575 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700576 EXPECT_CALL(*original_encoders[0], Release())
577 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
578 EXPECT_CALL(*original_encoders[1], Release())
579 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
580 EXPECT_CALL(*original_encoders[2], Release())
581 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
582 EXPECT_EQ(0, adapter_->Release());
583
584 // Encode with two streams.
585 codec_.width /= 2;
586 codec_.height /= 2;
587 codec_.numberOfSimulcastStreams = 2;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000588 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng16cb8f52019-04-12 13:59:09 +0200589 adapter_->SetRates(VideoEncoder::RateControlParameters(
590 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700591 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
592 ASSERT_EQ(2u, new_encoders.size());
593 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100594 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700595 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
596 ASSERT_EQ(original_encoders[1], new_encoders[1]);
Niels Möllerb859b322019-03-07 12:40:01 +0100597 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700598 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100599 frame_types.resize(2, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100600 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700601 EXPECT_CALL(*original_encoders[0], Release())
602 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
603 EXPECT_CALL(*original_encoders[1], Release())
604 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
605 EXPECT_EQ(0, adapter_->Release());
606
607 // Encode with single stream.
608 codec_.width /= 2;
609 codec_.height /= 2;
610 codec_.numberOfSimulcastStreams = 1;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000611 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng16cb8f52019-04-12 13:59:09 +0200612 adapter_->SetRates(VideoEncoder::RateControlParameters(
613 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700614 new_encoders = helper_->factory()->encoders();
615 ASSERT_EQ(1u, new_encoders.size());
616 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100617 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700618 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100619 frame_types.resize(1, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100620 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700621 EXPECT_CALL(*original_encoders[0], Release())
622 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
623 EXPECT_EQ(0, adapter_->Release());
624
625 // Encode with three streams, again.
626 codec_.width *= 4;
627 codec_.height *= 4;
628 codec_.numberOfSimulcastStreams = 3;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000629 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng16cb8f52019-04-12 13:59:09 +0200630 adapter_->SetRates(VideoEncoder::RateControlParameters(
631 rate_allocator_->GetAllocation(target_bitrate, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700632 new_encoders = helper_->factory()->encoders();
633 ASSERT_EQ(3u, new_encoders.size());
634 // The first encoder is reused.
635 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100636 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700637 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
638 // The second and third encoders are new.
Niels Möllerb859b322019-03-07 12:40:01 +0100639 EXPECT_CALL(*new_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700640 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100641 EXPECT_CALL(*new_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700642 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100643 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100644 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700645 EXPECT_CALL(*original_encoders[0], Release())
646 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
647 EXPECT_CALL(*new_encoders[1], Release())
648 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
649 EXPECT_CALL(*new_encoders[2], Release())
650 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
651 EXPECT_EQ(0, adapter_->Release());
652}
653
654TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
655 SetupCodec();
656 VerifyCodecSettings();
657
658 EXPECT_EQ(3u, helper_->factory()->encoders().size());
659
660 // The adapter should destroy all encoders it has allocated. Since
661 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
662 // lsan to find leaks here.
663 EXPECT_EQ(0, adapter_->Release());
664 adapter_.reset();
665}
666
667// This test verifies that an adapter reinit with the same codec settings as
668// before does not change the underlying encoder codec settings.
669TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
670 SetupCodec();
671 VerifyCodecSettings();
672
673 // Capture current codec settings.
674 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
675 ASSERT_EQ(3u, encoders.size());
676 std::array<VideoCodec, 3> codecs_before;
677 for (int i = 0; i < 3; ++i) {
678 codecs_before[i] = encoders[i]->codec();
679 }
680
681 // Reinitialize and verify that the new codec settings are the same.
682 EXPECT_EQ(0, adapter_->Release());
Philip Eliasson49d661a2019-06-11 11:55:47 +0000683 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
brandtr5e171752017-05-23 03:32:16 -0700684 for (int i = 0; i < 3; ++i) {
685 const VideoCodec& codec_before = codecs_before[i];
686 const VideoCodec& codec_after = encoders[i]->codec();
687
688 // webrtc::VideoCodec does not implement operator==.
689 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
690 EXPECT_EQ(codec_before.plType, codec_after.plType);
691 EXPECT_EQ(codec_before.width, codec_after.width);
692 EXPECT_EQ(codec_before.height, codec_after.height);
693 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
694 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
695 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700696 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
697 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
698 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
699 codec_after.numberOfSimulcastStreams);
700 EXPECT_EQ(codec_before.mode, codec_after.mode);
701 EXPECT_EQ(codec_before.expect_encode_from_texture,
702 codec_after.expect_encode_from_texture);
703 }
704}
705
706// This test is similar to the one above, except that it tests the simulcastIdx
707// from the CodecSpecificInfo that is connected to an encoded frame. The
708// PayloadRouter demuxes the incoming encoded frames on different RTP modules
709// using the simulcastIdx, so it's important that there is no corresponding
710// encoder reordering in between adapter reinits as this would lead to PictureID
711// discontinuities.
712TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
713 SetupCodec();
Erik Språng16cb8f52019-04-12 13:59:09 +0200714 adapter_->SetRates(VideoEncoder::RateControlParameters(
715 rate_allocator_->GetAllocation(1200, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700716 VerifyCodecSettings();
717
718 // Send frames on all streams.
719 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
720 ASSERT_EQ(3u, encoders.size());
721 encoders[0]->SendEncodedImage(1152, 704);
722 int width;
723 int height;
724 int simulcast_index;
725 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
726 EXPECT_EQ(0, simulcast_index);
727
728 encoders[1]->SendEncodedImage(300, 620);
729 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
730 EXPECT_EQ(1, simulcast_index);
731
732 encoders[2]->SendEncodedImage(120, 240);
733 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
734 EXPECT_EQ(2, simulcast_index);
735
736 // Reinitialize.
737 EXPECT_EQ(0, adapter_->Release());
Philip Eliasson49d661a2019-06-11 11:55:47 +0000738 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng16cb8f52019-04-12 13:59:09 +0200739 adapter_->SetRates(VideoEncoder::RateControlParameters(
740 rate_allocator_->GetAllocation(1200, 30), 30.0));
brandtr5e171752017-05-23 03:32:16 -0700741
742 // Verify that the same encoder sends out frames on the same simulcast index.
743 encoders[0]->SendEncodedImage(1152, 704);
744 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
745 EXPECT_EQ(0, simulcast_index);
746
747 encoders[1]->SendEncodedImage(300, 620);
748 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
749 EXPECT_EQ(1, simulcast_index);
750
751 encoders[2]->SendEncodedImage(120, 240);
752 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
753 EXPECT_EQ(2, simulcast_index);
754}
755
pbos65e15ba2015-10-15 10:52:15 -0700756TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200757 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200758 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
759 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700760 codec_.numberOfSimulcastStreams = 1;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000761 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
pbos65e15ba2015-10-15 10:52:15 -0700762 adapter_->RegisterEncodeCompleteCallback(this);
763 ASSERT_EQ(1u, helper_->factory()->encoders().size());
764 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Philip Eliasson49d661a2019-06-11 11:55:47 +0000765 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200766 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700767 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Philip Eliasson49d661a2019-06-11 11:55:47 +0000768 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200769 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700770}
771
noahricfac0ff02016-09-09 10:27:15 -0700772TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200773 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200774 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
775 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700776 codec_.minBitrate = 50;
777 codec_.numberOfSimulcastStreams = 1;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000778 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng82fad3d2018-03-21 09:57:23 +0100779 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700780
781 // Above min should be respected.
Erik Språng566124a2018-04-23 12:32:22 +0200782 VideoBitrateAllocation target_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100783 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
Erik Språng16cb8f52019-04-12 13:59:09 +0200784 adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100785 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200786 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700787
788 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng566124a2018-04-23 12:32:22 +0200789 VideoBitrateAllocation too_low_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100790 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
Erik Språng16cb8f52019-04-12 13:59:09 +0200791 adapter_->SetRates(
792 VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100793 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200794 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700795
796 // Zero should be passed on as is, since it means "pause".
Erik Språng16cb8f52019-04-12 13:59:09 +0200797 adapter_->SetRates(
798 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
Erik Språng566124a2018-04-23 12:32:22 +0200799 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng16cb8f52019-04-12 13:59:09 +0200800 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700801}
802
Peter Boströma5dec162016-01-20 15:53:55 +0100803TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
Erik Språnge2fd86a2018-10-24 11:32:39 +0200804 EXPECT_EQ("SimulcastEncoderAdapter",
805 adapter_->GetEncoderInfo().implementation_name);
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200806 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200807 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
808 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100809 std::vector<const char*> encoder_names;
810 encoder_names.push_back("codec1");
811 encoder_names.push_back("codec2");
812 encoder_names.push_back("codec3");
813 helper_->factory()->SetEncoderNames(encoder_names);
Philip Eliasson49d661a2019-06-11 11:55:47 +0000814 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200815 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
816 adapter_->GetEncoderInfo().implementation_name);
Peter Boströmd53c3892016-03-30 17:03:52 +0200817
818 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700819 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200820 codec_.numberOfSimulcastStreams = 1;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000821 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Peter Boströmd53c3892016-03-30 17:03:52 +0200822 adapter_->RegisterEncodeCompleteCallback(this);
823 ASSERT_EQ(1u, helper_->factory()->encoders().size());
Erik Språnge2fd86a2018-10-24 11:32:39 +0200824 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
Peter Boströma5dec162016-01-20 15:53:55 +0100825}
826
pbos65e15ba2015-10-15 10:52:15 -0700827TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700828 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200829 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200830 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
831 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700832 codec_.numberOfSimulcastStreams = 3;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000833 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
pbos65e15ba2015-10-15 10:52:15 -0700834 adapter_->RegisterEncodeCompleteCallback(this);
835 ASSERT_EQ(3u, helper_->factory()->encoders().size());
836 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
837 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700838 // If one encoder doesn't support it, then overall support is disabled.
839 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språnge2fd86a2018-10-24 11:32:39 +0200840 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700841 // Once all do, then the adapter claims support.
842 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Philip Eliasson49d661a2019-06-11 11:55:47 +0000843 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200844 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700845}
846
nisseaf916892017-01-10 07:44:26 -0800847// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200848class FakeNativeBufferNoI420 : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700849 public:
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200850 FakeNativeBufferNoI420(int width, int height)
851 : width_(width), height_(height) {}
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000852
853 Type type() const override { return Type::kNative; }
854 int width() const override { return width_; }
855 int height() const override { return height_; }
856
857 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700858 RTC_NOTREACHED();
859 return nullptr;
860 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000861
862 private:
863 const int width_;
864 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700865};
866
867TEST_F(TestSimulcastEncoderAdapterFake,
868 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200869 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200870 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
871 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700872 codec_.numberOfSimulcastStreams = 3;
873 // High start bitrate, so all streams are enabled.
874 codec_.startBitrate = 3000;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000875 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
noahricfe3654d2016-07-01 09:05:54 -0700876 adapter_->RegisterEncodeCompleteCallback(this);
877 ASSERT_EQ(3u, helper_->factory()->encoders().size());
878 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
879 encoder->set_supports_native_handle(true);
Philip Eliasson49d661a2019-06-11 11:55:47 +0000880 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200881 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700882
883 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200884 new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100885 VideoFrame input_frame = VideoFrame::Builder()
886 .set_video_frame_buffer(buffer)
887 .set_timestamp_rtp(100)
888 .set_timestamp_ms(1000)
889 .set_rotation(kVideoRotation_180)
890 .build();
noahricfe3654d2016-07-01 09:05:54 -0700891 // Expect calls with the given video frame verbatim, since it's a texture
892 // frame and can't otherwise be modified/resized.
893 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
Niels Möllerb859b322019-03-07 12:40:01 +0100894 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _)).Times(1);
Niels Möller8f7ce222019-03-21 15:43:58 +0100895 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100896 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700897}
898
noahric57779102016-05-25 06:48:46 -0700899TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200900 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200901 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
902 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700903 codec_.numberOfSimulcastStreams = 3;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000904 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
noahric57779102016-05-25 06:48:46 -0700905 adapter_->RegisterEncodeCompleteCallback(this);
906 ASSERT_EQ(3u, helper_->factory()->encoders().size());
907 // Tell the 2nd encoder to request software fallback.
Niels Möllerb859b322019-03-07 12:40:01 +0100908 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _))
noahricfe3654d2016-07-01 09:05:54 -0700909 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700910
911 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000912 rtc::scoped_refptr<I420Buffer> input_buffer =
913 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700914 input_buffer->InitializeData();
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100915 VideoFrame input_frame = VideoFrame::Builder()
916 .set_video_frame_buffer(input_buffer)
917 .set_timestamp_rtp(0)
918 .set_timestamp_us(0)
919 .set_rotation(kVideoRotation_0)
920 .build();
Niels Möller8f7ce222019-03-21 15:43:58 +0100921 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
noahric57779102016-05-25 06:48:46 -0700922 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Niels Möllerc8d2e732019-03-06 12:00:33 +0100923 adapter_->Encode(input_frame, &frame_types));
noahric57779102016-05-25 06:48:46 -0700924}
925
noahrice5ba75a2016-12-12 13:08:27 -0800926TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200927 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200928 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
929 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800930 codec_.numberOfSimulcastStreams = 3;
931 helper_->factory()->set_init_encode_return_value(
932 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
933 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Philip Eliasson49d661a2019-06-11 11:55:47 +0000934 adapter_->InitEncode(&codec_, 1, 1200));
noahrice5ba75a2016-12-12 13:08:27 -0800935 EXPECT_TRUE(helper_->factory()->encoders().empty());
936}
937
Erik Språng8d2995b2018-08-09 11:18:17 +0200938TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
939 const int kHighMaxQp = 56;
940 const int kLowMaxQp = 46;
941
942 SimulcastTestFixtureImpl::DefaultSettings(
943 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
944 kVideoCodecVP8);
945 codec_.numberOfSimulcastStreams = 3;
946 codec_.simulcastStream[0].qpMax = kHighMaxQp;
947 codec_.mode = VideoCodecMode::kScreensharing;
948
Philip Eliasson49d661a2019-06-11 11:55:47 +0000949 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng8d2995b2018-08-09 11:18:17 +0200950 EXPECT_EQ(3u, helper_->factory()->encoders().size());
951
952 // Just check the lowest stream, which is the one that where the adapter
953 // might alter the max qp setting.
954 VideoCodec ref_codec;
955 InitRefCodec(0, &ref_codec);
956 ref_codec.qpMax = kHighMaxQp;
957 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
958 ref_codec.VP8()->denoisingOn = false;
959 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
960 VerifyCodec(ref_codec, 0);
961
962 // Change the max qp and try again.
963 codec_.simulcastStream[0].qpMax = kLowMaxQp;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000964 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng8d2995b2018-08-09 11:18:17 +0200965 EXPECT_EQ(3u, helper_->factory()->encoders().size());
966 ref_codec.qpMax = kLowMaxQp;
967 VerifyCodec(ref_codec, 0);
968}
Erik Språng7d687b12018-09-12 17:04:10 +0200969
Florent Castelli1b761ca2019-01-21 14:33:02 +0100970TEST_F(TestSimulcastEncoderAdapterFake,
971 DoesNotAlterMaxQpForScreenshareReversedLayer) {
972 const int kHighMaxQp = 56;
973 const int kLowMaxQp = 46;
974
975 SimulcastTestFixtureImpl::DefaultSettings(
976 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
977 kVideoCodecVP8, true /* reverse_layer_order */);
978 codec_.numberOfSimulcastStreams = 3;
979 codec_.simulcastStream[2].qpMax = kHighMaxQp;
980 codec_.mode = VideoCodecMode::kScreensharing;
981
Philip Eliasson49d661a2019-06-11 11:55:47 +0000982 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Florent Castelli1b761ca2019-01-21 14:33:02 +0100983 EXPECT_EQ(3u, helper_->factory()->encoders().size());
984
985 // Just check the lowest stream, which is the one that where the adapter
986 // might alter the max qp setting.
987 VideoCodec ref_codec;
988 InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
989 ref_codec.qpMax = kHighMaxQp;
990 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
991 ref_codec.VP8()->denoisingOn = false;
992 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
993 VerifyCodec(ref_codec, 2);
994
995 // Change the max qp and try again.
996 codec_.simulcastStream[2].qpMax = kLowMaxQp;
Philip Eliasson49d661a2019-06-11 11:55:47 +0000997 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Florent Castelli1b761ca2019-01-21 14:33:02 +0100998 EXPECT_EQ(3u, helper_->factory()->encoders().size());
999 ref_codec.qpMax = kLowMaxQp;
1000 VerifyCodec(ref_codec, 2);
1001}
1002
Erik Språng7d687b12018-09-12 17:04:10 +02001003TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
1004 // Set up common settings for three streams.
1005 SimulcastTestFixtureImpl::DefaultSettings(
1006 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1007 kVideoCodecVP8);
1008 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1009 adapter_->RegisterEncodeCompleteCallback(this);
1010
1011 // Only enough start bitrate for the lowest stream.
1012 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1013 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1014 codec_.simulcastStream[1].minBitrate - 1;
1015
1016 // Input data.
1017 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001018 VideoFrame input_frame = VideoFrame::Builder()
1019 .set_video_frame_buffer(buffer)
1020 .set_timestamp_rtp(100)
1021 .set_timestamp_ms(1000)
1022 .set_rotation(kVideoRotation_180)
1023 .build();
Erik Språng7d687b12018-09-12 17:04:10 +02001024
1025 // Encode with three streams.
Philip Eliasson49d661a2019-06-11 11:55:47 +00001026 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng7d687b12018-09-12 17:04:10 +02001027 std::vector<MockVideoEncoder*> original_encoders =
1028 helper_->factory()->encoders();
1029 ASSERT_EQ(3u, original_encoders.size());
1030 // Only first encoder will be active and called.
Niels Möllerb859b322019-03-07 12:40:01 +01001031 EXPECT_CALL(*original_encoders[0], Encode(_, _))
Erik Språng7d687b12018-09-12 17:04:10 +02001032 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +01001033 EXPECT_CALL(*original_encoders[1], Encode(_, _)).Times(0);
1034 EXPECT_CALL(*original_encoders[2], Encode(_, _)).Times(0);
Erik Språng7d687b12018-09-12 17:04:10 +02001035
Niels Möller87e2d782019-03-07 10:18:23 +01001036 std::vector<VideoFrameType> frame_types;
Niels Möller8f7ce222019-03-21 15:43:58 +01001037 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +01001038 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
Erik Språng7d687b12018-09-12 17:04:10 +02001039}
Erik Språngd3438aa2018-11-08 16:56:43 +01001040
1041TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
1042 // Set up common settings for three streams.
1043 SimulcastTestFixtureImpl::DefaultSettings(
1044 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1045 kVideoCodecVP8);
1046 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1047 adapter_->RegisterEncodeCompleteCallback(this);
1048
1049 // Only enough start bitrate for the lowest stream.
1050 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1051 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1052 codec_.simulcastStream[1].minBitrate - 1;
1053
1054 // Input data.
1055 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001056 VideoFrame input_frame = VideoFrame::Builder()
1057 .set_video_frame_buffer(buffer)
1058 .set_timestamp_rtp(100)
1059 .set_timestamp_ms(1000)
1060 .set_rotation(kVideoRotation_180)
1061 .build();
Erik Språngd3438aa2018-11-08 16:56:43 +01001062
1063 // No encoder trusted, so simulcast adapter should not be either.
Philip Eliasson49d661a2019-06-11 11:55:47 +00001064 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språngd3438aa2018-11-08 16:56:43 +01001065 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1066
1067 // Encode with three streams.
1068 std::vector<MockVideoEncoder*> original_encoders =
1069 helper_->factory()->encoders();
1070
1071 // All encoders are trusted, so simulcast adapter should be too.
1072 original_encoders[0]->set_has_trusted_rate_controller(true);
1073 original_encoders[1]->set_has_trusted_rate_controller(true);
1074 original_encoders[2]->set_has_trusted_rate_controller(true);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001075 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språngd3438aa2018-11-08 16:56:43 +01001076 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1077
1078 // One encoder not trusted, so simulcast adapter should not be either.
1079 original_encoders[2]->set_has_trusted_rate_controller(false);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001080 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språngd3438aa2018-11-08 16:56:43 +01001081 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1082
1083 // No encoder trusted, so simulcast adapter should not be either.
1084 original_encoders[0]->set_has_trusted_rate_controller(false);
1085 original_encoders[1]->set_has_trusted_rate_controller(false);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001086 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språngd3438aa2018-11-08 16:56:43 +01001087 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1088}
1089
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001090TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1091 SimulcastTestFixtureImpl::DefaultSettings(
1092 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1093 kVideoCodecVP8);
1094 codec_.numberOfSimulcastStreams = 3;
1095 adapter_->RegisterEncodeCompleteCallback(this);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001096 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001097 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1098
1099 // None of the encoders uses HW support, so simulcast adapter reports false.
1100 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1101 encoder->set_is_hardware_accelerated(false);
1102 }
Philip Eliasson49d661a2019-06-11 11:55:47 +00001103 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001104 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1105
1106 // One encoder uses HW support, so simulcast adapter reports true.
1107 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001108 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001109 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1110}
1111
1112TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1113 SimulcastTestFixtureImpl::DefaultSettings(
1114 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1115 kVideoCodecVP8);
1116 codec_.numberOfSimulcastStreams = 3;
1117 adapter_->RegisterEncodeCompleteCallback(this);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001118 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001119 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1120
1121 // All encoders have internal source, simulcast adapter reports true.
1122 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1123 encoder->set_has_internal_source(true);
1124 }
Philip Eliasson49d661a2019-06-11 11:55:47 +00001125 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001126 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1127
1128 // One encoder does not have internal source, simulcast adapter reports false.
1129 helper_->factory()->encoders()[2]->set_has_internal_source(false);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001130 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001131 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1132}
1133
Erik Språngdbdd8392019-01-17 15:27:50 +01001134TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
1135 SimulcastTestFixtureImpl::DefaultSettings(
1136 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1137 kVideoCodecVP8);
1138 codec_.numberOfSimulcastStreams = 3;
1139 adapter_->RegisterEncodeCompleteCallback(this);
Philip Eliasson49d661a2019-06-11 11:55:47 +00001140 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språngdbdd8392019-01-17 15:27:50 +01001141 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1142
1143 // Combination of three different supported mode:
1144 // Simulcast stream 0 has undefined fps behavior.
1145 // Simulcast stream 1 has three temporal layers.
1146 // Simulcast stream 2 has 1 temporal layer.
1147 FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
1148 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 4);
1149 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 2);
1150 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction);
1151 expected_fps_allocation[2].push_back(EncoderInfo::kMaxFramerateFraction);
1152
1153 // All encoders have internal source, simulcast adapter reports true.
1154 for (size_t i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
1155 MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
1156 encoder->set_fps_allocation(expected_fps_allocation[i]);
1157 }
Philip Eliasson49d661a2019-06-11 11:55:47 +00001158 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språngdbdd8392019-01-17 15:27:50 +01001159 EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
1160 ::testing::ElementsAreArray(expected_fps_allocation));
1161}
1162
Erik Språng16cb8f52019-04-12 13:59:09 +02001163TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
1164 SimulcastTestFixtureImpl::DefaultSettings(
1165 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1166 kVideoCodecVP8);
1167 codec_.numberOfSimulcastStreams = 3;
1168 const DataRate target_bitrate =
1169 DataRate::kbps(codec_.simulcastStream[0].targetBitrate +
1170 codec_.simulcastStream[1].targetBitrate +
1171 codec_.simulcastStream[2].minBitrate);
1172 const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
1173
1174 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Philip Eliasson49d661a2019-06-11 11:55:47 +00001175 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng16cb8f52019-04-12 13:59:09 +02001176 adapter_->RegisterEncodeCompleteCallback(this);
1177
1178 // Set bitrates so that we send all layers.
1179 adapter_->SetRates(VideoEncoder::RateControlParameters(
1180 rate_allocator_->GetAllocation(target_bitrate.bps(), 30), 30.0,
1181 bandwidth_allocation));
1182
1183 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1184
1185 ASSERT_EQ(3u, encoders.size());
1186
1187 for (size_t i = 0; i < 3; ++i) {
1188 const uint32_t layer_bitrate_bps =
1189 (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
1190 ? codec_.simulcastStream[i].targetBitrate
1191 : codec_.simulcastStream[i].minBitrate) *
1192 1000;
1193 EXPECT_EQ(layer_bitrate_bps,
1194 encoders[i]->last_set_rates().bitrate.get_sum_bps())
1195 << i;
1196 EXPECT_EQ(
1197 (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
1198 encoders[i]->last_set_rates().bandwidth_allocation.bps())
1199 << i;
1200 }
1201}
1202
Rasmus Brandt0cedc052018-05-31 12:53:00 +02001203} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001204} // namespace webrtc