blob: d8fc4b6d78e6bec2c5cf2582b16bb3d6d4277873 [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 {
34 return rtc::MakeUnique<SimulcastEncoderAdapter>(factory_.get());
magjed6cc25612017-07-10 03:26:36 -070035 }
Magnus Jedvert46a27652017-11-13 14:10:02 +010036 std::unique_ptr<VP8Decoder> CreateDecoder() override {
37 return VP8Decoder::Create();
38 }
magjed6cc25612017-07-10 03:26:36 -070039
40 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010041 std::unique_ptr<VideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000042};
43
44TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) {
45 TestVp8Simulcast::TestKeyFrameRequestsOnAllStreams();
46}
47
48TEST_F(TestSimulcastEncoderAdapter, TestPaddingAllStreams) {
49 TestVp8Simulcast::TestPaddingAllStreams();
50}
51
52TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreams) {
53 TestVp8Simulcast::TestPaddingTwoStreams();
54}
55
56TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreamsOneMaxedOut) {
57 TestVp8Simulcast::TestPaddingTwoStreamsOneMaxedOut();
58}
59
60TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStream) {
61 TestVp8Simulcast::TestPaddingOneStream();
62}
63
64TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStreamTwoMaxedOut) {
65 TestVp8Simulcast::TestPaddingOneStreamTwoMaxedOut();
66}
67
68TEST_F(TestSimulcastEncoderAdapter, TestSendAllStreams) {
69 TestVp8Simulcast::TestSendAllStreams();
70}
71
72TEST_F(TestSimulcastEncoderAdapter, TestDisablingStreams) {
73 TestVp8Simulcast::TestDisablingStreams();
74}
75
Seth Hampson46e31ba2018-01-18 10:39:54 -080076TEST_F(TestSimulcastEncoderAdapter, TestActiveStreams) {
77 TestVp8Simulcast::TestActiveStreams();
78}
79
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000080TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneStream) {
81 TestVp8Simulcast::TestSwitchingToOneStream();
82}
83
84TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneOddStream) {
85 TestVp8Simulcast::TestSwitchingToOneOddStream();
86}
87
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000088TEST_F(TestSimulcastEncoderAdapter, TestStrideEncodeDecode) {
89 TestVp8Simulcast::TestStrideEncodeDecode();
90}
91
92TEST_F(TestSimulcastEncoderAdapter, TestSaptioTemporalLayers333PatternEncoder) {
93 TestVp8Simulcast::TestSaptioTemporalLayers333PatternEncoder();
94}
95
96TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
97 TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
98}
99
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100100class MockVideoEncoder;
101
102class MockVideoEncoderFactory : public VideoEncoderFactory {
103 public:
104 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
105
106 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
107 const SdpVideoFormat& format) override;
108
109 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
110
111 const std::vector<MockVideoEncoder*>& encoders() const;
112 void SetEncoderNames(const std::vector<const char*>& encoder_names);
113 void set_init_encode_return_value(int32_t value);
114
115 void DestroyVideoEncoder(VideoEncoder* encoder);
116
117 private:
118 int32_t init_encode_return_value_ = 0;
119 std::vector<MockVideoEncoder*> encoders_;
120 std::vector<const char*> encoder_names_;
121};
122
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000123class MockVideoEncoder : public VideoEncoder {
124 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100125 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
126 : factory_(factory) {}
127
nisseef8b61e2016-04-29 06:09:15 -0700128 // TODO(nisse): Valid overrides commented out, because the gmock
129 // methods don't use any override declarations, and we want to avoid
130 // warnings from -Winconsistent-missing-override. See
131 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000132 int32_t InitEncode(const VideoCodec* codecSettings,
133 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700134 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000135 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800136 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000137 }
138
noahricfe3654d2016-07-01 09:05:54 -0700139 MOCK_METHOD3(
140 Encode,
141 int32_t(const VideoFrame& inputImage,
142 const CodecSpecificInfo* codecSpecificInfo,
143 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000144
pbos65e15ba2015-10-15 10:52:15 -0700145 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700146 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700147 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000148 return 0;
149 }
150
brandtr5e171752017-05-23 03:32:16 -0700151 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000152
Erik Språng08127a92016-11-16 16:41:30 +0100153 int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation,
154 uint32_t framerate) {
155 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000156 return 0;
157 }
158
philipelcce46fc2015-12-21 03:04:49 -0800159 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000160
nisseef8b61e2016-04-29 06:09:15 -0700161 bool SupportsNativeHandle() const /* override */ {
162 return supports_native_handle_;
163 }
pbos65e15ba2015-10-15 10:52:15 -0700164
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100165 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000166
167 const VideoCodec& codec() const { return codec_; }
168
Noah Richards41ee1ea2015-04-15 09:24:26 -0700169 void SendEncodedImage(int width, int height) {
170 // Sends a fake image of the given width/height.
171 EncodedImage image;
172 image._encodedWidth = width;
173 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700174 CodecSpecificInfo codec_specific_info;
175 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
brandtr5e171752017-05-23 03:32:16 -0700176 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700177 }
178
pbos65e15ba2015-10-15 10:52:15 -0700179 void set_supports_native_handle(bool enabled) {
180 supports_native_handle_ = enabled;
181 }
noahrice5ba75a2016-12-12 13:08:27 -0800182
183 void set_init_encode_return_value(int32_t value) {
184 init_encode_return_value_ = value;
185 }
186
Erik Språng08127a92016-11-16 16:41:30 +0100187 BitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700188
Peter Boströma5dec162016-01-20 15:53:55 +0100189 MOCK_CONST_METHOD0(ImplementationName, const char*());
190
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000191 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100192 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700193 bool supports_native_handle_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800194 int32_t init_encode_return_value_ = 0;
Erik Språng08127a92016-11-16 16:41:30 +0100195 BitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700196
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000197 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700198 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000199};
200
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100201std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
202 const {
203 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
204 return formats;
205}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000206
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100207std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
208 const SdpVideoFormat& format) {
209 std::unique_ptr<MockVideoEncoder> encoder(
210 new ::testing::NiceMock<MockVideoEncoder>(this));
211 encoder->set_init_encode_return_value(init_encode_return_value_);
212 const char* encoder_name = encoder_names_.empty()
213 ? "codec_implementation_name"
214 : encoder_names_[encoders_.size()];
215 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
216 encoders_.push_back(encoder.get());
217 return encoder;
218}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000219
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100220void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
221 for (size_t i = 0; i < encoders_.size(); ++i) {
222 if (encoders_[i] == encoder) {
223 encoders_.erase(encoders_.begin() + i);
224 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000225 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000226 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100227}
Zhi Huangaea84f52017-11-16 18:46:27 +0000228
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100229VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
230 const SdpVideoFormat& format) const {
231 return CodecInfo();
232}
Zhi Huangaea84f52017-11-16 18:46:27 +0000233
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100234const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
235 const {
236 return encoders_;
237}
238void MockVideoEncoderFactory::SetEncoderNames(
239 const std::vector<const char*>& encoder_names) {
240 encoder_names_ = encoder_names;
241}
242void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
243 init_encode_return_value_ = value;
244}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000245
246class TestSimulcastEncoderAdapterFakeHelper {
247 public:
248 TestSimulcastEncoderAdapterFakeHelper()
249 : factory_(new MockVideoEncoderFactory()) {}
250
251 // Can only be called once as the SimulcastEncoderAdapter will take the
252 // ownership of |factory_|.
253 VP8Encoder* CreateMockEncoderAdapter() {
magjed6cc25612017-07-10 03:26:36 -0700254 return new SimulcastEncoderAdapter(factory_.get());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000255 }
256
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000257 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000258 EXPECT_TRUE(!factory_->encoders().empty());
259 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
260 EXPECT_CALL(*factory_->encoders()[i],
philipelcce46fc2015-12-21 03:04:49 -0800261 SetChannelParameters(packetLoss, rtt))
262 .Times(1);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000263 }
264 }
265
magjed6cc25612017-07-10 03:26:36 -0700266 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000267
268 private:
magjed6cc25612017-07-10 03:26:36 -0700269 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000270};
271
272static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
273
Noah Richards41ee1ea2015-04-15 09:24:26 -0700274class TestSimulcastEncoderAdapterFake : public ::testing::Test,
275 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000276 public:
277 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700278 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
279 adapter_(helper_->CreateMockEncoderAdapter()),
280 last_encoded_image_width_(-1),
281 last_encoded_image_height_(-1),
282 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700283 virtual ~TestSimulcastEncoderAdapterFake() {
284 if (adapter_) {
285 adapter_->Release();
286 }
287 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000288
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700289 Result OnEncodedImage(const EncodedImage& encoded_image,
290 const CodecSpecificInfo* codec_specific_info,
291 const RTPFragmentationHeader* fragmentation) override {
292 last_encoded_image_width_ = encoded_image._encodedWidth;
293 last_encoded_image_height_ = encoded_image._encodedHeight;
294 if (codec_specific_info) {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700295 last_encoded_image_simulcast_index_ =
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700296 codec_specific_info->codecSpecific.VP8.simulcastIdx;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700297 }
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700298 return Result(Result::OK, encoded_image._timeStamp);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700299 }
300
301 bool GetLastEncodedImageInfo(int* out_width,
302 int* out_height,
303 int* out_simulcast_index) {
304 if (last_encoded_image_width_ == -1) {
305 return false;
306 }
307 *out_width = last_encoded_image_width_;
308 *out_height = last_encoded_image_height_;
309 *out_simulcast_index = last_encoded_image_simulcast_index_;
310 return true;
311 }
312
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000313 void SetupCodec() {
314 TestVp8Simulcast::DefaultSettings(
philipelcce46fc2015-12-21 03:04:49 -0800315 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100316 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
317 tl_factory_.SetListener(rate_allocator_.get());
318 codec_.VP8()->tl_factory = &tl_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000319 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700320 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000321 }
322
323 void VerifyCodec(const VideoCodec& ref, int stream_index) {
324 const VideoCodec& target =
325 helper_->factory()->encoders()[stream_index]->codec();
326 EXPECT_EQ(ref.codecType, target.codecType);
327 EXPECT_EQ(0, strcmp(ref.plName, target.plName));
328 EXPECT_EQ(ref.plType, target.plType);
329 EXPECT_EQ(ref.width, target.width);
330 EXPECT_EQ(ref.height, target.height);
331 EXPECT_EQ(ref.startBitrate, target.startBitrate);
332 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
333 EXPECT_EQ(ref.minBitrate, target.minBitrate);
334 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700335 EXPECT_EQ(ref.VP8().pictureLossIndicationOn,
336 target.VP8().pictureLossIndicationOn);
hta257dc392016-10-25 09:05:06 -0700337 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
338 EXPECT_EQ(ref.VP8().resilience, target.VP8().resilience);
339 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
340 target.VP8().numberOfTemporalLayers);
341 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
342 EXPECT_EQ(ref.VP8().errorConcealmentOn, target.VP8().errorConcealmentOn);
343 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
344 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
345 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000346 EXPECT_EQ(ref.qpMax, target.qpMax);
347 EXPECT_EQ(0, target.numberOfSimulcastStreams);
348 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000349
350 // No need to compare simulcastStream as numberOfSimulcastStreams should
351 // always be 0.
352 }
353
354 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
355 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700356 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000357 kTestTemporalLayerProfile[stream_index];
Erik Språng08127a92016-11-16 16:41:30 +0100358 ref_codec->VP8()->tl_factory = &tl_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000359 ref_codec->width = codec_.simulcastStream[stream_index].width;
360 ref_codec->height = codec_.simulcastStream[stream_index].height;
361 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
362 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
363 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
364 }
365
366 void VerifyCodecSettings() {
367 EXPECT_EQ(3u, helper_->factory()->encoders().size());
368 VideoCodec ref_codec;
369
370 // stream 0, the lowest resolution stream.
371 InitRefCodec(0, &ref_codec);
372 ref_codec.qpMax = 45;
hta257dc392016-10-25 09:05:06 -0700373 ref_codec.VP8()->complexity = webrtc::kComplexityHigher;
374 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000375 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
376 VerifyCodec(ref_codec, 0);
377
378 // stream 1
379 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700380 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700381 // The start bitrate (300kbit) minus what we have for the lower layers
382 // (100kbit).
383 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000384 VerifyCodec(ref_codec, 1);
385
386 // stream 2, the biggest resolution stream.
387 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700388 // We don't have enough bits to send this, so the adapter should have
389 // configured it to use the min bitrate for this layer (600kbit) but turn
390 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000391 ref_codec.startBitrate = 600;
392 VerifyCodec(ref_codec, 2);
393 }
394
395 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800396 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
397 std::unique_ptr<VP8Encoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000398 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700399 int last_encoded_image_width_;
400 int last_encoded_image_height_;
401 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100402 TemporalLayersFactory tl_factory_;
403 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000404};
405
406TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
407 SetupCodec();
408 VerifyCodecSettings();
409}
410
brandtr5e171752017-05-23 03:32:16 -0700411TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
412 EXPECT_EQ(0, adapter_->Release());
413}
414
415TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
416 SetupCodec();
417 EXPECT_EQ(0, adapter_->Release());
418
419 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
420}
421
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000422TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
423 SetupCodec();
424 const uint32_t packetLoss = 5;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000425 const int64_t rtt = 30;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000426 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
427 adapter_->SetChannelParameters(packetLoss, rtt);
428}
429
Noah Richards41ee1ea2015-04-15 09:24:26 -0700430TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
431 SetupCodec();
432
Peter Boström5d0379d2015-10-06 14:04:51 +0200433 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100434 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200435
Noah Richards41ee1ea2015-04-15 09:24:26 -0700436 // At this point, the simulcast encoder adapter should have 3 streams: HD,
437 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
438 // resolutions, to test that the adapter forwards on the correct resolution
439 // and simulcast index values, going only off the encoder that generates the
440 // image.
brandtr5e171752017-05-23 03:32:16 -0700441 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
442 ASSERT_EQ(3u, encoders.size());
443 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700444 int width;
445 int height;
446 int simulcast_index;
447 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
448 EXPECT_EQ(1152, width);
449 EXPECT_EQ(704, height);
450 EXPECT_EQ(0, simulcast_index);
451
brandtr5e171752017-05-23 03:32:16 -0700452 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700453 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
454 EXPECT_EQ(300, width);
455 EXPECT_EQ(620, height);
456 EXPECT_EQ(1, simulcast_index);
457
brandtr5e171752017-05-23 03:32:16 -0700458 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700459 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
460 EXPECT_EQ(120, width);
461 EXPECT_EQ(240, height);
462 EXPECT_EQ(2, simulcast_index);
463}
464
brandtr5e171752017-05-23 03:32:16 -0700465// This test verifies that the underlying encoders are reused, when the adapter
466// is reinited with different number of simulcast streams. It further checks
467// that the allocated encoders are reused in the same order as before, starting
468// with the lowest stream.
469TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
470 // Set up common settings for three streams.
471 TestVp8Simulcast::DefaultSettings(
472 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
473 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
474 tl_factory_.SetListener(rate_allocator_.get());
475 codec_.VP8()->tl_factory = &tl_factory_;
476 adapter_->RegisterEncodeCompleteCallback(this);
477
478 // Input data.
479 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
480 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
481 std::vector<FrameType> frame_types;
482
483 // Encode with three streams.
484 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
485 VerifyCodecSettings();
486 std::vector<MockVideoEncoder*> original_encoders =
487 helper_->factory()->encoders();
488 ASSERT_EQ(3u, original_encoders.size());
489 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
490 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
491 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
492 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
493 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
494 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
495 frame_types.resize(3, kVideoFrameKey);
496 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
497 EXPECT_CALL(*original_encoders[0], Release())
498 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
499 EXPECT_CALL(*original_encoders[1], Release())
500 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
501 EXPECT_CALL(*original_encoders[2], Release())
502 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
503 EXPECT_EQ(0, adapter_->Release());
504
505 // Encode with two streams.
506 codec_.width /= 2;
507 codec_.height /= 2;
508 codec_.numberOfSimulcastStreams = 2;
509 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
510 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
511 ASSERT_EQ(2u, new_encoders.size());
512 ASSERT_EQ(original_encoders[0], new_encoders[0]);
513 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
514 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
515 ASSERT_EQ(original_encoders[1], new_encoders[1]);
516 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
517 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
518 frame_types.resize(2, kVideoFrameKey);
519 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
520 EXPECT_CALL(*original_encoders[0], Release())
521 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
522 EXPECT_CALL(*original_encoders[1], Release())
523 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
524 EXPECT_EQ(0, adapter_->Release());
525
526 // Encode with single stream.
527 codec_.width /= 2;
528 codec_.height /= 2;
529 codec_.numberOfSimulcastStreams = 1;
530 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
531 new_encoders = helper_->factory()->encoders();
532 ASSERT_EQ(1u, new_encoders.size());
533 ASSERT_EQ(original_encoders[0], new_encoders[0]);
534 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
535 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
536 frame_types.resize(1, kVideoFrameKey);
537 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
538 EXPECT_CALL(*original_encoders[0], Release())
539 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
540 EXPECT_EQ(0, adapter_->Release());
541
542 // Encode with three streams, again.
543 codec_.width *= 4;
544 codec_.height *= 4;
545 codec_.numberOfSimulcastStreams = 3;
546 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
547 new_encoders = helper_->factory()->encoders();
548 ASSERT_EQ(3u, new_encoders.size());
549 // The first encoder is reused.
550 ASSERT_EQ(original_encoders[0], new_encoders[0]);
551 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
552 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
553 // The second and third encoders are new.
554 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
555 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
556 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
557 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
558 frame_types.resize(3, kVideoFrameKey);
559 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
560 EXPECT_CALL(*original_encoders[0], Release())
561 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
562 EXPECT_CALL(*new_encoders[1], Release())
563 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
564 EXPECT_CALL(*new_encoders[2], Release())
565 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
566 EXPECT_EQ(0, adapter_->Release());
567}
568
569TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
570 SetupCodec();
571 VerifyCodecSettings();
572
573 EXPECT_EQ(3u, helper_->factory()->encoders().size());
574
575 // The adapter should destroy all encoders it has allocated. Since
576 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
577 // lsan to find leaks here.
578 EXPECT_EQ(0, adapter_->Release());
579 adapter_.reset();
580}
581
582// This test verifies that an adapter reinit with the same codec settings as
583// before does not change the underlying encoder codec settings.
584TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
585 SetupCodec();
586 VerifyCodecSettings();
587
588 // Capture current codec settings.
589 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
590 ASSERT_EQ(3u, encoders.size());
591 std::array<VideoCodec, 3> codecs_before;
592 for (int i = 0; i < 3; ++i) {
593 codecs_before[i] = encoders[i]->codec();
594 }
595
596 // Reinitialize and verify that the new codec settings are the same.
597 EXPECT_EQ(0, adapter_->Release());
598 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
599 for (int i = 0; i < 3; ++i) {
600 const VideoCodec& codec_before = codecs_before[i];
601 const VideoCodec& codec_after = encoders[i]->codec();
602
603 // webrtc::VideoCodec does not implement operator==.
604 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
605 EXPECT_EQ(codec_before.plType, codec_after.plType);
606 EXPECT_EQ(codec_before.width, codec_after.width);
607 EXPECT_EQ(codec_before.height, codec_after.height);
608 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
609 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
610 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
611 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
612 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
613 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
614 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
615 codec_after.numberOfSimulcastStreams);
616 EXPECT_EQ(codec_before.mode, codec_after.mode);
617 EXPECT_EQ(codec_before.expect_encode_from_texture,
618 codec_after.expect_encode_from_texture);
619 }
620}
621
622// This test is similar to the one above, except that it tests the simulcastIdx
623// from the CodecSpecificInfo that is connected to an encoded frame. The
624// PayloadRouter demuxes the incoming encoded frames on different RTP modules
625// using the simulcastIdx, so it's important that there is no corresponding
626// encoder reordering in between adapter reinits as this would lead to PictureID
627// discontinuities.
628TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
629 SetupCodec();
630 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
631 VerifyCodecSettings();
632
633 // Send frames on all streams.
634 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
635 ASSERT_EQ(3u, encoders.size());
636 encoders[0]->SendEncodedImage(1152, 704);
637 int width;
638 int height;
639 int simulcast_index;
640 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
641 EXPECT_EQ(0, simulcast_index);
642
643 encoders[1]->SendEncodedImage(300, 620);
644 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
645 EXPECT_EQ(1, simulcast_index);
646
647 encoders[2]->SendEncodedImage(120, 240);
648 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
649 EXPECT_EQ(2, simulcast_index);
650
651 // Reinitialize.
652 EXPECT_EQ(0, adapter_->Release());
653 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
654 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
655
656 // Verify that the same encoder sends out frames on the same simulcast index.
657 encoders[0]->SendEncodedImage(1152, 704);
658 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
659 EXPECT_EQ(0, simulcast_index);
660
661 encoders[1]->SendEncodedImage(300, 620);
662 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
663 EXPECT_EQ(1, simulcast_index);
664
665 encoders[2]->SendEncodedImage(120, 240);
666 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
667 EXPECT_EQ(2, simulcast_index);
668}
669
pbos65e15ba2015-10-15 10:52:15 -0700670TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
671 TestVp8Simulcast::DefaultSettings(
672 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100673 codec_.VP8()->tl_factory = &tl_factory_;
pbos65e15ba2015-10-15 10:52:15 -0700674 codec_.numberOfSimulcastStreams = 1;
675 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
676 adapter_->RegisterEncodeCompleteCallback(this);
677 ASSERT_EQ(1u, helper_->factory()->encoders().size());
678 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
679 EXPECT_TRUE(adapter_->SupportsNativeHandle());
680 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
681 EXPECT_FALSE(adapter_->SupportsNativeHandle());
682}
683
noahricfac0ff02016-09-09 10:27:15 -0700684TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
685 TestVp8Simulcast::DefaultSettings(
686 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100687 codec_.VP8()->tl_factory = &tl_factory_;
noahricfac0ff02016-09-09 10:27:15 -0700688 codec_.minBitrate = 50;
689 codec_.numberOfSimulcastStreams = 1;
690 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng08127a92016-11-16 16:41:30 +0100691 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
noahricfac0ff02016-09-09 10:27:15 -0700692
693 // Above min should be respected.
Erik Språng08127a92016-11-16 16:41:30 +0100694 BitrateAllocation target_bitrate =
695 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
696 adapter_->SetRateAllocation(target_bitrate, 30);
697 EXPECT_EQ(target_bitrate,
698 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700699
700 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng08127a92016-11-16 16:41:30 +0100701 BitrateAllocation too_low_bitrate =
702 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
703 adapter_->SetRateAllocation(too_low_bitrate, 30);
704 EXPECT_EQ(target_bitrate,
705 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700706
707 // Zero should be passed on as is, since it means "pause".
Erik Språng08127a92016-11-16 16:41:30 +0100708 adapter_->SetRateAllocation(BitrateAllocation(), 30);
709 EXPECT_EQ(BitrateAllocation(),
710 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700711}
712
Peter Boströma5dec162016-01-20 15:53:55 +0100713TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
714 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
715 TestVp8Simulcast::DefaultSettings(
716 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100717 codec_.VP8()->tl_factory = &tl_factory_;
Peter Boströma5dec162016-01-20 15:53:55 +0100718 std::vector<const char*> encoder_names;
719 encoder_names.push_back("codec1");
720 encoder_names.push_back("codec2");
721 encoder_names.push_back("codec3");
722 helper_->factory()->SetEncoderNames(encoder_names);
723 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
724 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
725 adapter_->ImplementationName());
Peter Boströmd53c3892016-03-30 17:03:52 +0200726
727 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700728 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200729 codec_.numberOfSimulcastStreams = 1;
730 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
731 adapter_->RegisterEncodeCompleteCallback(this);
732 ASSERT_EQ(1u, helper_->factory()->encoders().size());
733 EXPECT_STREQ("codec1", adapter_->ImplementationName());
Peter Boströma5dec162016-01-20 15:53:55 +0100734}
735
pbos65e15ba2015-10-15 10:52:15 -0700736TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700737 SupportsNativeHandleForMultipleStreams) {
pbos65e15ba2015-10-15 10:52:15 -0700738 TestVp8Simulcast::DefaultSettings(
739 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100740 codec_.VP8()->tl_factory = &tl_factory_;
pbos65e15ba2015-10-15 10:52:15 -0700741 codec_.numberOfSimulcastStreams = 3;
742 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
743 adapter_->RegisterEncodeCompleteCallback(this);
744 ASSERT_EQ(3u, helper_->factory()->encoders().size());
745 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
746 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700747 // If one encoder doesn't support it, then overall support is disabled.
748 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
pbos65e15ba2015-10-15 10:52:15 -0700749 EXPECT_FALSE(adapter_->SupportsNativeHandle());
noahricfe3654d2016-07-01 09:05:54 -0700750 // Once all do, then the adapter claims support.
751 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
752 EXPECT_TRUE(adapter_->SupportsNativeHandle());
753}
754
nisseaf916892017-01-10 07:44:26 -0800755// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000756class FakeNativeBuffer : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700757 public:
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000758 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
759
760 Type type() const override { return Type::kNative; }
761 int width() const override { return width_; }
762 int height() const override { return height_; }
763
764 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700765 RTC_NOTREACHED();
766 return nullptr;
767 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000768
769 private:
770 const int width_;
771 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700772};
773
774TEST_F(TestSimulcastEncoderAdapterFake,
775 NativeHandleForwardingForMultipleStreams) {
776 TestVp8Simulcast::DefaultSettings(
777 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100778 codec_.VP8()->tl_factory = &tl_factory_;
noahricfe3654d2016-07-01 09:05:54 -0700779 codec_.numberOfSimulcastStreams = 3;
780 // High start bitrate, so all streams are enabled.
781 codec_.startBitrate = 3000;
782 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
783 adapter_->RegisterEncodeCompleteCallback(this);
784 ASSERT_EQ(3u, helper_->factory()->encoders().size());
785 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
786 encoder->set_supports_native_handle(true);
787 EXPECT_TRUE(adapter_->SupportsNativeHandle());
788
789 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000790 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
noahricfe3654d2016-07-01 09:05:54 -0700791 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
792 // Expect calls with the given video frame verbatim, since it's a texture
793 // frame and can't otherwise be modified/resized.
794 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
795 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
796 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700797 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700798}
799
noahric57779102016-05-25 06:48:46 -0700800TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
801 TestVp8Simulcast::DefaultSettings(
802 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100803 codec_.VP8()->tl_factory = &tl_factory_;
noahric57779102016-05-25 06:48:46 -0700804 codec_.numberOfSimulcastStreams = 3;
805 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
806 adapter_->RegisterEncodeCompleteCallback(this);
807 ASSERT_EQ(3u, helper_->factory()->encoders().size());
808 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700809 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
810 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700811
812 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000813 rtc::scoped_refptr<I420Buffer> input_buffer =
814 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700815 input_buffer->InitializeData();
816 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
noahric57779102016-05-25 06:48:46 -0700817 std::vector<FrameType> frame_types(3, kVideoFrameKey);
818 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
819 adapter_->Encode(input_frame, nullptr, &frame_types));
820}
821
noahrice5ba75a2016-12-12 13:08:27 -0800822TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
823 TestVp8Simulcast::DefaultSettings(
824 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
825 codec_.VP8()->tl_factory = &tl_factory_;
826 codec_.numberOfSimulcastStreams = 3;
827 helper_->factory()->set_init_encode_return_value(
828 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
829 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
830 adapter_->InitEncode(&codec_, 1, 1200));
831 EXPECT_TRUE(helper_->factory()->encoders().empty());
832}
833
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000834} // namespace testing
835} // namespace webrtc