Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter_unittest.cc

Issue 2964953002: Remove webrtc::VideoEncoderFactory (Closed)
Patch Set: Add dep to base:sequenced_task_checker Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
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
11 #include <array>
12 #include <memory>
13 #include <vector>
14
15 #include "webrtc/common_video/include/video_frame_buffer.h"
16 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h"
17 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h"
18 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
19 #include "webrtc/test/gmock.h"
20
21 namespace webrtc {
22 namespace testing {
23
24 class TestSimulcastEncoderAdapter : public TestVp8Simulcast {
25 public:
26 TestSimulcastEncoderAdapter()
27 : TestVp8Simulcast(new SimulcastEncoderAdapter(new Vp8EncoderFactory()),
28 VP8Decoder::Create()) {}
29
30 protected:
31 class Vp8EncoderFactory : public VideoEncoderFactory {
32 public:
33 VideoEncoder* Create() override { return VP8Encoder::Create(); }
34
35 void Destroy(VideoEncoder* encoder) override { delete encoder; }
36
37 virtual ~Vp8EncoderFactory() {}
38 };
39
40 virtual void SetUp() { TestVp8Simulcast::SetUp(); }
41 virtual void TearDown() { TestVp8Simulcast::TearDown(); }
42 };
43
44 TEST_F(TestSimulcastEncoderAdapter, TestKeyFrameRequestsOnAllStreams) {
45 TestVp8Simulcast::TestKeyFrameRequestsOnAllStreams();
46 }
47
48 TEST_F(TestSimulcastEncoderAdapter, TestPaddingAllStreams) {
49 TestVp8Simulcast::TestPaddingAllStreams();
50 }
51
52 TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreams) {
53 TestVp8Simulcast::TestPaddingTwoStreams();
54 }
55
56 TEST_F(TestSimulcastEncoderAdapter, TestPaddingTwoStreamsOneMaxedOut) {
57 TestVp8Simulcast::TestPaddingTwoStreamsOneMaxedOut();
58 }
59
60 TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStream) {
61 TestVp8Simulcast::TestPaddingOneStream();
62 }
63
64 TEST_F(TestSimulcastEncoderAdapter, TestPaddingOneStreamTwoMaxedOut) {
65 TestVp8Simulcast::TestPaddingOneStreamTwoMaxedOut();
66 }
67
68 TEST_F(TestSimulcastEncoderAdapter, TestSendAllStreams) {
69 TestVp8Simulcast::TestSendAllStreams();
70 }
71
72 TEST_F(TestSimulcastEncoderAdapter, TestDisablingStreams) {
73 TestVp8Simulcast::TestDisablingStreams();
74 }
75
76 TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneStream) {
77 TestVp8Simulcast::TestSwitchingToOneStream();
78 }
79
80 TEST_F(TestSimulcastEncoderAdapter, TestSwitchingToOneOddStream) {
81 TestVp8Simulcast::TestSwitchingToOneOddStream();
82 }
83
84 TEST_F(TestSimulcastEncoderAdapter, TestStrideEncodeDecode) {
85 TestVp8Simulcast::TestStrideEncodeDecode();
86 }
87
88 TEST_F(TestSimulcastEncoderAdapter, TestSaptioTemporalLayers333PatternEncoder) {
89 TestVp8Simulcast::TestSaptioTemporalLayers333PatternEncoder();
90 }
91
92 TEST_F(TestSimulcastEncoderAdapter, TestSpatioTemporalLayers321PatternEncoder) {
93 TestVp8Simulcast::TestSpatioTemporalLayers321PatternEncoder();
94 }
95
96 class MockVideoEncoder : public VideoEncoder {
97 public:
98 // TODO(nisse): Valid overrides commented out, because the gmock
99 // methods don't use any override declarations, and we want to avoid
100 // warnings from -Winconsistent-missing-override. See
101 // http://crbug.com/428099.
102 int32_t InitEncode(const VideoCodec* codecSettings,
103 int32_t numberOfCores,
104 size_t maxPayloadSize) /* override */ {
105 codec_ = *codecSettings;
106 return init_encode_return_value_;
107 }
108
109 MOCK_METHOD3(
110 Encode,
111 int32_t(const VideoFrame& inputImage,
112 const CodecSpecificInfo* codecSpecificInfo,
113 const std::vector<FrameType>* frame_types) /* override */);
114
115 int32_t RegisterEncodeCompleteCallback(
116 EncodedImageCallback* callback) /* override */ {
117 callback_ = callback;
118 return 0;
119 }
120
121 MOCK_METHOD0(Release, int32_t());
122
123 int32_t SetRateAllocation(const BitrateAllocation& bitrate_allocation,
124 uint32_t framerate) {
125 last_set_bitrate_ = bitrate_allocation;
126 return 0;
127 }
128
129 MOCK_METHOD2(SetChannelParameters, int32_t(uint32_t packetLoss, int64_t rtt));
130
131 bool SupportsNativeHandle() const /* override */ {
132 return supports_native_handle_;
133 }
134
135 virtual ~MockVideoEncoder() {}
136
137 const VideoCodec& codec() const { return codec_; }
138
139 void SendEncodedImage(int width, int height) {
140 // Sends a fake image of the given width/height.
141 EncodedImage image;
142 image._encodedWidth = width;
143 image._encodedHeight = height;
144 CodecSpecificInfo codec_specific_info;
145 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
146 callback_->OnEncodedImage(image, &codec_specific_info, nullptr);
147 }
148
149 void set_supports_native_handle(bool enabled) {
150 supports_native_handle_ = enabled;
151 }
152
153 void set_init_encode_return_value(int32_t value) {
154 init_encode_return_value_ = value;
155 }
156
157 BitrateAllocation last_set_bitrate() const { return last_set_bitrate_; }
158
159 MOCK_CONST_METHOD0(ImplementationName, const char*());
160
161 private:
162 bool supports_native_handle_ = false;
163 int32_t init_encode_return_value_ = 0;
164 BitrateAllocation last_set_bitrate_;
165
166 VideoCodec codec_;
167 EncodedImageCallback* callback_;
168 };
169
170 class MockVideoEncoderFactory : public VideoEncoderFactory {
171 public:
172 VideoEncoder* Create() override {
173 MockVideoEncoder* encoder = new
174 ::testing::NiceMock<MockVideoEncoder>();
175 encoder->set_init_encode_return_value(init_encode_return_value_);
176 const char* encoder_name = encoder_names_.empty()
177 ? "codec_implementation_name"
178 : encoder_names_[encoders_.size()];
179 ON_CALL(*encoder, ImplementationName()).WillByDefault(Return(encoder_name));
180 encoders_.push_back(encoder);
181 return encoder;
182 }
183
184 void Destroy(VideoEncoder* encoder) override {
185 for (size_t i = 0; i < encoders_.size(); ++i) {
186 if (encoders_[i] == encoder) {
187 encoders_.erase(encoders_.begin() + i);
188 break;
189 }
190 }
191 delete encoder;
192 }
193
194 virtual ~MockVideoEncoderFactory() {}
195
196 const std::vector<MockVideoEncoder*>& encoders() const { return encoders_; }
197 void SetEncoderNames(const std::vector<const char*>& encoder_names) {
198 encoder_names_ = encoder_names;
199 }
200 void set_init_encode_return_value(int32_t value) {
201 init_encode_return_value_ = value;
202 }
203
204 private:
205 int32_t init_encode_return_value_ = 0;
206 std::vector<MockVideoEncoder*> encoders_;
207 std::vector<const char*> encoder_names_;
208 };
209
210 class TestSimulcastEncoderAdapterFakeHelper {
211 public:
212 TestSimulcastEncoderAdapterFakeHelper()
213 : factory_(new MockVideoEncoderFactory()) {}
214
215 // Can only be called once as the SimulcastEncoderAdapter will take the
216 // ownership of |factory_|.
217 VP8Encoder* CreateMockEncoderAdapter() {
218 return new SimulcastEncoderAdapter(factory_);
219 }
220
221 void ExpectCallSetChannelParameters(uint32_t packetLoss, int64_t rtt) {
222 EXPECT_TRUE(!factory_->encoders().empty());
223 for (size_t i = 0; i < factory_->encoders().size(); ++i) {
224 EXPECT_CALL(*factory_->encoders()[i],
225 SetChannelParameters(packetLoss, rtt))
226 .Times(1);
227 }
228 }
229
230 MockVideoEncoderFactory* factory() { return factory_; }
231
232 private:
233 MockVideoEncoderFactory* factory_;
234 };
235
236 static const int kTestTemporalLayerProfile[3] = {3, 2, 1};
237
238 class TestSimulcastEncoderAdapterFake : public ::testing::Test,
239 public EncodedImageCallback {
240 public:
241 TestSimulcastEncoderAdapterFake()
242 : helper_(new TestSimulcastEncoderAdapterFakeHelper()),
243 adapter_(helper_->CreateMockEncoderAdapter()),
244 last_encoded_image_width_(-1),
245 last_encoded_image_height_(-1),
246 last_encoded_image_simulcast_index_(-1) {}
247 virtual ~TestSimulcastEncoderAdapterFake() {
248 if (adapter_) {
249 adapter_->Release();
250 }
251 }
252
253 Result OnEncodedImage(const EncodedImage& encoded_image,
254 const CodecSpecificInfo* codec_specific_info,
255 const RTPFragmentationHeader* fragmentation) override {
256 last_encoded_image_width_ = encoded_image._encodedWidth;
257 last_encoded_image_height_ = encoded_image._encodedHeight;
258 if (codec_specific_info) {
259 last_encoded_image_simulcast_index_ =
260 codec_specific_info->codecSpecific.VP8.simulcastIdx;
261 }
262 return Result(Result::OK, encoded_image._timeStamp);
263 }
264
265 bool GetLastEncodedImageInfo(int* out_width,
266 int* out_height,
267 int* out_simulcast_index) {
268 if (last_encoded_image_width_ == -1) {
269 return false;
270 }
271 *out_width = last_encoded_image_width_;
272 *out_height = last_encoded_image_height_;
273 *out_simulcast_index = last_encoded_image_simulcast_index_;
274 return true;
275 }
276
277 void SetupCodec() {
278 TestVp8Simulcast::DefaultSettings(
279 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
280 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
281 tl_factory_.SetListener(rate_allocator_.get());
282 codec_.VP8()->tl_factory = &tl_factory_;
283 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
284 adapter_->RegisterEncodeCompleteCallback(this);
285 }
286
287 void VerifyCodec(const VideoCodec& ref, int stream_index) {
288 const VideoCodec& target =
289 helper_->factory()->encoders()[stream_index]->codec();
290 EXPECT_EQ(ref.codecType, target.codecType);
291 EXPECT_EQ(0, strcmp(ref.plName, target.plName));
292 EXPECT_EQ(ref.plType, target.plType);
293 EXPECT_EQ(ref.width, target.width);
294 EXPECT_EQ(ref.height, target.height);
295 EXPECT_EQ(ref.startBitrate, target.startBitrate);
296 EXPECT_EQ(ref.maxBitrate, target.maxBitrate);
297 EXPECT_EQ(ref.minBitrate, target.minBitrate);
298 EXPECT_EQ(ref.maxFramerate, target.maxFramerate);
299 EXPECT_EQ(ref.VP8().pictureLossIndicationOn,
300 target.VP8().pictureLossIndicationOn);
301 EXPECT_EQ(ref.VP8().complexity, target.VP8().complexity);
302 EXPECT_EQ(ref.VP8().resilience, target.VP8().resilience);
303 EXPECT_EQ(ref.VP8().numberOfTemporalLayers,
304 target.VP8().numberOfTemporalLayers);
305 EXPECT_EQ(ref.VP8().denoisingOn, target.VP8().denoisingOn);
306 EXPECT_EQ(ref.VP8().errorConcealmentOn, target.VP8().errorConcealmentOn);
307 EXPECT_EQ(ref.VP8().automaticResizeOn, target.VP8().automaticResizeOn);
308 EXPECT_EQ(ref.VP8().frameDroppingOn, target.VP8().frameDroppingOn);
309 EXPECT_EQ(ref.VP8().keyFrameInterval, target.VP8().keyFrameInterval);
310 EXPECT_EQ(ref.qpMax, target.qpMax);
311 EXPECT_EQ(0, target.numberOfSimulcastStreams);
312 EXPECT_EQ(ref.mode, target.mode);
313
314 // No need to compare simulcastStream as numberOfSimulcastStreams should
315 // always be 0.
316 }
317
318 void InitRefCodec(int stream_index, VideoCodec* ref_codec) {
319 *ref_codec = codec_;
320 ref_codec->VP8()->numberOfTemporalLayers =
321 kTestTemporalLayerProfile[stream_index];
322 ref_codec->VP8()->tl_factory = &tl_factory_;
323 ref_codec->width = codec_.simulcastStream[stream_index].width;
324 ref_codec->height = codec_.simulcastStream[stream_index].height;
325 ref_codec->maxBitrate = codec_.simulcastStream[stream_index].maxBitrate;
326 ref_codec->minBitrate = codec_.simulcastStream[stream_index].minBitrate;
327 ref_codec->qpMax = codec_.simulcastStream[stream_index].qpMax;
328 }
329
330 void VerifyCodecSettings() {
331 EXPECT_EQ(3u, helper_->factory()->encoders().size());
332 VideoCodec ref_codec;
333
334 // stream 0, the lowest resolution stream.
335 InitRefCodec(0, &ref_codec);
336 ref_codec.qpMax = 45;
337 ref_codec.VP8()->complexity = webrtc::kComplexityHigher;
338 ref_codec.VP8()->denoisingOn = false;
339 ref_codec.startBitrate = 100; // Should equal to the target bitrate.
340 VerifyCodec(ref_codec, 0);
341
342 // stream 1
343 InitRefCodec(1, &ref_codec);
344 ref_codec.VP8()->denoisingOn = false;
345 // The start bitrate (300kbit) minus what we have for the lower layers
346 // (100kbit).
347 ref_codec.startBitrate = 200;
348 VerifyCodec(ref_codec, 1);
349
350 // stream 2, the biggest resolution stream.
351 InitRefCodec(2, &ref_codec);
352 // We don't have enough bits to send this, so the adapter should have
353 // configured it to use the min bitrate for this layer (600kbit) but turn
354 // off sending.
355 ref_codec.startBitrate = 600;
356 VerifyCodec(ref_codec, 2);
357 }
358
359 protected:
360 std::unique_ptr<TestSimulcastEncoderAdapterFakeHelper> helper_;
361 std::unique_ptr<VP8Encoder> adapter_;
362 VideoCodec codec_;
363 int last_encoded_image_width_;
364 int last_encoded_image_height_;
365 int last_encoded_image_simulcast_index_;
366 TemporalLayersFactory tl_factory_;
367 std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
368 };
369
370 TEST_F(TestSimulcastEncoderAdapterFake, InitEncode) {
371 SetupCodec();
372 VerifyCodecSettings();
373 }
374
375 TEST_F(TestSimulcastEncoderAdapterFake, ReleaseWithoutInitEncode) {
376 EXPECT_EQ(0, adapter_->Release());
377 }
378
379 TEST_F(TestSimulcastEncoderAdapterFake, Reinit) {
380 SetupCodec();
381 EXPECT_EQ(0, adapter_->Release());
382
383 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
384 }
385
386 TEST_F(TestSimulcastEncoderAdapterFake, SetChannelParameters) {
387 SetupCodec();
388 const uint32_t packetLoss = 5;
389 const int64_t rtt = 30;
390 helper_->ExpectCallSetChannelParameters(packetLoss, rtt);
391 adapter_->SetChannelParameters(packetLoss, rtt);
392 }
393
394 TEST_F(TestSimulcastEncoderAdapterFake, EncodedCallbackForDifferentEncoders) {
395 SetupCodec();
396
397 // Set bitrates so that we send all layers.
398 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
399
400 // At this point, the simulcast encoder adapter should have 3 streams: HD,
401 // quarter HD, and quarter quarter HD. We're going to mostly ignore the exact
402 // resolutions, to test that the adapter forwards on the correct resolution
403 // and simulcast index values, going only off the encoder that generates the
404 // image.
405 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
406 ASSERT_EQ(3u, encoders.size());
407 encoders[0]->SendEncodedImage(1152, 704);
408 int width;
409 int height;
410 int simulcast_index;
411 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
412 EXPECT_EQ(1152, width);
413 EXPECT_EQ(704, height);
414 EXPECT_EQ(0, simulcast_index);
415
416 encoders[1]->SendEncodedImage(300, 620);
417 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
418 EXPECT_EQ(300, width);
419 EXPECT_EQ(620, height);
420 EXPECT_EQ(1, simulcast_index);
421
422 encoders[2]->SendEncodedImage(120, 240);
423 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
424 EXPECT_EQ(120, width);
425 EXPECT_EQ(240, height);
426 EXPECT_EQ(2, simulcast_index);
427 }
428
429 // This test verifies that the underlying encoders are reused, when the adapter
430 // is reinited with different number of simulcast streams. It further checks
431 // that the allocated encoders are reused in the same order as before, starting
432 // with the lowest stream.
433 TEST_F(TestSimulcastEncoderAdapterFake, ReusesEncodersInOrder) {
434 // Set up common settings for three streams.
435 TestVp8Simulcast::DefaultSettings(
436 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
437 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
438 tl_factory_.SetListener(rate_allocator_.get());
439 codec_.VP8()->tl_factory = &tl_factory_;
440 adapter_->RegisterEncodeCompleteCallback(this);
441
442 // Input data.
443 rtc::scoped_refptr<VideoFrameBuffer> buffer(I420Buffer::Create(1280, 720));
444 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
445 std::vector<FrameType> frame_types;
446
447 // Encode with three streams.
448 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
449 VerifyCodecSettings();
450 std::vector<MockVideoEncoder*> original_encoders =
451 helper_->factory()->encoders();
452 ASSERT_EQ(3u, original_encoders.size());
453 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
454 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
455 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
456 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
457 EXPECT_CALL(*original_encoders[2], Encode(_, _, _))
458 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
459 frame_types.resize(3, kVideoFrameKey);
460 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
461 EXPECT_CALL(*original_encoders[0], Release())
462 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
463 EXPECT_CALL(*original_encoders[1], Release())
464 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
465 EXPECT_CALL(*original_encoders[2], Release())
466 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
467 EXPECT_EQ(0, adapter_->Release());
468
469 // Encode with two streams.
470 codec_.width /= 2;
471 codec_.height /= 2;
472 codec_.numberOfSimulcastStreams = 2;
473 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
474 std::vector<MockVideoEncoder*> new_encoders = helper_->factory()->encoders();
475 ASSERT_EQ(2u, new_encoders.size());
476 ASSERT_EQ(original_encoders[0], new_encoders[0]);
477 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
478 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
479 ASSERT_EQ(original_encoders[1], new_encoders[1]);
480 EXPECT_CALL(*original_encoders[1], Encode(_, _, _))
481 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
482 frame_types.resize(2, kVideoFrameKey);
483 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
484 EXPECT_CALL(*original_encoders[0], Release())
485 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
486 EXPECT_CALL(*original_encoders[1], Release())
487 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
488 EXPECT_EQ(0, adapter_->Release());
489
490 // Encode with single stream.
491 codec_.width /= 2;
492 codec_.height /= 2;
493 codec_.numberOfSimulcastStreams = 1;
494 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
495 new_encoders = helper_->factory()->encoders();
496 ASSERT_EQ(1u, new_encoders.size());
497 ASSERT_EQ(original_encoders[0], new_encoders[0]);
498 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
499 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
500 frame_types.resize(1, kVideoFrameKey);
501 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
502 EXPECT_CALL(*original_encoders[0], Release())
503 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
504 EXPECT_EQ(0, adapter_->Release());
505
506 // Encode with three streams, again.
507 codec_.width *= 4;
508 codec_.height *= 4;
509 codec_.numberOfSimulcastStreams = 3;
510 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
511 new_encoders = helper_->factory()->encoders();
512 ASSERT_EQ(3u, new_encoders.size());
513 // The first encoder is reused.
514 ASSERT_EQ(original_encoders[0], new_encoders[0]);
515 EXPECT_CALL(*original_encoders[0], Encode(_, _, _))
516 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
517 // The second and third encoders are new.
518 EXPECT_CALL(*new_encoders[1], Encode(_, _, _))
519 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
520 EXPECT_CALL(*new_encoders[2], Encode(_, _, _))
521 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
522 frame_types.resize(3, kVideoFrameKey);
523 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
524 EXPECT_CALL(*original_encoders[0], Release())
525 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
526 EXPECT_CALL(*new_encoders[1], Release())
527 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
528 EXPECT_CALL(*new_encoders[2], Release())
529 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
530 EXPECT_EQ(0, adapter_->Release());
531 }
532
533 TEST_F(TestSimulcastEncoderAdapterFake, DoesNotLeakEncoders) {
534 SetupCodec();
535 VerifyCodecSettings();
536
537 EXPECT_EQ(3u, helper_->factory()->encoders().size());
538
539 // The adapter should destroy all encoders it has allocated. Since
540 // |helper_->factory()| is owned by |adapter_|, however, we need to rely on
541 // lsan to find leaks here.
542 EXPECT_EQ(0, adapter_->Release());
543 adapter_.reset();
544 }
545
546 // This test verifies that an adapter reinit with the same codec settings as
547 // before does not change the underlying encoder codec settings.
548 TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderEncoderSettings) {
549 SetupCodec();
550 VerifyCodecSettings();
551
552 // Capture current codec settings.
553 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
554 ASSERT_EQ(3u, encoders.size());
555 std::array<VideoCodec, 3> codecs_before;
556 for (int i = 0; i < 3; ++i) {
557 codecs_before[i] = encoders[i]->codec();
558 }
559
560 // Reinitialize and verify that the new codec settings are the same.
561 EXPECT_EQ(0, adapter_->Release());
562 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
563 for (int i = 0; i < 3; ++i) {
564 const VideoCodec& codec_before = codecs_before[i];
565 const VideoCodec& codec_after = encoders[i]->codec();
566
567 // webrtc::VideoCodec does not implement operator==.
568 EXPECT_EQ(codec_before.codecType, codec_after.codecType);
569 EXPECT_EQ(codec_before.plType, codec_after.plType);
570 EXPECT_EQ(codec_before.width, codec_after.width);
571 EXPECT_EQ(codec_before.height, codec_after.height);
572 EXPECT_EQ(codec_before.startBitrate, codec_after.startBitrate);
573 EXPECT_EQ(codec_before.maxBitrate, codec_after.maxBitrate);
574 EXPECT_EQ(codec_before.minBitrate, codec_after.minBitrate);
575 EXPECT_EQ(codec_before.targetBitrate, codec_after.targetBitrate);
576 EXPECT_EQ(codec_before.maxFramerate, codec_after.maxFramerate);
577 EXPECT_EQ(codec_before.qpMax, codec_after.qpMax);
578 EXPECT_EQ(codec_before.numberOfSimulcastStreams,
579 codec_after.numberOfSimulcastStreams);
580 EXPECT_EQ(codec_before.mode, codec_after.mode);
581 EXPECT_EQ(codec_before.expect_encode_from_texture,
582 codec_after.expect_encode_from_texture);
583 }
584 }
585
586 // This test is similar to the one above, except that it tests the simulcastIdx
587 // from the CodecSpecificInfo that is connected to an encoded frame. The
588 // PayloadRouter demuxes the incoming encoded frames on different RTP modules
589 // using the simulcastIdx, so it's important that there is no corresponding
590 // encoder reordering in between adapter reinits as this would lead to PictureID
591 // discontinuities.
592 TEST_F(TestSimulcastEncoderAdapterFake, ReinitDoesNotReorderFrameSimulcastIdx) {
593 SetupCodec();
594 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
595 VerifyCodecSettings();
596
597 // Send frames on all streams.
598 std::vector<MockVideoEncoder*> encoders = helper_->factory()->encoders();
599 ASSERT_EQ(3u, encoders.size());
600 encoders[0]->SendEncodedImage(1152, 704);
601 int width;
602 int height;
603 int simulcast_index;
604 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
605 EXPECT_EQ(0, simulcast_index);
606
607 encoders[1]->SendEncodedImage(300, 620);
608 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
609 EXPECT_EQ(1, simulcast_index);
610
611 encoders[2]->SendEncodedImage(120, 240);
612 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
613 EXPECT_EQ(2, simulcast_index);
614
615 // Reinitialize.
616 EXPECT_EQ(0, adapter_->Release());
617 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
618 adapter_->SetRateAllocation(rate_allocator_->GetAllocation(1200, 30), 30);
619
620 // Verify that the same encoder sends out frames on the same simulcast index.
621 encoders[0]->SendEncodedImage(1152, 704);
622 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
623 EXPECT_EQ(0, simulcast_index);
624
625 encoders[1]->SendEncodedImage(300, 620);
626 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
627 EXPECT_EQ(1, simulcast_index);
628
629 encoders[2]->SendEncodedImage(120, 240);
630 EXPECT_TRUE(GetLastEncodedImageInfo(&width, &height, &simulcast_index));
631 EXPECT_EQ(2, simulcast_index);
632 }
633
634 TEST_F(TestSimulcastEncoderAdapterFake, SupportsNativeHandleForSingleStreams) {
635 TestVp8Simulcast::DefaultSettings(
636 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
637 codec_.VP8()->tl_factory = &tl_factory_;
638 codec_.numberOfSimulcastStreams = 1;
639 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
640 adapter_->RegisterEncodeCompleteCallback(this);
641 ASSERT_EQ(1u, helper_->factory()->encoders().size());
642 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
643 EXPECT_TRUE(adapter_->SupportsNativeHandle());
644 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
645 EXPECT_FALSE(adapter_->SupportsNativeHandle());
646 }
647
648 TEST_F(TestSimulcastEncoderAdapterFake, SetRatesUnderMinBitrate) {
649 TestVp8Simulcast::DefaultSettings(
650 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
651 codec_.VP8()->tl_factory = &tl_factory_;
652 codec_.minBitrate = 50;
653 codec_.numberOfSimulcastStreams = 1;
654 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
655 rate_allocator_.reset(new SimulcastRateAllocator(codec_, nullptr));
656
657 // Above min should be respected.
658 BitrateAllocation target_bitrate =
659 rate_allocator_->GetAllocation(codec_.minBitrate * 1000, 30);
660 adapter_->SetRateAllocation(target_bitrate, 30);
661 EXPECT_EQ(target_bitrate,
662 helper_->factory()->encoders()[0]->last_set_bitrate());
663
664 // Below min but non-zero should be replaced with the min bitrate.
665 BitrateAllocation too_low_bitrate =
666 rate_allocator_->GetAllocation((codec_.minBitrate - 1) * 1000, 30);
667 adapter_->SetRateAllocation(too_low_bitrate, 30);
668 EXPECT_EQ(target_bitrate,
669 helper_->factory()->encoders()[0]->last_set_bitrate());
670
671 // Zero should be passed on as is, since it means "pause".
672 adapter_->SetRateAllocation(BitrateAllocation(), 30);
673 EXPECT_EQ(BitrateAllocation(),
674 helper_->factory()->encoders()[0]->last_set_bitrate());
675 }
676
677 TEST_F(TestSimulcastEncoderAdapterFake, SupportsImplementationName) {
678 EXPECT_STREQ("SimulcastEncoderAdapter", adapter_->ImplementationName());
679 TestVp8Simulcast::DefaultSettings(
680 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
681 codec_.VP8()->tl_factory = &tl_factory_;
682 std::vector<const char*> encoder_names;
683 encoder_names.push_back("codec1");
684 encoder_names.push_back("codec2");
685 encoder_names.push_back("codec3");
686 helper_->factory()->SetEncoderNames(encoder_names);
687 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
688 EXPECT_STREQ("SimulcastEncoderAdapter (codec1, codec2, codec3)",
689 adapter_->ImplementationName());
690
691 // Single streams should not expose "SimulcastEncoderAdapter" in name.
692 EXPECT_EQ(0, adapter_->Release());
693 codec_.numberOfSimulcastStreams = 1;
694 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
695 adapter_->RegisterEncodeCompleteCallback(this);
696 ASSERT_EQ(1u, helper_->factory()->encoders().size());
697 EXPECT_STREQ("codec1", adapter_->ImplementationName());
698 }
699
700 TEST_F(TestSimulcastEncoderAdapterFake,
701 SupportsNativeHandleForMultipleStreams) {
702 TestVp8Simulcast::DefaultSettings(
703 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
704 codec_.VP8()->tl_factory = &tl_factory_;
705 codec_.numberOfSimulcastStreams = 3;
706 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
707 adapter_->RegisterEncodeCompleteCallback(this);
708 ASSERT_EQ(3u, helper_->factory()->encoders().size());
709 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
710 encoder->set_supports_native_handle(true);
711 // If one encoder doesn't support it, then overall support is disabled.
712 helper_->factory()->encoders()[0]->set_supports_native_handle(false);
713 EXPECT_FALSE(adapter_->SupportsNativeHandle());
714 // Once all do, then the adapter claims support.
715 helper_->factory()->encoders()[0]->set_supports_native_handle(true);
716 EXPECT_TRUE(adapter_->SupportsNativeHandle());
717 }
718
719 // TODO(nisse): Reuse definition in webrtc/test/fake_texture_handle.h.
720 class FakeNativeBuffer : public VideoFrameBuffer {
721 public:
722 FakeNativeBuffer(int width, int height) : width_(width), height_(height) {}
723
724 Type type() const override { return Type::kNative; }
725 int width() const override { return width_; }
726 int height() const override { return height_; }
727
728 rtc::scoped_refptr<I420BufferInterface> ToI420() override {
729 RTC_NOTREACHED();
730 return nullptr;
731 }
732
733 private:
734 const int width_;
735 const int height_;
736 };
737
738 TEST_F(TestSimulcastEncoderAdapterFake,
739 NativeHandleForwardingForMultipleStreams) {
740 TestVp8Simulcast::DefaultSettings(
741 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
742 codec_.VP8()->tl_factory = &tl_factory_;
743 codec_.numberOfSimulcastStreams = 3;
744 // High start bitrate, so all streams are enabled.
745 codec_.startBitrate = 3000;
746 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
747 adapter_->RegisterEncodeCompleteCallback(this);
748 ASSERT_EQ(3u, helper_->factory()->encoders().size());
749 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
750 encoder->set_supports_native_handle(true);
751 EXPECT_TRUE(adapter_->SupportsNativeHandle());
752
753 rtc::scoped_refptr<VideoFrameBuffer> buffer(
754 new rtc::RefCountedObject<FakeNativeBuffer>(1280, 720));
755 VideoFrame input_frame(buffer, 100, 1000, kVideoRotation_180);
756 // Expect calls with the given video frame verbatim, since it's a texture
757 // frame and can't otherwise be modified/resized.
758 for (MockVideoEncoder* encoder : helper_->factory()->encoders())
759 EXPECT_CALL(*encoder, Encode(::testing::Ref(input_frame), _, _)).Times(1);
760 std::vector<FrameType> frame_types(3, kVideoFrameKey);
761 EXPECT_EQ(0, adapter_->Encode(input_frame, nullptr, &frame_types));
762 }
763
764 TEST_F(TestSimulcastEncoderAdapterFake, TestFailureReturnCodesFromEncodeCalls) {
765 TestVp8Simulcast::DefaultSettings(
766 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
767 codec_.VP8()->tl_factory = &tl_factory_;
768 codec_.numberOfSimulcastStreams = 3;
769 EXPECT_EQ(0, adapter_->InitEncode(&codec_, 1, 1200));
770 adapter_->RegisterEncodeCompleteCallback(this);
771 ASSERT_EQ(3u, helper_->factory()->encoders().size());
772 // Tell the 2nd encoder to request software fallback.
773 EXPECT_CALL(*helper_->factory()->encoders()[1], Encode(_, _, _))
774 .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
775
776 // Send a fake frame and assert the return is software fallback.
777 rtc::scoped_refptr<I420Buffer> input_buffer =
778 I420Buffer::Create(kDefaultWidth, kDefaultHeight);
779 input_buffer->InitializeData();
780 VideoFrame input_frame(input_buffer, 0, 0, webrtc::kVideoRotation_0);
781 std::vector<FrameType> frame_types(3, kVideoFrameKey);
782 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
783 adapter_->Encode(input_frame, nullptr, &frame_types));
784 }
785
786 TEST_F(TestSimulcastEncoderAdapterFake, TestInitFailureCleansUpEncoders) {
787 TestVp8Simulcast::DefaultSettings(
788 &codec_, static_cast<const int*>(kTestTemporalLayerProfile));
789 codec_.VP8()->tl_factory = &tl_factory_;
790 codec_.numberOfSimulcastStreams = 3;
791 helper_->factory()->set_init_encode_return_value(
792 WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
793 EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
794 adapter_->InitEncode(&codec_, 1, 1200));
795 EXPECT_TRUE(helper_->factory()->encoders().empty());
796 }
797
798 } // namespace testing
799 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698