blob: f6046be652c0f5e3fdc0df8f7df82057560224e6 [file] [log] [blame]
perkj26091b12016-09-01 01:17:40 -07001/*
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 11:45:46 -070011#include <limits>
Per512ecb32016-09-23 15:52:06 +020012#include <utility>
13
perkj26091b12016-09-01 01:17:40 -070014#include "webrtc/base/logging.h"
perkj803d97f2016-11-01 11:45:46 -070015#include "webrtc/system_wrappers/include/metrics_default.h"
perkj26091b12016-09-01 01:17:40 -070016#include "webrtc/test/encoder_settings.h"
17#include "webrtc/test/fake_encoder.h"
perkja49cbd32016-09-16 07:53:41 -070018#include "webrtc/test/frame_generator.h"
kwibergac9f8762016-09-30 22:29:43 -070019#include "webrtc/test/gtest.h"
perkj26091b12016-09-01 01:17:40 -070020#include "webrtc/video/send_statistics_proxy.h"
21#include "webrtc/video/vie_encoder.h"
22
23namespace webrtc {
24
perkj803d97f2016-11-01 11:45:46 -070025namespace {
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 01:17:40 -070072class 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-02 23:45:26 -070078 codec_width_(320),
79 codec_height_(240),
perkj26091b12016-09-01 01:17:40 -070080 fake_encoder_(),
perkj803d97f2016-11-01 11:45:46 -070081 stats_proxy_(new SendStatisticsProxy(
82 Clock::GetRealTimeClock(),
83 video_send_config_,
84 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
perkj26091b12016-09-01 01:17:40 -070085 sink_(&fake_encoder_) {}
86
87 void SetUp() override {
perkj803d97f2016-11-01 11:45:46 -070088 metrics::Reset();
perkj26091b12016-09-01 01:17:40 -070089 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 15:52:06 +020094 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -070095 test::FillEncoderConfiguration(1, &video_encoder_config);
Erik Språng08127a92016-11-16 16:41:30 +010096 video_encoder_config_ = video_encoder_config.Copy();
perkj803d97f2016-11-01 11:45:46 -070097 vie_encoder_.reset(new ViEEncoderUnderTest(
98 stats_proxy_.get(), video_send_config_.encoder_settings));
99 vie_encoder_->SetSink(&sink_, false /* rotation_applied */);
100 vie_encoder_->SetSource(&video_source_,
101 VideoSendStream::DegradationPreference::kBalanced);
perkj26091b12016-09-01 01:17:40 -0700102 vie_encoder_->SetStartBitrate(10000);
Per512ecb32016-09-23 15:52:06 +0200103 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), 1440);
perkj26091b12016-09-01 01:17:40 -0700104 }
105
106 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
Per512ecb32016-09-23 15:52:06 +0200107 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
108 destruction_event, codec_width_, codec_height_),
109 99, 99, kVideoRotation_0);
perkj26091b12016-09-01 01:17:40 -0700110 frame.set_ntp_time_ms(ntp_ts);
111 return frame;
112 }
113
perkj803d97f2016-11-01 11:45:46 -0700114 VideoFrame CreateFrame(int64_t ntp_ts, int width, int height) const {
115 VideoFrame frame(
116 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99,
117 kVideoRotation_0);
118 frame.set_ntp_time_ms(ntp_ts);
119 return frame;
120 }
121
perkj26091b12016-09-01 01:17:40 -0700122 class TestEncoder : public test::FakeEncoder {
123 public:
124 TestEncoder()
125 : FakeEncoder(Clock::GetRealTimeClock()),
126 continue_encode_event_(false, false) {}
127
perkjfa10b552016-10-02 23:45:26 -0700128 VideoCodec codec_config() {
129 rtc::CritScope lock(&crit_);
130 return config_;
131 }
132
133 void BlockNextEncode() {
134 rtc::CritScope lock(&crit_);
135 block_next_encode_ = true;
136 }
137
138 void ContinueEncode() { continue_encode_event_.Set(); }
139
140 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
141 uint32_t timestamp) const {
142 rtc::CritScope lock(&crit_);
143 EXPECT_EQ(timestamp_, timestamp);
144 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
145 }
146
147 private:
perkj26091b12016-09-01 01:17:40 -0700148 int32_t Encode(const VideoFrame& input_image,
149 const CodecSpecificInfo* codec_specific_info,
150 const std::vector<FrameType>* frame_types) override {
151 bool block_encode;
152 {
153 rtc::CritScope lock(&crit_);
154 EXPECT_GT(input_image.timestamp(), timestamp_);
155 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
156 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
157
158 timestamp_ = input_image.timestamp();
159 ntp_time_ms_ = input_image.ntp_time_ms();
perkj803d97f2016-11-01 11:45:46 -0700160 last_input_width_ = input_image.width();
161 last_input_height_ = input_image.height();
perkj26091b12016-09-01 01:17:40 -0700162 block_encode = block_next_encode_;
163 block_next_encode_ = false;
164 }
165 int32_t result =
166 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
167 if (block_encode)
perkja49cbd32016-09-16 07:53:41 -0700168 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700169 return result;
170 }
171
perkj26091b12016-09-01 01:17:40 -0700172 rtc::CriticalSection crit_;
173 bool block_next_encode_ = false;
174 rtc::Event continue_encode_event_;
175 uint32_t timestamp_ = 0;
176 int64_t ntp_time_ms_ = 0;
perkj803d97f2016-11-01 11:45:46 -0700177 int last_input_width_ = 0;
178 int last_input_height_ = 0;
perkj26091b12016-09-01 01:17:40 -0700179 };
180
Per512ecb32016-09-23 15:52:06 +0200181 class TestSink : public ViEEncoder::EncoderSink {
perkj26091b12016-09-01 01:17:40 -0700182 public:
183 explicit TestSink(TestEncoder* test_encoder)
184 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
185
perkj26091b12016-09-01 01:17:40 -0700186 void WaitForEncodedFrame(int64_t expected_ntp_time) {
187 uint32_t timestamp = 0;
perkja49cbd32016-09-16 07:53:41 -0700188 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700189 {
190 rtc::CritScope lock(&crit_);
191 timestamp = timestamp_;
192 }
193 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
194 }
195
196 void SetExpectNoFrames() {
197 rtc::CritScope lock(&crit_);
198 expect_frames_ = false;
199 }
200
Per512ecb32016-09-23 15:52:06 +0200201 int number_of_reconfigurations() {
202 rtc::CritScope lock(&crit_);
203 return number_of_reconfigurations_;
204 }
205
206 int last_min_transmit_bitrate() {
207 rtc::CritScope lock(&crit_);
208 return min_transmit_bitrate_bps_;
209 }
210
perkj26091b12016-09-01 01:17:40 -0700211 private:
sergeyu2cb155a2016-11-04 11:39:29 -0700212 Result OnEncodedImage(
213 const EncodedImage& encoded_image,
214 const CodecSpecificInfo* codec_specific_info,
215 const RTPFragmentationHeader* fragmentation) override {
Per512ecb32016-09-23 15:52:06 +0200216 rtc::CritScope lock(&crit_);
217 EXPECT_TRUE(expect_frames_);
218 timestamp_ = encoded_image._timeStamp;
219 encoded_frame_event_.Set();
sergeyu2cb155a2016-11-04 11:39:29 -0700220 return Result(Result::OK, timestamp_);
Per512ecb32016-09-23 15:52:06 +0200221 }
222
223 void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
224 int min_transmit_bitrate_bps) override {
225 rtc::CriticalSection crit_;
226 ++number_of_reconfigurations_;
227 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
228 }
229
perkj26091b12016-09-01 01:17:40 -0700230 rtc::CriticalSection crit_;
231 TestEncoder* test_encoder_;
232 rtc::Event encoded_frame_event_;
233 uint32_t timestamp_ = 0;
234 bool expect_frames_ = true;
Per512ecb32016-09-23 15:52:06 +0200235 int number_of_reconfigurations_ = 0;
236 int min_transmit_bitrate_bps_ = 0;
perkj26091b12016-09-01 01:17:40 -0700237 };
238
239 VideoSendStream::Config video_send_config_;
Erik Språng08127a92016-11-16 16:41:30 +0100240 VideoEncoderConfig video_encoder_config_;
Per512ecb32016-09-23 15:52:06 +0200241 int codec_width_;
242 int codec_height_;
perkj26091b12016-09-01 01:17:40 -0700243 TestEncoder fake_encoder_;
perkj803d97f2016-11-01 11:45:46 -0700244 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
perkj26091b12016-09-01 01:17:40 -0700245 TestSink sink_;
perkja49cbd32016-09-16 07:53:41 -0700246 test::FrameForwarder video_source_;
perkj803d97f2016-11-01 11:45:46 -0700247 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
perkj26091b12016-09-01 01:17:40 -0700248};
249
250TEST_F(ViEEncoderTest, EncodeOneFrame) {
251 const int kTargetBitrateBps = 100000;
252 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
253 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700254 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
perkj26091b12016-09-01 01:17:40 -0700255 sink_.WaitForEncodedFrame(1);
perkja49cbd32016-09-16 07:53:41 -0700256 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700257 vie_encoder_->Stop();
258}
259
260TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
261 // Dropped since no target bitrate has been set.
262 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700263 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
264 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700265
266 const int kTargetBitrateBps = 100000;
267 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
268
perkja49cbd32016-09-16 07:53:41 -0700269 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700270 sink_.WaitForEncodedFrame(2);
271 vie_encoder_->Stop();
272}
273
274TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
275 const int kTargetBitrateBps = 100000;
276 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700277 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700278 sink_.WaitForEncodedFrame(1);
279
280 vie_encoder_->OnBitrateUpdated(0, 0, 0);
281 // Dropped since bitrate is zero.
perkja49cbd32016-09-16 07:53:41 -0700282 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700283
284 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700285 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700286 sink_.WaitForEncodedFrame(3);
287 vie_encoder_->Stop();
288}
289
290TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
291 const int kTargetBitrateBps = 100000;
292 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700293 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700294 sink_.WaitForEncodedFrame(1);
295
296 // This frame will be dropped since it has the same ntp timestamp.
perkja49cbd32016-09-16 07:53:41 -0700297 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700298
perkja49cbd32016-09-16 07:53:41 -0700299 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700300 sink_.WaitForEncodedFrame(2);
301 vie_encoder_->Stop();
302}
303
304TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
305 const int kTargetBitrateBps = 100000;
306 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
307
perkja49cbd32016-09-16 07:53:41 -0700308 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700309 sink_.WaitForEncodedFrame(1);
310
311 vie_encoder_->Stop();
312 sink_.SetExpectNoFrames();
313 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700314 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
315 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700316}
317
318TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
319 const int kTargetBitrateBps = 100000;
320 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
321
322 fake_encoder_.BlockNextEncode();
perkja49cbd32016-09-16 07:53:41 -0700323 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700324 sink_.WaitForEncodedFrame(1);
325 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
326 // call to ContinueEncode.
perkja49cbd32016-09-16 07:53:41 -0700327 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
328 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700329 fake_encoder_.ContinueEncode();
330 sink_.WaitForEncodedFrame(3);
331
332 vie_encoder_->Stop();
333}
334
Per512ecb32016-09-23 15:52:06 +0200335TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
336 const int kTargetBitrateBps = 100000;
337 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
Per21d45d22016-10-30 21:37:57 +0100338 EXPECT_EQ(0, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200339
340 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200341 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
Per512ecb32016-09-23 15:52:06 +0200342 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100343 // The encoder will have been configured once when the first frame is
344 // received.
345 EXPECT_EQ(1, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200346
347 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700348 test::FillEncoderConfiguration(1, &video_encoder_config);
Per512ecb32016-09-23 15:52:06 +0200349 video_encoder_config.min_transmit_bitrate_bps = 9999;
350 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), 1440);
351
352 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200353 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
Per512ecb32016-09-23 15:52:06 +0200354 sink_.WaitForEncodedFrame(2);
Per21d45d22016-10-30 21:37:57 +0100355 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkj3b703ed2016-09-29 23:25:40 -0700356 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
perkj26105b42016-09-29 22:39:10 -0700357
358 vie_encoder_->Stop();
359}
360
perkjfa10b552016-10-02 23:45:26 -0700361TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
362 const int kTargetBitrateBps = 100000;
363 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
364
365 // Capture a frame and wait for it to synchronize with the encoder thread.
366 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
367 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100368 // The encoder will have been configured once.
369 EXPECT_EQ(1, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700370 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
371 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
372
373 codec_width_ *= 2;
374 codec_height_ *= 2;
375 // Capture a frame with a higher resolution and wait for it to synchronize
376 // with the encoder thread.
377 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
378 sink_.WaitForEncodedFrame(2);
379 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
380 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
Per21d45d22016-10-30 21:37:57 +0100381 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700382
383 vie_encoder_->Stop();
384}
385
perkj803d97f2016-11-01 11:45:46 -0700386TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
387 EXPECT_TRUE(video_source_.has_sinks());
388 test::FrameForwarder new_video_source;
389 vie_encoder_->SetSource(&new_video_source,
390 VideoSendStream::DegradationPreference::kBalanced);
391 EXPECT_FALSE(video_source_.has_sinks());
392 EXPECT_TRUE(new_video_source.has_sinks());
393
394 vie_encoder_->Stop();
395}
396
397TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
398 EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
399 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/);
400 EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
401 vie_encoder_->Stop();
402}
403
404TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
405 const int kTargetBitrateBps = 100000;
406 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
407
408 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
409 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
410
411 int frame_width = 1280;
412 int frame_height = 720;
413
414 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
415 // request lower resolution.
416 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) {
417 video_source_.IncomingCapturedFrame(
418 CreateFrame(i, frame_width, frame_height));
419 sink_.WaitForEncodedFrame(i);
420
421 vie_encoder_->TriggerCpuOveruse();
422
423 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
424 std::numeric_limits<int>::max()),
425 frame_width * frame_height);
426 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
427
428 frame_width /= 2;
429 frame_height /= 2;
430 }
431
432 // Trigger CPU overuse a one more time. This should not trigger request for
433 // lower resolution.
434 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
435 video_source_.IncomingCapturedFrame(CreateFrame(
436 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
437 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
438 vie_encoder_->TriggerCpuOveruse();
439 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
440 current_wants.max_pixel_count);
441 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
442 current_wants.max_pixel_count_step_up);
443
444 // Trigger CPU normal use.
445 vie_encoder_->TriggerCpuNormalUsage();
446 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
447 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
448 frame_width * frame_height);
449
450 vie_encoder_->Stop();
451}
452
453TEST_F(ViEEncoderTest,
454 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) {
455 const int kTargetBitrateBps = 100000;
456 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
457
458 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
459 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
460
461 int frame_width = 1280;
462 int frame_height = 720;
463
464 // Trigger CPU overuse.
465 vie_encoder_->TriggerCpuOveruse();
466
467 video_source_.IncomingCapturedFrame(
468 CreateFrame(1, frame_width, frame_height));
469 sink_.WaitForEncodedFrame(1);
470 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
471 std::numeric_limits<int>::max()),
472 frame_width * frame_height);
473 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
474
475 // Set new source.
476 test::FrameForwarder new_video_source;
477 vie_encoder_->SetSource(
478 &new_video_source,
479 VideoSendStream::DegradationPreference::kMaintainResolution);
480
481 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
482 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
483
484 new_video_source.IncomingCapturedFrame(
485 CreateFrame(2, frame_width, frame_height));
486 sink_.WaitForEncodedFrame(2);
487 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
488 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
489
490 // Calling SetSource with resolution scaling enabled apply the old SinkWants.
491 vie_encoder_->SetSource(&new_video_source,
492 VideoSendStream::DegradationPreference::kBalanced);
493 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or(
494 std::numeric_limits<int>::max()),
495 frame_width * frame_height);
496 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
497
498 vie_encoder_->Stop();
499}
500
501TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) {
502 const int kTargetBitrateBps = 100000;
503 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
504
505 int frame_width = 1280;
506 int frame_height = 720;
507
508 video_source_.IncomingCapturedFrame(
509 CreateFrame(1, frame_width, frame_height));
510 sink_.WaitForEncodedFrame(1);
511 VideoSendStream::Stats stats = stats_proxy_->GetStats();
512 EXPECT_FALSE(stats.cpu_limited_resolution);
513 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
514
515 // Trigger CPU overuse.
516 vie_encoder_->TriggerCpuOveruse();
517 video_source_.IncomingCapturedFrame(
518 CreateFrame(2, frame_width, frame_height));
519 sink_.WaitForEncodedFrame(2);
520
521 stats = stats_proxy_->GetStats();
522 EXPECT_TRUE(stats.cpu_limited_resolution);
523 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
524
525 // Trigger CPU normal use.
526 vie_encoder_->TriggerCpuNormalUsage();
527 video_source_.IncomingCapturedFrame(
528 CreateFrame(3, frame_width, frame_height));
529 sink_.WaitForEncodedFrame(3);
530
531 stats = stats_proxy_->GetStats();
532 EXPECT_FALSE(stats.cpu_limited_resolution);
533 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
534
535 vie_encoder_->Stop();
536}
537
538TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
539 const int kTargetBitrateBps = 100000;
540 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
541
542 // Trigger CPU overuse.
543 vie_encoder_->TriggerCpuOveruse();
544 int frame_width = 1280;
545 int frame_height = 720;
546
547 video_source_.IncomingCapturedFrame(
548 CreateFrame(1, frame_width, frame_height));
549 sink_.WaitForEncodedFrame(1);
550
551 VideoSendStream::Stats stats = stats_proxy_->GetStats();
552 EXPECT_TRUE(stats.cpu_limited_resolution);
553 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
554
555 // Set new source with adaptation still enabled.
556 test::FrameForwarder new_video_source;
557 vie_encoder_->SetSource(&new_video_source,
558 VideoSendStream::DegradationPreference::kBalanced);
559
560 new_video_source.IncomingCapturedFrame(
561 CreateFrame(2, frame_width, frame_height));
562 sink_.WaitForEncodedFrame(2);
563 stats = stats_proxy_->GetStats();
564 EXPECT_TRUE(stats.cpu_limited_resolution);
565 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
566
567 // Set adaptation disabled.
568 vie_encoder_->SetSource(
569 &new_video_source,
570 VideoSendStream::DegradationPreference::kMaintainResolution);
571 new_video_source.IncomingCapturedFrame(
572 CreateFrame(3, frame_width, frame_height));
573 sink_.WaitForEncodedFrame(3);
574 stats = stats_proxy_->GetStats();
575 EXPECT_FALSE(stats.cpu_limited_resolution);
576 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
577
578 // Switch back the source with adaptation enabled.
579 vie_encoder_->SetSource(&video_source_,
580 VideoSendStream::DegradationPreference::kBalanced);
581 video_source_.IncomingCapturedFrame(
582 CreateFrame(4, frame_width, frame_height));
583 sink_.WaitForEncodedFrame(4);
584 stats = stats_proxy_->GetStats();
585 EXPECT_TRUE(stats.cpu_limited_resolution);
586 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
587
588 // Trigger CPU normal usage.
589 vie_encoder_->TriggerCpuNormalUsage();
590 video_source_.IncomingCapturedFrame(
591 CreateFrame(5, frame_width, frame_height));
592 sink_.WaitForEncodedFrame(5);
593 stats = stats_proxy_->GetStats();
594 EXPECT_FALSE(stats.cpu_limited_resolution);
595 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
596
597 vie_encoder_->Stop();
598}
599
Erik Språng08127a92016-11-16 16:41:30 +0100600TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) {
601 const int kTargetBitrateBps = 100000;
602 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
603
604 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
605 sink_.WaitForEncodedFrame(1);
606
607 VideoSendStream::Stats stats = stats_proxy_->GetStats();
608 EXPECT_EQ(video_encoder_config_.max_bitrate_bps,
609 stats.preferred_media_bitrate_bps);
610
611 vie_encoder_->Stop();
612}
613
perkj803d97f2016-11-01 11:45:46 -0700614TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
615 const int kTargetBitrateBps = 100000;
616 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
617
618 int frame_width = 640;
619 int frame_height = 360;
620
621 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
622 video_source_.IncomingCapturedFrame(
623 CreateFrame(i, frame_width, frame_height));
624 sink_.WaitForEncodedFrame(i);
625 }
626
627 vie_encoder_->TriggerCpuOveruse();
628 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
629 video_source_.IncomingCapturedFrame(
630 CreateFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i,
631 frame_width, frame_height));
632 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples +
633 i);
634 }
635
636 vie_encoder_->Stop();
637
638 stats_proxy_.reset();
639 EXPECT_EQ(1,
640 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
641 EXPECT_EQ(
642 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
643}
644
perkj26091b12016-09-01 01:17:40 -0700645} // namespace webrtc