blob: 9f4fdc47e33094d3577dbe4f05eb226bfb37a173 [file] [log] [blame]
perkj26091b12016-09-01 08:17:401/*
2 * Copyright (c) 2016 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
perkj803d97f2016-11-01 18:45:4611#include <limits>
Per512ecb32016-09-23 13:52:0612#include <utility>
13
perkj26091b12016-09-01 08:17:4014#include "webrtc/base/logging.h"
perkj803d97f2016-11-01 18:45:4615#include "webrtc/system_wrappers/include/metrics_default.h"
perkj26091b12016-09-01 08:17:4016#include "webrtc/test/encoder_settings.h"
17#include "webrtc/test/fake_encoder.h"
perkja49cbd32016-09-16 14:53:4118#include "webrtc/test/frame_generator.h"
kwibergac9f8762016-10-01 05:29:4319#include "webrtc/test/gtest.h"
perkj26091b12016-09-01 08:17:4020#include "webrtc/video/send_statistics_proxy.h"
21#include "webrtc/video/vie_encoder.h"
22
23namespace webrtc {
24
perkj803d97f2016-11-01 18:45:4625namespace {
26class TestBuffer : public webrtc::I420Buffer {
27 public:
28 TestBuffer(rtc::Event* event, int width, int height)
29 : I420Buffer(width, height), event_(event) {}
30
31 private:
32 friend class rtc::RefCountedObject<TestBuffer>;
33 ~TestBuffer() override {
34 if (event_)
35 event_->Set();
36 }
37 rtc::Event* const event_;
38};
39
40class ViEEncoderUnderTest : public ViEEncoder {
41 public:
42 ViEEncoderUnderTest(
43 SendStatisticsProxy* stats_proxy,
44 const webrtc::VideoSendStream::Config::EncoderSettings& settings)
45 : ViEEncoder(1 /* number_of_cores */,
46 stats_proxy,
47 settings,
48 nullptr /* pre_encode_callback */,
49 nullptr /* encoder_timing */) {}
50
51 void TriggerCpuOveruse() {
52 rtc::Event event(false, false);
53 encoder_queue()->PostTask([this, &event] {
54 OveruseDetected();
55 event.Set();
56 });
57 event.Wait(rtc::Event::kForever);
58 }
59
60 void TriggerCpuNormalUsage() {
61 rtc::Event event(false, false);
62 encoder_queue()->PostTask([this, &event] {
63 NormalUsage();
64 event.Set();
65 });
66 event.Wait(rtc::Event::kForever);
67 }
68};
69
70} // namespace
71
perkj26091b12016-09-01 08:17:4072class ViEEncoderTest : public ::testing::Test {
73 public:
74 static const int kDefaultTimeoutMs = 30 * 1000;
75
76 ViEEncoderTest()
77 : video_send_config_(VideoSendStream::Config(nullptr)),
perkjfa10b552016-10-03 06:45:2678 codec_width_(320),
79 codec_height_(240),
perkj26091b12016-09-01 08:17:4080 fake_encoder_(),
perkj803d97f2016-11-01 18:45:4681 stats_proxy_(new SendStatisticsProxy(
82 Clock::GetRealTimeClock(),
83 video_send_config_,
84 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
perkj26091b12016-09-01 08:17:4085 sink_(&fake_encoder_) {}
86
87 void SetUp() override {
perkj803d97f2016-11-01 18:45:4688 metrics::Reset();
perkj26091b12016-09-01 08:17:4089 video_send_config_ = VideoSendStream::Config(nullptr);
90 video_send_config_.encoder_settings.encoder = &fake_encoder_;
91 video_send_config_.encoder_settings.payload_name = "FAKE";
92 video_send_config_.encoder_settings.payload_type = 125;
93
Per512ecb32016-09-23 13:52:0694 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-03 06:45:2695 test::FillEncoderConfiguration(1, &video_encoder_config);
perkj803d97f2016-11-01 18:45:4696 vie_encoder_.reset(new ViEEncoderUnderTest(
97 stats_proxy_.get(), video_send_config_.encoder_settings));
98 vie_encoder_->SetSink(&sink_, false /* rotation_applied */);
99 vie_encoder_->SetSource(&video_source_,
100 VideoSendStream::DegradationPreference::kBalanced);
perkj26091b12016-09-01 08:17:40101 vie_encoder_->SetStartBitrate(10000);
Per512ecb32016-09-23 13:52:06102 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), 1440);
perkj26091b12016-09-01 08:17:40103 }
104
105 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
Per512ecb32016-09-23 13:52:06106 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
107 destruction_event, codec_width_, codec_height_),
108 99, 99, kVideoRotation_0);
perkj26091b12016-09-01 08:17:40109 frame.set_ntp_time_ms(ntp_ts);
110 return frame;
111 }
112
perkj803d97f2016-11-01 18:45:46113 VideoFrame CreateFrame(int64_t ntp_ts, int width, int height) const {
114 VideoFrame frame(
115 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99,
116 kVideoRotation_0);
117 frame.set_ntp_time_ms(ntp_ts);
118 return frame;
119 }
120
perkj26091b12016-09-01 08:17:40121 class TestEncoder : public test::FakeEncoder {
122 public:
123 TestEncoder()
124 : FakeEncoder(Clock::GetRealTimeClock()),
125 continue_encode_event_(false, false) {}
126
perkjfa10b552016-10-03 06:45:26127 VideoCodec codec_config() {
128 rtc::CritScope lock(&crit_);
129 return config_;
130 }
131
132 void BlockNextEncode() {
133 rtc::CritScope lock(&crit_);
134 block_next_encode_ = true;
135 }
136
137 void ContinueEncode() { continue_encode_event_.Set(); }
138
139 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
140 uint32_t timestamp) const {
141 rtc::CritScope lock(&crit_);
142 EXPECT_EQ(timestamp_, timestamp);
143 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
144 }
145
146 private:
perkj26091b12016-09-01 08:17:40147 int32_t Encode(const VideoFrame& input_image,
148 const CodecSpecificInfo* codec_specific_info,
149 const std::vector<FrameType>* frame_types) override {
150 bool block_encode;
151 {
152 rtc::CritScope lock(&crit_);
153 EXPECT_GT(input_image.timestamp(), timestamp_);
154 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
155 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
156
157 timestamp_ = input_image.timestamp();
158 ntp_time_ms_ = input_image.ntp_time_ms();
perkj803d97f2016-11-01 18:45:46159 last_input_width_ = input_image.width();
160 last_input_height_ = input_image.height();
perkj26091b12016-09-01 08:17:40161 block_encode = block_next_encode_;
162 block_next_encode_ = false;
163 }
164 int32_t result =
165 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
166 if (block_encode)
perkja49cbd32016-09-16 14:53:41167 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40168 return result;
169 }
170
perkj26091b12016-09-01 08:17:40171 rtc::CriticalSection crit_;
172 bool block_next_encode_ = false;
173 rtc::Event continue_encode_event_;
174 uint32_t timestamp_ = 0;
175 int64_t ntp_time_ms_ = 0;
perkj803d97f2016-11-01 18:45:46176 int last_input_width_ = 0;
177 int last_input_height_ = 0;
perkj26091b12016-09-01 08:17:40178 };
179
Per512ecb32016-09-23 13:52:06180 class TestSink : public ViEEncoder::EncoderSink {
perkj26091b12016-09-01 08:17:40181 public:
182 explicit TestSink(TestEncoder* test_encoder)
183 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
184
perkj26091b12016-09-01 08:17:40185 void WaitForEncodedFrame(int64_t expected_ntp_time) {
186 uint32_t timestamp = 0;
perkja49cbd32016-09-16 14:53:41187 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40188 {
189 rtc::CritScope lock(&crit_);
190 timestamp = timestamp_;
191 }
192 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
193 }
194
195 void SetExpectNoFrames() {
196 rtc::CritScope lock(&crit_);
197 expect_frames_ = false;
198 }
199
Per512ecb32016-09-23 13:52:06200 int number_of_reconfigurations() {
201 rtc::CritScope lock(&crit_);
202 return number_of_reconfigurations_;
203 }
204
205 int last_min_transmit_bitrate() {
206 rtc::CritScope lock(&crit_);
207 return min_transmit_bitrate_bps_;
208 }
209
perkj26091b12016-09-01 08:17:40210 private:
sergeyu2cb155a2016-11-04 18:39:29211 Result OnEncodedImage(
212 const EncodedImage& encoded_image,
213 const CodecSpecificInfo* codec_specific_info,
214 const RTPFragmentationHeader* fragmentation) override {
Per512ecb32016-09-23 13:52:06215 rtc::CritScope lock(&crit_);
216 EXPECT_TRUE(expect_frames_);
217 timestamp_ = encoded_image._timeStamp;
218 encoded_frame_event_.Set();
sergeyu2cb155a2016-11-04 18:39:29219 return Result(Result::OK, timestamp_);
Per512ecb32016-09-23 13:52:06220 }
221
222 void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
223 int min_transmit_bitrate_bps) override {
224 rtc::CriticalSection crit_;
225 ++number_of_reconfigurations_;
226 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
227 }
228
perkj26091b12016-09-01 08:17:40229 rtc::CriticalSection crit_;
230 TestEncoder* test_encoder_;
231 rtc::Event encoded_frame_event_;
232 uint32_t timestamp_ = 0;
233 bool expect_frames_ = true;
Per512ecb32016-09-23 13:52:06234 int number_of_reconfigurations_ = 0;
235 int min_transmit_bitrate_bps_ = 0;
perkj26091b12016-09-01 08:17:40236 };
237
238 VideoSendStream::Config video_send_config_;
Per512ecb32016-09-23 13:52:06239 int codec_width_;
240 int codec_height_;
perkj26091b12016-09-01 08:17:40241 TestEncoder fake_encoder_;
perkj803d97f2016-11-01 18:45:46242 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
perkj26091b12016-09-01 08:17:40243 TestSink sink_;
perkja49cbd32016-09-16 14:53:41244 test::FrameForwarder video_source_;
perkj803d97f2016-11-01 18:45:46245 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
perkj26091b12016-09-01 08:17:40246};
247
248TEST_F(ViEEncoderTest, EncodeOneFrame) {
249 const int kTargetBitrateBps = 100000;
250 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
251 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 14:53:41252 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
perkj26091b12016-09-01 08:17:40253 sink_.WaitForEncodedFrame(1);
perkja49cbd32016-09-16 14:53:41254 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40255 vie_encoder_->Stop();
256}
257
258TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
259 // Dropped since no target bitrate has been set.
260 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 14:53:41261 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
262 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40263
264 const int kTargetBitrateBps = 100000;
265 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
266
perkja49cbd32016-09-16 14:53:41267 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 08:17:40268 sink_.WaitForEncodedFrame(2);
269 vie_encoder_->Stop();
270}
271
272TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
273 const int kTargetBitrateBps = 100000;
274 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 14:53:41275 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40276 sink_.WaitForEncodedFrame(1);
277
278 vie_encoder_->OnBitrateUpdated(0, 0, 0);
279 // Dropped since bitrate is zero.
perkja49cbd32016-09-16 14:53:41280 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 08:17:40281
282 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 14:53:41283 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 08:17:40284 sink_.WaitForEncodedFrame(3);
285 vie_encoder_->Stop();
286}
287
288TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
289 const int kTargetBitrateBps = 100000;
290 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 14:53:41291 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40292 sink_.WaitForEncodedFrame(1);
293
294 // This frame will be dropped since it has the same ntp timestamp.
perkja49cbd32016-09-16 14:53:41295 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40296
perkja49cbd32016-09-16 14:53:41297 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 08:17:40298 sink_.WaitForEncodedFrame(2);
299 vie_encoder_->Stop();
300}
301
302TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
303 const int kTargetBitrateBps = 100000;
304 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
305
perkja49cbd32016-09-16 14:53:41306 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40307 sink_.WaitForEncodedFrame(1);
308
309 vie_encoder_->Stop();
310 sink_.SetExpectNoFrames();
311 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 14:53:41312 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
313 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40314}
315
316TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
317 const int kTargetBitrateBps = 100000;
318 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
319
320 fake_encoder_.BlockNextEncode();
perkja49cbd32016-09-16 14:53:41321 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40322 sink_.WaitForEncodedFrame(1);
323 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
324 // call to ContinueEncode.
perkja49cbd32016-09-16 14:53:41325 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
326 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 08:17:40327 fake_encoder_.ContinueEncode();
328 sink_.WaitForEncodedFrame(3);
329
330 vie_encoder_->Stop();
331}
332
Per512ecb32016-09-23 13:52:06333TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
334 const int kTargetBitrateBps = 100000;
335 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
Per21d45d22016-10-30 20:37:57336 EXPECT_EQ(0, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 13:52:06337
338 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 14:24:55339 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
Per512ecb32016-09-23 13:52:06340 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 20:37:57341 // The encoder will have been configured once when the first frame is
342 // received.
343 EXPECT_EQ(1, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 13:52:06344
345 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-03 06:45:26346 test::FillEncoderConfiguration(1, &video_encoder_config);
Per512ecb32016-09-23 13:52:06347 video_encoder_config.min_transmit_bitrate_bps = 9999;
348 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), 1440);
349
350 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 14:24:55351 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
Per512ecb32016-09-23 13:52:06352 sink_.WaitForEncodedFrame(2);
Per21d45d22016-10-30 20:37:57353 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkj3b703ed2016-09-30 06:25:40354 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
perkj26105b42016-09-30 05:39:10355
356 vie_encoder_->Stop();
357}
358
perkjfa10b552016-10-03 06:45:26359TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
360 const int kTargetBitrateBps = 100000;
361 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
362
363 // Capture a frame and wait for it to synchronize with the encoder thread.
364 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
365 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 20:37:57366 // The encoder will have been configured once.
367 EXPECT_EQ(1, sink_.number_of_reconfigurations());
perkjfa10b552016-10-03 06:45:26368 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
369 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
370
371 codec_width_ *= 2;
372 codec_height_ *= 2;
373 // Capture a frame with a higher resolution and wait for it to synchronize
374 // with the encoder thread.
375 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
376 sink_.WaitForEncodedFrame(2);
377 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
378 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
Per21d45d22016-10-30 20:37:57379 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkjfa10b552016-10-03 06:45:26380
381 vie_encoder_->Stop();
382}
383
perkj803d97f2016-11-01 18:45:46384TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
385 EXPECT_TRUE(video_source_.has_sinks());
386 test::FrameForwarder new_video_source;
387 vie_encoder_->SetSource(&new_video_source,
388 VideoSendStream::DegradationPreference::kBalanced);
389 EXPECT_FALSE(video_source_.has_sinks());
390 EXPECT_TRUE(new_video_source.has_sinks());
391
392 vie_encoder_->Stop();
393}
394
395TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
396 EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
397 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/);
398 EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
399 vie_encoder_->Stop();
400}
401
402TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
403 const int kTargetBitrateBps = 100000;
404 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
405
406 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
407 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
408
409 int frame_width = 1280;
410 int frame_height = 720;
411
412 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
413 // request lower resolution.
414 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) {
415 video_source_.IncomingCapturedFrame(
416 CreateFrame(i, frame_width, frame_height));
417 sink_.WaitForEncodedFrame(i);
418
419 vie_encoder_->TriggerCpuOveruse();
420
421 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
422 std::numeric_limits<int>::max()),
423 frame_width * frame_height);
424 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
425
426 frame_width /= 2;
427 frame_height /= 2;
428 }
429
430 // Trigger CPU overuse a one more time. This should not trigger request for
431 // lower resolution.
432 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
433 video_source_.IncomingCapturedFrame(CreateFrame(
434 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
435 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
436 vie_encoder_->TriggerCpuOveruse();
437 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
438 current_wants.max_pixel_count);
439 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
440 current_wants.max_pixel_count_step_up);
441
442 // Trigger CPU normal use.
443 vie_encoder_->TriggerCpuNormalUsage();
444 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
445 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
446 frame_width * frame_height);
447
448 vie_encoder_->Stop();
449}
450
451TEST_F(ViEEncoderTest,
452 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) {
453 const int kTargetBitrateBps = 100000;
454 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
455
456 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
457 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
458
459 int frame_width = 1280;
460 int frame_height = 720;
461
462 // Trigger CPU overuse.
463 vie_encoder_->TriggerCpuOveruse();
464
465 video_source_.IncomingCapturedFrame(
466 CreateFrame(1, frame_width, frame_height));
467 sink_.WaitForEncodedFrame(1);
468 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
469 std::numeric_limits<int>::max()),
470 frame_width * frame_height);
471 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
472
473 // Set new source.
474 test::FrameForwarder new_video_source;
475 vie_encoder_->SetSource(
476 &new_video_source,
477 VideoSendStream::DegradationPreference::kMaintainResolution);
478
479 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
480 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
481
482 new_video_source.IncomingCapturedFrame(
483 CreateFrame(2, frame_width, frame_height));
484 sink_.WaitForEncodedFrame(2);
485 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
486 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
487
488 // Calling SetSource with resolution scaling enabled apply the old SinkWants.
489 vie_encoder_->SetSource(&new_video_source,
490 VideoSendStream::DegradationPreference::kBalanced);
491 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or(
492 std::numeric_limits<int>::max()),
493 frame_width * frame_height);
494 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
495
496 vie_encoder_->Stop();
497}
498
499TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) {
500 const int kTargetBitrateBps = 100000;
501 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
502
503 int frame_width = 1280;
504 int frame_height = 720;
505
506 video_source_.IncomingCapturedFrame(
507 CreateFrame(1, frame_width, frame_height));
508 sink_.WaitForEncodedFrame(1);
509 VideoSendStream::Stats stats = stats_proxy_->GetStats();
510 EXPECT_FALSE(stats.cpu_limited_resolution);
511 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
512
513 // Trigger CPU overuse.
514 vie_encoder_->TriggerCpuOveruse();
515 video_source_.IncomingCapturedFrame(
516 CreateFrame(2, frame_width, frame_height));
517 sink_.WaitForEncodedFrame(2);
518
519 stats = stats_proxy_->GetStats();
520 EXPECT_TRUE(stats.cpu_limited_resolution);
521 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
522
523 // Trigger CPU normal use.
524 vie_encoder_->TriggerCpuNormalUsage();
525 video_source_.IncomingCapturedFrame(
526 CreateFrame(3, frame_width, frame_height));
527 sink_.WaitForEncodedFrame(3);
528
529 stats = stats_proxy_->GetStats();
530 EXPECT_FALSE(stats.cpu_limited_resolution);
531 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
532
533 vie_encoder_->Stop();
534}
535
536TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
537 const int kTargetBitrateBps = 100000;
538 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
539
540 // Trigger CPU overuse.
541 vie_encoder_->TriggerCpuOveruse();
542 int frame_width = 1280;
543 int frame_height = 720;
544
545 video_source_.IncomingCapturedFrame(
546 CreateFrame(1, frame_width, frame_height));
547 sink_.WaitForEncodedFrame(1);
548
549 VideoSendStream::Stats stats = stats_proxy_->GetStats();
550 EXPECT_TRUE(stats.cpu_limited_resolution);
551 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
552
553 // Set new source with adaptation still enabled.
554 test::FrameForwarder new_video_source;
555 vie_encoder_->SetSource(&new_video_source,
556 VideoSendStream::DegradationPreference::kBalanced);
557
558 new_video_source.IncomingCapturedFrame(
559 CreateFrame(2, frame_width, frame_height));
560 sink_.WaitForEncodedFrame(2);
561 stats = stats_proxy_->GetStats();
562 EXPECT_TRUE(stats.cpu_limited_resolution);
563 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
564
565 // Set adaptation disabled.
566 vie_encoder_->SetSource(
567 &new_video_source,
568 VideoSendStream::DegradationPreference::kMaintainResolution);
569 new_video_source.IncomingCapturedFrame(
570 CreateFrame(3, frame_width, frame_height));
571 sink_.WaitForEncodedFrame(3);
572 stats = stats_proxy_->GetStats();
573 EXPECT_FALSE(stats.cpu_limited_resolution);
574 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
575
576 // Switch back the source with adaptation enabled.
577 vie_encoder_->SetSource(&video_source_,
578 VideoSendStream::DegradationPreference::kBalanced);
579 video_source_.IncomingCapturedFrame(
580 CreateFrame(4, frame_width, frame_height));
581 sink_.WaitForEncodedFrame(4);
582 stats = stats_proxy_->GetStats();
583 EXPECT_TRUE(stats.cpu_limited_resolution);
584 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
585
586 // Trigger CPU normal usage.
587 vie_encoder_->TriggerCpuNormalUsage();
588 video_source_.IncomingCapturedFrame(
589 CreateFrame(5, frame_width, frame_height));
590 sink_.WaitForEncodedFrame(5);
591 stats = stats_proxy_->GetStats();
592 EXPECT_FALSE(stats.cpu_limited_resolution);
593 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
594
595 vie_encoder_->Stop();
596}
597
598TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
599 const int kTargetBitrateBps = 100000;
600 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
601
602 int frame_width = 640;
603 int frame_height = 360;
604
605 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
606 video_source_.IncomingCapturedFrame(
607 CreateFrame(i, frame_width, frame_height));
608 sink_.WaitForEncodedFrame(i);
609 }
610
611 vie_encoder_->TriggerCpuOveruse();
612 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
613 video_source_.IncomingCapturedFrame(
614 CreateFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i,
615 frame_width, frame_height));
616 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples +
617 i);
618 }
619
620 vie_encoder_->Stop();
621
622 stats_proxy_.reset();
623 EXPECT_EQ(1,
624 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
625 EXPECT_EQ(
626 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
627}
628
perkj26091b12016-09-01 08:17:40629} // namespace webrtc