blob: 9aced296fbf6f20b1405b52abd42168fa41d5548 [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
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010015#include "api/video_codecs/sdp_video_format.h"
16#include "api/video_codecs/video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "common_video/include/video_frame_buffer.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010018#include "media/engine/internalencoderfactory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "media/engine/simulcast_encoder_adapter.h"
20#include "modules/video_coding/codecs/vp8/simulcast_test_utility.h"
21#include "modules/video_coding/include/video_codec_interface.h"
Magnus Jedvert46a27652017-11-13 14:10:02 +010022#include "rtc_base/ptr_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "test/gmock.h"
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000024
25namespace webrtc {
26namespace testing {
27
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000028class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
29 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010030 TestSimulcastEncoderAdapter() : factory_(new InternalEncoderFactory()) {}
philipelcce46fc2015-12-21 03:04:49 -080031
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000032 protected:
Magnus Jedvert46a27652017-11-13 14:10:02 +010033 std::unique_ptr<VP8Encoder> CreateEncoder() override {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +020034 return rtc::MakeUnique<SimulcastEncoderAdapter>(factory_.get(),
35 SdpVideoFormat("VP8"));
magjed6cc25612017-07-10 03:26:36 -070036 }
Magnus Jedvert46a27652017-11-13 14:10:02 +010037 std::unique_ptr<VP8Decoder> CreateDecoder() override {
38 return VP8Decoder::Create();
39 }
magjed6cc25612017-07-10 03:26:36 -070040
41 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010042 std::unique_ptr<VideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000043};
44
45TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) {
46 TestVp8Simulcast::TestKeyFrameRequestsOnAllStreams();
47}
48
49TEST_F(TestSimulcastEncoderAdapter, TestPaddingAllStreams) {
50 TestVp8Simulcast::TestPaddingAllStreams();
51}
52
53TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreams) {
54 TestVp8Simulcast::TestPaddingTwoStreams();
55}
56
57TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreamsOneMaxedOut) {
58 TestVp8Simulcast::TestPaddingTwoStreamsOneMaxedOut();
59}
60
61TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStream) {
62 TestVp8Simulcast::TestPaddingOneStream();
63}
64
65TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStreamTwoMaxedOut) {
66 TestVp8Simulcast::TestPaddingOneStreamTwoMaxedOut();
67}
68
69TEST_F(TestSimulcastEncoderAdapter, TestSendAllStreams) {
70 TestVp8Simulcast::TestSendAllStreams();
71}
72
73TEST_F(TestSimulcastEncoderAdapter, TestDisablingStreams) {
74 TestVp8Simulcast::TestDisablingStreams();
75}
76
Seth Hampson46e31ba2018-01-18 10:39:54 -080077TEST_F(TestSimulcastEncoderAdapter, TestActiveStreams) {
78 TestVp8Simulcast::TestActiveStreams();
79}
80
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000081TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneStream) {
82 TestVp8Simulcast::TestSwitchingToOneStream();
83}
84
85TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneOddStream) {
86 TestVp8Simulcast::TestSwitchingToOneOddStream();
87}
88
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000089TEST_F(TestSimulcastEncoderAdapter, TestStrideEncodeDecode) {
90 TestVp8Simulcast::TestStrideEncodeDecode();
91}
92
93TEST_F(TestSimulcastEncoderAdapter, TestSaptioTemporalLayers333PatternEncoder) {
94 TestVp8Simulcast::TestSaptioTemporalLayers333PatternEncoder();
95}
96
97TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
98 TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
99}
100
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100101class MockVideoEncoder;
102
103class MockVideoEncoderFactory : public VideoEncoderFactory {
104 public:
105 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
106
107 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
108 const SdpVideoFormat& format) override;
109
110 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
111
112 const std::vector<MockVideoEncoder*>& encoders() const;
113 void SetEncoderNames(const std::vector<const char*>& encoder_names);
114 void set_init_encode_return_value(int32_t value);
115
116 void DestroyVideoEncoder(VideoEncoder* encoder);
117
118 private:
119 int32_t init_encode_return_value_ = 0;
120 std::vector<MockVideoEncoder*> encoders_;
121 std::vector<const char*> encoder_names_;
122};
123
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000124class MockVideoEncoder : public VideoEncoder {
125 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100126 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
Erik Språng82fad3d2018-03-21 09:57:23 +0100127 : factory_(factory), callback_(nullptr) {}
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100128
nisseef8b61e2016-04-29 06:09:15 -0700129 // TODO(nisse): Valid overrides commented out, because the gmock
130 // methods don't use any override declarations, and we want to avoid
131 // warnings from -Winconsistent-missing-override. See
132 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000133 int32_t InitEncode(const VideoCodec* codecSettings,
134 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700135 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000136 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800137 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000138 }
139
noahricfe3654d2016-07-01 09:05:54 -0700140 MOCK_METHOD3(
141 Encode,
142 int32_t(const VideoFrame& inputImage,
143 const CodecSpecificInfo* codecSpecificInfo,
144 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000145
pbos65e15ba2015-10-15 10:52:15 -0700146 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700147 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700148 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000149 return 0;
150 }
151
brandtr5e171752017-05-23 03:32:16 -0700152 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000153
Erik Språng566124a2018-04-23 12:32:22 +0200154 int32_t SetRateAllocation(const VideoBitrateAllocation& bitrate_allocation,
Erik Språng08127a92016-11-16 16:41:30 +0100155 uint32_t framerate) {
156 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000157 return 0;
158 }
159
philipelcce46fc2015-12-21 03:04:49 -0800160 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000161
nisseef8b61e2016-04-29 06:09:15 -0700162 bool SupportsNativeHandle() const /* override */ {
163 return supports_native_handle_;
164 }
pbos65e15ba2015-10-15 10:52:15 -0700165
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100166 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000167
168 const VideoCodec& codec() const { return codec_; }
169
Noah Richards41ee1ea2015-04-15 09:24:26 -0700170 void SendEncodedImage(int width, int height) {
171 // Sends a fake image of the given width/height.
172 EncodedImage image;
173 image._encodedWidth = width;
174 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700175 CodecSpecificInfo codec_specific_info;
176 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
brandtr5e171752017-05-23 03:32:16 -0700177 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700178 }
179
pbos65e15ba2015-10-15 10:52:15 -0700180 void set_supports_native_handle(bool enabled) {
181 supports_native_handle_ = enabled;
182 }
noahrice5ba75a2016-12-12 13:08:27 -0800183
184 void set_init_encode_return_value(int32_t value) {
185 init_encode_return_value_ = value;
186 }
187
Erik Språng566124a2018-04-23 12:32:22 +0200188 VideoBitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700189
Peter Boströma5dec162016-01-20 15:53:55 +0100190 MOCK_CONST_METHOD0(ImplementationName, const char*());
191
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000192 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100193 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700194 bool supports_native_handle_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800195 int32_t init_encode_return_value_ = 0;
Erik Språng566124a2018-04-23 12:32:22 +0200196 VideoBitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700197
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000198 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700199 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000200};
201
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100202std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
203 const {
204 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
205 return formats;
206}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000207
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100208std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
209 const SdpVideoFormat& format) {
210 std::unique_ptr<MockVideoEncoder> encoder(
211 new ::testing::NiceMock<MockVideoEncoder>(this));
212 encoder->set_init_encode_return_value(init_encode_return_value_);
213 const char* encoder_name = encoder_names_.empty()
214 ? "codec_implementation_name"
215 : encoder_names_[encoders_.size()];
216 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
217 encoders_.push_back(encoder.get());
218 return encoder;
219}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000220
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100221void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
222 for (size_t i = 0; i < encoders_.size(); ++i) {
223 if (encoders_[i] == encoder) {
224 encoders_.erase(encoders_.begin() + i);
225 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000226 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000227 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100228}
Zhi Huangaea84f52017-11-16 18:46:27 +0000229
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100230VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
231 const SdpVideoFormat& format) const {
232 return CodecInfo();
233}
Zhi Huangaea84f52017-11-16 18:46:27 +0000234
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100235const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
236 const {
237 return encoders_;
238}
239void MockVideoEncoderFactory::SetEncoderNames(
240 const std::vector<const char*>& encoder_names) {
241 encoder_names_ = encoder_names;
242}
243void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
244 init_encode_return_value_ = value;
245}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000246
247class TestSimulcastEncoderAdapterFakeHelper {
248 public:
249 TestSimulcastEncoderAdapterFakeHelper()
250 : factory_(new MockVideoEncoderFactory()) {}
251
252 // Can only be called once as the SimulcastEncoderAdapter will take the
253 // ownership of |factory_|.
254 VP8Encoder* CreateMockEncoderAdapter() {
Ilya Nikolaevskiy97b4ee52018-05-28 10:24:22 +0200255 return new SimulcastEncoderAdapter(factory_.get(), SdpVideoFormat("VP8"));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000256 }
257
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000258 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000259 EXPECT_TRUE(!factory_->encoders().empty());
260 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
261 EXPECT_CALL(*factory_->encoders()[i],
philipelcce46fc2015-12-21 03:04:49 -0800262 SetChannelParameters(packetLoss, rtt))
263 .Times(1);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000264 }
265 }
266
magjed6cc25612017-07-10 03:26:36 -0700267 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000268
269 private:
magjed6cc25612017-07-10 03:26:36 -0700270 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000271};
272
273static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
274
Noah Richards41ee1ea2015-04-15 09:24:26 -0700275class TestSimulcastEncoderAdapterFake : public ::testing::Test,
276 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000277 public:
278 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700279 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
280 adapter_(helper_->CreateMockEncoderAdapter()),
281 last_encoded_image_width_(-1),
282 last_encoded_image_height_(-1),
283 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700284 virtual ~TestSimulcastEncoderAdapterFake() {
285 if (adapter_) {
286 adapter_->Release();
287 }
288 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000289
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700290 Result OnEncodedImage(const EncodedImage& encoded_image,
291 const CodecSpecificInfo* codec_specific_info,
292 const RTPFragmentationHeader* fragmentation) override {
293 last_encoded_image_width_ = encoded_image._encodedWidth;
294 last_encoded_image_height_ = encoded_image._encodedHeight;
295 if (codec_specific_info) {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700296 last_encoded_image_simulcast_index_ =
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700297 codec_specific_info->codecSpecific.VP8.simulcastIdx;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700298 }
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700299 return Result(Result::OK, encoded_image._timeStamp);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700300 }
301
302 bool GetLastEncodedImageInfo(int* out_width,
303 int* out_height,
304 int* out_simulcast_index) {
305 if (last_encoded_image_width_ == -1) {
306 return false;
307 }
308 *out_width = last_encoded_image_width_;
309 *out_height = last_encoded_image_height_;
310 *out_simulcast_index = last_encoded_image_simulcast_index_;
311 return true;
312 }
313
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000314 void SetupCodec() {
315 TestVp8Simulcast::DefaultSettings(
philipelcce46fc2015-12-21 03:04:49 -0800316 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng82fad3d2018-03-21 09:57:23 +0100317 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000318 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700319 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000320 }
321
322 void VerifyCodec(const VideoCodec& ref, int stream_index) {
323 const VideoCodec& target =
324 helper_->factory()->encoders()[stream_index]->codec();
325 EXPECT_EQ(ref.codecType, target.codecType);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000326 EXPECT_EQ(ref.plType, target.plType);
327 EXPECT_EQ(ref.width, target.width);
328 EXPECT_EQ(ref.height, target.height);
329 EXPECT_EQ(ref.startBitrate, target.startBitrate);
330 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
331 EXPECT_EQ(ref.minBitrate, target.minBitrate);
332 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700333 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
hta257dc392016-10-25 09:05:06 -0700334 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
335 target.VP8().numberOfTemporalLayers);
336 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
hta257dc392016-10-25 09:05:06 -0700337 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
338 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
339 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000340 EXPECT_EQ(ref.qpMax, target.qpMax);
341 EXPECT_EQ(0, target.numberOfSimulcastStreams);
342 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000343
344 // No need to compare simulcastStream as numberOfSimulcastStreams should
345 // always be 0.
346 }
347
348 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
349 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700350 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000351 kTestTemporalLayerProfile[stream_index];
352 ref_codec->width = codec_.simulcastStream[stream_index].width;
353 ref_codec->height = codec_.simulcastStream[stream_index].height;
354 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
355 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
356 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
357 }
358
359 void VerifyCodecSettings() {
360 EXPECT_EQ(3u, helper_->factory()->encoders().size());
361 VideoCodec ref_codec;
362
363 // stream 0, the lowest resolution stream.
364 InitRefCodec(0, &ref_codec);
365 ref_codec.qpMax = 45;
hta257dc392016-10-25 09:05:06 -0700366 ref_codec.VP8()->complexity = webrtc::kComplexityHigher;
367 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000368 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
369 VerifyCodec(ref_codec, 0);
370
371 // stream 1
372 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700373 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700374 // The start bitrate (300kbit) minus what we have for the lower layers
375 // (100kbit).
376 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000377 VerifyCodec(ref_codec, 1);
378
379 // stream 2, the biggest resolution stream.
380 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700381 // We don't have enough bits to send this, so the adapter should have
382 // configured it to use the min bitrate for this layer (600kbit) but turn
383 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000384 ref_codec.startBitrate = 600;
385 VerifyCodec(ref_codec, 2);
386 }
387
388 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800389 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
390 std::unique_ptr<VP8Encoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000391 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700392 int last_encoded_image_width_;
393 int last_encoded_image_height_;
394 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100395 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000396};
397
398TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
399 SetupCodec();
400 VerifyCodecSettings();
401}
402
brandtr5e171752017-05-23 03:32:16 -0700403TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
404 EXPECT_EQ(0, adapter_->Release());
405}
406
407TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
408 SetupCodec();
409 EXPECT_EQ(0, adapter_->Release());
410
411 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
412}
413
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000414TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
415 SetupCodec();
416 const uint32_t packetLoss = 5;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000417 const int64_t rtt = 30;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000418 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
419 adapter_->SetChannelParameters(packetLoss, rtt);
420}
421
Noah Richards41ee1ea2015-04-15 09:24:26 -0700422TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
423 SetupCodec();
424
Peter Boström5d0379d2015-10-06 14:04:51 +0200425 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100426 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200427
Noah Richards41ee1ea2015-04-15 09:24:26 -0700428 // At this point, the simulcast encoder adapter should have 3 streams: HD,
429 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
430 // resolutions, to test that the adapter forwards on the correct resolution
431 // and simulcast index values, going only off the encoder that generates the
432 // image.
brandtr5e171752017-05-23 03:32:16 -0700433 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
434 ASSERT_EQ(3u, encoders.size());
435 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700436 int width;
437 int height;
438 int simulcast_index;
439 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
440 EXPECT_EQ(1152, width);
441 EXPECT_EQ(704, height);
442 EXPECT_EQ(0, simulcast_index);
443
brandtr5e171752017-05-23 03:32:16 -0700444 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700445 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
446 EXPECT_EQ(300, width);
447 EXPECT_EQ(620, height);
448 EXPECT_EQ(1, simulcast_index);
449
brandtr5e171752017-05-23 03:32:16 -0700450 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700451 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
452 EXPECT_EQ(120, width);
453 EXPECT_EQ(240, height);
454 EXPECT_EQ(2, simulcast_index);
455}
456
brandtr5e171752017-05-23 03:32:16 -0700457// This test verifies that the underlying encoders are reused, when the adapter
458// is reinited with different number of simulcast streams. It further checks
459// that the allocated encoders are reused in the same order as before, starting
460// with the lowest stream.
461TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
462 // Set up common settings for three streams.
463 TestVp8Simulcast::DefaultSettings(
464 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng82fad3d2018-03-21 09:57:23 +0100465 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
brandtr5e171752017-05-23 03:32:16 -0700466 adapter_->RegisterEncodeCompleteCallback(this);
467
468 // Input data.
469 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
470 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
471 std::vector<FrameType> frame_types;
472
473 // Encode with three streams.
474 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
475 VerifyCodecSettings();
476 std::vector<MockVideoEncoder*> original_encoders =
477 helper_->factory()->encoders();
478 ASSERT_EQ(3u, original_encoders.size());
479 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
480 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
481 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
482 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
483 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
484 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
485 frame_types.resize(3, kVideoFrameKey);
486 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
487 EXPECT_CALL(*original_encoders[0], Release())
488 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
489 EXPECT_CALL(*original_encoders[1], Release())
490 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
491 EXPECT_CALL(*original_encoders[2], Release())
492 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
493 EXPECT_EQ(0, adapter_->Release());
494
495 // Encode with two streams.
496 codec_.width /= 2;
497 codec_.height /= 2;
498 codec_.numberOfSimulcastStreams = 2;
499 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
500 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
501 ASSERT_EQ(2u, new_encoders.size());
502 ASSERT_EQ(original_encoders[0], new_encoders[0]);
503 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
504 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
505 ASSERT_EQ(original_encoders[1], new_encoders[1]);
506 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
507 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
508 frame_types.resize(2, kVideoFrameKey);
509 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
510 EXPECT_CALL(*original_encoders[0], Release())
511 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
512 EXPECT_CALL(*original_encoders[1], Release())
513 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
514 EXPECT_EQ(0, adapter_->Release());
515
516 // Encode with single stream.
517 codec_.width /= 2;
518 codec_.height /= 2;
519 codec_.numberOfSimulcastStreams = 1;
520 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
521 new_encoders = helper_->factory()->encoders();
522 ASSERT_EQ(1u, new_encoders.size());
523 ASSERT_EQ(original_encoders[0], new_encoders[0]);
524 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
525 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
526 frame_types.resize(1, kVideoFrameKey);
527 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
528 EXPECT_CALL(*original_encoders[0], Release())
529 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
530 EXPECT_EQ(0, adapter_->Release());
531
532 // Encode with three streams, again.
533 codec_.width *= 4;
534 codec_.height *= 4;
535 codec_.numberOfSimulcastStreams = 3;
536 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
537 new_encoders = helper_->factory()->encoders();
538 ASSERT_EQ(3u, new_encoders.size());
539 // The first encoder is reused.
540 ASSERT_EQ(original_encoders[0], new_encoders[0]);
541 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
542 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
543 // The second and third encoders are new.
544 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
545 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
546 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
547 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
548 frame_types.resize(3, kVideoFrameKey);
549 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
550 EXPECT_CALL(*original_encoders[0], Release())
551 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
552 EXPECT_CALL(*new_encoders[1], Release())
553 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
554 EXPECT_CALL(*new_encoders[2], Release())
555 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
556 EXPECT_EQ(0, adapter_->Release());
557}
558
559TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
560 SetupCodec();
561 VerifyCodecSettings();
562
563 EXPECT_EQ(3u, helper_->factory()->encoders().size());
564
565 // The adapter should destroy all encoders it has allocated. Since
566 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
567 // lsan to find leaks here.
568 EXPECT_EQ(0, adapter_->Release());
569 adapter_.reset();
570}
571
572// This test verifies that an adapter reinit with the same codec settings as
573// before does not change the underlying encoder codec settings.
574TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
575 SetupCodec();
576 VerifyCodecSettings();
577
578 // Capture current codec settings.
579 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
580 ASSERT_EQ(3u, encoders.size());
581 std::array<VideoCodec, 3> codecs_before;
582 for (int i = 0; i < 3; ++i) {
583 codecs_before[i] = encoders[i]->codec();
584 }
585
586 // Reinitialize and verify that the new codec settings are the same.
587 EXPECT_EQ(0, adapter_->Release());
588 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
589 for (int i = 0; i < 3; ++i) {
590 const VideoCodec& codec_before = codecs_before[i];
591 const VideoCodec& codec_after = encoders[i]->codec();
592
593 // webrtc::VideoCodec does not implement operator==.
594 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
595 EXPECT_EQ(codec_before.plType, codec_after.plType);
596 EXPECT_EQ(codec_before.width, codec_after.width);
597 EXPECT_EQ(codec_before.height, codec_after.height);
598 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
599 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
600 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
601 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
602 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
603 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
604 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
605 codec_after.numberOfSimulcastStreams);
606 EXPECT_EQ(codec_before.mode, codec_after.mode);
607 EXPECT_EQ(codec_before.expect_encode_from_texture,
608 codec_after.expect_encode_from_texture);
609 }
610}
611
612// This test is similar to the one above, except that it tests the simulcastIdx
613// from the CodecSpecificInfo that is connected to an encoded frame. The
614// PayloadRouter demuxes the incoming encoded frames on different RTP modules
615// using the simulcastIdx, so it's important that there is no corresponding
616// encoder reordering in between adapter reinits as this would lead to PictureID
617// discontinuities.
618TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
619 SetupCodec();
620 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
621 VerifyCodecSettings();
622
623 // Send frames on all streams.
624 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
625 ASSERT_EQ(3u, encoders.size());
626 encoders[0]->SendEncodedImage(1152, 704);
627 int width;
628 int height;
629 int simulcast_index;
630 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
631 EXPECT_EQ(0, simulcast_index);
632
633 encoders[1]->SendEncodedImage(300, 620);
634 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
635 EXPECT_EQ(1, simulcast_index);
636
637 encoders[2]->SendEncodedImage(120, 240);
638 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
639 EXPECT_EQ(2, simulcast_index);
640
641 // Reinitialize.
642 EXPECT_EQ(0, adapter_->Release());
643 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
644 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
645
646 // Verify that the same encoder sends out frames on the same simulcast index.
647 encoders[0]->SendEncodedImage(1152, 704);
648 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
649 EXPECT_EQ(0, simulcast_index);
650
651 encoders[1]->SendEncodedImage(300, 620);
652 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
653 EXPECT_EQ(1, simulcast_index);
654
655 encoders[2]->SendEncodedImage(120, 240);
656 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
657 EXPECT_EQ(2, simulcast_index);
658}
659
pbos65e15ba2015-10-15 10:52:15 -0700660TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
661 TestVp8Simulcast::DefaultSettings(
662 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
663 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));
676 codec_.minBitrate = 50;
677 codec_.numberOfSimulcastStreams = 1;
678 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng82fad3d2018-03-21 09:57:23 +0100679 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
noahricfac0ff02016-09-09 10:27:15 -0700680
681 // Above min should be respected.
Erik Språng566124a2018-04-23 12:32:22 +0200682 VideoBitrateAllocation target_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100683 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
684 adapter_->SetRateAllocation(target_bitrate, 30);
685 EXPECT_EQ(target_bitrate,
686 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700687
688 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng566124a2018-04-23 12:32:22 +0200689 VideoBitrateAllocation too_low_bitrate =
Erik Språng08127a92016-11-16 16:41:30 +0100690 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
691 adapter_->SetRateAllocation(too_low_bitrate, 30);
692 EXPECT_EQ(target_bitrate,
693 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700694
695 // Zero should be passed on as is, since it means "pause".
Erik Språng566124a2018-04-23 12:32:22 +0200696 adapter_->SetRateAllocation(VideoBitrateAllocation(), 30);
697 EXPECT_EQ(VideoBitrateAllocation(),
Erik Språng08127a92016-11-16 16:41:30 +0100698 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700699}
700
Peter Boströma5dec162016-01-20 15:53:55 +0100701TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
702 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
703 TestVp8Simulcast::DefaultSettings(
704 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
705 std::vector<const char*> encoder_names;
706 encoder_names.push_back("codec1");
707 encoder_names.push_back("codec2");
708 encoder_names.push_back("codec3");
709 helper_->factory()->SetEncoderNames(encoder_names);
710 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
711 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
712 adapter_->ImplementationName());
Peter Boströmd53c3892016-03-30 17:03:52 +0200713
714 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700715 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200716 codec_.numberOfSimulcastStreams = 1;
717 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
718 adapter_->RegisterEncodeCompleteCallback(this);
719 ASSERT_EQ(1u, helper_->factory()->encoders().size());
720 EXPECT_STREQ("codec1", adapter_->ImplementationName());
Peter Boströma5dec162016-01-20 15:53:55 +0100721}
722
pbos65e15ba2015-10-15 10:52:15 -0700723TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700724 SupportsNativeHandleForMultipleStreams) {
pbos65e15ba2015-10-15 10:52:15 -0700725 TestVp8Simulcast::DefaultSettings(
726 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
727 codec_.numberOfSimulcastStreams = 3;
728 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
729 adapter_->RegisterEncodeCompleteCallback(this);
730 ASSERT_EQ(3u, helper_->factory()->encoders().size());
731 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
732 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700733 // If one encoder doesn't support it, then overall support is disabled.
734 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
pbos65e15ba2015-10-15 10:52:15 -0700735 EXPECT_FALSE(adapter_->SupportsNativeHandle());
noahricfe3654d2016-07-01 09:05:54 -0700736 // Once all do, then the adapter claims support.
737 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
738 EXPECT_TRUE(adapter_->SupportsNativeHandle());
739}
740
nisseaf916892017-01-10 07:44:26 -0800741// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000742class FakeNativeBuffer : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700743 public:
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000744 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
745
746 Type type() const override { return Type::kNative; }
747 int width() const override { return width_; }
748 int height() const override { return height_; }
749
750 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700751 RTC_NOTREACHED();
752 return nullptr;
753 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000754
755 private:
756 const int width_;
757 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700758};
759
760TEST_F(TestSimulcastEncoderAdapterFake,
761 NativeHandleForwardingForMultipleStreams) {
762 TestVp8Simulcast::DefaultSettings(
763 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
764 codec_.numberOfSimulcastStreams = 3;
765 // High start bitrate, so all streams are enabled.
766 codec_.startBitrate = 3000;
767 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
768 adapter_->RegisterEncodeCompleteCallback(this);
769 ASSERT_EQ(3u, helper_->factory()->encoders().size());
770 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
771 encoder->set_supports_native_handle(true);
772 EXPECT_TRUE(adapter_->SupportsNativeHandle());
773
774 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000775 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
noahricfe3654d2016-07-01 09:05:54 -0700776 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
777 // Expect calls with the given video frame verbatim, since it's a texture
778 // frame and can't otherwise be modified/resized.
779 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
780 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
781 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700782 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700783}
784
noahric57779102016-05-25 06:48:46 -0700785TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
786 TestVp8Simulcast::DefaultSettings(
787 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
788 codec_.numberOfSimulcastStreams = 3;
789 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
790 adapter_->RegisterEncodeCompleteCallback(this);
791 ASSERT_EQ(3u, helper_->factory()->encoders().size());
792 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700793 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
794 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700795
796 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000797 rtc::scoped_refptr<I420Buffer> input_buffer =
798 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700799 input_buffer->InitializeData();
800 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
noahric57779102016-05-25 06:48:46 -0700801 std::vector<FrameType> frame_types(3, kVideoFrameKey);
802 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
803 adapter_->Encode(input_frame, nullptr, &frame_types));
804}
805
noahrice5ba75a2016-12-12 13:08:27 -0800806TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
807 TestVp8Simulcast::DefaultSettings(
808 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
noahrice5ba75a2016-12-12 13:08:27 -0800809 codec_.numberOfSimulcastStreams = 3;
810 helper_->factory()->set_init_encode_return_value(
811 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
812 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
813 adapter_->InitEncode(&codec_, 1, 1200));
814 EXPECT_TRUE(helper_->factory()->encoders().empty());
815}
816
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000817} // namespace testing
818} // namespace webrtc