blob: 60fc814f032e0ce770de97c616be92801b0bb224 [file] [log] [blame]
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001/*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/engine/simulcast_encoder_adapter.h"
12
brandtr5e171752017-05-23 03:32:16 -070013#include <array>
kwiberg3f55dea2016-02-29 05:51:59 -080014#include <memory>
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000015#include <vector>
16
Rasmus Brandt0cedc052018-05-31 12:53:00 +020017#include "api/test/create_simulcast_test_fixture.h"
18#include "api/test/simulcast_test_fixture.h"
Danil Chapovalov99b71df2018-10-26 15:57:48 +020019#include "api/test/video/function_video_decoder_factory.h"
20#include "api/test/video/function_video_encoder_factory.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010021#include "api/video_codecs/sdp_video_format.h"
Elad Alon370f93a2019-06-11 14:57:57 +020022#include "api/video_codecs/video_encoder.h"
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010023#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "common_video/include/video_frame_buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "media/base/media_constants.h"
26#include "media/engine/internal_encoder_factory.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020027#include "modules/video_coding/codecs/vp8/include/vp8.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "modules/video_coding/include/video_codec_interface.h"
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020029#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "test/gmock.h"
Rasmus Brandt0cedc052018-05-31 12:53:00 +020031#include "test/gtest.h"
32
33using ::testing::_;
34using ::testing::Return;
Erik Språngdbdd8392019-01-17 15:27:50 +010035using EncoderInfo = webrtc::VideoEncoder::EncoderInfo;
36using FramerateFractions =
37 absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000038
39namespace webrtc {
Rasmus Brandt0cedc052018-05-31 12:53:00 +020040namespace test {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000041
Rasmus Brandt0cedc052018-05-31 12:53:00 +020042namespace {
philipelcce46fc2015-12-21 03:04:49 -080043
Rasmus Brandt0cedc052018-05-31 12:53:00 +020044constexpr int kDefaultWidth = 1280;
45constexpr int kDefaultHeight = 720;
magjed6cc25612017-07-10 03:26:36 -070046
Elad Alon370f93a2019-06-11 14:57:57 +020047const VideoEncoder::Capabilities kCapabilities(false);
48const VideoEncoder::Settings kSettings(kCapabilities, 1, 1200);
49
Rasmus Brandt0cedc052018-05-31 12:53:00 +020050std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture(
51 VideoEncoderFactory* internal_encoder_factory) {
52 std::unique_ptr<VideoEncoderFactory> encoder_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +020053 std::make_unique<FunctionVideoEncoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020054 [internal_encoder_factory]() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020055 return std::make_unique<SimulcastEncoderAdapter>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020056 internal_encoder_factory,
57 SdpVideoFormat(cricket::kVp8CodecName));
58 });
59 std::unique_ptr<VideoDecoderFactory> decoder_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +020060 std::make_unique<FunctionVideoDecoderFactory>(
Rasmus Brandt0cedc052018-05-31 12:53:00 +020061 []() { return VP8Decoder::Create(); });
62 return CreateSimulcastTestFixture(std::move(encoder_factory),
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +020063 std::move(decoder_factory),
64 SdpVideoFormat(cricket::kVp8CodecName));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000065}
Rasmus Brandt0cedc052018-05-31 12:53:00 +020066} // namespace
67
68TEST(SimulcastEncoderAdapterSimulcastTest, TestKeyFrameRequestsOnAllStreams) {
69 InternalEncoderFactory internal_encoder_factory;
70 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
71 fixture->TestKeyFrameRequestsOnAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000072}
73
Rasmus Brandt0cedc052018-05-31 12:53:00 +020074TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingAllStreams) {
75 InternalEncoderFactory internal_encoder_factory;
76 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
77 fixture->TestPaddingAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000078}
79
Rasmus Brandt0cedc052018-05-31 12:53:00 +020080TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreams) {
81 InternalEncoderFactory internal_encoder_factory;
82 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
83 fixture->TestPaddingTwoStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000084}
85
Rasmus Brandt0cedc052018-05-31 12:53:00 +020086TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingTwoStreamsOneMaxedOut) {
87 InternalEncoderFactory internal_encoder_factory;
88 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
89 fixture->TestPaddingTwoStreamsOneMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000090}
91
Rasmus Brandt0cedc052018-05-31 12:53:00 +020092TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStream) {
93 InternalEncoderFactory internal_encoder_factory;
94 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
95 fixture->TestPaddingOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000096}
97
Rasmus Brandt0cedc052018-05-31 12:53:00 +020098TEST(SimulcastEncoderAdapterSimulcastTest, TestPaddingOneStreamTwoMaxedOut) {
99 InternalEncoderFactory internal_encoder_factory;
100 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
101 fixture->TestPaddingOneStreamTwoMaxedOut();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000102}
103
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200104TEST(SimulcastEncoderAdapterSimulcastTest, TestSendAllStreams) {
105 InternalEncoderFactory internal_encoder_factory;
106 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
107 fixture->TestSendAllStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000108}
109
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200110TEST(SimulcastEncoderAdapterSimulcastTest, TestDisablingStreams) {
111 InternalEncoderFactory internal_encoder_factory;
112 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
113 fixture->TestDisablingStreams();
Seth Hampson46e31ba2018-01-18 10:39:54 -0800114}
115
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200116TEST(SimulcastEncoderAdapterSimulcastTest, TestActiveStreams) {
117 InternalEncoderFactory internal_encoder_factory;
118 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
119 fixture->TestActiveStreams();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000120}
121
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200122TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneStream) {
123 InternalEncoderFactory internal_encoder_factory;
124 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
125 fixture->TestSwitchingToOneStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000126}
127
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200128TEST(SimulcastEncoderAdapterSimulcastTest, TestSwitchingToOneOddStream) {
129 InternalEncoderFactory internal_encoder_factory;
130 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
131 fixture->TestSwitchingToOneOddStream();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000132}
133
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200134TEST(SimulcastEncoderAdapterSimulcastTest, TestStrideEncodeDecode) {
135 InternalEncoderFactory internal_encoder_factory;
136 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
137 fixture->TestStrideEncodeDecode();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000138}
139
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200140TEST(SimulcastEncoderAdapterSimulcastTest,
141 TestSpatioTemporalLayers333PatternEncoder) {
142 InternalEncoderFactory internal_encoder_factory;
143 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
144 fixture->TestSpatioTemporalLayers333PatternEncoder();
145}
146
147TEST(SimulcastEncoderAdapterSimulcastTest,
148 TestSpatioTemporalLayers321PatternEncoder) {
149 InternalEncoderFactory internal_encoder_factory;
150 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
151 fixture->TestSpatioTemporalLayers321PatternEncoder();
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000152}
153
Per Kjellander841c9122018-10-04 18:40:28 +0200154TEST(SimulcastEncoderAdapterSimulcastTest, TestDecodeWidthHeightSet) {
155 InternalEncoderFactory internal_encoder_factory;
156 auto fixture = CreateSpecificSimulcastTestFixture(&internal_encoder_factory);
157 fixture->TestDecodeWidthHeightSet();
158}
159
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100160class MockVideoEncoder;
161
162class MockVideoEncoderFactory : public VideoEncoderFactory {
163 public:
164 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
165
166 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
167 const SdpVideoFormat& format) override;
168
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000169 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
170
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100171 const std::vector<MockVideoEncoder*>& encoders() const;
172 void SetEncoderNames(const std::vector<const char*>& encoder_names);
173 void set_init_encode_return_value(int32_t value);
174
175 void DestroyVideoEncoder(VideoEncoder* encoder);
176
177 private:
178 int32_t init_encode_return_value_ = 0;
179 std::vector<MockVideoEncoder*> encoders_;
180 std::vector<const char*> encoder_names_;
181};
182
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000183class MockVideoEncoder : public VideoEncoder {
184 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100185 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng75de46a2018-11-07 14:53:32 +0100186 : factory_(factory),
187 scaling_settings_(VideoEncoder::ScalingSettings::kOff),
188 callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100189
Elad Alon8f01c4e2019-06-28 15:19:43 +0200190 MOCK_METHOD1(SetFecControllerOverride,
191 void(FecControllerOverride* fec_controller_override));
192
nisseef8b61e2016-04-29 06:09:15 -0700193 // TODO(nisse): Valid overrides commented out, because the gmock
194 // methods don't use any override declarations, and we want to avoid
195 // warnings from -Winconsistent-missing-override. See
196 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000197 int32_t InitEncode(const VideoCodec* codecSettings,
Elad Alona9952cb2019-06-11 19:03:16 +0200198 const VideoEncoder::Settings& settings) override {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000199 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800200 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000201 }
202
Niels Möllerb859b322019-03-07 12:40:01 +0100203 MOCK_METHOD2(
noahricfe3654d2016-07-01 09:05:54 -0700204 Encode,
205 int32_t(const VideoFrame& inputImage,
Niels Möller87e2d782019-03-07 10:18:23 +0100206 const std::vector<VideoFrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000207
pbos65e15ba2015-10-15 10:52:15 -0700208 int32_t RegisterEncodeCompleteCallback(
Elad Alona9952cb2019-06-11 19:03:16 +0200209 EncodedImageCallback* callback) override {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700210 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000211 return 0;
212 }
213
Elad Alona9952cb2019-06-11 19:03:16 +0200214 MOCK_METHOD0(Release, int32_t() /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000215
Erik Språng16cb8f52019-04-12 13:59:09 +0200216 void SetRates(const RateControlParameters& parameters) {
217 last_set_rates_ = parameters;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000218 }
219
Erik Språng9b5b0702018-11-01 14:52:30 +0100220 EncoderInfo GetEncoderInfo() const override {
221 EncoderInfo info;
222 info.supports_native_handle = supports_native_handle_;
223 info.implementation_name = implementation_name_;
Erik Språng75de46a2018-11-07 14:53:32 +0100224 info.scaling_settings = scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100225 info.has_trusted_rate_controller = has_trusted_rate_controller_;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100226 info.is_hardware_accelerated = is_hardware_accelerated_;
227 info.has_internal_source = has_internal_source_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100228 info.fps_allocation[0] = fps_allocation_;
Erik Språng9b5b0702018-11-01 14:52:30 +0100229 return info;
nisseef8b61e2016-04-29 06:09:15 -0700230 }
pbos65e15ba2015-10-15 10:52:15 -0700231
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100232 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000233
234 const VideoCodec& codec() const { return codec_; }
235
Noah Richards41ee1ea2015-04-15 09:24:26 -0700236 void SendEncodedImage(int width, int height) {
237 // Sends a fake image of the given width/height.
238 EncodedImage image;
239 image._encodedWidth = width;
240 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700241 CodecSpecificInfo codec_specific_info;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200242 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
brandtr5e171752017-05-23 03:32:16 -0700243 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700244 }
245
pbos65e15ba2015-10-15 10:52:15 -0700246 void set_supports_native_handle(bool enabled) {
247 supports_native_handle_ = enabled;
248 }
noahrice5ba75a2016-12-12 13:08:27 -0800249
Erik Språng9b5b0702018-11-01 14:52:30 +0100250 void set_implementation_name(const std::string& name) {
251 implementation_name_ = name;
252 }
253
noahrice5ba75a2016-12-12 13:08:27 -0800254 void set_init_encode_return_value(int32_t value) {
255 init_encode_return_value_ = value;
256 }
257
Erik Språng75de46a2018-11-07 14:53:32 +0100258 void set_scaling_settings(const VideoEncoder::ScalingSettings& settings) {
259 scaling_settings_ = settings;
260 }
261
Erik Språngd3438aa2018-11-08 16:56:43 +0100262 void set_has_trusted_rate_controller(bool trusted) {
263 has_trusted_rate_controller_ = trusted;
264 }
265
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100266 void set_is_hardware_accelerated(bool is_hardware_accelerated) {
267 is_hardware_accelerated_ = is_hardware_accelerated;
268 }
269
270 void set_has_internal_source(bool has_internal_source) {
271 has_internal_source_ = has_internal_source;
272 }
273
Erik Språngdbdd8392019-01-17 15:27:50 +0100274 void set_fps_allocation(const FramerateFractions& fps_allocation) {
275 fps_allocation_ = fps_allocation;
276 }
277
Erik Språng16cb8f52019-04-12 13:59:09 +0200278 RateControlParameters last_set_rates() const { return last_set_rates_; }
pbos65e15ba2015-10-15 10:52:15 -0700279
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000280 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100281 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700282 bool supports_native_handle_ = false;
Erik Språng9b5b0702018-11-01 14:52:30 +0100283 std::string implementation_name_ = "unknown";
Erik Språng75de46a2018-11-07 14:53:32 +0100284 VideoEncoder::ScalingSettings scaling_settings_;
Erik Språngd3438aa2018-11-08 16:56:43 +0100285 bool has_trusted_rate_controller_ = false;
Mirta Dvornicic897a9912018-11-30 13:12:21 +0100286 bool is_hardware_accelerated_ = false;
287 bool has_internal_source_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800288 int32_t init_encode_return_value_ = 0;
Erik Språng16cb8f52019-04-12 13:59:09 +0200289 VideoEncoder::RateControlParameters last_set_rates_;
Erik Språngdbdd8392019-01-17 15:27:50 +0100290 FramerateFractions fps_allocation_;
noahricfac0ff02016-09-09 10:27:15 -0700291
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000292 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700293 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000294};
295
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100296std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
297 const {
298 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
299 return formats;
300}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000301
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100302std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
303 const SdpVideoFormat& format) {
304 std::unique_ptr<MockVideoEncoder> encoder(
305 new ::testing::NiceMock<MockVideoEncoder>(this));
306 encoder->set_init_encode_return_value(init_encode_return_value_);
307 const char* encoder_name = encoder_names_.empty()
308 ? "codec_implementation_name"
309 : encoder_names_[encoders_.size()];
Erik Språng9b5b0702018-11-01 14:52:30 +0100310 encoder->set_implementation_name(encoder_name);
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100311 encoders_.push_back(encoder.get());
312 return encoder;
313}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000314
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100315void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
316 for (size_t i = 0; i < encoders_.size(); ++i) {
317 if (encoders_[i] == encoder) {
318 encoders_.erase(encoders_.begin() + i);
319 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000320 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000321 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100322}
Zhi Huangaea84f52017-11-16 18:46:27 +0000323
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +0000324VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
325 const SdpVideoFormat& format) const {
326 return CodecInfo();
327}
328
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100329const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
330 const {
331 return encoders_;
332}
333void MockVideoEncoderFactory::SetEncoderNames(
334 const std::vector<const char*>& encoder_names) {
335 encoder_names_ = encoder_names;
336}
337void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
338 init_encode_return_value_ = value;
339}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000340
341class TestSimulcastEncoderAdapterFakeHelper {
342 public:
343 TestSimulcastEncoderAdapterFakeHelper()
344 : factory_(new MockVideoEncoderFactory()) {}
345
346 // Can only be called once as the SimulcastEncoderAdapter will take the
347 // ownership of |factory_|.
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200348 VideoEncoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200349 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000350 }
351
magjed6cc25612017-07-10 03:26:36 -0700352 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000353
354 private:
magjed6cc25612017-07-10 03:26:36 -0700355 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000356};
357
358static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
359
Noah Richards41ee1ea2015-04-15 09:24:26 -0700360class TestSimulcastEncoderAdapterFake : public ::testing::Test,
361 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000362 public:
363 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700364 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
365 adapter_(helper_->CreateMockEncoderAdapter()),
366 last_encoded_image_width_(-1),
367 last_encoded_image_height_(-1),
368 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700369 virtual ~TestSimulcastEncoderAdapterFake() {
370 if (adapter_) {
371 adapter_->Release();
372 }
373 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000374
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700375 Result OnEncodedImage(const EncodedImage& encoded_image,
376 const CodecSpecificInfo* codec_specific_info,
377 const RTPFragmentationHeader* fragmentation) override {
378 last_encoded_image_width_ = encoded_image._encodedWidth;
379 last_encoded_image_height_ = encoded_image._encodedHeight;
Niels Möllerd3b8c632018-08-27 15:33:42 +0200380 last_encoded_image_simulcast_index_ =
381 encoded_image.SpatialIndex().value_or(-1);
382
Niels Möller72bc8d62018-09-12 10:03:51 +0200383 return Result(Result::OK, encoded_image.Timestamp());
Noah Richards41ee1ea2015-04-15 09:24:26 -0700384 }
385
386 bool GetLastEncodedImageInfo(int* out_width,
387 int* out_height,
388 int* out_simulcast_index) {
389 if (last_encoded_image_width_ == -1) {
390 return false;
391 }
392 *out_width = last_encoded_image_width_;
393 *out_height = last_encoded_image_height_;
394 *out_simulcast_index = last_encoded_image_simulcast_index_;
395 return true;
396 }
397
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000398 void SetupCodec() {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200399 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200400 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
401 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100402 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 14:57:57 +0200403 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700404 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000405 }
406
407 void VerifyCodec(const VideoCodec& ref, int stream_index) {
408 const VideoCodec& target =
409 helper_->factory()->encoders()[stream_index]->codec();
410 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000411 EXPECT_EQ(ref.plType, target.plType);
412 EXPECT_EQ(ref.width, target.width);
413 EXPECT_EQ(ref.height, target.height);
414 EXPECT_EQ(ref.startBitrate, target.startBitrate);
415 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
416 EXPECT_EQ(ref.minBitrate, target.minBitrate);
417 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700418 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700419 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
420 target.VP8().numberOfTemporalLayers);
421 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700422 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
423 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
424 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000425 EXPECT_EQ(ref.qpMax, target.qpMax);
426 EXPECT_EQ(0, target.numberOfSimulcastStreams);
427 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000428
429 // No need to compare simulcastStream as numberOfSimulcastStreams should
430 // always be 0.
431 }
432
Florent Castelli1b761ca2019-01-21 14:33:02 +0100433 void InitRefCodec(int stream_index,
434 VideoCodec* ref_codec,
435 bool reverse_layer_order = false) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000436 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700437 ref_codec->VP8()->numberOfTemporalLayers =
Florent Castelli1b761ca2019-01-21 14:33:02 +0100438 kTestTemporalLayerProfile[reverse_layer_order ? 2 - stream_index
439 : stream_index];
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000440 ref_codec->width = codec_.simulcastStream[stream_index].width;
441 ref_codec->height = codec_.simulcastStream[stream_index].height;
442 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
443 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
444 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
445 }
446
447 void VerifyCodecSettings() {
448 EXPECT_EQ(3u, helper_->factory()->encoders().size());
449 VideoCodec ref_codec;
450
451 // stream 0, the lowest resolution stream.
452 InitRefCodec(0, &ref_codec);
453 ref_codec.qpMax = 45;
Niels Möllere3cf3d02018-06-13 11:52:16 +0200454 ref_codec.VP8()->complexity =
455 webrtc::VideoCodecComplexity::kComplexityHigher;
hta257dc392016-10-25 09:05:06 -0700456 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000457 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
458 VerifyCodec(ref_codec, 0);
459
460 // stream 1
461 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700462 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700463 // The start bitrate (300kbit) minus what we have for the lower layers
464 // (100kbit).
465 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000466 VerifyCodec(ref_codec, 1);
467
468 // stream 2, the biggest resolution stream.
469 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700470 // We don't have enough bits to send this, so the adapter should have
471 // configured it to use the min bitrate for this layer (600kbit) but turn
472 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000473 ref_codec.startBitrate = 600;
474 VerifyCodec(ref_codec, 2);
475 }
476
477 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800478 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200479 std::unique_ptr<VideoEncoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000480 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700481 int last_encoded_image_width_;
482 int last_encoded_image_height_;
483 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100484 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000485};
486
487TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
488 SetupCodec();
489 VerifyCodecSettings();
490}
491
brandtr5e171752017-05-23 03:32:16 -0700492TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
493 EXPECT_EQ(0, adapter_->Release());
494}
495
496TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
497 SetupCodec();
498 EXPECT_EQ(0, adapter_->Release());
499
Elad Alon370f93a2019-06-11 14:57:57 +0200500 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700501}
502
Noah Richards41ee1ea2015-04-15 09:24:26 -0700503TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
504 SetupCodec();
505
Peter Boström5d0379d2015-10-06 14:04:51 +0200506 // Set bitrates so that we send all layers.
Erik Språng16cb8f52019-04-12 13:59:09 +0200507 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200508 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
509 30.0));
Peter Boström5d0379d2015-10-06 14:04:51 +0200510
Noah Richards41ee1ea2015-04-15 09:24:26 -0700511 // At this point, the simulcast encoder adapter should have 3 streams: HD,
512 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
513 // resolutions, to test that the adapter forwards on the correct resolution
514 // and simulcast index values, going only off the encoder that generates the
515 // image.
brandtr5e171752017-05-23 03:32:16 -0700516 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
517 ASSERT_EQ(3u, encoders.size());
518 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700519 int width;
520 int height;
521 int simulcast_index;
522 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
523 EXPECT_EQ(1152, width);
524 EXPECT_EQ(704, height);
525 EXPECT_EQ(0, simulcast_index);
526
brandtr5e171752017-05-23 03:32:16 -0700527 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700528 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
529 EXPECT_EQ(300, width);
530 EXPECT_EQ(620, height);
531 EXPECT_EQ(1, simulcast_index);
532
brandtr5e171752017-05-23 03:32:16 -0700533 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700534 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
535 EXPECT_EQ(120, width);
536 EXPECT_EQ(240, height);
537 EXPECT_EQ(2, simulcast_index);
538}
539
brandtr5e171752017-05-23 03:32:16 -0700540// This test verifies that the underlying encoders are reused, when the adapter
541// is reinited with different number of simulcast streams. It further checks
542// that the allocated encoders are reused in the same order as before, starting
543// with the lowest stream.
544TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
545 // Set up common settings for three streams.
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200546 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200547 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
548 kVideoCodecVP8);
Erik Språng82fad3d2018-03-21 09:57:23 +0100549 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700550 adapter_->RegisterEncodeCompleteCallback(this);
Erik Språng7d687b12018-09-12 17:04:10 +0200551 const uint32_t target_bitrate =
552 1000 * (codec_.simulcastStream[0].targetBitrate +
553 codec_.simulcastStream[1].targetBitrate +
554 codec_.simulcastStream[2].minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700555
556 // Input data.
557 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100558 VideoFrame input_frame = VideoFrame::Builder()
559 .set_video_frame_buffer(buffer)
560 .set_timestamp_rtp(100)
561 .set_timestamp_ms(1000)
562 .set_rotation(kVideoRotation_180)
563 .build();
Niels Möller87e2d782019-03-07 10:18:23 +0100564 std::vector<VideoFrameType> frame_types;
brandtr5e171752017-05-23 03:32:16 -0700565
566 // Encode with three streams.
Elad Alon370f93a2019-06-11 14:57:57 +0200567 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700568 VerifyCodecSettings();
Erik Språng16cb8f52019-04-12 13:59:09 +0200569 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200570 rate_allocator_->Allocate(
571 VideoBitrateAllocationParameters(target_bitrate, 30)),
572 30.0));
Erik Språng7d687b12018-09-12 17:04:10 +0200573
brandtr5e171752017-05-23 03:32:16 -0700574 std::vector<MockVideoEncoder*> original_encoders =
575 helper_->factory()->encoders();
576 ASSERT_EQ(3u, original_encoders.size());
Niels Möllerb859b322019-03-07 12:40:01 +0100577 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700578 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100579 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700580 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100581 EXPECT_CALL(*original_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700582 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100583 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100584 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700585 EXPECT_CALL(*original_encoders[0], Release())
586 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
587 EXPECT_CALL(*original_encoders[1], Release())
588 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
589 EXPECT_CALL(*original_encoders[2], Release())
590 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
591 EXPECT_EQ(0, adapter_->Release());
592
593 // Encode with two streams.
594 codec_.width /= 2;
595 codec_.height /= 2;
596 codec_.numberOfSimulcastStreams = 2;
Elad Alon370f93a2019-06-11 14:57:57 +0200597 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200598 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200599 rate_allocator_->Allocate(
600 VideoBitrateAllocationParameters(target_bitrate, 30)),
601 30.0));
brandtr5e171752017-05-23 03:32:16 -0700602 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
603 ASSERT_EQ(2u, new_encoders.size());
604 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100605 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700606 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
607 ASSERT_EQ(original_encoders[1], new_encoders[1]);
Niels Möllerb859b322019-03-07 12:40:01 +0100608 EXPECT_CALL(*original_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700609 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100610 frame_types.resize(2, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100611 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700612 EXPECT_CALL(*original_encoders[0], Release())
613 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
614 EXPECT_CALL(*original_encoders[1], Release())
615 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
616 EXPECT_EQ(0, adapter_->Release());
617
618 // Encode with single stream.
619 codec_.width /= 2;
620 codec_.height /= 2;
621 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200622 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200623 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200624 rate_allocator_->Allocate(
625 VideoBitrateAllocationParameters(target_bitrate, 30)),
626 30.0));
brandtr5e171752017-05-23 03:32:16 -0700627 new_encoders = helper_->factory()->encoders();
628 ASSERT_EQ(1u, new_encoders.size());
629 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100630 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700631 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100632 frame_types.resize(1, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100633 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700634 EXPECT_CALL(*original_encoders[0], Release())
635 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
636 EXPECT_EQ(0, adapter_->Release());
637
638 // Encode with three streams, again.
639 codec_.width *= 4;
640 codec_.height *= 4;
641 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200642 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200643 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200644 rate_allocator_->Allocate(
645 VideoBitrateAllocationParameters(target_bitrate, 30)),
646 30.0));
brandtr5e171752017-05-23 03:32:16 -0700647 new_encoders = helper_->factory()->encoders();
648 ASSERT_EQ(3u, new_encoders.size());
649 // The first encoder is reused.
650 ASSERT_EQ(original_encoders[0], new_encoders[0]);
Niels Möllerb859b322019-03-07 12:40:01 +0100651 EXPECT_CALL(*original_encoders[0], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700652 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
653 // The second and third encoders are new.
Niels Möllerb859b322019-03-07 12:40:01 +0100654 EXPECT_CALL(*new_encoders[1], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700655 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +0100656 EXPECT_CALL(*new_encoders[2], Encode(_, _))
brandtr5e171752017-05-23 03:32:16 -0700657 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möller8f7ce222019-03-21 15:43:58 +0100658 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100659 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
brandtr5e171752017-05-23 03:32:16 -0700660 EXPECT_CALL(*original_encoders[0], Release())
661 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
662 EXPECT_CALL(*new_encoders[1], Release())
663 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
664 EXPECT_CALL(*new_encoders[2], Release())
665 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
666 EXPECT_EQ(0, adapter_->Release());
667}
668
669TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
670 SetupCodec();
671 VerifyCodecSettings();
672
673 EXPECT_EQ(3u, helper_->factory()->encoders().size());
674
675 // The adapter should destroy all encoders it has allocated. Since
676 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
677 // lsan to find leaks here.
678 EXPECT_EQ(0, adapter_->Release());
679 adapter_.reset();
680}
681
682// This test verifies that an adapter reinit with the same codec settings as
683// before does not change the underlying encoder codec settings.
684TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
685 SetupCodec();
686 VerifyCodecSettings();
687
688 // Capture current codec settings.
689 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
690 ASSERT_EQ(3u, encoders.size());
691 std::array<VideoCodec, 3> codecs_before;
692 for (int i = 0; i < 3; ++i) {
693 codecs_before[i] = encoders[i]->codec();
694 }
695
696 // Reinitialize and verify that the new codec settings are the same.
697 EXPECT_EQ(0, adapter_->Release());
Elad Alon370f93a2019-06-11 14:57:57 +0200698 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
brandtr5e171752017-05-23 03:32:16 -0700699 for (int i = 0; i < 3; ++i) {
700 const VideoCodec& codec_before = codecs_before[i];
701 const VideoCodec& codec_after = encoders[i]->codec();
702
703 // webrtc::VideoCodec does not implement operator==.
704 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
705 EXPECT_EQ(codec_before.plType, codec_after.plType);
706 EXPECT_EQ(codec_before.width, codec_after.width);
707 EXPECT_EQ(codec_before.height, codec_after.height);
708 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
709 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
710 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
brandtr5e171752017-05-23 03:32:16 -0700711 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
712 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
713 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
714 codec_after.numberOfSimulcastStreams);
715 EXPECT_EQ(codec_before.mode, codec_after.mode);
716 EXPECT_EQ(codec_before.expect_encode_from_texture,
717 codec_after.expect_encode_from_texture);
718 }
719}
720
721// This test is similar to the one above, except that it tests the simulcastIdx
722// from the CodecSpecificInfo that is connected to an encoded frame. The
723// PayloadRouter demuxes the incoming encoded frames on different RTP modules
724// using the simulcastIdx, so it's important that there is no corresponding
725// encoder reordering in between adapter reinits as this would lead to PictureID
726// discontinuities.
727TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
728 SetupCodec();
Erik Språng16cb8f52019-04-12 13:59:09 +0200729 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200730 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
731 30.0));
brandtr5e171752017-05-23 03:32:16 -0700732 VerifyCodecSettings();
733
734 // Send frames on all streams.
735 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
736 ASSERT_EQ(3u, encoders.size());
737 encoders[0]->SendEncodedImage(1152, 704);
738 int width;
739 int height;
740 int simulcast_index;
741 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
742 EXPECT_EQ(0, simulcast_index);
743
744 encoders[1]->SendEncodedImage(300, 620);
745 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
746 EXPECT_EQ(1, simulcast_index);
747
748 encoders[2]->SendEncodedImage(120, 240);
749 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
750 EXPECT_EQ(2, simulcast_index);
751
752 // Reinitialize.
753 EXPECT_EQ(0, adapter_->Release());
Elad Alon370f93a2019-06-11 14:57:57 +0200754 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +0200755 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200756 rate_allocator_->Allocate(VideoBitrateAllocationParameters(1200, 30)),
757 30.0));
brandtr5e171752017-05-23 03:32:16 -0700758
759 // Verify that the same encoder sends out frames on the same simulcast index.
760 encoders[0]->SendEncodedImage(1152, 704);
761 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
762 EXPECT_EQ(0, simulcast_index);
763
764 encoders[1]->SendEncodedImage(300, 620);
765 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
766 EXPECT_EQ(1, simulcast_index);
767
768 encoders[2]->SendEncodedImage(120, 240);
769 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
770 EXPECT_EQ(2, simulcast_index);
771}
772
pbos65e15ba2015-10-15 10:52:15 -0700773TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200774 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200775 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
776 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700777 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200778 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700779 adapter_->RegisterEncodeCompleteCallback(this);
780 ASSERT_EQ(1u, helper_->factory()->encoders().size());
781 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200782 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200783 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700784 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Elad Alon370f93a2019-06-11 14:57:57 +0200785 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200786 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
pbos65e15ba2015-10-15 10:52:15 -0700787}
788
noahricfac0ff02016-09-09 10:27:15 -0700789TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200790 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200791 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
792 kVideoCodecVP8);
noahricfac0ff02016-09-09 10:27:15 -0700793 codec_.minBitrate = 50;
794 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200795 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng82fad3d2018-03-21 09:57:23 +0100796 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700797
798 // Above min should be respected.
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200799 VideoBitrateAllocation target_bitrate = rate_allocator_->Allocate(
800 VideoBitrateAllocationParameters(codec_.minBitrate * 1000, 30));
Erik Språng16cb8f52019-04-12 13:59:09 +0200801 adapter_->SetRates(VideoEncoder::RateControlParameters(target_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100802 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200803 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700804
805 // Below min but non-zero should be replaced with the min bitrate.
Florent Castelli8bbdb5b2019-08-02 15:16:28 +0200806 VideoBitrateAllocation too_low_bitrate = rate_allocator_->Allocate(
807 VideoBitrateAllocationParameters((codec_.minBitrate - 1) * 1000, 30));
Erik Språng16cb8f52019-04-12 13:59:09 +0200808 adapter_->SetRates(
809 VideoEncoder::RateControlParameters(too_low_bitrate, 30.0));
Erik Språng08127a92016-11-16 16:41:30 +0100810 EXPECT_EQ(target_bitrate,
Erik Språng16cb8f52019-04-12 13:59:09 +0200811 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700812
813 // Zero should be passed on as is, since it means "pause".
Erik Språng16cb8f52019-04-12 13:59:09 +0200814 adapter_->SetRates(
815 VideoEncoder::RateControlParameters(VideoBitrateAllocation(), 30.0));
Erik Språng566124a2018-04-23 12:32:22 +0200816 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng16cb8f52019-04-12 13:59:09 +0200817 helper_->factory()->encoders()[0]->last_set_rates().bitrate);
noahricfac0ff02016-09-09 10:27:15 -0700818}
819
Peter Boströma5dec162016-01-20 15:53:55 +0100820TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
Erik Språnge2fd86a2018-10-24 11:32:39 +0200821 EXPECT_EQ("SimulcastEncoderAdapter",
822 adapter_->GetEncoderInfo().implementation_name);
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200823 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200824 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
825 kVideoCodecVP8);
Peter Boströma5dec162016-01-20 15:53:55 +0100826 std::vector<const char*> encoder_names;
827 encoder_names.push_back("codec1");
828 encoder_names.push_back("codec2");
829 encoder_names.push_back("codec3");
830 helper_->factory()->SetEncoderNames(encoder_names);
Elad Alon370f93a2019-06-11 14:57:57 +0200831 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200832 EXPECT_EQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
833 adapter_->GetEncoderInfo().implementation_name);
Peter Boströmd53c3892016-03-30 17:03:52 +0200834
835 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700836 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200837 codec_.numberOfSimulcastStreams = 1;
Elad Alon370f93a2019-06-11 14:57:57 +0200838 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Peter Boströmd53c3892016-03-30 17:03:52 +0200839 adapter_->RegisterEncodeCompleteCallback(this);
840 ASSERT_EQ(1u, helper_->factory()->encoders().size());
Erik Språnge2fd86a2018-10-24 11:32:39 +0200841 EXPECT_EQ("codec1", adapter_->GetEncoderInfo().implementation_name);
Peter Boströma5dec162016-01-20 15:53:55 +0100842}
843
pbos65e15ba2015-10-15 10:52:15 -0700844TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700845 SupportsNativeHandleForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200846 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200847 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
848 kVideoCodecVP8);
pbos65e15ba2015-10-15 10:52:15 -0700849 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200850 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
pbos65e15ba2015-10-15 10:52:15 -0700851 adapter_->RegisterEncodeCompleteCallback(this);
852 ASSERT_EQ(3u, helper_->factory()->encoders().size());
853 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
854 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700855 // If one encoder doesn't support it, then overall support is disabled.
856 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
Erik Språnge2fd86a2018-10-24 11:32:39 +0200857 EXPECT_FALSE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700858 // Once all do, then the adapter claims support.
859 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200860 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200861 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700862}
863
nisseaf916892017-01-10 07:44:26 -0800864// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200865class FakeNativeBufferNoI420 : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700866 public:
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200867 FakeNativeBufferNoI420(int width, int height)
868 : width_(width), height_(height) {}
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000869
870 Type type() const override { return Type::kNative; }
871 int width() const override { return width_; }
872 int height() const override { return height_; }
873
874 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700875 RTC_NOTREACHED();
876 return nullptr;
877 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000878
879 private:
880 const int width_;
881 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700882};
883
884TEST_F(TestSimulcastEncoderAdapterFake,
885 NativeHandleForwardingForMultipleStreams) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200886 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200887 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
888 kVideoCodecVP8);
noahricfe3654d2016-07-01 09:05:54 -0700889 codec_.numberOfSimulcastStreams = 3;
890 // High start bitrate, so all streams are enabled.
891 codec_.startBitrate = 3000;
Elad Alon370f93a2019-06-11 14:57:57 +0200892 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahricfe3654d2016-07-01 09:05:54 -0700893 adapter_->RegisterEncodeCompleteCallback(this);
894 ASSERT_EQ(3u, helper_->factory()->encoders().size());
895 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
896 encoder->set_supports_native_handle(true);
Elad Alon370f93a2019-06-11 14:57:57 +0200897 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språnge2fd86a2018-10-24 11:32:39 +0200898 EXPECT_TRUE(adapter_->GetEncoderInfo().supports_native_handle);
noahricfe3654d2016-07-01 09:05:54 -0700899
900 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Mirko Bonadeid93a51d2018-07-17 15:47:51 +0200901 new rtc::RefCountedObject<FakeNativeBufferNoI420>(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100902 VideoFrame input_frame = VideoFrame::Builder()
903 .set_video_frame_buffer(buffer)
904 .set_timestamp_rtp(100)
905 .set_timestamp_ms(1000)
906 .set_rotation(kVideoRotation_180)
907 .build();
noahricfe3654d2016-07-01 09:05:54 -0700908 // Expect calls with the given video frame verbatim, since it's a texture
909 // frame and can't otherwise be modified/resized.
910 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
Niels Möllerb859b322019-03-07 12:40:01 +0100911 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _)).Times(1);
Niels Möller8f7ce222019-03-21 15:43:58 +0100912 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +0100913 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700914}
915
noahric57779102016-05-25 06:48:46 -0700916TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200917 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200918 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
919 kVideoCodecVP8);
noahric57779102016-05-25 06:48:46 -0700920 codec_.numberOfSimulcastStreams = 3;
Elad Alon370f93a2019-06-11 14:57:57 +0200921 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
noahric57779102016-05-25 06:48:46 -0700922 adapter_->RegisterEncodeCompleteCallback(this);
923 ASSERT_EQ(3u, helper_->factory()->encoders().size());
924 // Tell the 2nd encoder to request software fallback.
Niels Möllerb859b322019-03-07 12:40:01 +0100925 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _))
noahricfe3654d2016-07-01 09:05:54 -0700926 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700927
928 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000929 rtc::scoped_refptr<I420Buffer> input_buffer =
930 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700931 input_buffer->InitializeData();
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100932 VideoFrame input_frame = VideoFrame::Builder()
933 .set_video_frame_buffer(input_buffer)
934 .set_timestamp_rtp(0)
935 .set_timestamp_us(0)
936 .set_rotation(kVideoRotation_0)
937 .build();
Niels Möller8f7ce222019-03-21 15:43:58 +0100938 std::vector<VideoFrameType> frame_types(3, VideoFrameType::kVideoFrameKey);
noahric57779102016-05-25 06:48:46 -0700939 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Niels Möllerc8d2e732019-03-06 12:00:33 +0100940 adapter_->Encode(input_frame, &frame_types));
noahric57779102016-05-25 06:48:46 -0700941}
942
noahrice5ba75a2016-12-12 13:08:27 -0800943TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
Rasmus Brandt0cedc052018-05-31 12:53:00 +0200944 SimulcastTestFixtureImpl::DefaultSettings(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200945 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
946 kVideoCodecVP8);
noahrice5ba75a2016-12-12 13:08:27 -0800947 codec_.numberOfSimulcastStreams = 3;
948 helper_->factory()->set_init_encode_return_value(
949 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
950 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
Elad Alon370f93a2019-06-11 14:57:57 +0200951 adapter_->InitEncode(&codec_, kSettings));
noahrice5ba75a2016-12-12 13:08:27 -0800952 EXPECT_TRUE(helper_->factory()->encoders().empty());
953}
954
Erik Språng8d2995b2018-08-09 11:18:17 +0200955TEST_F(TestSimulcastEncoderAdapterFake, DoesNotAlterMaxQpForScreenshare) {
956 const int kHighMaxQp = 56;
957 const int kLowMaxQp = 46;
958
959 SimulcastTestFixtureImpl::DefaultSettings(
960 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
961 kVideoCodecVP8);
962 codec_.numberOfSimulcastStreams = 3;
963 codec_.simulcastStream[0].qpMax = kHighMaxQp;
964 codec_.mode = VideoCodecMode::kScreensharing;
965
Elad Alon370f93a2019-06-11 14:57:57 +0200966 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200967 EXPECT_EQ(3u, helper_->factory()->encoders().size());
968
969 // Just check the lowest stream, which is the one that where the adapter
970 // might alter the max qp setting.
971 VideoCodec ref_codec;
972 InitRefCodec(0, &ref_codec);
973 ref_codec.qpMax = kHighMaxQp;
974 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
975 ref_codec.VP8()->denoisingOn = false;
976 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
977 VerifyCodec(ref_codec, 0);
978
979 // Change the max qp and try again.
980 codec_.simulcastStream[0].qpMax = kLowMaxQp;
Elad Alon370f93a2019-06-11 14:57:57 +0200981 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng8d2995b2018-08-09 11:18:17 +0200982 EXPECT_EQ(3u, helper_->factory()->encoders().size());
983 ref_codec.qpMax = kLowMaxQp;
984 VerifyCodec(ref_codec, 0);
985}
Erik Språng7d687b12018-09-12 17:04:10 +0200986
Florent Castelli1b761ca2019-01-21 14:33:02 +0100987TEST_F(TestSimulcastEncoderAdapterFake,
988 DoesNotAlterMaxQpForScreenshareReversedLayer) {
989 const int kHighMaxQp = 56;
990 const int kLowMaxQp = 46;
991
992 SimulcastTestFixtureImpl::DefaultSettings(
993 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
994 kVideoCodecVP8, true /* reverse_layer_order */);
995 codec_.numberOfSimulcastStreams = 3;
996 codec_.simulcastStream[2].qpMax = kHighMaxQp;
997 codec_.mode = VideoCodecMode::kScreensharing;
998
Elad Alon370f93a2019-06-11 14:57:57 +0200999 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001000 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1001
1002 // Just check the lowest stream, which is the one that where the adapter
1003 // might alter the max qp setting.
1004 VideoCodec ref_codec;
1005 InitRefCodec(2, &ref_codec, true /* reverse_layer_order */);
1006 ref_codec.qpMax = kHighMaxQp;
1007 ref_codec.VP8()->complexity = webrtc::VideoCodecComplexity::kComplexityHigher;
1008 ref_codec.VP8()->denoisingOn = false;
1009 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
1010 VerifyCodec(ref_codec, 2);
1011
1012 // Change the max qp and try again.
1013 codec_.simulcastStream[2].qpMax = kLowMaxQp;
Elad Alon370f93a2019-06-11 14:57:57 +02001014 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Florent Castelli1b761ca2019-01-21 14:33:02 +01001015 EXPECT_EQ(3u, helper_->factory()->encoders().size());
1016 ref_codec.qpMax = kLowMaxQp;
1017 VerifyCodec(ref_codec, 2);
1018}
1019
Erik Språng7d687b12018-09-12 17:04:10 +02001020TEST_F(TestSimulcastEncoderAdapterFake, ActivatesCorrectStreamsInInitEncode) {
1021 // Set up common settings for three streams.
1022 SimulcastTestFixtureImpl::DefaultSettings(
1023 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1024 kVideoCodecVP8);
1025 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1026 adapter_->RegisterEncodeCompleteCallback(this);
1027
1028 // Only enough start bitrate for the lowest stream.
1029 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1030 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1031 codec_.simulcastStream[1].minBitrate - 1;
1032
1033 // Input data.
1034 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001035 VideoFrame input_frame = VideoFrame::Builder()
1036 .set_video_frame_buffer(buffer)
1037 .set_timestamp_rtp(100)
1038 .set_timestamp_ms(1000)
1039 .set_rotation(kVideoRotation_180)
1040 .build();
Erik Språng7d687b12018-09-12 17:04:10 +02001041
1042 // Encode with three streams.
Elad Alon370f93a2019-06-11 14:57:57 +02001043 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng7d687b12018-09-12 17:04:10 +02001044 std::vector<MockVideoEncoder*> original_encoders =
1045 helper_->factory()->encoders();
1046 ASSERT_EQ(3u, original_encoders.size());
1047 // Only first encoder will be active and called.
Niels Möllerb859b322019-03-07 12:40:01 +01001048 EXPECT_CALL(*original_encoders[0], Encode(_, _))
Erik Språng7d687b12018-09-12 17:04:10 +02001049 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
Niels Möllerb859b322019-03-07 12:40:01 +01001050 EXPECT_CALL(*original_encoders[1], Encode(_, _)).Times(0);
1051 EXPECT_CALL(*original_encoders[2], Encode(_, _)).Times(0);
Erik Språng7d687b12018-09-12 17:04:10 +02001052
Niels Möller87e2d782019-03-07 10:18:23 +01001053 std::vector<VideoFrameType> frame_types;
Niels Möller8f7ce222019-03-21 15:43:58 +01001054 frame_types.resize(3, VideoFrameType::kVideoFrameKey);
Niels Möllerc8d2e732019-03-06 12:00:33 +01001055 EXPECT_EQ(0, adapter_->Encode(input_frame, &frame_types));
Erik Språng7d687b12018-09-12 17:04:10 +02001056}
Erik Språngd3438aa2018-11-08 16:56:43 +01001057
1058TEST_F(TestSimulcastEncoderAdapterFake, TrustedRateControl) {
1059 // Set up common settings for three streams.
1060 SimulcastTestFixtureImpl::DefaultSettings(
1061 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1062 kVideoCodecVP8);
1063 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
1064 adapter_->RegisterEncodeCompleteCallback(this);
1065
1066 // Only enough start bitrate for the lowest stream.
1067 ASSERT_EQ(3u, codec_.numberOfSimulcastStreams);
1068 codec_.startBitrate = codec_.simulcastStream[0].targetBitrate +
1069 codec_.simulcastStream[1].minBitrate - 1;
1070
1071 // Input data.
1072 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
Artem Titov1ebfb6a2019-01-03 23:49:37 +01001073 VideoFrame input_frame = VideoFrame::Builder()
1074 .set_video_frame_buffer(buffer)
1075 .set_timestamp_rtp(100)
1076 .set_timestamp_ms(1000)
1077 .set_rotation(kVideoRotation_180)
1078 .build();
Erik Språngd3438aa2018-11-08 16:56:43 +01001079
1080 // No encoder trusted, so simulcast adapter should not be either.
Elad Alon370f93a2019-06-11 14:57:57 +02001081 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001082 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1083
1084 // Encode with three streams.
1085 std::vector<MockVideoEncoder*> original_encoders =
1086 helper_->factory()->encoders();
1087
1088 // All encoders are trusted, so simulcast adapter should be too.
1089 original_encoders[0]->set_has_trusted_rate_controller(true);
1090 original_encoders[1]->set_has_trusted_rate_controller(true);
1091 original_encoders[2]->set_has_trusted_rate_controller(true);
Elad Alon370f93a2019-06-11 14:57:57 +02001092 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001093 EXPECT_TRUE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1094
1095 // One encoder not trusted, so simulcast adapter should not be either.
1096 original_encoders[2]->set_has_trusted_rate_controller(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001097 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001098 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1099
1100 // No encoder trusted, so simulcast adapter should not be either.
1101 original_encoders[0]->set_has_trusted_rate_controller(false);
1102 original_encoders[1]->set_has_trusted_rate_controller(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001103 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngd3438aa2018-11-08 16:56:43 +01001104 EXPECT_FALSE(adapter_->GetEncoderInfo().has_trusted_rate_controller);
1105}
1106
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001107TEST_F(TestSimulcastEncoderAdapterFake, ReportsHardwareAccelerated) {
1108 SimulcastTestFixtureImpl::DefaultSettings(
1109 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1110 kVideoCodecVP8);
1111 codec_.numberOfSimulcastStreams = 3;
1112 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001113 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001114 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1115
1116 // None of the encoders uses HW support, so simulcast adapter reports false.
1117 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1118 encoder->set_is_hardware_accelerated(false);
1119 }
Elad Alon370f93a2019-06-11 14:57:57 +02001120 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001121 EXPECT_FALSE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1122
1123 // One encoder uses HW support, so simulcast adapter reports true.
1124 helper_->factory()->encoders()[2]->set_is_hardware_accelerated(true);
Elad Alon370f93a2019-06-11 14:57:57 +02001125 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001126 EXPECT_TRUE(adapter_->GetEncoderInfo().is_hardware_accelerated);
1127}
1128
1129TEST_F(TestSimulcastEncoderAdapterFake, ReportsInternalSource) {
1130 SimulcastTestFixtureImpl::DefaultSettings(
1131 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1132 kVideoCodecVP8);
1133 codec_.numberOfSimulcastStreams = 3;
1134 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001135 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001136 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1137
1138 // All encoders have internal source, simulcast adapter reports true.
1139 for (MockVideoEncoder* encoder : helper_->factory()->encoders()) {
1140 encoder->set_has_internal_source(true);
1141 }
Elad Alon370f93a2019-06-11 14:57:57 +02001142 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001143 EXPECT_TRUE(adapter_->GetEncoderInfo().has_internal_source);
1144
1145 // One encoder does not have internal source, simulcast adapter reports false.
1146 helper_->factory()->encoders()[2]->set_has_internal_source(false);
Elad Alon370f93a2019-06-11 14:57:57 +02001147 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Mirta Dvornicic897a9912018-11-30 13:12:21 +01001148 EXPECT_FALSE(adapter_->GetEncoderInfo().has_internal_source);
1149}
1150
Erik Språngdbdd8392019-01-17 15:27:50 +01001151TEST_F(TestSimulcastEncoderAdapterFake, ReportsFpsAllocation) {
1152 SimulcastTestFixtureImpl::DefaultSettings(
1153 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1154 kVideoCodecVP8);
1155 codec_.numberOfSimulcastStreams = 3;
1156 adapter_->RegisterEncodeCompleteCallback(this);
Elad Alon370f93a2019-06-11 14:57:57 +02001157 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001158 ASSERT_EQ(3u, helper_->factory()->encoders().size());
1159
1160 // Combination of three different supported mode:
1161 // Simulcast stream 0 has undefined fps behavior.
1162 // Simulcast stream 1 has three temporal layers.
1163 // Simulcast stream 2 has 1 temporal layer.
1164 FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
1165 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 4);
1166 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction / 2);
1167 expected_fps_allocation[1].push_back(EncoderInfo::kMaxFramerateFraction);
1168 expected_fps_allocation[2].push_back(EncoderInfo::kMaxFramerateFraction);
1169
1170 // All encoders have internal source, simulcast adapter reports true.
1171 for (size_t i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
1172 MockVideoEncoder* encoder = helper_->factory()->encoders()[i];
1173 encoder->set_fps_allocation(expected_fps_allocation[i]);
1174 }
Elad Alon370f93a2019-06-11 14:57:57 +02001175 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språngdbdd8392019-01-17 15:27:50 +01001176 EXPECT_THAT(adapter_->GetEncoderInfo().fps_allocation,
1177 ::testing::ElementsAreArray(expected_fps_allocation));
1178}
1179
Erik Språng16cb8f52019-04-12 13:59:09 +02001180TEST_F(TestSimulcastEncoderAdapterFake, SetRateDistributesBandwithAllocation) {
1181 SimulcastTestFixtureImpl::DefaultSettings(
1182 &codec_, static_cast<const int*>(kTestTemporalLayerProfile),
1183 kVideoCodecVP8);
1184 codec_.numberOfSimulcastStreams = 3;
1185 const DataRate target_bitrate =
1186 DataRate::kbps(codec_.simulcastStream[0].targetBitrate +
1187 codec_.simulcastStream[1].targetBitrate +
1188 codec_.simulcastStream[2].minBitrate);
1189 const DataRate bandwidth_allocation = target_bitrate + DataRate::kbps(600);
1190
1191 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
Elad Alon370f93a2019-06-11 14:57:57 +02001192 EXPECT_EQ(0, adapter_->InitEncode(&codec_, kSettings));
Erik Språng16cb8f52019-04-12 13:59:09 +02001193 adapter_->RegisterEncodeCompleteCallback(this);
1194
1195 // Set bitrates so that we send all layers.
1196 adapter_->SetRates(VideoEncoder::RateControlParameters(
Florent Castelli8bbdb5b2019-08-02 15:16:28 +02001197 rate_allocator_->Allocate(
1198 VideoBitrateAllocationParameters(target_bitrate.bps(), 30)),
1199 30.0, bandwidth_allocation));
Erik Språng16cb8f52019-04-12 13:59:09 +02001200
1201 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
1202
1203 ASSERT_EQ(3u, encoders.size());
1204
1205 for (size_t i = 0; i < 3; ++i) {
1206 const uint32_t layer_bitrate_bps =
1207 (i < static_cast<size_t>(codec_.numberOfSimulcastStreams) - 1
1208 ? codec_.simulcastStream[i].targetBitrate
1209 : codec_.simulcastStream[i].minBitrate) *
1210 1000;
1211 EXPECT_EQ(layer_bitrate_bps,
1212 encoders[i]->last_set_rates().bitrate.get_sum_bps())
1213 << i;
1214 EXPECT_EQ(
1215 (layer_bitrate_bps * bandwidth_allocation.bps()) / target_bitrate.bps(),
1216 encoders[i]->last_set_rates().bandwidth_allocation.bps())
1217 << i;
1218 }
1219}
1220
Rasmus Brandt0cedc052018-05-31 12:53:00 +02001221} // namespace test
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001222} // namespace webrtc