blob: c42825d05c5cd8fc7ef52c4d7a5955514c3cfa6a [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
nisseaf916892017-01-10 07:44:26 -080014#include "webrtc/api/video/i420_buffer.h"
perkj26091b12016-09-01 01:17:40 -070015#include "webrtc/base/logging.h"
perkj803d97f2016-11-01 11:45:46 -070016#include "webrtc/system_wrappers/include/metrics_default.h"
perkj26091b12016-09-01 01:17:40 -070017#include "webrtc/test/encoder_settings.h"
18#include "webrtc/test/fake_encoder.h"
perkja49cbd32016-09-16 07:53:41 -070019#include "webrtc/test/frame_generator.h"
kwibergac9f8762016-09-30 22:29:43 -070020#include "webrtc/test/gtest.h"
perkj26091b12016-09-01 01:17:40 -070021#include "webrtc/video/send_statistics_proxy.h"
22#include "webrtc/video/vie_encoder.h"
23
kthelgason33ce8892016-12-09 03:53:59 -080024namespace {
25#if defined(WEBRTC_ANDROID)
26// TODO(kthelgason): Lower this limit when better testing
27// on MediaCodec and fallback implementations are in place.
28const int kMinPixelsPerFrame = 320 * 180;
29#else
30const int kMinPixelsPerFrame = 120 * 90;
31#endif
32}
33
perkj26091b12016-09-01 01:17:40 -070034namespace webrtc {
35
kthelgason876222f2016-11-29 01:44:11 -080036using DegredationPreference = VideoSendStream::DegradationPreference;
37using ScaleReason = ScalingObserverInterface::ScaleReason;
38
perkj803d97f2016-11-01 11:45:46 -070039namespace {
asapersson5f7226f2016-11-25 04:37:00 -080040const size_t kMaxPayloadLength = 1440;
41const int kTargetBitrateBps = 100000;
42
perkj803d97f2016-11-01 11:45:46 -070043class TestBuffer : public webrtc::I420Buffer {
44 public:
45 TestBuffer(rtc::Event* event, int width, int height)
46 : I420Buffer(width, height), event_(event) {}
47
48 private:
49 friend class rtc::RefCountedObject<TestBuffer>;
50 ~TestBuffer() override {
51 if (event_)
52 event_->Set();
53 }
54 rtc::Event* const event_;
55};
56
57class ViEEncoderUnderTest : public ViEEncoder {
58 public:
kthelgason876222f2016-11-29 01:44:11 -080059 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
60 const VideoSendStream::Config::EncoderSettings& settings)
perkj803d97f2016-11-01 11:45:46 -070061 : ViEEncoder(1 /* number_of_cores */,
62 stats_proxy,
63 settings,
64 nullptr /* pre_encode_callback */,
65 nullptr /* encoder_timing */) {}
66
kthelgason876222f2016-11-29 01:44:11 -080067 void PostTaskAndWait(bool down, ScaleReason reason) {
perkj803d97f2016-11-01 11:45:46 -070068 rtc::Event event(false, false);
kthelgason876222f2016-11-29 01:44:11 -080069 encoder_queue()->PostTask([this, &event, reason, down] {
70 down ? ScaleDown(reason) : ScaleUp(reason);
perkj803d97f2016-11-01 11:45:46 -070071 event.Set();
72 });
kthelgason876222f2016-11-29 01:44:11 -080073 RTC_DCHECK(event.Wait(5000));
perkj803d97f2016-11-01 11:45:46 -070074 }
75
kthelgason876222f2016-11-29 01:44:11 -080076 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); }
77
78 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); }
79
80 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); }
81
82 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); }
perkj803d97f2016-11-01 11:45:46 -070083};
84
asapersson5f7226f2016-11-25 04:37:00 -080085class VideoStreamFactory
86 : public VideoEncoderConfig::VideoStreamFactoryInterface {
87 public:
88 explicit VideoStreamFactory(size_t num_temporal_layers)
89 : num_temporal_layers_(num_temporal_layers) {
90 EXPECT_GT(num_temporal_layers, 0u);
91 }
92
93 private:
94 std::vector<VideoStream> CreateEncoderStreams(
95 int width,
96 int height,
97 const VideoEncoderConfig& encoder_config) override {
98 std::vector<VideoStream> streams =
99 test::CreateVideoStreams(width, height, encoder_config);
100 for (VideoStream& stream : streams) {
101 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ - 1);
102 }
103 return streams;
104 }
105 const size_t num_temporal_layers_;
106};
107
perkj803d97f2016-11-01 11:45:46 -0700108} // namespace
109
perkj26091b12016-09-01 01:17:40 -0700110class ViEEncoderTest : public ::testing::Test {
111 public:
112 static const int kDefaultTimeoutMs = 30 * 1000;
113
114 ViEEncoderTest()
115 : video_send_config_(VideoSendStream::Config(nullptr)),
perkjfa10b552016-10-02 23:45:26 -0700116 codec_width_(320),
117 codec_height_(240),
perkj26091b12016-09-01 01:17:40 -0700118 fake_encoder_(),
perkj803d97f2016-11-01 11:45:46 -0700119 stats_proxy_(new SendStatisticsProxy(
120 Clock::GetRealTimeClock(),
121 video_send_config_,
122 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
perkj26091b12016-09-01 01:17:40 -0700123 sink_(&fake_encoder_) {}
124
125 void SetUp() override {
perkj803d97f2016-11-01 11:45:46 -0700126 metrics::Reset();
perkj26091b12016-09-01 01:17:40 -0700127 video_send_config_ = VideoSendStream::Config(nullptr);
128 video_send_config_.encoder_settings.encoder = &fake_encoder_;
129 video_send_config_.encoder_settings.payload_name = "FAKE";
130 video_send_config_.encoder_settings.payload_type = 125;
131
Per512ecb32016-09-23 15:52:06 +0200132 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700133 test::FillEncoderConfiguration(1, &video_encoder_config);
Erik Språng08127a92016-11-16 16:41:30 +0100134 video_encoder_config_ = video_encoder_config.Copy();
asapersson5f7226f2016-11-25 04:37:00 -0800135 ConfigureEncoder(std::move(video_encoder_config), true /* nack_enabled */);
136 }
137
138 void ConfigureEncoder(VideoEncoderConfig video_encoder_config,
139 bool nack_enabled) {
140 if (vie_encoder_)
141 vie_encoder_->Stop();
perkj803d97f2016-11-01 11:45:46 -0700142 vie_encoder_.reset(new ViEEncoderUnderTest(
143 stats_proxy_.get(), video_send_config_.encoder_settings));
144 vie_encoder_->SetSink(&sink_, false /* rotation_applied */);
145 vie_encoder_->SetSource(&video_source_,
146 VideoSendStream::DegradationPreference::kBalanced);
perkj26091b12016-09-01 01:17:40 -0700147 vie_encoder_->SetStartBitrate(10000);
asapersson5f7226f2016-11-25 04:37:00 -0800148 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
149 kMaxPayloadLength, nack_enabled);
150 }
151
152 void ResetEncoder(const std::string& payload_name,
153 size_t num_streams,
154 size_t num_temporal_layers,
155 bool nack_enabled) {
156 video_send_config_.encoder_settings.payload_name = payload_name;
157
158 VideoEncoderConfig video_encoder_config;
159 video_encoder_config.number_of_streams = num_streams;
160 video_encoder_config.max_bitrate_bps = 1000000;
161 video_encoder_config.video_stream_factory =
162 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers);
163 ConfigureEncoder(std::move(video_encoder_config), nack_enabled);
perkj26091b12016-09-01 01:17:40 -0700164 }
165
166 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
Per512ecb32016-09-23 15:52:06 +0200167 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
168 destruction_event, codec_width_, codec_height_),
169 99, 99, kVideoRotation_0);
perkj26091b12016-09-01 01:17:40 -0700170 frame.set_ntp_time_ms(ntp_ts);
171 return frame;
172 }
173
perkj803d97f2016-11-01 11:45:46 -0700174 VideoFrame CreateFrame(int64_t ntp_ts, int width, int height) const {
175 VideoFrame frame(
176 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99,
177 kVideoRotation_0);
178 frame.set_ntp_time_ms(ntp_ts);
179 return frame;
180 }
181
perkj26091b12016-09-01 01:17:40 -0700182 class TestEncoder : public test::FakeEncoder {
183 public:
184 TestEncoder()
185 : FakeEncoder(Clock::GetRealTimeClock()),
186 continue_encode_event_(false, false) {}
187
perkjfa10b552016-10-02 23:45:26 -0700188 VideoCodec codec_config() {
189 rtc::CritScope lock(&crit_);
190 return config_;
191 }
192
193 void BlockNextEncode() {
194 rtc::CritScope lock(&crit_);
195 block_next_encode_ = true;
196 }
197
kthelgason876222f2016-11-29 01:44:11 -0800198 VideoEncoder::ScalingSettings GetScalingSettings() const override {
199 return VideoEncoder::ScalingSettings(true, 1, 2);
200 }
201
perkjfa10b552016-10-02 23:45:26 -0700202 void ContinueEncode() { continue_encode_event_.Set(); }
203
204 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
205 uint32_t timestamp) const {
206 rtc::CritScope lock(&crit_);
207 EXPECT_EQ(timestamp_, timestamp);
208 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
209 }
210
211 private:
perkj26091b12016-09-01 01:17:40 -0700212 int32_t Encode(const VideoFrame& input_image,
213 const CodecSpecificInfo* codec_specific_info,
214 const std::vector<FrameType>* frame_types) override {
215 bool block_encode;
216 {
217 rtc::CritScope lock(&crit_);
218 EXPECT_GT(input_image.timestamp(), timestamp_);
219 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
220 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
221
222 timestamp_ = input_image.timestamp();
223 ntp_time_ms_ = input_image.ntp_time_ms();
perkj803d97f2016-11-01 11:45:46 -0700224 last_input_width_ = input_image.width();
225 last_input_height_ = input_image.height();
perkj26091b12016-09-01 01:17:40 -0700226 block_encode = block_next_encode_;
227 block_next_encode_ = false;
228 }
229 int32_t result =
230 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
231 if (block_encode)
perkja49cbd32016-09-16 07:53:41 -0700232 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700233 return result;
234 }
235
perkj26091b12016-09-01 01:17:40 -0700236 rtc::CriticalSection crit_;
237 bool block_next_encode_ = false;
238 rtc::Event continue_encode_event_;
239 uint32_t timestamp_ = 0;
240 int64_t ntp_time_ms_ = 0;
perkj803d97f2016-11-01 11:45:46 -0700241 int last_input_width_ = 0;
242 int last_input_height_ = 0;
perkj26091b12016-09-01 01:17:40 -0700243 };
244
Per512ecb32016-09-23 15:52:06 +0200245 class TestSink : public ViEEncoder::EncoderSink {
perkj26091b12016-09-01 01:17:40 -0700246 public:
247 explicit TestSink(TestEncoder* test_encoder)
248 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
249
perkj26091b12016-09-01 01:17:40 -0700250 void WaitForEncodedFrame(int64_t expected_ntp_time) {
251 uint32_t timestamp = 0;
perkja49cbd32016-09-16 07:53:41 -0700252 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700253 {
254 rtc::CritScope lock(&crit_);
255 timestamp = timestamp_;
256 }
257 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
258 }
259
260 void SetExpectNoFrames() {
261 rtc::CritScope lock(&crit_);
262 expect_frames_ = false;
263 }
264
Per512ecb32016-09-23 15:52:06 +0200265 int number_of_reconfigurations() {
266 rtc::CritScope lock(&crit_);
267 return number_of_reconfigurations_;
268 }
269
270 int last_min_transmit_bitrate() {
271 rtc::CritScope lock(&crit_);
272 return min_transmit_bitrate_bps_;
273 }
274
perkj26091b12016-09-01 01:17:40 -0700275 private:
sergeyu2cb155a2016-11-04 11:39:29 -0700276 Result OnEncodedImage(
277 const EncodedImage& encoded_image,
278 const CodecSpecificInfo* codec_specific_info,
279 const RTPFragmentationHeader* fragmentation) override {
Per512ecb32016-09-23 15:52:06 +0200280 rtc::CritScope lock(&crit_);
281 EXPECT_TRUE(expect_frames_);
282 timestamp_ = encoded_image._timeStamp;
283 encoded_frame_event_.Set();
sergeyu2cb155a2016-11-04 11:39:29 -0700284 return Result(Result::OK, timestamp_);
Per512ecb32016-09-23 15:52:06 +0200285 }
286
287 void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
288 int min_transmit_bitrate_bps) override {
289 rtc::CriticalSection crit_;
290 ++number_of_reconfigurations_;
291 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
292 }
293
perkj26091b12016-09-01 01:17:40 -0700294 rtc::CriticalSection crit_;
295 TestEncoder* test_encoder_;
296 rtc::Event encoded_frame_event_;
297 uint32_t timestamp_ = 0;
298 bool expect_frames_ = true;
Per512ecb32016-09-23 15:52:06 +0200299 int number_of_reconfigurations_ = 0;
300 int min_transmit_bitrate_bps_ = 0;
perkj26091b12016-09-01 01:17:40 -0700301 };
302
303 VideoSendStream::Config video_send_config_;
Erik Språng08127a92016-11-16 16:41:30 +0100304 VideoEncoderConfig video_encoder_config_;
Per512ecb32016-09-23 15:52:06 +0200305 int codec_width_;
306 int codec_height_;
perkj26091b12016-09-01 01:17:40 -0700307 TestEncoder fake_encoder_;
perkj803d97f2016-11-01 11:45:46 -0700308 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
perkj26091b12016-09-01 01:17:40 -0700309 TestSink sink_;
perkja49cbd32016-09-16 07:53:41 -0700310 test::FrameForwarder video_source_;
perkj803d97f2016-11-01 11:45:46 -0700311 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
perkj26091b12016-09-01 01:17:40 -0700312};
313
314TEST_F(ViEEncoderTest, EncodeOneFrame) {
perkj26091b12016-09-01 01:17:40 -0700315 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
316 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700317 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
perkj26091b12016-09-01 01:17:40 -0700318 sink_.WaitForEncodedFrame(1);
perkja49cbd32016-09-16 07:53:41 -0700319 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700320 vie_encoder_->Stop();
321}
322
323TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
324 // Dropped since no target bitrate has been set.
325 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700326 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
327 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700328
perkj26091b12016-09-01 01:17:40 -0700329 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
330
perkja49cbd32016-09-16 07:53:41 -0700331 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700332 sink_.WaitForEncodedFrame(2);
333 vie_encoder_->Stop();
334}
335
336TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
perkj26091b12016-09-01 01:17:40 -0700337 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700338 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700339 sink_.WaitForEncodedFrame(1);
340
341 vie_encoder_->OnBitrateUpdated(0, 0, 0);
342 // Dropped since bitrate is zero.
perkja49cbd32016-09-16 07:53:41 -0700343 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700344
345 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700346 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700347 sink_.WaitForEncodedFrame(3);
348 vie_encoder_->Stop();
349}
350
351TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
perkj26091b12016-09-01 01:17:40 -0700352 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700353 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700354 sink_.WaitForEncodedFrame(1);
355
356 // This frame will be dropped since it has the same ntp timestamp.
perkja49cbd32016-09-16 07:53:41 -0700357 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700358
perkja49cbd32016-09-16 07:53:41 -0700359 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700360 sink_.WaitForEncodedFrame(2);
361 vie_encoder_->Stop();
362}
363
364TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
perkj26091b12016-09-01 01:17:40 -0700365 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
366
perkja49cbd32016-09-16 07:53:41 -0700367 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700368 sink_.WaitForEncodedFrame(1);
369
370 vie_encoder_->Stop();
371 sink_.SetExpectNoFrames();
372 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700373 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
374 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700375}
376
377TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
perkj26091b12016-09-01 01:17:40 -0700378 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
379
380 fake_encoder_.BlockNextEncode();
perkja49cbd32016-09-16 07:53:41 -0700381 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700382 sink_.WaitForEncodedFrame(1);
383 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
384 // call to ContinueEncode.
perkja49cbd32016-09-16 07:53:41 -0700385 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
386 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700387 fake_encoder_.ContinueEncode();
388 sink_.WaitForEncodedFrame(3);
389
390 vie_encoder_->Stop();
391}
392
Per512ecb32016-09-23 15:52:06 +0200393TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
Per512ecb32016-09-23 15:52:06 +0200394 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
Per21d45d22016-10-30 21:37:57 +0100395 EXPECT_EQ(0, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200396
397 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200398 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
Per512ecb32016-09-23 15:52:06 +0200399 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100400 // The encoder will have been configured once when the first frame is
401 // received.
402 EXPECT_EQ(1, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200403
404 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700405 test::FillEncoderConfiguration(1, &video_encoder_config);
Per512ecb32016-09-23 15:52:06 +0200406 video_encoder_config.min_transmit_bitrate_bps = 9999;
asapersson5f7226f2016-11-25 04:37:00 -0800407 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
408 kMaxPayloadLength, true /* nack_enabled */);
Per512ecb32016-09-23 15:52:06 +0200409
410 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200411 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
Per512ecb32016-09-23 15:52:06 +0200412 sink_.WaitForEncodedFrame(2);
Per21d45d22016-10-30 21:37:57 +0100413 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkj3b703ed2016-09-29 23:25:40 -0700414 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
perkj26105b42016-09-29 22:39:10 -0700415
416 vie_encoder_->Stop();
417}
418
perkjfa10b552016-10-02 23:45:26 -0700419TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
perkjfa10b552016-10-02 23:45:26 -0700420 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
421
422 // Capture a frame and wait for it to synchronize with the encoder thread.
423 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
424 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100425 // The encoder will have been configured once.
426 EXPECT_EQ(1, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700427 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
428 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
429
430 codec_width_ *= 2;
431 codec_height_ *= 2;
432 // Capture a frame with a higher resolution and wait for it to synchronize
433 // with the encoder thread.
434 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
435 sink_.WaitForEncodedFrame(2);
436 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
437 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
Per21d45d22016-10-30 21:37:57 +0100438 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700439
440 vie_encoder_->Stop();
441}
442
asapersson5f7226f2016-11-25 04:37:00 -0800443TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor1S1TLWithNackEnabled) {
444 const bool kNackEnabled = true;
445 const size_t kNumStreams = 1;
446 const size_t kNumTl = 1;
asaperssona90799d2016-12-09 02:35:20 -0800447 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800448 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
449
450 // Capture a frame and wait for it to synchronize with the encoder thread.
451 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
452 sink_.WaitForEncodedFrame(1);
453 // The encoder have been configured once when the first frame is received.
454 EXPECT_EQ(1, sink_.number_of_reconfigurations());
455 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
456 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
457 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
458 // Resilience is off for no temporal layers with nack on.
459 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
460 vie_encoder_->Stop();
461}
462
463TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor2S1TlWithNackEnabled) {
464 const bool kNackEnabled = true;
465 const size_t kNumStreams = 2;
466 const size_t kNumTl = 1;
asaperssona90799d2016-12-09 02:35:20 -0800467 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800468 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
469
470 // Capture a frame and wait for it to synchronize with the encoder thread.
471 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
472 sink_.WaitForEncodedFrame(1);
473 // The encoder have been configured once when the first frame is received.
474 EXPECT_EQ(1, sink_.number_of_reconfigurations());
475 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
476 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
477 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
478 // Resilience is off for no temporal layers and >1 streams with nack on.
479 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
480 vie_encoder_->Stop();
481}
482
483TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S1TLWithNackDisabled) {
484 const bool kNackEnabled = false;
485 const size_t kNumStreams = 1;
486 const size_t kNumTl = 1;
asaperssona90799d2016-12-09 02:35:20 -0800487 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800488 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
489
490 // Capture a frame and wait for it to synchronize with the encoder thread.
491 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
492 sink_.WaitForEncodedFrame(1);
493 // The encoder have been configured once when the first frame is received.
494 EXPECT_EQ(1, sink_.number_of_reconfigurations());
495 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
496 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
497 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
498 // Resilience is on for no temporal layers with nack off.
499 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
500 vie_encoder_->Stop();
501}
502
503TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S2TlWithNackEnabled) {
504 const bool kNackEnabled = true;
505 const size_t kNumStreams = 1;
506 const size_t kNumTl = 2;
asaperssona90799d2016-12-09 02:35:20 -0800507 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800508 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
509
510 // Capture a frame and wait for it to synchronize with the encoder thread.
511 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
512 sink_.WaitForEncodedFrame(1);
513 // The encoder have been configured once when the first frame is received.
514 EXPECT_EQ(1, sink_.number_of_reconfigurations());
515 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
516 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
517 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
518 // Resilience is on for temporal layers.
519 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
520 vie_encoder_->Stop();
521}
522
perkj803d97f2016-11-01 11:45:46 -0700523TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
524 EXPECT_TRUE(video_source_.has_sinks());
525 test::FrameForwarder new_video_source;
526 vie_encoder_->SetSource(&new_video_source,
527 VideoSendStream::DegradationPreference::kBalanced);
528 EXPECT_FALSE(video_source_.has_sinks());
529 EXPECT_TRUE(new_video_source.has_sinks());
530
531 vie_encoder_->Stop();
532}
533
534TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
535 EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
536 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/);
537 EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
538 vie_encoder_->Stop();
539}
540
541TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
perkj803d97f2016-11-01 11:45:46 -0700542 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
543
544 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
545 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
546
547 int frame_width = 1280;
548 int frame_height = 720;
549
550 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
551 // request lower resolution.
552 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) {
553 video_source_.IncomingCapturedFrame(
554 CreateFrame(i, frame_width, frame_height));
555 sink_.WaitForEncodedFrame(i);
556
557 vie_encoder_->TriggerCpuOveruse();
558
559 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
560 std::numeric_limits<int>::max()),
561 frame_width * frame_height);
562 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
563
564 frame_width /= 2;
565 frame_height /= 2;
566 }
567
kthelgason876222f2016-11-29 01:44:11 -0800568 // Trigger CPU overuse one more time. This should not trigger a request for
perkj803d97f2016-11-01 11:45:46 -0700569 // lower resolution.
570 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
571 video_source_.IncomingCapturedFrame(CreateFrame(
572 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
573 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
574 vie_encoder_->TriggerCpuOveruse();
575 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
576 current_wants.max_pixel_count);
577 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
578 current_wants.max_pixel_count_step_up);
579
580 // Trigger CPU normal use.
581 vie_encoder_->TriggerCpuNormalUsage();
582 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
583 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
584 frame_width * frame_height);
585
586 vie_encoder_->Stop();
587}
588
589TEST_F(ViEEncoderTest,
590 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) {
perkj803d97f2016-11-01 11:45:46 -0700591 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
592
593 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
594 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
595
596 int frame_width = 1280;
597 int frame_height = 720;
598
kthelgason5e13d412016-12-01 03:59:51 -0800599 video_source_.IncomingCapturedFrame(
600 CreateFrame(1, frame_width, frame_height));
601 sink_.WaitForEncodedFrame(1);
perkj803d97f2016-11-01 11:45:46 -0700602 // Trigger CPU overuse.
603 vie_encoder_->TriggerCpuOveruse();
604
605 video_source_.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800606 CreateFrame(2, frame_width, frame_height));
607 sink_.WaitForEncodedFrame(2);
perkj803d97f2016-11-01 11:45:46 -0700608 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
609 std::numeric_limits<int>::max()),
610 frame_width * frame_height);
611 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
612
613 // Set new source.
614 test::FrameForwarder new_video_source;
615 vie_encoder_->SetSource(
616 &new_video_source,
617 VideoSendStream::DegradationPreference::kMaintainResolution);
618
619 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
620 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
621
622 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800623 CreateFrame(3, frame_width, frame_height));
624 sink_.WaitForEncodedFrame(3);
perkj803d97f2016-11-01 11:45:46 -0700625 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
626 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
627
628 // Calling SetSource with resolution scaling enabled apply the old SinkWants.
629 vie_encoder_->SetSource(&new_video_source,
630 VideoSendStream::DegradationPreference::kBalanced);
631 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or(
632 std::numeric_limits<int>::max()),
633 frame_width * frame_height);
634 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
635
636 vie_encoder_->Stop();
637}
638
639TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -0700640 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
641
642 int frame_width = 1280;
643 int frame_height = 720;
644
645 video_source_.IncomingCapturedFrame(
646 CreateFrame(1, frame_width, frame_height));
647 sink_.WaitForEncodedFrame(1);
648 VideoSendStream::Stats stats = stats_proxy_->GetStats();
649 EXPECT_FALSE(stats.cpu_limited_resolution);
650 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
651
652 // Trigger CPU overuse.
653 vie_encoder_->TriggerCpuOveruse();
654 video_source_.IncomingCapturedFrame(
655 CreateFrame(2, frame_width, frame_height));
656 sink_.WaitForEncodedFrame(2);
657
658 stats = stats_proxy_->GetStats();
659 EXPECT_TRUE(stats.cpu_limited_resolution);
660 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
661
662 // Trigger CPU normal use.
663 vie_encoder_->TriggerCpuNormalUsage();
664 video_source_.IncomingCapturedFrame(
665 CreateFrame(3, frame_width, frame_height));
666 sink_.WaitForEncodedFrame(3);
667
668 stats = stats_proxy_->GetStats();
669 EXPECT_FALSE(stats.cpu_limited_resolution);
670 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
671
672 vie_encoder_->Stop();
673}
674
kthelgason876222f2016-11-29 01:44:11 -0800675TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
676 const int kTargetBitrateBps = 100000;
677 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
678
679 int frame_width = 1280;
680 int frame_height = 720;
681 video_source_.IncomingCapturedFrame(
682 CreateFrame(1, frame_width, frame_height));
683 sink_.WaitForEncodedFrame(1);
684
685 VideoSendStream::Stats stats = stats_proxy_->GetStats();
686 EXPECT_FALSE(stats.cpu_limited_resolution);
687 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
688
689 vie_encoder_->TriggerCpuOveruse();
690
691 video_source_.IncomingCapturedFrame(
692 CreateFrame(2, frame_width, frame_height));
693 sink_.WaitForEncodedFrame(2);
694 stats = stats_proxy_->GetStats();
695 EXPECT_TRUE(stats.cpu_limited_resolution);
696 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
697
698 // Set new source with adaptation still enabled.
699 test::FrameForwarder new_video_source;
700 vie_encoder_->SetSource(&new_video_source,
701 VideoSendStream::DegradationPreference::kBalanced);
702
703 new_video_source.IncomingCapturedFrame(
704 CreateFrame(3, frame_width, frame_height));
705 sink_.WaitForEncodedFrame(3);
706 stats = stats_proxy_->GetStats();
707 EXPECT_TRUE(stats.cpu_limited_resolution);
708 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
709
710 // Set adaptation disabled.
711 vie_encoder_->SetSource(
712 &new_video_source,
713 VideoSendStream::DegradationPreference::kMaintainResolution);
714
715 new_video_source.IncomingCapturedFrame(
716 CreateFrame(4, frame_width, frame_height));
717 sink_.WaitForEncodedFrame(4);
718 stats = stats_proxy_->GetStats();
719 EXPECT_FALSE(stats.cpu_limited_resolution);
720 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
721
722 // Set adaptation back to enabled.
723 vie_encoder_->SetSource(&new_video_source,
724 VideoSendStream::DegradationPreference::kBalanced);
725
726 new_video_source.IncomingCapturedFrame(
727 CreateFrame(5, frame_width, frame_height));
728 sink_.WaitForEncodedFrame(5);
729 stats = stats_proxy_->GetStats();
730 EXPECT_TRUE(stats.cpu_limited_resolution);
731 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
732
733 vie_encoder_->TriggerCpuNormalUsage();
734
735 new_video_source.IncomingCapturedFrame(
736 CreateFrame(6, frame_width, frame_height));
737 sink_.WaitForEncodedFrame(6);
738 stats = stats_proxy_->GetStats();
739 EXPECT_FALSE(stats.cpu_limited_resolution);
740 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
741
742 vie_encoder_->Stop();
743}
744
745TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
746 const int kTargetBitrateBps = 100000;
747 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
748
749 int frame_width = 1280;
750 int frame_height = 720;
751 video_source_.IncomingCapturedFrame(
752 CreateFrame(1, frame_width, frame_height));
753 sink_.WaitForEncodedFrame(1);
754
755 VideoSendStream::Stats stats = stats_proxy_->GetStats();
756 EXPECT_FALSE(stats.cpu_limited_resolution);
757 EXPECT_FALSE(stats.bw_limited_resolution);
758 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
759
760 // Set new source with adaptation still enabled.
761 test::FrameForwarder new_video_source;
762 vie_encoder_->SetSource(&new_video_source,
763 VideoSendStream::DegradationPreference::kBalanced);
764
765 new_video_source.IncomingCapturedFrame(
766 CreateFrame(2, frame_width, frame_height));
767 sink_.WaitForEncodedFrame(2);
768 stats = stats_proxy_->GetStats();
769 EXPECT_FALSE(stats.cpu_limited_resolution);
770 EXPECT_FALSE(stats.bw_limited_resolution);
771 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
772
773 vie_encoder_->TriggerQualityLow();
774
775 new_video_source.IncomingCapturedFrame(
776 CreateFrame(3, frame_width, frame_height));
777 sink_.WaitForEncodedFrame(3);
778 stats = stats_proxy_->GetStats();
779 EXPECT_FALSE(stats.cpu_limited_resolution);
780 EXPECT_TRUE(stats.bw_limited_resolution);
781
782 vie_encoder_->SetSource(&new_video_source,
783 VideoSendStream::DegradationPreference::kBalanced);
784
785 new_video_source.IncomingCapturedFrame(
786 CreateFrame(4, frame_width, frame_height));
787 sink_.WaitForEncodedFrame(4);
788 stats = stats_proxy_->GetStats();
789 EXPECT_FALSE(stats.cpu_limited_resolution);
790 EXPECT_TRUE(stats.bw_limited_resolution);
791
792 // Set adaptation disabled.
793 vie_encoder_->SetSource(
794 &new_video_source,
795 VideoSendStream::DegradationPreference::kMaintainResolution);
796
797 new_video_source.IncomingCapturedFrame(
798 CreateFrame(5, frame_width, frame_height));
799 sink_.WaitForEncodedFrame(5);
800 stats = stats_proxy_->GetStats();
801 EXPECT_FALSE(stats.cpu_limited_resolution);
802 EXPECT_FALSE(stats.bw_limited_resolution);
803
804 vie_encoder_->Stop();
805}
806
perkj803d97f2016-11-01 11:45:46 -0700807TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
perkj803d97f2016-11-01 11:45:46 -0700808 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
809
810 // Trigger CPU overuse.
811 vie_encoder_->TriggerCpuOveruse();
812 int frame_width = 1280;
813 int frame_height = 720;
814
815 video_source_.IncomingCapturedFrame(
816 CreateFrame(1, frame_width, frame_height));
817 sink_.WaitForEncodedFrame(1);
818
819 VideoSendStream::Stats stats = stats_proxy_->GetStats();
820 EXPECT_TRUE(stats.cpu_limited_resolution);
821 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
822
823 // Set new source with adaptation still enabled.
824 test::FrameForwarder new_video_source;
825 vie_encoder_->SetSource(&new_video_source,
826 VideoSendStream::DegradationPreference::kBalanced);
827
828 new_video_source.IncomingCapturedFrame(
829 CreateFrame(2, frame_width, frame_height));
830 sink_.WaitForEncodedFrame(2);
831 stats = stats_proxy_->GetStats();
832 EXPECT_TRUE(stats.cpu_limited_resolution);
833 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
834
835 // Set adaptation disabled.
836 vie_encoder_->SetSource(
837 &new_video_source,
838 VideoSendStream::DegradationPreference::kMaintainResolution);
839 new_video_source.IncomingCapturedFrame(
840 CreateFrame(3, frame_width, frame_height));
841 sink_.WaitForEncodedFrame(3);
842 stats = stats_proxy_->GetStats();
843 EXPECT_FALSE(stats.cpu_limited_resolution);
844 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
845
846 // Switch back the source with adaptation enabled.
847 vie_encoder_->SetSource(&video_source_,
848 VideoSendStream::DegradationPreference::kBalanced);
849 video_source_.IncomingCapturedFrame(
850 CreateFrame(4, frame_width, frame_height));
851 sink_.WaitForEncodedFrame(4);
852 stats = stats_proxy_->GetStats();
853 EXPECT_TRUE(stats.cpu_limited_resolution);
854 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
855
856 // Trigger CPU normal usage.
857 vie_encoder_->TriggerCpuNormalUsage();
858 video_source_.IncomingCapturedFrame(
859 CreateFrame(5, frame_width, frame_height));
860 sink_.WaitForEncodedFrame(5);
861 stats = stats_proxy_->GetStats();
862 EXPECT_FALSE(stats.cpu_limited_resolution);
863 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
864
865 vie_encoder_->Stop();
866}
867
Erik Språng08127a92016-11-16 16:41:30 +0100868TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) {
Erik Språng08127a92016-11-16 16:41:30 +0100869 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
870
871 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
872 sink_.WaitForEncodedFrame(1);
873
874 VideoSendStream::Stats stats = stats_proxy_->GetStats();
875 EXPECT_EQ(video_encoder_config_.max_bitrate_bps,
876 stats.preferred_media_bitrate_bps);
877
878 vie_encoder_->Stop();
879}
880
kthelgason876222f2016-11-29 01:44:11 -0800881TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) {
882 const int kTargetBitrateBps = 100000;
883 int frame_width = 1280;
884 int frame_height = 720;
885 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
886
887 // Expect no scaling to begin with
888 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
889 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
890
kthelgason876222f2016-11-29 01:44:11 -0800891 video_source_.IncomingCapturedFrame(
892 CreateFrame(1, frame_width, frame_height));
893 sink_.WaitForEncodedFrame(1);
894
kthelgason5e13d412016-12-01 03:59:51 -0800895 // Trigger scale down
896 vie_encoder_->TriggerQualityLow();
897
898 video_source_.IncomingCapturedFrame(
899 CreateFrame(2, frame_width, frame_height));
900 sink_.WaitForEncodedFrame(2);
901
kthelgason876222f2016-11-29 01:44:11 -0800902 // Expect a scale down.
903 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count);
904 EXPECT_LT(*video_source_.sink_wants().max_pixel_count,
905 frame_width * frame_height);
906
907 // Set adaptation disabled.
908 test::FrameForwarder new_video_source;
909 vie_encoder_->SetSource(
910 &new_video_source,
911 VideoSendStream::DegradationPreference::kMaintainResolution);
912
913 // Trigger scale down
914 vie_encoder_->TriggerQualityLow();
915 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800916 CreateFrame(3, frame_width, frame_height));
917 sink_.WaitForEncodedFrame(3);
kthelgason876222f2016-11-29 01:44:11 -0800918
919 // Expect no scaling
920 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
921
922 // Trigger scale up
923 vie_encoder_->TriggerQualityHigh();
924 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800925 CreateFrame(4, frame_width, frame_height));
926 sink_.WaitForEncodedFrame(4);
kthelgason876222f2016-11-29 01:44:11 -0800927
928 // Expect nothing to change, still no scaling
929 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
930
931 vie_encoder_->Stop();
932}
933
kthelgason5e13d412016-12-01 03:59:51 -0800934TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) {
935 const int kTargetBitrateBps = 100000;
936 int frame_width = 1280;
937 int frame_height = 720;
kthelgason5e13d412016-12-01 03:59:51 -0800938 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
939
940 for (size_t i = 1; i <= 10; i++) {
941 video_source_.IncomingCapturedFrame(
942 CreateFrame(i, frame_width, frame_height));
943 sink_.WaitForEncodedFrame(i);
944 // Trigger scale down
945 vie_encoder_->TriggerQualityLow();
946 EXPECT_GE(*video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame);
947 }
948
949 vie_encoder_->Stop();
950}
951
perkj803d97f2016-11-01 11:45:46 -0700952TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
perkj803d97f2016-11-01 11:45:46 -0700953 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
954
955 int frame_width = 640;
956 int frame_height = 360;
957
958 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
959 video_source_.IncomingCapturedFrame(
960 CreateFrame(i, frame_width, frame_height));
961 sink_.WaitForEncodedFrame(i);
962 }
963
964 vie_encoder_->TriggerCpuOveruse();
965 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
966 video_source_.IncomingCapturedFrame(
967 CreateFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i,
968 frame_width, frame_height));
969 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples +
970 i);
971 }
972
973 vie_encoder_->Stop();
974
975 stats_proxy_.reset();
976 EXPECT_EQ(1,
977 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
978 EXPECT_EQ(
979 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
980}
981
perkj26091b12016-09-01 01:17:40 -0700982} // namespace webrtc