blob: 1bb904be7cc7f39983cca026707c5bd9c238709c [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
kthelgason876222f2016-11-29 09:44:1125using DegredationPreference = VideoSendStream::DegradationPreference;
26using ScaleReason = ScalingObserverInterface::ScaleReason;
27
perkj803d97f2016-11-01 18:45:4628namespace {
asapersson5f7226f2016-11-25 12:37:0029const size_t kMaxPayloadLength = 1440;
30const int kTargetBitrateBps = 100000;
31
perkj803d97f2016-11-01 18:45:4632class TestBuffer : public webrtc::I420Buffer {
33 public:
34 TestBuffer(rtc::Event* event, int width, int height)
35 : I420Buffer(width, height), event_(event) {}
36
37 private:
38 friend class rtc::RefCountedObject<TestBuffer>;
39 ~TestBuffer() override {
40 if (event_)
41 event_->Set();
42 }
43 rtc::Event* const event_;
44};
45
46class ViEEncoderUnderTest : public ViEEncoder {
47 public:
kthelgason876222f2016-11-29 09:44:1148 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
49 const VideoSendStream::Config::EncoderSettings& settings)
perkj803d97f2016-11-01 18:45:4650 : ViEEncoder(1 /* number_of_cores */,
51 stats_proxy,
52 settings,
53 nullptr /* pre_encode_callback */,
54 nullptr /* encoder_timing */) {}
55
kthelgason876222f2016-11-29 09:44:1156 void PostTaskAndWait(bool down, ScaleReason reason) {
perkj803d97f2016-11-01 18:45:4657 rtc::Event event(false, false);
kthelgason876222f2016-11-29 09:44:1158 encoder_queue()->PostTask([this, &event, reason, down] {
59 down ? ScaleDown(reason) : ScaleUp(reason);
perkj803d97f2016-11-01 18:45:4660 event.Set();
61 });
kthelgason876222f2016-11-29 09:44:1162 RTC_DCHECK(event.Wait(5000));
perkj803d97f2016-11-01 18:45:4663 }
64
kthelgason876222f2016-11-29 09:44:1165 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); }
66
67 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); }
68
69 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); }
70
71 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); }
perkj803d97f2016-11-01 18:45:4672};
73
asapersson5f7226f2016-11-25 12:37:0074class VideoStreamFactory
75 : public VideoEncoderConfig::VideoStreamFactoryInterface {
76 public:
77 explicit VideoStreamFactory(size_t num_temporal_layers)
78 : num_temporal_layers_(num_temporal_layers) {
79 EXPECT_GT(num_temporal_layers, 0u);
80 }
81
82 private:
83 std::vector<VideoStream> CreateEncoderStreams(
84 int width,
85 int height,
86 const VideoEncoderConfig& encoder_config) override {
87 std::vector<VideoStream> streams =
88 test::CreateVideoStreams(width, height, encoder_config);
89 for (VideoStream& stream : streams) {
90 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ - 1);
91 }
92 return streams;
93 }
94 const size_t num_temporal_layers_;
95};
96
perkj803d97f2016-11-01 18:45:4697} // namespace
98
perkj26091b12016-09-01 08:17:4099class ViEEncoderTest : public ::testing::Test {
100 public:
101 static const int kDefaultTimeoutMs = 30 * 1000;
102
103 ViEEncoderTest()
104 : video_send_config_(VideoSendStream::Config(nullptr)),
perkjfa10b552016-10-03 06:45:26105 codec_width_(320),
106 codec_height_(240),
perkj26091b12016-09-01 08:17:40107 fake_encoder_(),
perkj803d97f2016-11-01 18:45:46108 stats_proxy_(new SendStatisticsProxy(
109 Clock::GetRealTimeClock(),
110 video_send_config_,
111 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
perkj26091b12016-09-01 08:17:40112 sink_(&fake_encoder_) {}
113
114 void SetUp() override {
perkj803d97f2016-11-01 18:45:46115 metrics::Reset();
perkj26091b12016-09-01 08:17:40116 video_send_config_ = VideoSendStream::Config(nullptr);
117 video_send_config_.encoder_settings.encoder = &fake_encoder_;
118 video_send_config_.encoder_settings.payload_name = "FAKE";
119 video_send_config_.encoder_settings.payload_type = 125;
120
Per512ecb32016-09-23 13:52:06121 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-03 06:45:26122 test::FillEncoderConfiguration(1, &video_encoder_config);
Erik Språng08127a92016-11-16 15:41:30123 video_encoder_config_ = video_encoder_config.Copy();
asapersson5f7226f2016-11-25 12:37:00124 ConfigureEncoder(std::move(video_encoder_config), true /* nack_enabled */);
125 }
126
127 void ConfigureEncoder(VideoEncoderConfig video_encoder_config,
128 bool nack_enabled) {
129 if (vie_encoder_)
130 vie_encoder_->Stop();
perkj803d97f2016-11-01 18:45:46131 vie_encoder_.reset(new ViEEncoderUnderTest(
132 stats_proxy_.get(), video_send_config_.encoder_settings));
133 vie_encoder_->SetSink(&sink_, false /* rotation_applied */);
134 vie_encoder_->SetSource(&video_source_,
135 VideoSendStream::DegradationPreference::kBalanced);
perkj26091b12016-09-01 08:17:40136 vie_encoder_->SetStartBitrate(10000);
asapersson5f7226f2016-11-25 12:37:00137 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
138 kMaxPayloadLength, nack_enabled);
139 }
140
141 void ResetEncoder(const std::string& payload_name,
142 size_t num_streams,
143 size_t num_temporal_layers,
144 bool nack_enabled) {
145 video_send_config_.encoder_settings.payload_name = payload_name;
146
147 VideoEncoderConfig video_encoder_config;
148 video_encoder_config.number_of_streams = num_streams;
149 video_encoder_config.max_bitrate_bps = 1000000;
150 video_encoder_config.video_stream_factory =
151 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers);
152 ConfigureEncoder(std::move(video_encoder_config), nack_enabled);
perkj26091b12016-09-01 08:17:40153 }
154
155 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
Per512ecb32016-09-23 13:52:06156 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
157 destruction_event, codec_width_, codec_height_),
158 99, 99, kVideoRotation_0);
perkj26091b12016-09-01 08:17:40159 frame.set_ntp_time_ms(ntp_ts);
160 return frame;
161 }
162
perkj803d97f2016-11-01 18:45:46163 VideoFrame CreateFrame(int64_t ntp_ts, int width, int height) const {
164 VideoFrame frame(
165 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99,
166 kVideoRotation_0);
167 frame.set_ntp_time_ms(ntp_ts);
168 return frame;
169 }
170
perkj26091b12016-09-01 08:17:40171 class TestEncoder : public test::FakeEncoder {
172 public:
173 TestEncoder()
174 : FakeEncoder(Clock::GetRealTimeClock()),
175 continue_encode_event_(false, false) {}
176
perkjfa10b552016-10-03 06:45:26177 VideoCodec codec_config() {
178 rtc::CritScope lock(&crit_);
179 return config_;
180 }
181
182 void BlockNextEncode() {
183 rtc::CritScope lock(&crit_);
184 block_next_encode_ = true;
185 }
186
kthelgason876222f2016-11-29 09:44:11187 VideoEncoder::ScalingSettings GetScalingSettings() const override {
188 return VideoEncoder::ScalingSettings(true, 1, 2);
189 }
190
perkjfa10b552016-10-03 06:45:26191 void ContinueEncode() { continue_encode_event_.Set(); }
192
193 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
194 uint32_t timestamp) const {
195 rtc::CritScope lock(&crit_);
196 EXPECT_EQ(timestamp_, timestamp);
197 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
198 }
199
200 private:
perkj26091b12016-09-01 08:17:40201 int32_t Encode(const VideoFrame& input_image,
202 const CodecSpecificInfo* codec_specific_info,
203 const std::vector<FrameType>* frame_types) override {
204 bool block_encode;
205 {
206 rtc::CritScope lock(&crit_);
207 EXPECT_GT(input_image.timestamp(), timestamp_);
208 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
209 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
210
211 timestamp_ = input_image.timestamp();
212 ntp_time_ms_ = input_image.ntp_time_ms();
perkj803d97f2016-11-01 18:45:46213 last_input_width_ = input_image.width();
214 last_input_height_ = input_image.height();
perkj26091b12016-09-01 08:17:40215 block_encode = block_next_encode_;
216 block_next_encode_ = false;
217 }
218 int32_t result =
219 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
220 if (block_encode)
perkja49cbd32016-09-16 14:53:41221 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40222 return result;
223 }
224
perkj26091b12016-09-01 08:17:40225 rtc::CriticalSection crit_;
226 bool block_next_encode_ = false;
227 rtc::Event continue_encode_event_;
228 uint32_t timestamp_ = 0;
229 int64_t ntp_time_ms_ = 0;
perkj803d97f2016-11-01 18:45:46230 int last_input_width_ = 0;
231 int last_input_height_ = 0;
perkj26091b12016-09-01 08:17:40232 };
233
Per512ecb32016-09-23 13:52:06234 class TestSink : public ViEEncoder::EncoderSink {
perkj26091b12016-09-01 08:17:40235 public:
236 explicit TestSink(TestEncoder* test_encoder)
237 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
238
perkj26091b12016-09-01 08:17:40239 void WaitForEncodedFrame(int64_t expected_ntp_time) {
240 uint32_t timestamp = 0;
perkja49cbd32016-09-16 14:53:41241 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40242 {
243 rtc::CritScope lock(&crit_);
244 timestamp = timestamp_;
245 }
246 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
247 }
248
249 void SetExpectNoFrames() {
250 rtc::CritScope lock(&crit_);
251 expect_frames_ = false;
252 }
253
Per512ecb32016-09-23 13:52:06254 int number_of_reconfigurations() {
255 rtc::CritScope lock(&crit_);
256 return number_of_reconfigurations_;
257 }
258
259 int last_min_transmit_bitrate() {
260 rtc::CritScope lock(&crit_);
261 return min_transmit_bitrate_bps_;
262 }
263
perkj26091b12016-09-01 08:17:40264 private:
sergeyu2cb155a2016-11-04 18:39:29265 Result OnEncodedImage(
266 const EncodedImage& encoded_image,
267 const CodecSpecificInfo* codec_specific_info,
268 const RTPFragmentationHeader* fragmentation) override {
Per512ecb32016-09-23 13:52:06269 rtc::CritScope lock(&crit_);
270 EXPECT_TRUE(expect_frames_);
271 timestamp_ = encoded_image._timeStamp;
272 encoded_frame_event_.Set();
sergeyu2cb155a2016-11-04 18:39:29273 return Result(Result::OK, timestamp_);
Per512ecb32016-09-23 13:52:06274 }
275
276 void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
277 int min_transmit_bitrate_bps) override {
278 rtc::CriticalSection crit_;
279 ++number_of_reconfigurations_;
280 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
281 }
282
perkj26091b12016-09-01 08:17:40283 rtc::CriticalSection crit_;
284 TestEncoder* test_encoder_;
285 rtc::Event encoded_frame_event_;
286 uint32_t timestamp_ = 0;
287 bool expect_frames_ = true;
Per512ecb32016-09-23 13:52:06288 int number_of_reconfigurations_ = 0;
289 int min_transmit_bitrate_bps_ = 0;
perkj26091b12016-09-01 08:17:40290 };
291
292 VideoSendStream::Config video_send_config_;
Erik Språng08127a92016-11-16 15:41:30293 VideoEncoderConfig video_encoder_config_;
Per512ecb32016-09-23 13:52:06294 int codec_width_;
295 int codec_height_;
perkj26091b12016-09-01 08:17:40296 TestEncoder fake_encoder_;
perkj803d97f2016-11-01 18:45:46297 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
perkj26091b12016-09-01 08:17:40298 TestSink sink_;
perkja49cbd32016-09-16 14:53:41299 test::FrameForwarder video_source_;
perkj803d97f2016-11-01 18:45:46300 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
perkj26091b12016-09-01 08:17:40301};
302
303TEST_F(ViEEncoderTest, EncodeOneFrame) {
perkj26091b12016-09-01 08:17:40304 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
305 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 14:53:41306 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
perkj26091b12016-09-01 08:17:40307 sink_.WaitForEncodedFrame(1);
perkja49cbd32016-09-16 14:53:41308 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40309 vie_encoder_->Stop();
310}
311
312TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
313 // Dropped since no target bitrate has been set.
314 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 14:53:41315 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
316 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40317
perkj26091b12016-09-01 08:17:40318 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
319
perkja49cbd32016-09-16 14:53:41320 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 08:17:40321 sink_.WaitForEncodedFrame(2);
322 vie_encoder_->Stop();
323}
324
325TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
perkj26091b12016-09-01 08:17:40326 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 14:53:41327 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40328 sink_.WaitForEncodedFrame(1);
329
330 vie_encoder_->OnBitrateUpdated(0, 0, 0);
331 // Dropped since bitrate is zero.
perkja49cbd32016-09-16 14:53:41332 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 08:17:40333
334 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 14:53:41335 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 08:17:40336 sink_.WaitForEncodedFrame(3);
337 vie_encoder_->Stop();
338}
339
340TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
perkj26091b12016-09-01 08:17:40341 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 14:53:41342 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40343 sink_.WaitForEncodedFrame(1);
344
345 // This frame will be dropped since it has the same ntp timestamp.
perkja49cbd32016-09-16 14:53:41346 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40347
perkja49cbd32016-09-16 14:53:41348 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 08:17:40349 sink_.WaitForEncodedFrame(2);
350 vie_encoder_->Stop();
351}
352
353TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
perkj26091b12016-09-01 08:17:40354 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
355
perkja49cbd32016-09-16 14:53:41356 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40357 sink_.WaitForEncodedFrame(1);
358
359 vie_encoder_->Stop();
360 sink_.SetExpectNoFrames();
361 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 14:53:41362 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
363 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 08:17:40364}
365
366TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
perkj26091b12016-09-01 08:17:40367 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
368
369 fake_encoder_.BlockNextEncode();
perkja49cbd32016-09-16 14:53:41370 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 08:17:40371 sink_.WaitForEncodedFrame(1);
372 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
373 // call to ContinueEncode.
perkja49cbd32016-09-16 14:53:41374 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
375 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 08:17:40376 fake_encoder_.ContinueEncode();
377 sink_.WaitForEncodedFrame(3);
378
379 vie_encoder_->Stop();
380}
381
Per512ecb32016-09-23 13:52:06382TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
Per512ecb32016-09-23 13:52:06383 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
Per21d45d22016-10-30 20:37:57384 EXPECT_EQ(0, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 13:52:06385
386 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 14:24:55387 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
Per512ecb32016-09-23 13:52:06388 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 20:37:57389 // The encoder will have been configured once when the first frame is
390 // received.
391 EXPECT_EQ(1, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 13:52:06392
393 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-03 06:45:26394 test::FillEncoderConfiguration(1, &video_encoder_config);
Per512ecb32016-09-23 13:52:06395 video_encoder_config.min_transmit_bitrate_bps = 9999;
asapersson5f7226f2016-11-25 12:37:00396 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
397 kMaxPayloadLength, true /* nack_enabled */);
Per512ecb32016-09-23 13:52:06398
399 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 14:24:55400 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
Per512ecb32016-09-23 13:52:06401 sink_.WaitForEncodedFrame(2);
Per21d45d22016-10-30 20:37:57402 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkj3b703ed2016-09-30 06:25:40403 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
perkj26105b42016-09-30 05:39:10404
405 vie_encoder_->Stop();
406}
407
perkjfa10b552016-10-03 06:45:26408TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
perkjfa10b552016-10-03 06:45:26409 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
410
411 // Capture a frame and wait for it to synchronize with the encoder thread.
412 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
413 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 20:37:57414 // The encoder will have been configured once.
415 EXPECT_EQ(1, sink_.number_of_reconfigurations());
perkjfa10b552016-10-03 06:45:26416 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
417 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
418
419 codec_width_ *= 2;
420 codec_height_ *= 2;
421 // Capture a frame with a higher resolution and wait for it to synchronize
422 // with the encoder thread.
423 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
424 sink_.WaitForEncodedFrame(2);
425 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
426 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
Per21d45d22016-10-30 20:37:57427 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkjfa10b552016-10-03 06:45:26428
429 vie_encoder_->Stop();
430}
431
asapersson5f7226f2016-11-25 12:37:00432TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor1S1TLWithNackEnabled) {
433 const bool kNackEnabled = true;
434 const size_t kNumStreams = 1;
435 const size_t kNumTl = 1;
436 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
437 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
438
439 // Capture a frame and wait for it to synchronize with the encoder thread.
440 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
441 sink_.WaitForEncodedFrame(1);
442 // The encoder have been configured once when the first frame is received.
443 EXPECT_EQ(1, sink_.number_of_reconfigurations());
444 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
445 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
446 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
447 // Resilience is off for no temporal layers with nack on.
448 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
449 vie_encoder_->Stop();
450}
451
452TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor2S1TlWithNackEnabled) {
453 const bool kNackEnabled = true;
454 const size_t kNumStreams = 2;
455 const size_t kNumTl = 1;
456 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
457 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
458
459 // Capture a frame and wait for it to synchronize with the encoder thread.
460 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
461 sink_.WaitForEncodedFrame(1);
462 // The encoder have been configured once when the first frame is received.
463 EXPECT_EQ(1, sink_.number_of_reconfigurations());
464 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
465 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
466 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
467 // Resilience is off for no temporal layers and >1 streams with nack on.
468 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
469 vie_encoder_->Stop();
470}
471
472TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S1TLWithNackDisabled) {
473 const bool kNackEnabled = false;
474 const size_t kNumStreams = 1;
475 const size_t kNumTl = 1;
476 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
477 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
478
479 // Capture a frame and wait for it to synchronize with the encoder thread.
480 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
481 sink_.WaitForEncodedFrame(1);
482 // The encoder have been configured once when the first frame is received.
483 EXPECT_EQ(1, sink_.number_of_reconfigurations());
484 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
485 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
486 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
487 // Resilience is on for no temporal layers with nack off.
488 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
489 vie_encoder_->Stop();
490}
491
492TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S2TlWithNackEnabled) {
493 const bool kNackEnabled = true;
494 const size_t kNumStreams = 1;
495 const size_t kNumTl = 2;
496 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
497 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
498
499 // Capture a frame and wait for it to synchronize with the encoder thread.
500 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
501 sink_.WaitForEncodedFrame(1);
502 // The encoder have been configured once when the first frame is received.
503 EXPECT_EQ(1, sink_.number_of_reconfigurations());
504 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
505 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
506 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
507 // Resilience is on for temporal layers.
508 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
509 vie_encoder_->Stop();
510}
511
perkj803d97f2016-11-01 18:45:46512TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
513 EXPECT_TRUE(video_source_.has_sinks());
514 test::FrameForwarder new_video_source;
515 vie_encoder_->SetSource(&new_video_source,
516 VideoSendStream::DegradationPreference::kBalanced);
517 EXPECT_FALSE(video_source_.has_sinks());
518 EXPECT_TRUE(new_video_source.has_sinks());
519
520 vie_encoder_->Stop();
521}
522
523TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
524 EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
525 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/);
526 EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
527 vie_encoder_->Stop();
528}
529
530TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
perkj803d97f2016-11-01 18:45:46531 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
532
533 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
534 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
535
536 int frame_width = 1280;
537 int frame_height = 720;
538
539 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
540 // request lower resolution.
541 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) {
542 video_source_.IncomingCapturedFrame(
543 CreateFrame(i, frame_width, frame_height));
544 sink_.WaitForEncodedFrame(i);
545
546 vie_encoder_->TriggerCpuOveruse();
547
548 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
549 std::numeric_limits<int>::max()),
550 frame_width * frame_height);
551 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
552
553 frame_width /= 2;
554 frame_height /= 2;
555 }
556
kthelgason876222f2016-11-29 09:44:11557 // Trigger CPU overuse one more time. This should not trigger a request for
perkj803d97f2016-11-01 18:45:46558 // lower resolution.
559 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
560 video_source_.IncomingCapturedFrame(CreateFrame(
561 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
562 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
563 vie_encoder_->TriggerCpuOveruse();
564 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
565 current_wants.max_pixel_count);
566 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
567 current_wants.max_pixel_count_step_up);
568
569 // Trigger CPU normal use.
570 vie_encoder_->TriggerCpuNormalUsage();
571 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
572 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
573 frame_width * frame_height);
574
575 vie_encoder_->Stop();
576}
577
578TEST_F(ViEEncoderTest,
579 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) {
perkj803d97f2016-11-01 18:45:46580 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
581
582 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
583 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
584
585 int frame_width = 1280;
586 int frame_height = 720;
587
kthelgason5e13d412016-12-01 11:59:51588 video_source_.IncomingCapturedFrame(
589 CreateFrame(1, frame_width, frame_height));
590 sink_.WaitForEncodedFrame(1);
perkj803d97f2016-11-01 18:45:46591 // Trigger CPU overuse.
592 vie_encoder_->TriggerCpuOveruse();
593
594 video_source_.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 11:59:51595 CreateFrame(2, frame_width, frame_height));
596 sink_.WaitForEncodedFrame(2);
perkj803d97f2016-11-01 18:45:46597 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
598 std::numeric_limits<int>::max()),
599 frame_width * frame_height);
600 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
601
602 // Set new source.
603 test::FrameForwarder new_video_source;
604 vie_encoder_->SetSource(
605 &new_video_source,
606 VideoSendStream::DegradationPreference::kMaintainResolution);
607
608 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
609 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
610
611 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 11:59:51612 CreateFrame(3, frame_width, frame_height));
613 sink_.WaitForEncodedFrame(3);
perkj803d97f2016-11-01 18:45:46614 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
615 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
616
617 // Calling SetSource with resolution scaling enabled apply the old SinkWants.
618 vie_encoder_->SetSource(&new_video_source,
619 VideoSendStream::DegradationPreference::kBalanced);
620 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or(
621 std::numeric_limits<int>::max()),
622 frame_width * frame_height);
623 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
624
625 vie_encoder_->Stop();
626}
627
628TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) {
perkj803d97f2016-11-01 18:45:46629 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
630
631 int frame_width = 1280;
632 int frame_height = 720;
633
634 video_source_.IncomingCapturedFrame(
635 CreateFrame(1, frame_width, frame_height));
636 sink_.WaitForEncodedFrame(1);
637 VideoSendStream::Stats stats = stats_proxy_->GetStats();
638 EXPECT_FALSE(stats.cpu_limited_resolution);
639 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
640
641 // Trigger CPU overuse.
642 vie_encoder_->TriggerCpuOveruse();
643 video_source_.IncomingCapturedFrame(
644 CreateFrame(2, frame_width, frame_height));
645 sink_.WaitForEncodedFrame(2);
646
647 stats = stats_proxy_->GetStats();
648 EXPECT_TRUE(stats.cpu_limited_resolution);
649 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
650
651 // Trigger CPU normal use.
652 vie_encoder_->TriggerCpuNormalUsage();
653 video_source_.IncomingCapturedFrame(
654 CreateFrame(3, frame_width, frame_height));
655 sink_.WaitForEncodedFrame(3);
656
657 stats = stats_proxy_->GetStats();
658 EXPECT_FALSE(stats.cpu_limited_resolution);
659 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
660
661 vie_encoder_->Stop();
662}
663
kthelgason876222f2016-11-29 09:44:11664TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
665 const int kTargetBitrateBps = 100000;
666 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
667
668 int frame_width = 1280;
669 int frame_height = 720;
670 video_source_.IncomingCapturedFrame(
671 CreateFrame(1, frame_width, frame_height));
672 sink_.WaitForEncodedFrame(1);
673
674 VideoSendStream::Stats stats = stats_proxy_->GetStats();
675 EXPECT_FALSE(stats.cpu_limited_resolution);
676 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
677
678 vie_encoder_->TriggerCpuOveruse();
679
680 video_source_.IncomingCapturedFrame(
681 CreateFrame(2, frame_width, frame_height));
682 sink_.WaitForEncodedFrame(2);
683 stats = stats_proxy_->GetStats();
684 EXPECT_TRUE(stats.cpu_limited_resolution);
685 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
686
687 // Set new source with adaptation still enabled.
688 test::FrameForwarder new_video_source;
689 vie_encoder_->SetSource(&new_video_source,
690 VideoSendStream::DegradationPreference::kBalanced);
691
692 new_video_source.IncomingCapturedFrame(
693 CreateFrame(3, frame_width, frame_height));
694 sink_.WaitForEncodedFrame(3);
695 stats = stats_proxy_->GetStats();
696 EXPECT_TRUE(stats.cpu_limited_resolution);
697 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
698
699 // Set adaptation disabled.
700 vie_encoder_->SetSource(
701 &new_video_source,
702 VideoSendStream::DegradationPreference::kMaintainResolution);
703
704 new_video_source.IncomingCapturedFrame(
705 CreateFrame(4, frame_width, frame_height));
706 sink_.WaitForEncodedFrame(4);
707 stats = stats_proxy_->GetStats();
708 EXPECT_FALSE(stats.cpu_limited_resolution);
709 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
710
711 // Set adaptation back to enabled.
712 vie_encoder_->SetSource(&new_video_source,
713 VideoSendStream::DegradationPreference::kBalanced);
714
715 new_video_source.IncomingCapturedFrame(
716 CreateFrame(5, frame_width, frame_height));
717 sink_.WaitForEncodedFrame(5);
718 stats = stats_proxy_->GetStats();
719 EXPECT_TRUE(stats.cpu_limited_resolution);
720 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
721
722 vie_encoder_->TriggerCpuNormalUsage();
723
724 new_video_source.IncomingCapturedFrame(
725 CreateFrame(6, frame_width, frame_height));
726 sink_.WaitForEncodedFrame(6);
727 stats = stats_proxy_->GetStats();
728 EXPECT_FALSE(stats.cpu_limited_resolution);
729 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
730
731 vie_encoder_->Stop();
732}
733
734TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
735 const int kTargetBitrateBps = 100000;
736 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
737
738 int frame_width = 1280;
739 int frame_height = 720;
740 video_source_.IncomingCapturedFrame(
741 CreateFrame(1, frame_width, frame_height));
742 sink_.WaitForEncodedFrame(1);
743
744 VideoSendStream::Stats stats = stats_proxy_->GetStats();
745 EXPECT_FALSE(stats.cpu_limited_resolution);
746 EXPECT_FALSE(stats.bw_limited_resolution);
747 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
748
749 // Set new source with adaptation still enabled.
750 test::FrameForwarder new_video_source;
751 vie_encoder_->SetSource(&new_video_source,
752 VideoSendStream::DegradationPreference::kBalanced);
753
754 new_video_source.IncomingCapturedFrame(
755 CreateFrame(2, frame_width, frame_height));
756 sink_.WaitForEncodedFrame(2);
757 stats = stats_proxy_->GetStats();
758 EXPECT_FALSE(stats.cpu_limited_resolution);
759 EXPECT_FALSE(stats.bw_limited_resolution);
760 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
761
762 vie_encoder_->TriggerQualityLow();
763
764 new_video_source.IncomingCapturedFrame(
765 CreateFrame(3, frame_width, frame_height));
766 sink_.WaitForEncodedFrame(3);
767 stats = stats_proxy_->GetStats();
768 EXPECT_FALSE(stats.cpu_limited_resolution);
769 EXPECT_TRUE(stats.bw_limited_resolution);
770
771 vie_encoder_->SetSource(&new_video_source,
772 VideoSendStream::DegradationPreference::kBalanced);
773
774 new_video_source.IncomingCapturedFrame(
775 CreateFrame(4, frame_width, frame_height));
776 sink_.WaitForEncodedFrame(4);
777 stats = stats_proxy_->GetStats();
778 EXPECT_FALSE(stats.cpu_limited_resolution);
779 EXPECT_TRUE(stats.bw_limited_resolution);
780
781 // Set adaptation disabled.
782 vie_encoder_->SetSource(
783 &new_video_source,
784 VideoSendStream::DegradationPreference::kMaintainResolution);
785
786 new_video_source.IncomingCapturedFrame(
787 CreateFrame(5, frame_width, frame_height));
788 sink_.WaitForEncodedFrame(5);
789 stats = stats_proxy_->GetStats();
790 EXPECT_FALSE(stats.cpu_limited_resolution);
791 EXPECT_FALSE(stats.bw_limited_resolution);
792
793 vie_encoder_->Stop();
794}
795
perkj803d97f2016-11-01 18:45:46796TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
perkj803d97f2016-11-01 18:45:46797 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
798
799 // Trigger CPU overuse.
800 vie_encoder_->TriggerCpuOveruse();
801 int frame_width = 1280;
802 int frame_height = 720;
803
804 video_source_.IncomingCapturedFrame(
805 CreateFrame(1, frame_width, frame_height));
806 sink_.WaitForEncodedFrame(1);
807
808 VideoSendStream::Stats stats = stats_proxy_->GetStats();
809 EXPECT_TRUE(stats.cpu_limited_resolution);
810 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
811
812 // Set new source with adaptation still enabled.
813 test::FrameForwarder new_video_source;
814 vie_encoder_->SetSource(&new_video_source,
815 VideoSendStream::DegradationPreference::kBalanced);
816
817 new_video_source.IncomingCapturedFrame(
818 CreateFrame(2, frame_width, frame_height));
819 sink_.WaitForEncodedFrame(2);
820 stats = stats_proxy_->GetStats();
821 EXPECT_TRUE(stats.cpu_limited_resolution);
822 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
823
824 // Set adaptation disabled.
825 vie_encoder_->SetSource(
826 &new_video_source,
827 VideoSendStream::DegradationPreference::kMaintainResolution);
828 new_video_source.IncomingCapturedFrame(
829 CreateFrame(3, frame_width, frame_height));
830 sink_.WaitForEncodedFrame(3);
831 stats = stats_proxy_->GetStats();
832 EXPECT_FALSE(stats.cpu_limited_resolution);
833 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
834
835 // Switch back the source with adaptation enabled.
836 vie_encoder_->SetSource(&video_source_,
837 VideoSendStream::DegradationPreference::kBalanced);
838 video_source_.IncomingCapturedFrame(
839 CreateFrame(4, frame_width, frame_height));
840 sink_.WaitForEncodedFrame(4);
841 stats = stats_proxy_->GetStats();
842 EXPECT_TRUE(stats.cpu_limited_resolution);
843 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
844
845 // Trigger CPU normal usage.
846 vie_encoder_->TriggerCpuNormalUsage();
847 video_source_.IncomingCapturedFrame(
848 CreateFrame(5, frame_width, frame_height));
849 sink_.WaitForEncodedFrame(5);
850 stats = stats_proxy_->GetStats();
851 EXPECT_FALSE(stats.cpu_limited_resolution);
852 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
853
854 vie_encoder_->Stop();
855}
856
Erik Språng08127a92016-11-16 15:41:30857TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) {
Erik Språng08127a92016-11-16 15:41:30858 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
859
860 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
861 sink_.WaitForEncodedFrame(1);
862
863 VideoSendStream::Stats stats = stats_proxy_->GetStats();
864 EXPECT_EQ(video_encoder_config_.max_bitrate_bps,
865 stats.preferred_media_bitrate_bps);
866
867 vie_encoder_->Stop();
868}
869
kthelgason876222f2016-11-29 09:44:11870TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) {
871 const int kTargetBitrateBps = 100000;
872 int frame_width = 1280;
873 int frame_height = 720;
874 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
875
876 // Expect no scaling to begin with
877 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
878 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
879
kthelgason876222f2016-11-29 09:44:11880 video_source_.IncomingCapturedFrame(
881 CreateFrame(1, frame_width, frame_height));
882 sink_.WaitForEncodedFrame(1);
883
kthelgason5e13d412016-12-01 11:59:51884 // Trigger scale down
885 vie_encoder_->TriggerQualityLow();
886
887 video_source_.IncomingCapturedFrame(
888 CreateFrame(2, frame_width, frame_height));
889 sink_.WaitForEncodedFrame(2);
890
kthelgason876222f2016-11-29 09:44:11891 // Expect a scale down.
892 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count);
893 EXPECT_LT(*video_source_.sink_wants().max_pixel_count,
894 frame_width * frame_height);
895
896 // Set adaptation disabled.
897 test::FrameForwarder new_video_source;
898 vie_encoder_->SetSource(
899 &new_video_source,
900 VideoSendStream::DegradationPreference::kMaintainResolution);
901
902 // Trigger scale down
903 vie_encoder_->TriggerQualityLow();
904 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 11:59:51905 CreateFrame(3, frame_width, frame_height));
906 sink_.WaitForEncodedFrame(3);
kthelgason876222f2016-11-29 09:44:11907
908 // Expect no scaling
909 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
910
911 // Trigger scale up
912 vie_encoder_->TriggerQualityHigh();
913 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 11:59:51914 CreateFrame(4, frame_width, frame_height));
915 sink_.WaitForEncodedFrame(4);
kthelgason876222f2016-11-29 09:44:11916
917 // Expect nothing to change, still no scaling
918 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
919
920 vie_encoder_->Stop();
921}
922
kthelgason5e13d412016-12-01 11:59:51923TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) {
924 const int kTargetBitrateBps = 100000;
925 int frame_width = 1280;
926 int frame_height = 720;
927 // from vie_encoder.cc
928 const int kMinPixelsPerFrame = 120 * 90;
929 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
930
931 for (size_t i = 1; i <= 10; i++) {
932 video_source_.IncomingCapturedFrame(
933 CreateFrame(i, frame_width, frame_height));
934 sink_.WaitForEncodedFrame(i);
935 // Trigger scale down
936 vie_encoder_->TriggerQualityLow();
937 EXPECT_GE(*video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame);
938 }
939
940 vie_encoder_->Stop();
941}
942
perkj803d97f2016-11-01 18:45:46943TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
perkj803d97f2016-11-01 18:45:46944 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
945
946 int frame_width = 640;
947 int frame_height = 360;
948
949 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
950 video_source_.IncomingCapturedFrame(
951 CreateFrame(i, frame_width, frame_height));
952 sink_.WaitForEncodedFrame(i);
953 }
954
955 vie_encoder_->TriggerCpuOveruse();
956 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
957 video_source_.IncomingCapturedFrame(
958 CreateFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i,
959 frame_width, frame_height));
960 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples +
961 i);
962 }
963
964 vie_encoder_->Stop();
965
966 stats_proxy_.reset();
967 EXPECT_EQ(1,
968 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
969 EXPECT_EQ(
970 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
971}
972
perkj26091b12016-09-01 08:17:40973} // namespace webrtc