blob: f6d57e8684653241fc808770df0899650167eced [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
Karl Wiberg918f50c2018-07-05 11:40:33 +020017#include "absl/memory/memory.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020018#include "api/test/create_simulcast_test_fixture.h"
19#include "api/test/simulcast_test_fixture.h"
Danil Chapovalov99b71df2018-10-26 15:57:48 +020020#include "api/test/video/function_video_decoder_factory.h"
21#include "api/test/video/function_video_encoder_factory.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010022#include "api/video_codecs/sdp_video_format.h"
Elad Alon370f93a2019-06-11 14:57:57 +020023#include "api/video_codecs/video_encoder.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010024#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "common_video/include/video_frame_buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "media/base/media_constants.h"
27#include "media/engine/internal_encoder_factory.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020028#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "modules/video_coding/include/video_codec_interface.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020030#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020032#include "test/gtest.h"
33
34using ::testing::_;
35using ::testing::Return;
Erik Språngdbdd8392019-01-17 15:27:50 +010036using EncoderInfo = webrtc::VideoEncoder::EncoderInfo;
37using FramerateFractions =
38 absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000039
40namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020041namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000042
Rasmus Brandt0cedc052018-05-31 12:53:00 +020043namespace {
philipelcce46fc2015-12-21 03:04:49 -080044
Rasmus Brandt0cedc052018-05-31 12:53:00 +020045constexpr int kDefaultWidth = 1280;
46constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070047
Elad Alon370f93a2019-06-11 14:57:57 +020048const VideoEncoder::Capabilities kCapabilities(false);
49const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200);
50
Rasmus Brandt0cedc052018-05-31 12:53:00 +020051std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
52 VideoEncoderFactory* internal_encoder_factory) {
53 std::unique_ptr<VideoEncoderFactory> encoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020054 absl::make_unique<FunctionVideoEncoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020055 [internal_encoder_factory]() {
Karl Wiberg918f50c2018-07-05 11:40:33 +020056 return absl::make_unique<SimulcastEncoderAdapter>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020057 internal_encoder_factory,
58 SdpVideoFormat(cricket::kVp8CodecName));
59 });
60 std::unique_ptr<VideoDecoderFactory> decoder_factory =
Karl Wiberg918f50c2018-07-05 11:40:33 +020061 absl::make_unique<FunctionVideoDecoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020062 []() { return VP8Decoder::Create(); });
63 return CreateSimulcastTestFixture(std::move(encoder_factory),
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020064 std::move(decoder_factory),
65 SdpVideoFormat(cricket::kVp8CodecName));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000066}
Rasmus Brandt0cedc052018-05-31 12:53:00 +020067} // namespace
68
69TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
70 InternalEncoderFactory internal_encoder_factory;
71 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
72 fixture->TestKeyFrameRequestsOnAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000073}
74
Rasmus Brandt0cedc052018-05-31 12:53:00 +020075TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
76 InternalEncoderFactory internal_encoder_factory;
77 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
78 fixture->TestPaddingAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000079}
80
Rasmus Brandt0cedc052018-05-31 12:53:00 +020081TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
82 InternalEncoderFactory internal_encoder_factory;
83 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
84 fixture->TestPaddingTwoStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000085}
86
Rasmus Brandt0cedc052018-05-31 12:53:00 +020087TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
88 InternalEncoderFactory internal_encoder_factory;
89 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
90 fixture->TestPaddingTwoStreamsOneMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000091}
92
Rasmus Brandt0cedc052018-05-31 12:53:00 +020093TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
94 InternalEncoderFactory internal_encoder_factory;
95 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
96 fixture->TestPaddingOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000097}
98
Rasmus Brandt0cedc052018-05-31 12:53:00 +020099TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
100 InternalEncoderFactory internal_encoder_factory;
101 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
102 fixture->TestPaddingOneStreamTwoMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000103}
104
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200105TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
106 InternalEncoderFactory internal_encoder_factory;
107 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
108 fixture->TestSendAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000109}
110
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200111TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
112 InternalEncoderFactory internal_encoder_factory;
113 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
114 fixture->TestDisablingStreams();
Seth Hampson46e31ba2018-01-18 10:39:54 -0800115}
116
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200117TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
118 InternalEncoderFactory internal_encoder_factory;
119 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
120 fixture->TestActiveStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000121}
122
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200123TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
124 InternalEncoderFactory internal_encoder_factory;
125 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
126 fixture->TestSwitchingToOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000127}
128
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200129TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
130 InternalEncoderFactory internal_encoder_factory;
131 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
132 fixture->TestSwitchingToOneOddStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000133}
134
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200135TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
136 InternalEncoderFactory internal_encoder_factory;
137 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
138 fixture->TestStrideEncodeDecode();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000139}
140
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200141TEST(SimulcastEncoderAdapterSimulcastTest,
142 TestSpatioTemporalLayers333PatternEncoder) {
143 InternalEncoderFactory internal_encoder_factory;
144 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
145 fixture->TestSpatioTemporalLayers333PatternEncoder();
146}
147
148TEST(SimulcastEncoderAdapterSimulcastTest,
149 TestSpatioTemporalLayers321PatternEncoder) {
150 InternalEncoderFactory internal_encoder_factory;
151 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
152 fixture->TestSpatioTemporalLayers321PatternEncoder();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000153}
154
Per Kjellander841c9122018-10-04 18:40:28 +0200155TEST(SimulcastEncoderAdapterSimulcastTest, TestDecodeWidthHeightSet) {
156 InternalEncoderFactory internal_encoder_factory;
157 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
158 fixture->TestDecodeWidthHeightSet();
159}
160
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100161class MockVideoEncoder;
162
163class MockVideoEncoderFactory : public VideoEncoderFactory {
164 public:
165 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
166
167 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
168 const SdpVideoFormat& format) override;
169
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000170 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
171
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100172 const std::vector<MockVideoEncoder*>& encoders() const;
173 void SetEncoderNames(const std::vector<const char*>& encoder_names);
174 void set_init_encode_return_value(int32_t value);
175
176 void DestroyVideoEncoder(VideoEncoder* encoder);
177
178 private:
179 int32_t init_encode_return_value_ = 0;
180 std::vector<MockVideoEncoder*> encoders_;
181 std::vector<const char*> encoder_names_;
182};
183
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000184class MockVideoEncoder : public VideoEncoder {
185 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100186 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng75de46a2018-11-07 14:53:32 +0100187 : factory_(factory),
188 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
189 callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100190
Elad Alon8f01c4e2019-06-28 15:19:43 +0200191 MOCK_METHOD1(SetFecControllerOverride,
192 void(FecControllerOverride* fec_controller_override));
193
nisseef8b61e2016-04-29 06:09:15 -0700194 // TODO(nisse): Valid overrides commented out, because the gmock
195 // methods don't use any override declarations, and we want to avoid
196 // warnings from -Winconsistent-missing-override. See
197 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000198 int32_t InitEncode(const VideoCodec* codecSettings,
Elad Alona9952cb2019-06-11 19:03:16 +0200199 const VideoEncoder::Settings& settings) override {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000200 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800201 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000202 }
203
Niels Möllerb859b322019-03-07 12:40:01 +0100204 MOCK_METHOD2(
noahricfe3654d2016-07-01 09:05:54 -0700205 Encode,
206 int32_t(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +0100207 const std::vector<VideoFrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000208
pbos65e15ba2015-10-15 10:52:15 -0700209 int32_t RegisterEncodeCompleteCallback(
Elad Alona9952cb2019-06-11 19:03:16 +0200210 EncodedImageCallback* callback) override {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700211 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000212 return 0;
213 }
214
Elad Alona9952cb2019-06-11 19:03:16 +0200215 MOCK_METHOD0(Release, int32_t() /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000216
Erik Språng16cb8f52019-04-12 13:59:09 +0200217 void SetRates(const RateControlParameters& parameters) {
218 last_set_rates_ = parameters;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000219 }
220
Erik Språng9b5b0702018-11-01 14:52:30 +0100221 EncoderInfo GetEncoderInfo() const override {
222 EncoderInfo info;
223 info.supports_native_handle = supports_native_handle_;
224 info.implementation_name = implementation_name_;
Erik Språng75de46a2018-11-07 14:53:32 +0100225 info.scaling_settings = scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100226 info.has_trusted_rate_controller = has_trusted_rate_controller_;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100227 info.is_hardware_accelerated = is_hardware_accelerated_;
228 info.has_internal_source = has_internal_source_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100229 info.fps_allocation[0] = fps_allocation_;
Erik Språng9b5b0702018-11-01 14:52:30 +0100230 return info;
nisseef8b61e2016-04-29 06:09:15 -0700231 }
pbos65e15ba2015-10-15 10:52:15 -0700232
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100233 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000234
235 const VideoCodec& codec() const { return codec_; }
236
Noah Richards41ee1ea2015-04-15 09:24:26 -0700237 void SendEncodedImage(int width, int height) {
238 // Sends a fake image of the given width/height.
239 EncodedImage image;
240 image._encodedWidth = width;
241 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700242 CodecSpecificInfo codec_specific_info;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200243 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700244 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700245 }
246
pbos65e15ba2015-10-15 10:52:15 -0700247 void set_supports_native_handle(bool enabled) {
248 supports_native_handle_ = enabled;
249 }
noahrice5ba75a2016-12-12 13:08:27 -0800250
Erik Språng9b5b0702018-11-01 14:52:30 +0100251 void set_implementation_name(const std::string& name) {
252 implementation_name_ = name;
253 }
254
noahrice5ba75a2016-12-12 13:08:27 -0800255 void set_init_encode_return_value(int32_t value) {
256 init_encode_return_value_ = value;
257 }
258
Erik Språng75de46a2018-11-07 14:53:32 +0100259 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
260 scaling_settings_ = settings;
261 }
262
Erik Språngd3438aa2018-11-08 16:56:43 +0100263 void set_has_trusted_rate_controller(bool trusted) {
264 has_trusted_rate_controller_ = trusted;
265 }
266
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100267 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
268 is_hardware_accelerated_ = is_hardware_accelerated;
269 }
270
271 void set_has_internal_source(bool has_internal_source) {
272 has_internal_source_ = has_internal_source;
273 }
274
Erik Språngdbdd8392019-01-17 15:27:50 +0100275 void set_fps_allocation(const FramerateFractions& fps_allocation) {
276 fps_allocation_ = fps_allocation;
277 }
278
Erik Språng16cb8f52019-04-12 13:59:09 +0200279 RateControlParameters last_set_rates() const { return last_set_rates_; }
pbos65e15ba2015-10-15 10:52:15 -0700280
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000281 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100282 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700283 bool supports_native_handle_ = false;
Erik Språng9b5b0702018-11-01 14:52:30 +0100284 std::string implementation_name_ = "unknown";
Erik Språng75de46a2018-11-07 14:53:32 +0100285 VideoEncoder::ScalingSettings scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100286 bool has_trusted_rate_controller_ = false;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100287 bool is_hardware_accelerated_ = false;
288 bool has_internal_source_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800289 int32_t init_encode_return_value_ = 0;
Erik Språng16cb8f52019-04-12 13:59:09 +0200290 VideoEncoder::RateControlParameters last_set_rates_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100291 FramerateFractions fps_allocation_;
noahricfac0ff02016-09-09 10:27:15 -0700292
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000293 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700294 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000295};
296
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100297std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
298 const {
299 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
300 return formats;
301}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000302
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100303std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
304 const SdpVideoFormat& format) {
305 std::unique_ptr<MockVideoEncoder> encoder(
306 new ::testing::NiceMock<MockVideoEncoder>(this));
307 encoder->set_init_encode_return_value(init_encode_return_value_);
308 const char* encoder_name = encoder_names_.empty()
309 ? "codec_implementation_name"
310 : encoder_names_[encoders_.size()];
Erik Språng9b5b0702018-11-01 14:52:30 +0100311 encoder->set_implementation_name(encoder_name);
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100312 encoders_.push_back(encoder.get());
313 return encoder;
314}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000315
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100316void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
317 for (size_t i = 0; i < encoders_.size(); ++i) {
318 if (encoders_[i] == encoder) {
319 encoders_.erase(encoders_.begin() + i);
320 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000321 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000322 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100323}
Zhi Huangaea84f52017-11-16 18:46:27 +0000324
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000325VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
326 const SdpVideoFormat& format) const {
327 return CodecInfo();
328}
329
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100330const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
331 const {
332 return encoders_;
333}
334void MockVideoEncoderFactory::SetEncoderNames(
335 const std::vector<const char*>& encoder_names) {
336 encoder_names_ = encoder_names;
337}
338void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
339 init_encode_return_value_ = value;
340}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000341
342class TestSimulcastEncoderAdapterFakeHelper {
343 public:
344 TestSimulcastEncoderAdapterFakeHelper()
345 : factory_(new MockVideoEncoderFactory()) {}
346
347 // Can only be called once as the SimulcastEncoderAdapter will take the
348 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200349 VideoEncoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200350 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000351 }
352
magjed6cc25612017-07-10 03:26:36 -0700353 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000354
355 private:
magjed6cc25612017-07-10 03:26:36 -0700356 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000357};
358
359static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
360
Noah Richards41ee1ea2015-04-15 09:24:26 -0700361class TestSimulcastEncoderAdapterFake : public ::testing::Test,
362 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000363 public:
364 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700365 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
366 adapter_(helper_->CreateMockEncoderAdapter()),
367 last_encoded_image_width_(-1),
368 last_encoded_image_height_(-1),
369 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700370 virtual ~TestSimulcastEncoderAdapterFake() {
371 if (adapter_) {
372 adapter_->Release();
373 }
374 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000375
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700376 Result OnEncodedImage(const EncodedImage& encoded_image,
377 const CodecSpecificInfo* codec_specific_info,
378 const RTPFragmentationHeader* fragmentation) override {
379 last_encoded_image_width_ = encoded_image._encodedWidth;
380 last_encoded_image_height_ = encoded_image._encodedHeight;
Niels Möllerd3b8c632018-08-27 15:33:42 +0200381 last_encoded_image_simulcast_index_ =
382 encoded_image.SpatialIndex().value_or(-1);
383
Niels Möller72bc8d62018-09-12 10:03:51 +0200384 return Result(Result::OK, encoded_image.Timestamp());
Noah Richards41ee1ea2015-04-15 09:24:26 -0700385 }
386
387 bool GetLastEncodedImageInfo(int* out_width,
388 int* out_height,
389 int* out_simulcast_index) {
390 if (last_encoded_image_width_ == -1) {
391 return false;
392 }
393 *out_width = last_encoded_image_width_;
394 *out_height = last_encoded_image_height_;
395 *out_simulcast_index = last_encoded_image_simulcast_index_;
396 return true;
397 }
398
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000399 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200400 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200401 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
402 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100403 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 14:57:57 +0200404 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700405 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000406 }
407
408 void VerifyCodec(const VideoCodec& ref, int stream_index) {
409 const VideoCodec& target =
410 helper_->factory()->encoders()[stream_index]->codec();
411 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000412 EXPECT_EQ(ref.plType, target.plType);
413 EXPECT_EQ(ref.width, target.width);
414 EXPECT_EQ(ref.height, target.height);
415 EXPECT_EQ(ref.startBitrate, target.startBitrate);
416 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
417 EXPECT_EQ(ref.minBitrate, target.minBitrate);
418 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700419 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700420 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
421 target.VP8().numberOfTemporalLayers);
422 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700423 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
424 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
425 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000426 EXPECT_EQ(ref.qpMax, target.qpMax);
427 EXPECT_EQ(0, target.numberOfSimulcastStreams);
428 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000429
430 // No need to compare simulcastStream as numberOfSimulcastStreams should
431 // always be 0.
432 }
433
Florent Castelli1b761ca2019-01-21 14:33:02 +0100434 void InitRefCodec(int stream_index,
435 VideoCodec* ref_codec,
436 bool reverse_layer_order = false) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000437 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700438 ref_codec->VP8()->numberOfTemporalLayers =
Florent Castelli1b761ca2019-01-21 14:33:02 +0100439 kTestTemporalLayerProfile[reverse_layer_order ? 2 - stream_index
440 : stream_index];
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000441 ref_codec->width = codec_.simulcastStream[stream_index].width;
442 ref_codec->height = codec_.simulcastStream[stream_index].height;
443 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
444 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
445 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
446 }
447
448 void VerifyCodecSettings() {
449 EXPECT_EQ(3u, helper_->factory()->encoders().size());
450 VideoCodec ref_codec;
451
452 // stream 0, the lowest resolution stream.
453 InitRefCodec(0, &ref_codec);
454 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200455 ref_codec.VP8()->complexity =
456 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700457 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000458 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
459 VerifyCodec(ref_codec, 0);
460
461 // stream 1
462 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700463 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700464 // The start bitrate (300kbit) minus what we have for the lower layers
465 // (100kbit).
466 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000467 VerifyCodec(ref_codec, 1);
468
469 // stream 2, the biggest resolution stream.
470 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700471 // We don't have enough bits to send this, so the adapter should have
472 // configured it to use the min bitrate for this layer (600kbit) but turn
473 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000474 ref_codec.startBitrate = 600;
475 VerifyCodec(ref_codec, 2);
476 }
477
478 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800479 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200480 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000481 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700482 int last_encoded_image_width_;
483 int last_encoded_image_height_;
484 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100485 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000486};
487
488TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
489 SetupCodec();
490 VerifyCodecSettings();
491}
492
brandtr5e171752017-05-23 03:32:16 -0700493TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
494 EXPECT_EQ(0, adapter_->Release());
495}
496
497TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
498 SetupCodec();
499 EXPECT_EQ(0, adapter_->Release());
500
Elad Alon370f93a2019-06-11 14:57:57 +0200501 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700502}
503
Noah Richards41ee1ea2015-04-15 09:24:26 -0700504TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
505 SetupCodec();
506
Peter Boström5d0379d2015-10-06 14:04:51 +0200507 // Set bitrates so that we send all layers.
Erik Språng16cb8f52019-04-12 13:59:09 +0200508 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200509 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
510 30.0));
Peter Boström5d0379d2015-10-06 14:04:51 +0200511
Noah Richards41ee1ea2015-04-15 09:24:26 -0700512 // At this point, the simulcast encoder adapter should have 3 streams: HD,
513 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
514 // resolutions, to test that the adapter forwards on the correct resolution
515 // and simulcast index values, going only off the encoder that generates the
516 // image.
brandtr5e171752017-05-23 03:32:16 -0700517 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
518 ASSERT_EQ(3u, encoders.size());
519 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700520 int width;
521 int height;
522 int simulcast_index;
523 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
524 EXPECT_EQ(1152, width);
525 EXPECT_EQ(704, height);
526 EXPECT_EQ(0, simulcast_index);
527
brandtr5e171752017-05-23 03:32:16 -0700528 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700529 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
530 EXPECT_EQ(300, width);
531 EXPECT_EQ(620, height);
532 EXPECT_EQ(1, simulcast_index);
533
brandtr5e171752017-05-23 03:32:16 -0700534 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700535 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
536 EXPECT_EQ(120, width);
537 EXPECT_EQ(240, height);
538 EXPECT_EQ(2, simulcast_index);
539}
540
brandtr5e171752017-05-23 03:32:16 -0700541// This test verifies that the underlying encoders are reused, when the adapter
542// is reinited with different number of simulcast streams. It further checks
543// that the allocated encoders are reused in the same order as before, starting
544// with the lowest stream.
545TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
546 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200547 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200548 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
549 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100550 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700551 adapter_->RegisterEncodeCompleteCallback(this);
Erik Språng7d687b12018-09-12 17:04:10 +0200552 const uint32_t target_bitrate =
553 1000 * (codec_.simulcastStream[0].targetBitrate +
554 codec_.simulcastStream[1].targetBitrate +
555 codec_.simulcastStream[2].minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700556
557 // Input data.
558 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100559 VideoFrame input_frame = VideoFrame::Builder()
560 .set_video_frame_buffer(buffer)
561 .set_timestamp_rtp(100)
562 .set_timestamp_ms(1000)
563 .set_rotation(kVideoRotation_180)
564 .build();
Niels Möller87e2d782019-03-07 10:18:23 +0100565 std::vector<VideoFrameType> frame_types;
brandtr5e171752017-05-23 03:32:16 -0700566
567 // Encode with three streams.
Elad Alon370f93a2019-06-11 14:57:57 +0200568 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700569 VerifyCodecSettings();
Erik Språng16cb8f52019-04-12 13:59:09 +0200570 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200571 rate_allocator_->Allocate(
572 VideoBitrateAllocationParameters(target_bitrate, 30)),
573 30.0));
Erik Språng7d687b12018-09-12 17:04:10 +0200574
brandtr5e171752017-05-23 03:32:16 -0700575 std::vector<MockVideoEncoder*> original_encoders =
576 helper_->factory()->encoders();
577 ASSERT_EQ(3u, original_encoders.size());
Niels Möllerb859b322019-03-07 12:40:01 +0100578 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700579 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100580 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700581 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100582 EXPECT_CALL(*original_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700583 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100584 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100585 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700586 EXPECT_CALL(*original_encoders[0], Release())
587 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
588 EXPECT_CALL(*original_encoders[1], Release())
589 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
590 EXPECT_CALL(*original_encoders[2], Release())
591 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
592 EXPECT_EQ(0, adapter_->Release());
593
594 // Encode with two streams.
595 codec_.width /= 2;
596 codec_.height /= 2;
597 codec_.numberOfSimulcastStreams = 2;
Elad Alon370f93a2019-06-11 14:57:57 +0200598 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
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));
brandtr5e171752017-05-23 03:32:16 -0700603 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
604 ASSERT_EQ(2u, new_encoders.size());
605 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100606 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700607 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
608 ASSERT_EQ(original_encoders[1], new_encoders[1]);
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öller8f7ce222019-03-21 15:43:58 +0100611 frame_types.resize(2, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100612 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700613 EXPECT_CALL(*original_encoders[0], Release())
614 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
615 EXPECT_CALL(*original_encoders[1], Release())
616 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
617 EXPECT_EQ(0, adapter_->Release());
618
619 // Encode with single stream.
620 codec_.width /= 2;
621 codec_.height /= 2;
622 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200623 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200624 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200625 rate_allocator_->Allocate(
626 VideoBitrateAllocationParameters(target_bitrate, 30)),
627 30.0));
brandtr5e171752017-05-23 03:32:16 -0700628 new_encoders = helper_->factory()->encoders();
629 ASSERT_EQ(1u, new_encoders.size());
630 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100631 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700632 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100633 frame_types.resize(1, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100634 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700635 EXPECT_CALL(*original_encoders[0], Release())
636 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
637 EXPECT_EQ(0, adapter_->Release());
638
639 // Encode with three streams, again.
640 codec_.width *= 4;
641 codec_.height *= 4;
642 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200643 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200644 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200645 rate_allocator_->Allocate(
646 VideoBitrateAllocationParameters(target_bitrate, 30)),
647 30.0));
brandtr5e171752017-05-23 03:32:16 -0700648 new_encoders = helper_->factory()->encoders();
649 ASSERT_EQ(3u, new_encoders.size());
650 // The first encoder is reused.
651 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100652 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700653 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
654 // The second and third encoders are new.
Niels Möllerb859b322019-03-07 12:40:01 +0100655 EXPECT_CALL(*new_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700656 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100657 EXPECT_CALL(*new_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700658 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100659 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100660 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700661 EXPECT_CALL(*original_encoders[0], Release())
662 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
663 EXPECT_CALL(*new_encoders[1], Release())
664 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
665 EXPECT_CALL(*new_encoders[2], Release())
666 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
667 EXPECT_EQ(0, adapter_->Release());
668}
669
670TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
671 SetupCodec();
672 VerifyCodecSettings();
673
674 EXPECT_EQ(3u, helper_->factory()->encoders().size());
675
676 // The adapter should destroy all encoders it has allocated. Since
677 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
678 // lsan to find leaks here.
679 EXPECT_EQ(0, adapter_->Release());
680 adapter_.reset();
681}
682
683// This test verifies that an adapter reinit with the same codec settings as
684// before does not change the underlying encoder codec settings.
685TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
686 SetupCodec();
687 VerifyCodecSettings();
688
689 // Capture current codec settings.
690 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
691 ASSERT_EQ(3u, encoders.size());
692 std::array<VideoCodec, 3> codecs_before;
693 for (int i = 0; i < 3; ++i) {
694 codecs_before[i] = encoders[i]->codec();
695 }
696
697 // Reinitialize and verify that the new codec settings are the same.
698 EXPECT_EQ(0, adapter_->Release());
Elad Alon370f93a2019-06-11 14:57:57 +0200699 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700700 for (int i = 0; i < 3; ++i) {
701 const VideoCodec& codec_before = codecs_before[i];
702 const VideoCodec& codec_after = encoders[i]->codec();
703
704 // webrtc::VideoCodec does not implement operator==.
705 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
706 EXPECT_EQ(codec_before.plType, codec_after.plType);
707 EXPECT_EQ(codec_before.width, codec_after.width);
708 EXPECT_EQ(codec_before.height, codec_after.height);
709 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
710 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
711 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700712 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
713 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
714 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
715 codec_after.numberOfSimulcastStreams);
716 EXPECT_EQ(codec_before.mode, codec_after.mode);
717 EXPECT_EQ(codec_before.expect_encode_from_texture,
718 codec_after.expect_encode_from_texture);
719 }
720}
721
722// This test is similar to the one above, except that it tests the simulcastIdx
723// from the CodecSpecificInfo that is connected to an encoded frame. The
724// PayloadRouter demuxes the incoming encoded frames on different RTP modules
725// using the simulcastIdx, so it's important that there is no corresponding
726// encoder reordering in between adapter reinits as this would lead to PictureID
727// discontinuities.
728TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
729 SetupCodec();
Erik Språng16cb8f52019-04-12 13:59:09 +0200730 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200731 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
732 30.0));
brandtr5e171752017-05-23 03:32:16 -0700733 VerifyCodecSettings();
734
735 // Send frames on all streams.
736 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
737 ASSERT_EQ(3u, encoders.size());
738 encoders[0]->SendEncodedImage(1152, 704);
739 int width;
740 int height;
741 int simulcast_index;
742 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
743 EXPECT_EQ(0, simulcast_index);
744
745 encoders[1]->SendEncodedImage(300, 620);
746 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
747 EXPECT_EQ(1, simulcast_index);
748
749 encoders[2]->SendEncodedImage(120, 240);
750 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
751 EXPECT_EQ(2, simulcast_index);
752
753 // Reinitialize.
754 EXPECT_EQ(0, adapter_->Release());
Elad Alon370f93a2019-06-11 14:57:57 +0200755 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200756 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200757 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
758 30.0));
brandtr5e171752017-05-23 03:32:16 -0700759
760 // Verify that the same encoder sends out frames on the same simulcast index.
761 encoders[0]->SendEncodedImage(1152, 704);
762 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
763 EXPECT_EQ(0, simulcast_index);
764
765 encoders[1]->SendEncodedImage(300, 620);
766 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
767 EXPECT_EQ(1, simulcast_index);
768
769 encoders[2]->SendEncodedImage(120, 240);
770 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
771 EXPECT_EQ(2, simulcast_index);
772}
773
pbos65e15ba2015-10-15 10:52:15 -0700774TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200775 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200776 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
777 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700778 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200779 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700780 adapter_->RegisterEncodeCompleteCallback(this);
781 ASSERT_EQ(1u, helper_->factory()->encoders().size());
782 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200783 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200784 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700785 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Elad Alon370f93a2019-06-11 14:57:57 +0200786 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200787 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700788}
789
noahricfac0ff02016-09-09 10:27:15 -0700790TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200791 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200792 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
793 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700794 codec_.minBitrate = 50;
795 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200796 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng82fad3d2018-03-21 09:57:23 +0100797 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700798
799 // Above min should be respected.
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200800 VideoBitrateAllocation target_bitrate = rate_allocator_->Allocate(
801 VideoBitrateAllocationParameters(codec_.minBitrate * 1000, 30));
Erik Språng16cb8f52019-04-12 13:59:09 +0200802 adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100803 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200804 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700805
806 // Below min but non-zero should be replaced with the min bitrate.
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200807 VideoBitrateAllocation too_low_bitrate = rate_allocator_->Allocate(
808 VideoBitrateAllocationParameters((codec_.minBitrate - 1) * 1000, 30));
Erik Språng16cb8f52019-04-12 13:59:09 +0200809 adapter_->SetRates(
810 VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100811 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200812 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700813
814 // Zero should be passed on as is, since it means "pause".
Erik Språng16cb8f52019-04-12 13:59:09 +0200815 adapter_->SetRates(
816 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
Erik Språng566124a2018-04-23 12:32:22 +0200817 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng16cb8f52019-04-12 13:59:09 +0200818 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700819}
820
Peter Boströma5dec162016-01-20 15:53:55 +0100821TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
Erik Språnge2fd86a2018-10-24 11:32:39 +0200822 EXPECT_EQ("SimulcastEncoderAdapter",
823 adapter_->GetEncoderInfo().implementation_name);
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200824 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200825 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
826 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100827 std::vector<const char*> encoder_names;
828 encoder_names.push_back("codec1");
829 encoder_names.push_back("codec2");
830 encoder_names.push_back("codec3");
831 helper_->factory()->SetEncoderNames(encoder_names);
Elad Alon370f93a2019-06-11 14:57:57 +0200832 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200833 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
834 adapter_->GetEncoderInfo().implementation_name);
Peter Boströmd53c3892016-03-30 17:03:52 +0200835
836 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700837 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200838 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200839 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Peter Boströmd53c3892016-03-30 17:03:52 +0200840 adapter_->RegisterEncodeCompleteCallback(this);
841 ASSERT_EQ(1u, helper_->factory()->encoders().size());
Erik Språnge2fd86a2018-10-24 11:32:39 +0200842 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
Peter Boströma5dec162016-01-20 15:53:55 +0100843}
844
pbos65e15ba2015-10-15 10:52:15 -0700845TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700846 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200847 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200848 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
849 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700850 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200851 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700852 adapter_->RegisterEncodeCompleteCallback(this);
853 ASSERT_EQ(3u, helper_->factory()->encoders().size());
854 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
855 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700856 // If one encoder doesn't support it, then overall support is disabled.
857 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språnge2fd86a2018-10-24 11:32:39 +0200858 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700859 // Once all do, then the adapter claims support.
860 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
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_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700863}
864
nisseaf916892017-01-10 07:44:26 -0800865// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200866class FakeNativeBufferNoI420 : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700867 public:
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200868 FakeNativeBufferNoI420(int width, int height)
869 : width_(width), height_(height) {}
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000870
871 Type type() const override { return Type::kNative; }
872 int width() const override { return width_; }
873 int height() const override { return height_; }
874
875 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700876 RTC_NOTREACHED();
877 return nullptr;
878 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000879
880 private:
881 const int width_;
882 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700883};
884
885TEST_F(TestSimulcastEncoderAdapterFake,
886 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200887 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200888 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
889 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700890 codec_.numberOfSimulcastStreams = 3;
891 // High start bitrate, so all streams are enabled.
892 codec_.startBitrate = 3000;
Elad Alon370f93a2019-06-11 14:57:57 +0200893 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahricfe3654d2016-07-01 09:05:54 -0700894 adapter_->RegisterEncodeCompleteCallback(this);
895 ASSERT_EQ(3u, helper_->factory()->encoders().size());
896 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
897 encoder->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200898 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200899 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700900
901 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200902 new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100903 VideoFrame input_frame = VideoFrame::Builder()
904 .set_video_frame_buffer(buffer)
905 .set_timestamp_rtp(100)
906 .set_timestamp_ms(1000)
907 .set_rotation(kVideoRotation_180)
908 .build();
noahricfe3654d2016-07-01 09:05:54 -0700909 // Expect calls with the given video frame verbatim, since it's a texture
910 // frame and can't otherwise be modified/resized.
911 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
Niels Möllerb859b322019-03-07 12:40:01 +0100912 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _)).Times(1);
Niels Möller8f7ce222019-03-21 15:43:58 +0100913 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100914 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700915}
916
noahric57779102016-05-25 06:48:46 -0700917TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200918 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200919 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
920 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700921 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200922 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahric57779102016-05-25 06:48:46 -0700923 adapter_->RegisterEncodeCompleteCallback(this);
924 ASSERT_EQ(3u, helper_->factory()->encoders().size());
925 // Tell the 2nd encoder to request software fallback.
Niels Möllerb859b322019-03-07 12:40:01 +0100926 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _))
noahricfe3654d2016-07-01 09:05:54 -0700927 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700928
929 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000930 rtc::scoped_refptr<I420Buffer> input_buffer =
931 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700932 input_buffer->InitializeData();
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100933 VideoFrame input_frame = VideoFrame::Builder()
934 .set_video_frame_buffer(input_buffer)
935 .set_timestamp_rtp(0)
936 .set_timestamp_us(0)
937 .set_rotation(kVideoRotation_0)
938 .build();
Niels Möller8f7ce222019-03-21 15:43:58 +0100939 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
noahric57779102016-05-25 06:48:46 -0700940 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Niels Möllerc8d2e732019-03-06 12:00:33 +0100941 adapter_->Encode(input_frame, &frame_types));
noahric57779102016-05-25 06:48:46 -0700942}
943
noahrice5ba75a2016-12-12 13:08:27 -0800944TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200945 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200946 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
947 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800948 codec_.numberOfSimulcastStreams = 3;
949 helper_->factory()->set_init_encode_return_value(
950 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
951 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Elad Alon370f93a2019-06-11 14:57:57 +0200952 adapter_->InitEncode(&codec_, kSettings));
noahrice5ba75a2016-12-12 13:08:27 -0800953 EXPECT_TRUE(helper_->factory()->encoders().empty());
954}
955
Erik Språng8d2995b2018-08-09 11:18:17 +0200956TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
957 const int kHighMaxQp = 56;
958 const int kLowMaxQp = 46;
959
960 SimulcastTestFixtureImpl::DefaultSettings(
961 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
962 kVideoCodecVP8);
963 codec_.numberOfSimulcastStreams = 3;
964 codec_.simulcastStream[0].qpMax = kHighMaxQp;
965 codec_.mode = VideoCodecMode::kScreensharing;
966
Elad Alon370f93a2019-06-11 14:57:57 +0200967 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200968 EXPECT_EQ(3u, helper_->factory()->encoders().size());
969
970 // Just check the lowest stream, which is the one that where the adapter
971 // might alter the max qp setting.
972 VideoCodec ref_codec;
973 InitRefCodec(0, &ref_codec);
974 ref_codec.qpMax = kHighMaxQp;
975 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
976 ref_codec.VP8()->denoisingOn = false;
977 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
978 VerifyCodec(ref_codec, 0);
979
980 // Change the max qp and try again.
981 codec_.simulcastStream[0].qpMax = kLowMaxQp;
Elad Alon370f93a2019-06-11 14:57:57 +0200982 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200983 EXPECT_EQ(3u, helper_->factory()->encoders().size());
984 ref_codec.qpMax = kLowMaxQp;
985 VerifyCodec(ref_codec, 0);
986}
Erik Språng7d687b12018-09-12 17:04:10 +0200987
Florent Castelli1b761ca2019-01-21 14:33:02 +0100988TEST_F(TestSimulcastEncoderAdapterFake,
989 DoesNotAlterMaxQpForScreenshareReversedLayer) {
990 const int kHighMaxQp = 56;
991 const int kLowMaxQp = 46;
992
993 SimulcastTestFixtureImpl::DefaultSettings(
994 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
995 kVideoCodecVP8, true /* reverse_layer_order */);
996 codec_.numberOfSimulcastStreams = 3;
997 codec_.simulcastStream[2].qpMax = kHighMaxQp;
998 codec_.mode = VideoCodecMode::kScreensharing;
999
Elad Alon370f93a2019-06-11 14:57:57 +02001000 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001001 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1002
1003 // Just check the lowest stream, which is the one that where the adapter
1004 // might alter the max qp setting.
1005 VideoCodec ref_codec;
1006 InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
1007 ref_codec.qpMax = kHighMaxQp;
1008 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1009 ref_codec.VP8()->denoisingOn = false;
1010 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1011 VerifyCodec(ref_codec, 2);
1012
1013 // Change the max qp and try again.
1014 codec_.simulcastStream[2].qpMax = kLowMaxQp;
Elad Alon370f93a2019-06-11 14:57:57 +02001015 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001016 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1017 ref_codec.qpMax = kLowMaxQp;
1018 VerifyCodec(ref_codec, 2);
1019}
1020
Erik Språng7d687b12018-09-12 17:04:10 +02001021TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
1022 // Set up common settings for three streams.
1023 SimulcastTestFixtureImpl::DefaultSettings(
1024 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1025 kVideoCodecVP8);
1026 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1027 adapter_->RegisterEncodeCompleteCallback(this);
1028
1029 // Only enough start bitrate for the lowest stream.
1030 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1031 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1032 codec_.simulcastStream[1].minBitrate - 1;
1033
1034 // Input data.
1035 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001036 VideoFrame input_frame = VideoFrame::Builder()
1037 .set_video_frame_buffer(buffer)
1038 .set_timestamp_rtp(100)
1039 .set_timestamp_ms(1000)
1040 .set_rotation(kVideoRotation_180)
1041 .build();
Erik Språng7d687b12018-09-12 17:04:10 +02001042
1043 // Encode with three streams.
Elad Alon370f93a2019-06-11 14:57:57 +02001044 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng7d687b12018-09-12 17:04:10 +02001045 std::vector<MockVideoEncoder*> original_encoders =
1046 helper_->factory()->encoders();
1047 ASSERT_EQ(3u, original_encoders.size());
1048 // Only first encoder will be active and called.
Niels Möllerb859b322019-03-07 12:40:01 +01001049 EXPECT_CALL(*original_encoders[0], Encode(_, _))
Erik Språng7d687b12018-09-12 17:04:10 +02001050 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +01001051 EXPECT_CALL(*original_encoders[1], Encode(_, _)).Times(0);
1052 EXPECT_CALL(*original_encoders[2], Encode(_, _)).Times(0);
Erik Språng7d687b12018-09-12 17:04:10 +02001053
Niels Möller87e2d782019-03-07 10:18:23 +01001054 std::vector<VideoFrameType> frame_types;
Niels Möller8f7ce222019-03-21 15:43:58 +01001055 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +01001056 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
Erik Språng7d687b12018-09-12 17:04:10 +02001057}
Erik Språngd3438aa2018-11-08 16:56:43 +01001058
1059TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
1060 // Set up common settings for three streams.
1061 SimulcastTestFixtureImpl::DefaultSettings(
1062 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1063 kVideoCodecVP8);
1064 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1065 adapter_->RegisterEncodeCompleteCallback(this);
1066
1067 // Only enough start bitrate for the lowest stream.
1068 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1069 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1070 codec_.simulcastStream[1].minBitrate - 1;
1071
1072 // Input data.
1073 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001074 VideoFrame input_frame = VideoFrame::Builder()
1075 .set_video_frame_buffer(buffer)
1076 .set_timestamp_rtp(100)
1077 .set_timestamp_ms(1000)
1078 .set_rotation(kVideoRotation_180)
1079 .build();
Erik Språngd3438aa2018-11-08 16:56:43 +01001080
1081 // No encoder trusted, so simulcast adapter should not be either.
Elad Alon370f93a2019-06-11 14:57:57 +02001082 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001083 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1084
1085 // Encode with three streams.
1086 std::vector<MockVideoEncoder*> original_encoders =
1087 helper_->factory()->encoders();
1088
1089 // All encoders are trusted, so simulcast adapter should be too.
1090 original_encoders[0]->set_has_trusted_rate_controller(true);
1091 original_encoders[1]->set_has_trusted_rate_controller(true);
1092 original_encoders[2]->set_has_trusted_rate_controller(true);
Elad Alon370f93a2019-06-11 14:57:57 +02001093 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001094 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1095
1096 // One encoder not trusted, so simulcast adapter should not be either.
1097 original_encoders[2]->set_has_trusted_rate_controller(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001098 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001099 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1100
1101 // No encoder trusted, so simulcast adapter should not be either.
1102 original_encoders[0]->set_has_trusted_rate_controller(false);
1103 original_encoders[1]->set_has_trusted_rate_controller(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001104 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001105 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1106}
1107
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001108TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1109 SimulcastTestFixtureImpl::DefaultSettings(
1110 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1111 kVideoCodecVP8);
1112 codec_.numberOfSimulcastStreams = 3;
1113 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001114 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001115 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1116
1117 // None of the encoders uses HW support, so simulcast adapter reports false.
1118 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1119 encoder->set_is_hardware_accelerated(false);
1120 }
Elad Alon370f93a2019-06-11 14:57:57 +02001121 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001122 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1123
1124 // One encoder uses HW support, so simulcast adapter reports true.
1125 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
Elad Alon370f93a2019-06-11 14:57:57 +02001126 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001127 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1128}
1129
1130TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1131 SimulcastTestFixtureImpl::DefaultSettings(
1132 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1133 kVideoCodecVP8);
1134 codec_.numberOfSimulcastStreams = 3;
1135 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001136 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001137 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1138
1139 // All encoders have internal source, simulcast adapter reports true.
1140 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1141 encoder->set_has_internal_source(true);
1142 }
Elad Alon370f93a2019-06-11 14:57:57 +02001143 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001144 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1145
1146 // One encoder does not have internal source, simulcast adapter reports false.
1147 helper_->factory()->encoders()[2]->set_has_internal_source(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001148 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001149 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1150}
1151
Erik Språngdbdd8392019-01-17 15:27:50 +01001152TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
1153 SimulcastTestFixtureImpl::DefaultSettings(
1154 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1155 kVideoCodecVP8);
1156 codec_.numberOfSimulcastStreams = 3;
1157 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001158 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001159 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1160
1161 // Combination of three different supported mode:
1162 // Simulcast stream 0 has undefined fps behavior.
1163 // Simulcast stream 1 has three temporal layers.
1164 // Simulcast stream 2 has 1 temporal layer.
1165 FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
1166 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 4);
1167 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 2);
1168 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction);
1169 expected_fps_allocation[2].push_back(EncoderInfo::kMaxFramerateFraction);
1170
1171 // All encoders have internal source, simulcast adapter reports true.
1172 for (size_t i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
1173 MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
1174 encoder->set_fps_allocation(expected_fps_allocation[i]);
1175 }
Elad Alon370f93a2019-06-11 14:57:57 +02001176 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001177 EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
1178 ::testing::ElementsAreArray(expected_fps_allocation));
1179}
1180
Erik Språng16cb8f52019-04-12 13:59:09 +02001181TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
1182 SimulcastTestFixtureImpl::DefaultSettings(
1183 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1184 kVideoCodecVP8);
1185 codec_.numberOfSimulcastStreams = 3;
1186 const DataRate target_bitrate =
1187 DataRate::kbps(codec_.simulcastStream[0].targetBitrate +
1188 codec_.simulcastStream[1].targetBitrate +
1189 codec_.simulcastStream[2].minBitrate);
1190 const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
1191
1192 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 14:57:57 +02001193 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +02001194 adapter_->RegisterEncodeCompleteCallback(this);
1195
1196 // Set bitrates so that we send all layers.
1197 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +02001198 rate_allocator_->Allocate(
1199 VideoBitrateAllocationParameters(target_bitrate.bps(), 30)),
1200 30.0, bandwidth_allocation));
Erik Språng16cb8f52019-04-12 13:59:09 +02001201
1202 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1203
1204 ASSERT_EQ(3u, encoders.size());
1205
1206 for (size_t i = 0; i < 3; ++i) {
1207 const uint32_t layer_bitrate_bps =
1208 (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
1209 ? codec_.simulcastStream[i].targetBitrate
1210 : codec_.simulcastStream[i].minBitrate) *
1211 1000;
1212 EXPECT_EQ(layer_bitrate_bps,
1213 encoders[i]->last_set_rates().bitrate.get_sum_bps())
1214 << i;
1215 EXPECT_EQ(
1216 (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
1217 encoders[i]->last_set_rates().bandwidth_allocation.bps())
1218 << i;
1219 }
1220}
1221
Rasmus Brandt0cedc052018-05-31 12:53:00 +02001222} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001223} // namespace webrtc