blob: 8087d7be0bb5aebc1c9ce5f8c4e6c8511c7bb853 [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
76TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneStream) {
77 TestVp8Simulcast::TestSwitchingToOneStream();
78}
79
80TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneOddStream) {
81 TestVp8Simulcast::TestSwitchingToOneOddStream();
82}
83
pbos@webrtc.org9115cde2014-12-09 10:36:40 +000084TEST_F(TestSimulcastEncoderAdapter, TestStrideEncodeDecode) {
85 TestVp8Simulcast::TestStrideEncodeDecode();
86}
87
88TEST_F(TestSimulcastEncoderAdapter, TestSaptioTemporalLayers333PatternEncoder) {
89 TestVp8Simulcast::TestSaptioTemporalLayers333PatternEncoder();
90}
91
92TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
93 TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
94}
95
Magnus Jedvertdf4883d2017-11-17 14:44:55 +010096class MockVideoEncoder;
97
98class MockVideoEncoderFactory : public VideoEncoderFactory {
99 public:
100 std::vector<SdpVideoFormat> GetSupportedFormats() const override;
101
102 std::unique_ptr<VideoEncoder> CreateVideoEncoder(
103 const SdpVideoFormat& format) override;
104
105 CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override;
106
107 const std::vector<MockVideoEncoder*>& encoders() const;
108 void SetEncoderNames(const std::vector<const char*>& encoder_names);
109 void set_init_encode_return_value(int32_t value);
110
111 void DestroyVideoEncoder(VideoEncoder* encoder);
112
113 private:
114 int32_t init_encode_return_value_ = 0;
115 std::vector<MockVideoEncoder*> encoders_;
116 std::vector<const char*> encoder_names_;
117};
118
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000119class MockVideoEncoder : public VideoEncoder {
120 public:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100121 explicit MockVideoEncoder(MockVideoEncoderFactory* factory)
122 : factory_(factory) {}
123
nisseef8b61e2016-04-29 06:09:15 -0700124 // TODO(nisse): Valid overrides commented out, because the gmock
125 // methods don't use any override declarations, and we want to avoid
126 // warnings from -Winconsistent-missing-override. See
127 // http://crbug.com/428099.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000128 int32_t InitEncode(const VideoCodec* codecSettings,
129 int32_t numberOfCores,
nisseef8b61e2016-04-29 06:09:15 -0700130 size_t maxPayloadSize) /* override */ {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000131 codec_ = *codecSettings;
noahrice5ba75a2016-12-12 13:08:27 -0800132 return init_encode_return_value_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000133 }
134
noahricfe3654d2016-07-01 09:05:54 -0700135 MOCK_METHOD3(
136 Encode,
137 int32_t(const VideoFrame& inputImage,
138 const CodecSpecificInfo* codecSpecificInfo,
139 const std::vector<FrameType>* frame_types) /* override */);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000140
pbos65e15ba2015-10-15 10:52:15 -0700141 int32_t RegisterEncodeCompleteCallback(
nisseef8b61e2016-04-29 06:09:15 -0700142 EncodedImageCallback* callback) /* override */ {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700143 callback_ = callback;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000144 return 0;
145 }
146
brandtr5e171752017-05-23 03:32:16 -0700147 MOCK_METHOD0(Release, int32_t());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000148
Erik Språng08127a92016-11-16 16:41:30 +0100149 int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation,
150 uint32_t framerate) {
151 last_set_bitrate_ = bitrate_allocation;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000152 return 0;
153 }
154
philipelcce46fc2015-12-21 03:04:49 -0800155 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000156
nisseef8b61e2016-04-29 06:09:15 -0700157 bool SupportsNativeHandle() const /* override */ {
158 return supports_native_handle_;
159 }
pbos65e15ba2015-10-15 10:52:15 -0700160
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100161 virtual ~MockVideoEncoder() { factory_->DestroyVideoEncoder(this); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000162
163 const VideoCodec& codec() const { return codec_; }
164
Noah Richards41ee1ea2015-04-15 09:24:26 -0700165 void SendEncodedImage(int width, int height) {
166 // Sends a fake image of the given width/height.
167 EncodedImage image;
168 image._encodedWidth = width;
169 image._encodedHeight = height;
sergeyu2cb155a2016-11-04 11:39:29 -0700170 CodecSpecificInfo codec_specific_info;
171 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
brandtr5e171752017-05-23 03:32:16 -0700172 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700173 }
174
pbos65e15ba2015-10-15 10:52:15 -0700175 void set_supports_native_handle(bool enabled) {
176 supports_native_handle_ = enabled;
177 }
noahrice5ba75a2016-12-12 13:08:27 -0800178
179 void set_init_encode_return_value(int32_t value) {
180 init_encode_return_value_ = value;
181 }
182
Erik Språng08127a92016-11-16 16:41:30 +0100183 BitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
pbos65e15ba2015-10-15 10:52:15 -0700184
Peter Boströma5dec162016-01-20 15:53:55 +0100185 MOCK_CONST_METHOD0(ImplementationName, const char*());
186
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000187 private:
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100188 MockVideoEncoderFactory* const factory_;
pbos65e15ba2015-10-15 10:52:15 -0700189 bool supports_native_handle_ = false;
noahrice5ba75a2016-12-12 13:08:27 -0800190 int32_t init_encode_return_value_ = 0;
Erik Språng08127a92016-11-16 16:41:30 +0100191 BitrateAllocation last_set_bitrate_;
noahricfac0ff02016-09-09 10:27:15 -0700192
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000193 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700194 EncodedImageCallback* callback_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000195};
196
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100197std::vector<SdpVideoFormat> MockVideoEncoderFactory::GetSupportedFormats()
198 const {
199 std::vector<SdpVideoFormat> formats = {SdpVideoFormat("VP8")};
200 return formats;
201}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000202
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100203std::unique_ptr<VideoEncoder> MockVideoEncoderFactory::CreateVideoEncoder(
204 const SdpVideoFormat& format) {
205 std::unique_ptr<MockVideoEncoder> encoder(
206 new ::testing::NiceMock<MockVideoEncoder>(this));
207 encoder->set_init_encode_return_value(init_encode_return_value_);
208 const char* encoder_name = encoder_names_.empty()
209 ? "codec_implementation_name"
210 : encoder_names_[encoders_.size()];
211 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
212 encoders_.push_back(encoder.get());
213 return encoder;
214}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000215
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100216void MockVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
217 for (size_t i = 0; i < encoders_.size(); ++i) {
218 if (encoders_[i] == encoder) {
219 encoders_.erase(encoders_.begin() + i);
220 break;
Zhi Huangaea84f52017-11-16 18:46:27 +0000221 }
Zhi Huangaea84f52017-11-16 18:46:27 +0000222 }
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100223}
Zhi Huangaea84f52017-11-16 18:46:27 +0000224
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100225VideoEncoderFactory::CodecInfo MockVideoEncoderFactory::QueryVideoEncoder(
226 const SdpVideoFormat& format) const {
227 return CodecInfo();
228}
Zhi Huangaea84f52017-11-16 18:46:27 +0000229
Magnus Jedvertdf4883d2017-11-17 14:44:55 +0100230const std::vector<MockVideoEncoder*>& MockVideoEncoderFactory::encoders()
231 const {
232 return encoders_;
233}
234void MockVideoEncoderFactory::SetEncoderNames(
235 const std::vector<const char*>& encoder_names) {
236 encoder_names_ = encoder_names;
237}
238void MockVideoEncoderFactory::set_init_encode_return_value(int32_t value) {
239 init_encode_return_value_ = value;
240}
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000241
242class TestSimulcastEncoderAdapterFakeHelper {
243 public:
244 TestSimulcastEncoderAdapterFakeHelper()
245 : factory_(new MockVideoEncoderFactory()) {}
246
247 // Can only be called once as the SimulcastEncoderAdapter will take the
248 // ownership of |factory_|.
249 VP8Encoder* CreateMockEncoderAdapter() {
magjed6cc25612017-07-10 03:26:36 -0700250 return new SimulcastEncoderAdapter(factory_.get());
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000251 }
252
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000253 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000254 EXPECT_TRUE(!factory_->encoders().empty());
255 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
256 EXPECT_CALL(*factory_->encoders()[i],
philipelcce46fc2015-12-21 03:04:49 -0800257 SetChannelParameters(packetLoss, rtt))
258 .Times(1);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000259 }
260 }
261
magjed6cc25612017-07-10 03:26:36 -0700262 MockVideoEncoderFactory* factory() { return factory_.get(); }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000263
264 private:
magjed6cc25612017-07-10 03:26:36 -0700265 std::unique_ptr<MockVideoEncoderFactory> factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000266};
267
268static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
269
Noah Richards41ee1ea2015-04-15 09:24:26 -0700270class TestSimulcastEncoderAdapterFake : public ::testing::Test,
271 public EncodedImageCallback {
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000272 public:
273 TestSimulcastEncoderAdapterFake()
Noah Richards41ee1ea2015-04-15 09:24:26 -0700274 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
275 adapter_(helper_->CreateMockEncoderAdapter()),
276 last_encoded_image_width_(-1),
277 last_encoded_image_height_(-1),
278 last_encoded_image_simulcast_index_(-1) {}
brandtr5e171752017-05-23 03:32:16 -0700279 virtual ~TestSimulcastEncoderAdapterFake() {
280 if (adapter_) {
281 adapter_->Release();
282 }
283 }
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000284
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700285 Result OnEncodedImage(const EncodedImage& encoded_image,
286 const CodecSpecificInfo* codec_specific_info,
287 const RTPFragmentationHeader* fragmentation) override {
288 last_encoded_image_width_ = encoded_image._encodedWidth;
289 last_encoded_image_height_ = encoded_image._encodedHeight;
290 if (codec_specific_info) {
Noah Richards41ee1ea2015-04-15 09:24:26 -0700291 last_encoded_image_simulcast_index_ =
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700292 codec_specific_info->codecSpecific.VP8.simulcastIdx;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700293 }
Sergey Ulanov525df3f2016-08-02 17:46:41 -0700294 return Result(Result::OK, encoded_image._timeStamp);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700295 }
296
297 bool GetLastEncodedImageInfo(int* out_width,
298 int* out_height,
299 int* out_simulcast_index) {
300 if (last_encoded_image_width_ == -1) {
301 return false;
302 }
303 *out_width = last_encoded_image_width_;
304 *out_height = last_encoded_image_height_;
305 *out_simulcast_index = last_encoded_image_simulcast_index_;
306 return true;
307 }
308
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000309 void SetupCodec() {
310 TestVp8Simulcast::DefaultSettings(
philipelcce46fc2015-12-21 03:04:49 -0800311 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100312 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
313 tl_factory_.SetListener(rate_allocator_.get());
314 codec_.VP8()->tl_factory = &tl_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000315 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Noah Richards41ee1ea2015-04-15 09:24:26 -0700316 adapter_->RegisterEncodeCompleteCallback(this);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000317 }
318
319 void VerifyCodec(const VideoCodec& ref, int stream_index) {
320 const VideoCodec& target =
321 helper_->factory()->encoders()[stream_index]->codec();
322 EXPECT_EQ(ref.codecType, target.codecType);
323 EXPECT_EQ(0, strcmp(ref.plName, target.plName));
324 EXPECT_EQ(ref.plType, target.plType);
325 EXPECT_EQ(ref.width, target.width);
326 EXPECT_EQ(ref.height, target.height);
327 EXPECT_EQ(ref.startBitrate, target.startBitrate);
328 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
329 EXPECT_EQ(ref.minBitrate, target.minBitrate);
330 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
hta257dc392016-10-25 09:05:06 -0700331 EXPECT_EQ(ref.VP8().pictureLossIndicationOn,
332 target.VP8().pictureLossIndicationOn);
hta257dc392016-10-25 09:05:06 -0700333 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
334 EXPECT_EQ(ref.VP8().resilience, target.VP8().resilience);
335 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
336 target.VP8().numberOfTemporalLayers);
337 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
338 EXPECT_EQ(ref.VP8().errorConcealmentOn, target.VP8().errorConcealmentOn);
339 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
340 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
341 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000342 EXPECT_EQ(ref.qpMax, target.qpMax);
343 EXPECT_EQ(0, target.numberOfSimulcastStreams);
344 EXPECT_EQ(ref.mode, target.mode);
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000345
346 // No need to compare simulcastStream as numberOfSimulcastStreams should
347 // always be 0.
348 }
349
350 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
351 *ref_codec = codec_;
hta257dc392016-10-25 09:05:06 -0700352 ref_codec->VP8()->numberOfTemporalLayers =
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000353 kTestTemporalLayerProfile[stream_index];
Erik Språng08127a92016-11-16 16:41:30 +0100354 ref_codec->VP8()->tl_factory = &tl_factory_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000355 ref_codec->width = codec_.simulcastStream[stream_index].width;
356 ref_codec->height = codec_.simulcastStream[stream_index].height;
357 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
358 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
359 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
360 }
361
362 void VerifyCodecSettings() {
363 EXPECT_EQ(3u, helper_->factory()->encoders().size());
364 VideoCodec ref_codec;
365
366 // stream 0, the lowest resolution stream.
367 InitRefCodec(0, &ref_codec);
368 ref_codec.qpMax = 45;
hta257dc392016-10-25 09:05:06 -0700369 ref_codec.VP8()->complexity = webrtc::kComplexityHigher;
370 ref_codec.VP8()->denoisingOn = false;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000371 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
372 VerifyCodec(ref_codec, 0);
373
374 // stream 1
375 InitRefCodec(1, &ref_codec);
hta257dc392016-10-25 09:05:06 -0700376 ref_codec.VP8()->denoisingOn = false;
Noah Richards67b635a2015-05-22 14:12:10 -0700377 // The start bitrate (300kbit) minus what we have for the lower layers
378 // (100kbit).
379 ref_codec.startBitrate = 200;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000380 VerifyCodec(ref_codec, 1);
381
382 // stream 2, the biggest resolution stream.
383 InitRefCodec(2, &ref_codec);
Noah Richards67b635a2015-05-22 14:12:10 -0700384 // We don't have enough bits to send this, so the adapter should have
385 // configured it to use the min bitrate for this layer (600kbit) but turn
386 // off sending.
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000387 ref_codec.startBitrate = 600;
388 VerifyCodec(ref_codec, 2);
389 }
390
391 protected:
kwiberg3f55dea2016-02-29 05:51:59 -0800392 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
393 std::unique_ptr<VP8Encoder> adapter_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000394 VideoCodec codec_;
Noah Richards41ee1ea2015-04-15 09:24:26 -0700395 int last_encoded_image_width_;
396 int last_encoded_image_height_;
397 int last_encoded_image_simulcast_index_;
Erik Språng08127a92016-11-16 16:41:30 +0100398 TemporalLayersFactory tl_factory_;
399 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000400};
401
402TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
403 SetupCodec();
404 VerifyCodecSettings();
405}
406
brandtr5e171752017-05-23 03:32:16 -0700407TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
408 EXPECT_EQ(0, adapter_->Release());
409}
410
411TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
412 SetupCodec();
413 EXPECT_EQ(0, adapter_->Release());
414
415 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
416}
417
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000418TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
419 SetupCodec();
420 const uint32_t packetLoss = 5;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000421 const int64_t rtt = 30;
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000422 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
423 adapter_->SetChannelParameters(packetLoss, rtt);
424}
425
Noah Richards41ee1ea2015-04-15 09:24:26 -0700426TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
427 SetupCodec();
428
Peter Boström5d0379d2015-10-06 14:04:51 +0200429 // Set bitrates so that we send all layers.
Erik Språng08127a92016-11-16 16:41:30 +0100430 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
Peter Boström5d0379d2015-10-06 14:04:51 +0200431
Noah Richards41ee1ea2015-04-15 09:24:26 -0700432 // At this point, the simulcast encoder adapter should have 3 streams: HD,
433 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
434 // resolutions, to test that the adapter forwards on the correct resolution
435 // and simulcast index values, going only off the encoder that generates the
436 // image.
brandtr5e171752017-05-23 03:32:16 -0700437 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
438 ASSERT_EQ(3u, encoders.size());
439 encoders[0]->SendEncodedImage(1152, 704);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700440 int width;
441 int height;
442 int simulcast_index;
443 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
444 EXPECT_EQ(1152, width);
445 EXPECT_EQ(704, height);
446 EXPECT_EQ(0, simulcast_index);
447
brandtr5e171752017-05-23 03:32:16 -0700448 encoders[1]->SendEncodedImage(300, 620);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700449 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
450 EXPECT_EQ(300, width);
451 EXPECT_EQ(620, height);
452 EXPECT_EQ(1, simulcast_index);
453
brandtr5e171752017-05-23 03:32:16 -0700454 encoders[2]->SendEncodedImage(120, 240);
Noah Richards41ee1ea2015-04-15 09:24:26 -0700455 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
456 EXPECT_EQ(120, width);
457 EXPECT_EQ(240, height);
458 EXPECT_EQ(2, simulcast_index);
459}
460
brandtr5e171752017-05-23 03:32:16 -0700461// This test verifies that the underlying encoders are reused, when the adapter
462// is reinited with different number of simulcast streams. It further checks
463// that the allocated encoders are reused in the same order as before, starting
464// with the lowest stream.
465TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
466 // Set up common settings for three streams.
467 TestVp8Simulcast::DefaultSettings(
468 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
469 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
470 tl_factory_.SetListener(rate_allocator_.get());
471 codec_.VP8()->tl_factory = &tl_factory_;
472 adapter_->RegisterEncodeCompleteCallback(this);
473
474 // Input data.
475 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
476 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
477 std::vector<FrameType> frame_types;
478
479 // Encode with three streams.
480 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
481 VerifyCodecSettings();
482 std::vector<MockVideoEncoder*> original_encoders =
483 helper_->factory()->encoders();
484 ASSERT_EQ(3u, original_encoders.size());
485 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
486 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
487 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
488 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
489 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
490 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
491 frame_types.resize(3, kVideoFrameKey);
492 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
493 EXPECT_CALL(*original_encoders[0], Release())
494 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
495 EXPECT_CALL(*original_encoders[1], Release())
496 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
497 EXPECT_CALL(*original_encoders[2], Release())
498 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
499 EXPECT_EQ(0, adapter_->Release());
500
501 // Encode with two streams.
502 codec_.width /= 2;
503 codec_.height /= 2;
504 codec_.numberOfSimulcastStreams = 2;
505 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
506 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
507 ASSERT_EQ(2u, new_encoders.size());
508 ASSERT_EQ(original_encoders[0], new_encoders[0]);
509 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
510 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
511 ASSERT_EQ(original_encoders[1], new_encoders[1]);
512 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
513 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
514 frame_types.resize(2, kVideoFrameKey);
515 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
516 EXPECT_CALL(*original_encoders[0], Release())
517 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
518 EXPECT_CALL(*original_encoders[1], Release())
519 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
520 EXPECT_EQ(0, adapter_->Release());
521
522 // Encode with single stream.
523 codec_.width /= 2;
524 codec_.height /= 2;
525 codec_.numberOfSimulcastStreams = 1;
526 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
527 new_encoders = helper_->factory()->encoders();
528 ASSERT_EQ(1u, new_encoders.size());
529 ASSERT_EQ(original_encoders[0], new_encoders[0]);
530 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
531 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
532 frame_types.resize(1, kVideoFrameKey);
533 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
534 EXPECT_CALL(*original_encoders[0], Release())
535 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
536 EXPECT_EQ(0, adapter_->Release());
537
538 // Encode with three streams, again.
539 codec_.width *= 4;
540 codec_.height *= 4;
541 codec_.numberOfSimulcastStreams = 3;
542 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
543 new_encoders = helper_->factory()->encoders();
544 ASSERT_EQ(3u, new_encoders.size());
545 // The first encoder is reused.
546 ASSERT_EQ(original_encoders[0], new_encoders[0]);
547 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
548 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
549 // The second and third encoders are new.
550 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
551 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
552 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
553 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
554 frame_types.resize(3, kVideoFrameKey);
555 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
556 EXPECT_CALL(*original_encoders[0], Release())
557 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
558 EXPECT_CALL(*new_encoders[1], Release())
559 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
560 EXPECT_CALL(*new_encoders[2], Release())
561 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
562 EXPECT_EQ(0, adapter_->Release());
563}
564
565TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
566 SetupCodec();
567 VerifyCodecSettings();
568
569 EXPECT_EQ(3u, helper_->factory()->encoders().size());
570
571 // The adapter should destroy all encoders it has allocated. Since
572 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
573 // lsan to find leaks here.
574 EXPECT_EQ(0, adapter_->Release());
575 adapter_.reset();
576}
577
578// This test verifies that an adapter reinit with the same codec settings as
579// before does not change the underlying encoder codec settings.
580TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
581 SetupCodec();
582 VerifyCodecSettings();
583
584 // Capture current codec settings.
585 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
586 ASSERT_EQ(3u, encoders.size());
587 std::array<VideoCodec, 3> codecs_before;
588 for (int i = 0; i < 3; ++i) {
589 codecs_before[i] = encoders[i]->codec();
590 }
591
592 // Reinitialize and verify that the new codec settings are the same.
593 EXPECT_EQ(0, adapter_->Release());
594 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
595 for (int i = 0; i < 3; ++i) {
596 const VideoCodec& codec_before = codecs_before[i];
597 const VideoCodec& codec_after = encoders[i]->codec();
598
599 // webrtc::VideoCodec does not implement operator==.
600 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
601 EXPECT_EQ(codec_before.plType, codec_after.plType);
602 EXPECT_EQ(codec_before.width, codec_after.width);
603 EXPECT_EQ(codec_before.height, codec_after.height);
604 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
605 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
606 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
607 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
608 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
609 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
610 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
611 codec_after.numberOfSimulcastStreams);
612 EXPECT_EQ(codec_before.mode, codec_after.mode);
613 EXPECT_EQ(codec_before.expect_encode_from_texture,
614 codec_after.expect_encode_from_texture);
615 }
616}
617
618// This test is similar to the one above, except that it tests the simulcastIdx
619// from the CodecSpecificInfo that is connected to an encoded frame. The
620// PayloadRouter demuxes the incoming encoded frames on different RTP modules
621// using the simulcastIdx, so it's important that there is no corresponding
622// encoder reordering in between adapter reinits as this would lead to PictureID
623// discontinuities.
624TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
625 SetupCodec();
626 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
627 VerifyCodecSettings();
628
629 // Send frames on all streams.
630 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
631 ASSERT_EQ(3u, encoders.size());
632 encoders[0]->SendEncodedImage(1152, 704);
633 int width;
634 int height;
635 int simulcast_index;
636 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
637 EXPECT_EQ(0, simulcast_index);
638
639 encoders[1]->SendEncodedImage(300, 620);
640 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
641 EXPECT_EQ(1, simulcast_index);
642
643 encoders[2]->SendEncodedImage(120, 240);
644 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
645 EXPECT_EQ(2, simulcast_index);
646
647 // Reinitialize.
648 EXPECT_EQ(0, adapter_->Release());
649 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
650 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
651
652 // Verify that the same encoder sends out frames on the same simulcast index.
653 encoders[0]->SendEncodedImage(1152, 704);
654 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
655 EXPECT_EQ(0, simulcast_index);
656
657 encoders[1]->SendEncodedImage(300, 620);
658 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
659 EXPECT_EQ(1, simulcast_index);
660
661 encoders[2]->SendEncodedImage(120, 240);
662 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
663 EXPECT_EQ(2, simulcast_index);
664}
665
pbos65e15ba2015-10-15 10:52:15 -0700666TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
667 TestVp8Simulcast::DefaultSettings(
668 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100669 codec_.VP8()->tl_factory = &tl_factory_;
pbos65e15ba2015-10-15 10:52:15 -0700670 codec_.numberOfSimulcastStreams = 1;
671 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
672 adapter_->RegisterEncodeCompleteCallback(this);
673 ASSERT_EQ(1u, helper_->factory()->encoders().size());
674 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
675 EXPECT_TRUE(adapter_->SupportsNativeHandle());
676 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
677 EXPECT_FALSE(adapter_->SupportsNativeHandle());
678}
679
noahricfac0ff02016-09-09 10:27:15 -0700680TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
681 TestVp8Simulcast::DefaultSettings(
682 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100683 codec_.VP8()->tl_factory = &tl_factory_;
noahricfac0ff02016-09-09 10:27:15 -0700684 codec_.minBitrate = 50;
685 codec_.numberOfSimulcastStreams = 1;
686 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
Erik Språng08127a92016-11-16 16:41:30 +0100687 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
noahricfac0ff02016-09-09 10:27:15 -0700688
689 // Above min should be respected.
Erik Språng08127a92016-11-16 16:41:30 +0100690 BitrateAllocation target_bitrate =
691 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
692 adapter_->SetRateAllocation(target_bitrate, 30);
693 EXPECT_EQ(target_bitrate,
694 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700695
696 // Below min but non-zero should be replaced with the min bitrate.
Erik Språng08127a92016-11-16 16:41:30 +0100697 BitrateAllocation too_low_bitrate =
698 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
699 adapter_->SetRateAllocation(too_low_bitrate, 30);
700 EXPECT_EQ(target_bitrate,
701 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700702
703 // Zero should be passed on as is, since it means "pause".
Erik Språng08127a92016-11-16 16:41:30 +0100704 adapter_->SetRateAllocation(BitrateAllocation(), 30);
705 EXPECT_EQ(BitrateAllocation(),
706 helper_->factory()->encoders()[0]->last_set_bitrate());
noahricfac0ff02016-09-09 10:27:15 -0700707}
708
Peter Boströma5dec162016-01-20 15:53:55 +0100709TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
710 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
711 TestVp8Simulcast::DefaultSettings(
712 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100713 codec_.VP8()->tl_factory = &tl_factory_;
Peter Boströma5dec162016-01-20 15:53:55 +0100714 std::vector<const char*> encoder_names;
715 encoder_names.push_back("codec1");
716 encoder_names.push_back("codec2");
717 encoder_names.push_back("codec3");
718 helper_->factory()->SetEncoderNames(encoder_names);
719 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
720 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
721 adapter_->ImplementationName());
Peter Boströmd53c3892016-03-30 17:03:52 +0200722
723 // Single streams should not expose "SimulcastEncoderAdapter" in name.
brandtr5e171752017-05-23 03:32:16 -0700724 EXPECT_EQ(0, adapter_->Release());
Peter Boströmd53c3892016-03-30 17:03:52 +0200725 codec_.numberOfSimulcastStreams = 1;
726 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
727 adapter_->RegisterEncodeCompleteCallback(this);
728 ASSERT_EQ(1u, helper_->factory()->encoders().size());
729 EXPECT_STREQ("codec1", adapter_->ImplementationName());
Peter Boströma5dec162016-01-20 15:53:55 +0100730}
731
pbos65e15ba2015-10-15 10:52:15 -0700732TEST_F(TestSimulcastEncoderAdapterFake,
noahricfe3654d2016-07-01 09:05:54 -0700733 SupportsNativeHandleForMultipleStreams) {
pbos65e15ba2015-10-15 10:52:15 -0700734 TestVp8Simulcast::DefaultSettings(
735 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100736 codec_.VP8()->tl_factory = &tl_factory_;
pbos65e15ba2015-10-15 10:52:15 -0700737 codec_.numberOfSimulcastStreams = 3;
738 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
739 adapter_->RegisterEncodeCompleteCallback(this);
740 ASSERT_EQ(3u, helper_->factory()->encoders().size());
741 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
742 encoder->set_supports_native_handle(true);
noahricfe3654d2016-07-01 09:05:54 -0700743 // If one encoder doesn't support it, then overall support is disabled.
744 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
pbos65e15ba2015-10-15 10:52:15 -0700745 EXPECT_FALSE(adapter_->SupportsNativeHandle());
noahricfe3654d2016-07-01 09:05:54 -0700746 // Once all do, then the adapter claims support.
747 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
748 EXPECT_TRUE(adapter_->SupportsNativeHandle());
749}
750
nisseaf916892017-01-10 07:44:26 -0800751// TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000752class FakeNativeBuffer : public VideoFrameBuffer {
noahricfe3654d2016-07-01 09:05:54 -0700753 public:
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000754 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
755
756 Type type() const override { return Type::kNative; }
757 int width() const override { return width_; }
758 int height() const override { return height_; }
759
760 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
noahricfe3654d2016-07-01 09:05:54 -0700761 RTC_NOTREACHED();
762 return nullptr;
763 }
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000764
765 private:
766 const int width_;
767 const int height_;
noahricfe3654d2016-07-01 09:05:54 -0700768};
769
770TEST_F(TestSimulcastEncoderAdapterFake,
771 NativeHandleForwardingForMultipleStreams) {
772 TestVp8Simulcast::DefaultSettings(
773 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100774 codec_.VP8()->tl_factory = &tl_factory_;
noahricfe3654d2016-07-01 09:05:54 -0700775 codec_.numberOfSimulcastStreams = 3;
776 // High start bitrate, so all streams are enabled.
777 codec_.startBitrate = 3000;
778 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
779 adapter_->RegisterEncodeCompleteCallback(this);
780 ASSERT_EQ(3u, helper_->factory()->encoders().size());
781 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
782 encoder->set_supports_native_handle(true);
783 EXPECT_TRUE(adapter_->SupportsNativeHandle());
784
785 rtc::scoped_refptr<VideoFrameBuffer> buffer(
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000786 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
noahricfe3654d2016-07-01 09:05:54 -0700787 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
788 // Expect calls with the given video frame verbatim, since it's a texture
789 // frame and can't otherwise be modified/resized.
790 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
791 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
792 std::vector<FrameType> frame_types(3, kVideoFrameKey);
brandtr5e171752017-05-23 03:32:16 -0700793 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
pbos65e15ba2015-10-15 10:52:15 -0700794}
795
noahric57779102016-05-25 06:48:46 -0700796TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
797 TestVp8Simulcast::DefaultSettings(
798 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
Erik Språng08127a92016-11-16 16:41:30 +0100799 codec_.VP8()->tl_factory = &tl_factory_;
noahric57779102016-05-25 06:48:46 -0700800 codec_.numberOfSimulcastStreams = 3;
801 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
802 adapter_->RegisterEncodeCompleteCallback(this);
803 ASSERT_EQ(3u, helper_->factory()->encoders().size());
804 // Tell the 2nd encoder to request software fallback.
noahricfe3654d2016-07-01 09:05:54 -0700805 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
806 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
noahric57779102016-05-25 06:48:46 -0700807
808 // Send a fake frame and assert the return is software fallback.
Magnus Jedvert72dbe2a2017-06-10 17:03:37 +0000809 rtc::scoped_refptr<I420Buffer> input_buffer =
810 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
nisse64ec8f82016-09-27 00:17:25 -0700811 input_buffer->InitializeData();
812 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
noahric57779102016-05-25 06:48:46 -0700813 std::vector<FrameType> frame_types(3, kVideoFrameKey);
814 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
815 adapter_->Encode(input_frame, nullptr, &frame_types));
816}
817
noahrice5ba75a2016-12-12 13:08:27 -0800818TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
819 TestVp8Simulcast::DefaultSettings(
820 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
821 codec_.VP8()->tl_factory = &tl_factory_;
822 codec_.numberOfSimulcastStreams = 3;
823 helper_->factory()->set_init_encode_return_value(
824 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
825 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
826 adapter_->InitEncode(&codec_, 1, 1200));
827 EXPECT_TRUE(helper_->factory()->encoders().empty());
828}
829
pbos@webrtc.org9115cde2014-12-09 10:36:40 +0000830} // namespace testing
831} // namespace webrtc