blob: 91b47deff6b0d88aed8632d6f26180d5176ca28b [file] [log] [blame]
pbos@webrtc.org9115cde2014-12-09 10:36:40 +00001/*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
brandtr5e171752017-05-23 03:32:16 -070011#include <array>
kwiberg3f55dea2016-02-29 05:51:59 -080012#include <memory>
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000013#include <vector>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "common_video/include/video_frame_buffer.h"
16#include "media/engine/simulcast_encoder_adapter.h"
17#include "modules/video_coding/codecs/vp8/simulcast_test_utility.h"
18#include "modules/video_coding/include/video_codec_interface.h"
19#include "test/gmock.h"
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000020
21namespace webrtc {
22namespace testing {
23
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000024class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
25 public:
magjed6cc25612017-07-10 03:26:36 -070026 TestSimulcastEncoderAdapter() : factory_(new Vp8EncoderFactory()) {}
philipelcce46fc2015-12-21 03:04:49 -080027
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000028 protected:
magjed6cc25612017-07-10 03:26:36 -070029 class Vp8EncoderFactory : public cricket::WebRtcVideoEncoderFactory {
Peter Boström85b22e22016-01-25 17:58:00 +010030 public:
magjed6cc25612017-07-10 03:26:36 -070031 Vp8EncoderFactory() {
32 supported_codecs_.push_back(cricket::VideoCodec("VP8"));
33 }
Peter Boström85b22e22016-01-25 17:58:00 +010034
magjed6cc25612017-07-10 03:26:36 -070035 const std::vector<cricket::VideoCodec>& supported_codecs() const override {
36 return supported_codecs_;
37 }
38
39 VideoEncoder* CreateVideoEncoder(
40 const cricket::VideoCodec& codec) override {
41 return VP8Encoder::Create();
42 }
43
44 void DestroyVideoEncoder(VideoEncoder* encoder) override { delete encoder; }
Peter Boström85b22e22016-01-25 17:58:00 +010045
46 virtual ~Vp8EncoderFactory() {}
magjed6cc25612017-07-10 03:26:36 -070047
48 private:
49 std::vector<cricket::VideoCodec> supported_codecs_;
Peter Boström85b22e22016-01-25 17:58:00 +010050 };
51
magjed6cc25612017-07-10 03:26:36 -070052 VP8Encoder* CreateEncoder() override {
53 return new SimulcastEncoderAdapter(factory_.get());
54 }
55 VP8Decoder* CreateDecoder() override { return VP8Decoder::Create(); }
56
57 private:
58 std::unique_ptr<Vp8EncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000059};
60
61TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) {
62 TestVp8Simulcast::TestKeyFrameRequestsOnAllStreams();
63}
64
65TEST_F(TestSimulcastEncoderAdapter, TestPaddingAllStreams) {
66 TestVp8Simulcast::TestPaddingAllStreams();
67}
68
69TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreams) {
70 TestVp8Simulcast::TestPaddingTwoStreams();
71}
72
73TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreamsOneMaxedOut) {
74 TestVp8Simulcast::TestPaddingTwoStreamsOneMaxedOut();
75}
76
77TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStream) {
78 TestVp8Simulcast::TestPaddingOneStream();
79}
80
81TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStreamTwoMaxedOut) {
82 TestVp8Simulcast::TestPaddingOneStreamTwoMaxedOut();
83}
84
85TEST_F(TestSimulcastEncoderAdapter, TestSendAllStreams) {
86 TestVp8Simulcast::TestSendAllStreams();
87}
88
89TEST_F(TestSimulcastEncoderAdapter, TestDisablingStreams) {
90 TestVp8Simulcast::TestDisablingStreams();
91}
92
93TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneStream) {
94 TestVp8Simulcast::TestSwitchingToOneStream();
95}
96
97TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneOddStream) {
98 TestVp8Simulcast::TestSwitchingToOneOddStream();
99}
100
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000101TEST_F(TestSimulcastEncoderAdapter, TestStrideEncodeDecode) {
102 TestVp8Simulcast::TestStrideEncodeDecode();
103}
104
105TEST_F(TestSimulcastEncoderAdapter, TestSaptioTemporalLayers333PatternEncoder) {
106 TestVp8Simulcast::TestSaptioTemporalLayers333PatternEncoder();
107}
108
109TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
110 TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
111}
112
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000113class MockVideoEncoder : public VideoEncoder {
114 public:
nisseef8b61e2016-04-29 06:09:15 -0700115 // TODO(nisse): Valid overrides commented out, because the gmock
116 // methods don't use any override declarations, and we want to avoid
117 // warnings from -Winconsistent-missing-override. See
118 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000119 int32_t InitEncode(const VideoCodec* codecSettings,
120 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700121 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000122 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800123 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000124 }
125
noahricfe3654d2016-07-01 09:05:54 -0700126 MOCK_METHOD3(
127 Encode,
128 int32_t(const VideoFrame& inputImage,
129 const CodecSpecificInfo* codecSpecificInfo,
130 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000131
pbos65e15ba2015-10-15 10:52:15 -0700132 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700133 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700134 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000135 return 0;
136 }
137
brandtr5e171752017-05-23 03:32:16 -0700138 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000139
Erik Språng08127a92016-11-16 16:41:30 +0100140 int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation,
141 uint32_t framerate) {
142 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000143 return 0;
144 }
145
philipelcce46fc2015-12-21 03:04:49 -0800146 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000147
nisseef8b61e2016-04-29 06:09:15 -0700148 bool SupportsNativeHandle() const /* override */ {
149 return supports_native_handle_;
150 }
pbos65e15ba2015-10-15 10:52:15 -0700151
philipelcce46fc2015-12-21 03:04:49 -0800152 virtual ~MockVideoEncoder() {}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000153
154 const VideoCodec& codec() const { return codec_; }
155
Noah Richards41ee1ea2015-04-15 09:24:26 -0700156 void SendEncodedImage(int width, int height) {
157 // Sends a fake image of the given width/height.
158 EncodedImage image;
159 image._encodedWidth = width;
160 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700161 CodecSpecificInfo codec_specific_info;
162 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
brandtr5e171752017-05-23 03:32:16 -0700163 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700164 }
165
pbos65e15ba2015-10-15 10:52:15 -0700166 void set_supports_native_handle(bool enabled) {
167 supports_native_handle_ = enabled;
168 }
noahrice5ba75a2016-12-12 13:08:27 -0800169
170 void set_init_encode_return_value(int32_t value) {
171 init_encode_return_value_ = value;
172 }
173
Erik Språng08127a92016-11-16 16:41:30 +0100174 BitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700175
Peter Boströma5dec162016-01-20 15:53:55 +0100176 MOCK_CONST_METHOD0(ImplementationName, const char*());
177
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000178 private:
pbos65e15ba2015-10-15 10:52:15 -0700179 bool supports_native_handle_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800180 int32_t init_encode_return_value_ = 0;
Erik Språng08127a92016-11-16 16:41:30 +0100181 BitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700182
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000183 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700184 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000185};
186
magjed6cc25612017-07-10 03:26:36 -0700187class MockVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000188 public:
magjed6cc25612017-07-10 03:26:36 -0700189 MockVideoEncoderFactory() {
190 supported_codecs_.push_back(cricket::VideoCodec("VP8"));
191 }
192
193 const std::vector<cricket::VideoCodec>& supported_codecs() const override {
194 return supported_codecs_;
195 }
196
197 VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override {
198 MockVideoEncoder* encoder = new ::testing::NiceMock<MockVideoEncoder>();
noahrice5ba75a2016-12-12 13:08:27 -0800199 encoder->set_init_encode_return_value(init_encode_return_value_);
Peter Boströma5dec162016-01-20 15:53:55 +0100200 const char* encoder_name = encoder_names_.empty()
201 ? "codec_implementation_name"
202 : encoder_names_[encoders_.size()];
203 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000204 encoders_.push_back(encoder);
205 return encoder;
206 }
207
magjed6cc25612017-07-10 03:26:36 -0700208 void DestroyVideoEncoder(VideoEncoder* encoder) override {
Peter Boströmd53c3892016-03-30 17:03:52 +0200209 for (size_t i = 0; i < encoders_.size(); ++i) {
210 if (encoders_[i] == encoder) {
211 encoders_.erase(encoders_.begin() + i);
212 break;
213 }
214 }
215 delete encoder;
216 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000217
218 virtual ~MockVideoEncoderFactory() {}
219
220 const std::vector<MockVideoEncoder*>& encoders() const { return encoders_; }
Peter Boströma5dec162016-01-20 15:53:55 +0100221 void SetEncoderNames(const std::vector<const char*>& encoder_names) {
222 encoder_names_ = encoder_names;
223 }
noahrice5ba75a2016-12-12 13:08:27 -0800224 void set_init_encode_return_value(int32_t value) {
225 init_encode_return_value_ = value;
226 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000227
228 private:
magjed6cc25612017-07-10 03:26:36 -0700229 std::vector<cricket::VideoCodec> supported_codecs_;
noahrice5ba75a2016-12-12 13:08:27 -0800230 int32_t init_encode_return_value_ = 0;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000231 std::vector<MockVideoEncoder*> encoders_;
Peter Boströma5dec162016-01-20 15:53:55 +0100232 std::vector<const char*> encoder_names_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000233};
234
235class TestSimulcastEncoderAdapterFakeHelper {
236 public:
237 TestSimulcastEncoderAdapterFakeHelper()
238 : factory_(new MockVideoEncoderFactory()) {}
239
240 // Can only be called once as the SimulcastEncoderAdapter will take the
241 // ownership of |factory_|.
242 VP8Encoder* CreateMockEncoderAdapter() {
magjed6cc25612017-07-10 03:26:36 -0700243 return new SimulcastEncoderAdapter(factory_.get());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000244 }
245
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000246 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000247 EXPECT_TRUE(!factory_->encoders().empty());
248 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
249 EXPECT_CALL(*factory_->encoders()[i],
philipelcce46fc2015-12-21 03:04:49 -0800250 SetChannelParameters(packetLoss, rtt))
251 .Times(1);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000252 }
253 }
254
magjed6cc25612017-07-10 03:26:36 -0700255 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000256
257 private:
magjed6cc25612017-07-10 03:26:36 -0700258 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000259};
260
261static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
262
Noah Richards41ee1ea2015-04-15 09:24:26 -0700263class TestSimulcastEncoderAdapterFake : public ::testing::Test,
264 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000265 public:
266 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700267 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
268 adapter_(helper_->CreateMockEncoderAdapter()),
269 last_encoded_image_width_(-1),
270 last_encoded_image_height_(-1),
271 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700272 virtual ~TestSimulcastEncoderAdapterFake() {
273 if (adapter_) {
274 adapter_->Release();
275 }
276 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000277
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700278 Result OnEncodedImage(const EncodedImage& encoded_image,
279 const CodecSpecificInfo* codec_specific_info,
280 const RTPFragmentationHeader* fragmentation) override {
281 last_encoded_image_width_ = encoded_image._encodedWidth;
282 last_encoded_image_height_ = encoded_image._encodedHeight;
283 if (codec_specific_info) {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700284 last_encoded_image_simulcast_index_ =
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700285 codec_specific_info->codecSpecific.VP8.simulcastIdx;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700286 }
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700287 return Result(Result::OK, encoded_image._timeStamp);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700288 }
289
290 bool GetLastEncodedImageInfo(int* out_width,
291 int* out_height,
292 int* out_simulcast_index) {
293 if (last_encoded_image_width_ == -1) {
294 return false;
295 }
296 *out_width = last_encoded_image_width_;
297 *out_height = last_encoded_image_height_;
298 *out_simulcast_index = last_encoded_image_simulcast_index_;
299 return true;
300 }
301
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000302 void SetupCodec() {
303 TestVp8Simulcast::DefaultSettings(
philipelcce46fc2015-12-21 03:04:49 -0800304 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100305 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
306 tl_factory_.SetListener(rate_allocator_.get());
307 codec_.VP8()->tl_factory = &tl_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000308 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700309 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000310 }
311
312 void VerifyCodec(const VideoCodec& ref, int stream_index) {
313 const VideoCodec& target =
314 helper_->factory()->encoders()[stream_index]->codec();
315 EXPECT_EQ(ref.codecType, target.codecType);
316 EXPECT_EQ(0, strcmp(ref.plName, target.plName));
317 EXPECT_EQ(ref.plType, target.plType);
318 EXPECT_EQ(ref.width, target.width);
319 EXPECT_EQ(ref.height, target.height);
320 EXPECT_EQ(ref.startBitrate, target.startBitrate);
321 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
322 EXPECT_EQ(ref.minBitrate, target.minBitrate);
323 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700324 EXPECT_EQ(ref.VP8().pictureLossIndicationOn,
325 target.VP8().pictureLossIndicationOn);
hta257dc392016-10-25 09:05:06 -0700326 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
327 EXPECT_EQ(ref.VP8().resilience, target.VP8().resilience);
328 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
329 target.VP8().numberOfTemporalLayers);
330 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
331 EXPECT_EQ(ref.VP8().errorConcealmentOn, target.VP8().errorConcealmentOn);
332 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
333 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
334 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000335 EXPECT_EQ(ref.qpMax, target.qpMax);
336 EXPECT_EQ(0, target.numberOfSimulcastStreams);
337 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000338
339 // No need to compare simulcastStream as numberOfSimulcastStreams should
340 // always be 0.
341 }
342
343 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
344 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700345 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000346 kTestTemporalLayerProfile[stream_index];
Erik Språng08127a92016-11-16 16:41:30 +0100347 ref_codec->VP8()->tl_factory = &tl_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000348 ref_codec->width = codec_.simulcastStream[stream_index].width;
349 ref_codec->height = codec_.simulcastStream[stream_index].height;
350 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
351 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
352 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
353 }
354
355 void VerifyCodecSettings() {
356 EXPECT_EQ(3u, helper_->factory()->encoders().size());
357 VideoCodec ref_codec;
358
359 // stream 0, the lowest resolution stream.
360 InitRefCodec(0, &ref_codec);
361 ref_codec.qpMax = 45;
hta257dc392016-10-25 09:05:06 -0700362 ref_codec.VP8()->complexity = webrtc::kComplexityHigher;
363 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000364 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
365 VerifyCodec(ref_codec, 0);
366
367 // stream 1
368 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700369 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700370 // The start bitrate (300kbit) minus what we have for the lower layers
371 // (100kbit).
372 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000373 VerifyCodec(ref_codec, 1);
374
375 // stream 2, the biggest resolution stream.
376 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700377 // We don't have enough bits to send this, so the adapter should have
378 // configured it to use the min bitrate for this layer (600kbit) but turn
379 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000380 ref_codec.startBitrate = 600;
381 VerifyCodec(ref_codec, 2);
382 }
383
384 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800385 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
386 std::unique_ptr<VP8Encoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000387 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700388 int last_encoded_image_width_;
389 int last_encoded_image_height_;
390 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100391 TemporalLayersFactory tl_factory_;
392 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000393};
394
395TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
396 SetupCodec();
397 VerifyCodecSettings();
398}
399
brandtr5e171752017-05-23 03:32:16 -0700400TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
401 EXPECT_EQ(0, adapter_->Release());
402}
403
404TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
405 SetupCodec();
406 EXPECT_EQ(0, adapter_->Release());
407
408 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
409}
410
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000411TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
412 SetupCodec();
413 const uint32_t packetLoss = 5;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000414 const int64_t rtt = 30;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000415 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
416 adapter_->SetChannelParameters(packetLoss, rtt);
417}
418
Noah Richards41ee1ea2015-04-15 09:24:26 -0700419TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
420 SetupCodec();
421
Peter Boström5d0379d2015-10-06 14:04:51 +0200422 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100423 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200424
Noah Richards41ee1ea2015-04-15 09:24:26 -0700425 // At this point, the simulcast encoder adapter should have 3 streams: HD,
426 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
427 // resolutions, to test that the adapter forwards on the correct resolution
428 // and simulcast index values, going only off the encoder that generates the
429 // image.
brandtr5e171752017-05-23 03:32:16 -0700430 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
431 ASSERT_EQ(3u, encoders.size());
432 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700433 int width;
434 int height;
435 int simulcast_index;
436 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
437 EXPECT_EQ(1152, width);
438 EXPECT_EQ(704, height);
439 EXPECT_EQ(0, simulcast_index);
440
brandtr5e171752017-05-23 03:32:16 -0700441 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700442 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
443 EXPECT_EQ(300, width);
444 EXPECT_EQ(620, height);
445 EXPECT_EQ(1, simulcast_index);
446
brandtr5e171752017-05-23 03:32:16 -0700447 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700448 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
449 EXPECT_EQ(120, width);
450 EXPECT_EQ(240, height);
451 EXPECT_EQ(2, simulcast_index);
452}
453
brandtr5e171752017-05-23 03:32:16 -0700454// This test verifies that the underlying encoders are reused, when the adapter
455// is reinited with different number of simulcast streams. It further checks
456// that the allocated encoders are reused in the same order as before, starting
457// with the lowest stream.
458TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
459 // Set up common settings for three streams.
460 TestVp8Simulcast::DefaultSettings(
461 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
462 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
463 tl_factory_.SetListener(rate_allocator_.get());
464 codec_.VP8()->tl_factory = &tl_factory_;
465 adapter_->RegisterEncodeCompleteCallback(this);
466
467 // Input data.
468 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
469 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
470 std::vector<FrameType> frame_types;
471
472 // Encode with three streams.
473 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
474 VerifyCodecSettings();
475 std::vector<MockVideoEncoder*> original_encoders =
476 helper_->factory()->encoders();
477 ASSERT_EQ(3u, original_encoders.size());
478 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
479 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
480 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
481 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
482 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
483 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
484 frame_types.resize(3, kVideoFrameKey);
485 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
486 EXPECT_CALL(*original_encoders[0], Release())
487 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
488 EXPECT_CALL(*original_encoders[1], Release())
489 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
490 EXPECT_CALL(*original_encoders[2], Release())
491 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
492 EXPECT_EQ(0, adapter_->Release());
493
494 // Encode with two streams.
495 codec_.width /= 2;
496 codec_.height /= 2;
497 codec_.numberOfSimulcastStreams = 2;
498 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
499 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
500 ASSERT_EQ(2u, new_encoders.size());
501 ASSERT_EQ(original_encoders[0], new_encoders[0]);
502 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
503 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
504 ASSERT_EQ(original_encoders[1], new_encoders[1]);
505 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
506 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
507 frame_types.resize(2, kVideoFrameKey);
508 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
509 EXPECT_CALL(*original_encoders[0], Release())
510 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
511 EXPECT_CALL(*original_encoders[1], Release())
512 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
513 EXPECT_EQ(0, adapter_->Release());
514
515 // Encode with single stream.
516 codec_.width /= 2;
517 codec_.height /= 2;
518 codec_.numberOfSimulcastStreams = 1;
519 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
520 new_encoders = helper_->factory()->encoders();
521 ASSERT_EQ(1u, new_encoders.size());
522 ASSERT_EQ(original_encoders[0], new_encoders[0]);
523 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
524 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
525 frame_types.resize(1, kVideoFrameKey);
526 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
527 EXPECT_CALL(*original_encoders[0], Release())
528 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
529 EXPECT_EQ(0, adapter_->Release());
530
531 // Encode with three streams, again.
532 codec_.width *= 4;
533 codec_.height *= 4;
534 codec_.numberOfSimulcastStreams = 3;
535 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
536 new_encoders = helper_->factory()->encoders();
537 ASSERT_EQ(3u, new_encoders.size());
538 // The first encoder is reused.
539 ASSERT_EQ(original_encoders[0], new_encoders[0]);
540 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
541 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
542 // The second and third encoders are new.
543 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
544 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
545 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
546 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
547 frame_types.resize(3, kVideoFrameKey);
548 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
549 EXPECT_CALL(*original_encoders[0], Release())
550 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
551 EXPECT_CALL(*new_encoders[1], Release())
552 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
553 EXPECT_CALL(*new_encoders[2], Release())
554 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
555 EXPECT_EQ(0, adapter_->Release());
556}
557
558TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
559 SetupCodec();
560 VerifyCodecSettings();
561
562 EXPECT_EQ(3u, helper_->factory()->encoders().size());
563
564 // The adapter should destroy all encoders it has allocated. Since
565 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
566 // lsan to find leaks here.
567 EXPECT_EQ(0, adapter_->Release());
568 adapter_.reset();
569}
570
571// This test verifies that an adapter reinit with the same codec settings as
572// before does not change the underlying encoder codec settings.
573TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
574 SetupCodec();
575 VerifyCodecSettings();
576
577 // Capture current codec settings.
578 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
579 ASSERT_EQ(3u, encoders.size());
580 std::array<VideoCodec, 3> codecs_before;
581 for (int i = 0; i < 3; ++i) {
582 codecs_before[i] = encoders[i]->codec();
583 }
584
585 // Reinitialize and verify that the new codec settings are the same.
586 EXPECT_EQ(0, adapter_->Release());
587 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
588 for (int i = 0; i < 3; ++i) {
589 const VideoCodec& codec_before = codecs_before[i];
590 const VideoCodec& codec_after = encoders[i]->codec();
591
592 // webrtc::VideoCodec does not implement operator==.
593 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
594 EXPECT_EQ(codec_before.plType, codec_after.plType);
595 EXPECT_EQ(codec_before.width, codec_after.width);
596 EXPECT_EQ(codec_before.height, codec_after.height);
597 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
598 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
599 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
600 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
601 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
602 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
603 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
604 codec_after.numberOfSimulcastStreams);
605 EXPECT_EQ(codec_before.mode, codec_after.mode);
606 EXPECT_EQ(codec_before.expect_encode_from_texture,
607 codec_after.expect_encode_from_texture);
608 }
609}
610
611// This test is similar to the one above, except that it tests the simulcastIdx
612// from the CodecSpecificInfo that is connected to an encoded frame. The
613// PayloadRouter demuxes the incoming encoded frames on different RTP modules
614// using the simulcastIdx, so it's important that there is no corresponding
615// encoder reordering in between adapter reinits as this would lead to PictureID
616// discontinuities.
617TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
618 SetupCodec();
619 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
620 VerifyCodecSettings();
621
622 // Send frames on all streams.
623 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
624 ASSERT_EQ(3u, encoders.size());
625 encoders[0]->SendEncodedImage(1152, 704);
626 int width;
627 int height;
628 int simulcast_index;
629 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
630 EXPECT_EQ(0, simulcast_index);
631
632 encoders[1]->SendEncodedImage(300, 620);
633 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
634 EXPECT_EQ(1, simulcast_index);
635
636 encoders[2]->SendEncodedImage(120, 240);
637 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
638 EXPECT_EQ(2, simulcast_index);
639
640 // Reinitialize.
641 EXPECT_EQ(0, adapter_->Release());
642 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
643 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
644
645 // Verify that the same encoder sends out frames on the same simulcast index.
646 encoders[0]->SendEncodedImage(1152, 704);
647 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
648 EXPECT_EQ(0, simulcast_index);
649
650 encoders[1]->SendEncodedImage(300, 620);
651 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
652 EXPECT_EQ(1, simulcast_index);
653
654 encoders[2]->SendEncodedImage(120, 240);
655 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
656 EXPECT_EQ(2, simulcast_index);
657}
658
pbos65e15ba2015-10-15 10:52:15 -0700659TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
660 TestVp8Simulcast::DefaultSettings(
661 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100662 codec_.VP8()->tl_factory = &tl_factory_;
pbos65e15ba2015-10-15 10:52:15 -0700663 codec_.numberOfSimulcastStreams = 1;
664 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
665 adapter_->RegisterEncodeCompleteCallback(this);
666 ASSERT_EQ(1u, helper_->factory()->encoders().size());
667 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
668 EXPECT_TRUE(adapter_->SupportsNativeHandle());
669 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
670 EXPECT_FALSE(adapter_->SupportsNativeHandle());
671}
672
noahricfac0ff02016-09-09 10:27:15 -0700673TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
674 TestVp8Simulcast::DefaultSettings(
675 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100676 codec_.VP8()->tl_factory = &tl_factory_;
noahricfac0ff02016-09-09 10:27:15 -0700677 codec_.minBitrate = 50;
678 codec_.numberOfSimulcastStreams = 1;
679 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng08127a92016-11-16 16:41:30 +0100680 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
noahricfac0ff02016-09-09 10:27:15 -0700681
682 // Above min should be respected.
Erik Språng08127a92016-11-16 16:41:30 +0100683 BitrateAllocation target_bitrate =
684 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
685 adapter_->SetRateAllocation(target_bitrate, 30);
686 EXPECT_EQ(target_bitrate,
687 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700688
689 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng08127a92016-11-16 16:41:30 +0100690 BitrateAllocation too_low_bitrate =
691 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
692 adapter_->SetRateAllocation(too_low_bitrate, 30);
693 EXPECT_EQ(target_bitrate,
694 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700695
696 // Zero should be passed on as is, since it means "pause".
Erik Språng08127a92016-11-16 16:41:30 +0100697 adapter_->SetRateAllocation(BitrateAllocation(), 30);
698 EXPECT_EQ(BitrateAllocation(),
699 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700700}
701
Peter Boströma5dec162016-01-20 15:53:55 +0100702TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
703 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
704 TestVp8Simulcast::DefaultSettings(
705 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100706 codec_.VP8()->tl_factory = &tl_factory_;
Peter Boströma5dec162016-01-20 15:53:55 +0100707 std::vector<const char*> encoder_names;
708 encoder_names.push_back("codec1");
709 encoder_names.push_back("codec2");
710 encoder_names.push_back("codec3");
711 helper_->factory()->SetEncoderNames(encoder_names);
712 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
713 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
714 adapter_->ImplementationName());
Peter Boströmd53c3892016-03-30 17:03:52 +0200715
716 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700717 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200718 codec_.numberOfSimulcastStreams = 1;
719 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
720 adapter_->RegisterEncodeCompleteCallback(this);
721 ASSERT_EQ(1u, helper_->factory()->encoders().size());
722 EXPECT_STREQ("codec1", adapter_->ImplementationName());
Peter Boströma5dec162016-01-20 15:53:55 +0100723}
724
pbos65e15ba2015-10-15 10:52:15 -0700725TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700726 SupportsNativeHandleForMultipleStreams) {
pbos65e15ba2015-10-15 10:52:15 -0700727 TestVp8Simulcast::DefaultSettings(
728 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100729 codec_.VP8()->tl_factory = &tl_factory_;
pbos65e15ba2015-10-15 10:52:15 -0700730 codec_.numberOfSimulcastStreams = 3;
731 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
732 adapter_->RegisterEncodeCompleteCallback(this);
733 ASSERT_EQ(3u, helper_->factory()->encoders().size());
734 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
735 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700736 // If one encoder doesn't support it, then overall support is disabled.
737 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
pbos65e15ba2015-10-15 10:52:15 -0700738 EXPECT_FALSE(adapter_->SupportsNativeHandle());
noahricfe3654d2016-07-01 09:05:54 -0700739 // Once all do, then the adapter claims support.
740 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
741 EXPECT_TRUE(adapter_->SupportsNativeHandle());
742}
743
nisseaf916892017-01-10 07:44:26 -0800744// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000745class FakeNativeBuffer : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700746 public:
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000747 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
748
749 Type type() const override { return Type::kNative; }
750 int width() const override { return width_; }
751 int height() const override { return height_; }
752
753 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700754 RTC_NOTREACHED();
755 return nullptr;
756 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000757
758 private:
759 const int width_;
760 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700761};
762
763TEST_F(TestSimulcastEncoderAdapterFake,
764 NativeHandleForwardingForMultipleStreams) {
765 TestVp8Simulcast::DefaultSettings(
766 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100767 codec_.VP8()->tl_factory = &tl_factory_;
noahricfe3654d2016-07-01 09:05:54 -0700768 codec_.numberOfSimulcastStreams = 3;
769 // High start bitrate, so all streams are enabled.
770 codec_.startBitrate = 3000;
771 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
772 adapter_->RegisterEncodeCompleteCallback(this);
773 ASSERT_EQ(3u, helper_->factory()->encoders().size());
774 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
775 encoder->set_supports_native_handle(true);
776 EXPECT_TRUE(adapter_->SupportsNativeHandle());
777
778 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000779 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
noahricfe3654d2016-07-01 09:05:54 -0700780 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
781 // Expect calls with the given video frame verbatim, since it's a texture
782 // frame and can't otherwise be modified/resized.
783 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
784 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
785 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700786 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700787}
788
noahric57779102016-05-25 06:48:46 -0700789TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
790 TestVp8Simulcast::DefaultSettings(
791 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100792 codec_.VP8()->tl_factory = &tl_factory_;
noahric57779102016-05-25 06:48:46 -0700793 codec_.numberOfSimulcastStreams = 3;
794 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
795 adapter_->RegisterEncodeCompleteCallback(this);
796 ASSERT_EQ(3u, helper_->factory()->encoders().size());
797 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700798 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
799 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700800
801 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000802 rtc::scoped_refptr<I420Buffer> input_buffer =
803 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700804 input_buffer->InitializeData();
805 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
noahric57779102016-05-25 06:48:46 -0700806 std::vector<FrameType> frame_types(3, kVideoFrameKey);
807 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
808 adapter_->Encode(input_frame, nullptr, &frame_types));
809}
810
noahrice5ba75a2016-12-12 13:08:27 -0800811TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
812 TestVp8Simulcast::DefaultSettings(
813 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
814 codec_.VP8()->tl_factory = &tl_factory_;
815 codec_.numberOfSimulcastStreams = 3;
816 helper_->factory()->set_init_encode_return_value(
817 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
818 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
819 adapter_->InitEncode(&codec_, 1, 1200));
820 EXPECT_TRUE(helper_->factory()->encoders().empty());
821}
822
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000823} // namespace testing
824} // namespace webrtc