blob: 1bb904be7cc7f39983cca026707c5bd9c238709c [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
kthelgason876222f2016-11-29 01:44:11 -080025using DegredationPreference = VideoSendStream::DegradationPreference;
26using ScaleReason = ScalingObserverInterface::ScaleReason;
27
perkj803d97f2016-11-01 11:45:46 -070028namespace {
asapersson5f7226f2016-11-25 04:37:00 -080029const size_t kMaxPayloadLength = 1440;
30const int kTargetBitrateBps = 100000;
31
perkj803d97f2016-11-01 11:45:46 -070032class 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 01:44:11 -080048 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
49 const VideoSendStream::Config::EncoderSettings& settings)
perkj803d97f2016-11-01 11:45:46 -070050 : ViEEncoder(1 /* number_of_cores */,
51 stats_proxy,
52 settings,
53 nullptr /* pre_encode_callback */,
54 nullptr /* encoder_timing */) {}
55
kthelgason876222f2016-11-29 01:44:11 -080056 void PostTaskAndWait(bool down, ScaleReason reason) {
perkj803d97f2016-11-01 11:45:46 -070057 rtc::Event event(false, false);
kthelgason876222f2016-11-29 01:44:11 -080058 encoder_queue()->PostTask([this, &event, reason, down] {
59 down ? ScaleDown(reason) : ScaleUp(reason);
perkj803d97f2016-11-01 11:45:46 -070060 event.Set();
61 });
kthelgason876222f2016-11-29 01:44:11 -080062 RTC_DCHECK(event.Wait(5000));
perkj803d97f2016-11-01 11:45:46 -070063 }
64
kthelgason876222f2016-11-29 01:44:11 -080065 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 11:45:46 -070072};
73
asapersson5f7226f2016-11-25 04:37:00 -080074class 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 11:45:46 -070097} // namespace
98
perkj26091b12016-09-01 01:17:40 -070099class 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-02 23:45:26 -0700105 codec_width_(320),
106 codec_height_(240),
perkj26091b12016-09-01 01:17:40 -0700107 fake_encoder_(),
perkj803d97f2016-11-01 11:45:46 -0700108 stats_proxy_(new SendStatisticsProxy(
109 Clock::GetRealTimeClock(),
110 video_send_config_,
111 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
perkj26091b12016-09-01 01:17:40 -0700112 sink_(&fake_encoder_) {}
113
114 void SetUp() override {
perkj803d97f2016-11-01 11:45:46 -0700115 metrics::Reset();
perkj26091b12016-09-01 01:17:40 -0700116 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 15:52:06 +0200121 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700122 test::FillEncoderConfiguration(1, &video_encoder_config);
Erik Språng08127a92016-11-16 16:41:30 +0100123 video_encoder_config_ = video_encoder_config.Copy();
asapersson5f7226f2016-11-25 04:37:00 -0800124 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 11:45:46 -0700131 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 01:17:40 -0700136 vie_encoder_->SetStartBitrate(10000);
asapersson5f7226f2016-11-25 04:37:00 -0800137 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 01:17:40 -0700153 }
154
155 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
Per512ecb32016-09-23 15:52:06 +0200156 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
157 destruction_event, codec_width_, codec_height_),
158 99, 99, kVideoRotation_0);
perkj26091b12016-09-01 01:17:40 -0700159 frame.set_ntp_time_ms(ntp_ts);
160 return frame;
161 }
162
perkj803d97f2016-11-01 11:45:46 -0700163 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 01:17:40 -0700171 class TestEncoder : public test::FakeEncoder {
172 public:
173 TestEncoder()
174 : FakeEncoder(Clock::GetRealTimeClock()),
175 continue_encode_event_(false, false) {}
176
perkjfa10b552016-10-02 23:45:26 -0700177 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 01:44:11 -0800187 VideoEncoder::ScalingSettings GetScalingSettings() const override {
188 return VideoEncoder::ScalingSettings(true, 1, 2);
189 }
190
perkjfa10b552016-10-02 23:45:26 -0700191 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 01:17:40 -0700201 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 11:45:46 -0700213 last_input_width_ = input_image.width();
214 last_input_height_ = input_image.height();
perkj26091b12016-09-01 01:17:40 -0700215 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 07:53:41 -0700221 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700222 return result;
223 }
224
perkj26091b12016-09-01 01:17:40 -0700225 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 11:45:46 -0700230 int last_input_width_ = 0;
231 int last_input_height_ = 0;
perkj26091b12016-09-01 01:17:40 -0700232 };
233
Per512ecb32016-09-23 15:52:06 +0200234 class TestSink : public ViEEncoder::EncoderSink {
perkj26091b12016-09-01 01:17:40 -0700235 public:
236 explicit TestSink(TestEncoder* test_encoder)
237 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
238
perkj26091b12016-09-01 01:17:40 -0700239 void WaitForEncodedFrame(int64_t expected_ntp_time) {
240 uint32_t timestamp = 0;
perkja49cbd32016-09-16 07:53:41 -0700241 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700242 {
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 15:52:06 +0200254 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 01:17:40 -0700264 private:
sergeyu2cb155a2016-11-04 11:39:29 -0700265 Result OnEncodedImage(
266 const EncodedImage& encoded_image,
267 const CodecSpecificInfo* codec_specific_info,
268 const RTPFragmentationHeader* fragmentation) override {
Per512ecb32016-09-23 15:52:06 +0200269 rtc::CritScope lock(&crit_);
270 EXPECT_TRUE(expect_frames_);
271 timestamp_ = encoded_image._timeStamp;
272 encoded_frame_event_.Set();
sergeyu2cb155a2016-11-04 11:39:29 -0700273 return Result(Result::OK, timestamp_);
Per512ecb32016-09-23 15:52:06 +0200274 }
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 01:17:40 -0700283 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 15:52:06 +0200288 int number_of_reconfigurations_ = 0;
289 int min_transmit_bitrate_bps_ = 0;
perkj26091b12016-09-01 01:17:40 -0700290 };
291
292 VideoSendStream::Config video_send_config_;
Erik Språng08127a92016-11-16 16:41:30 +0100293 VideoEncoderConfig video_encoder_config_;
Per512ecb32016-09-23 15:52:06 +0200294 int codec_width_;
295 int codec_height_;
perkj26091b12016-09-01 01:17:40 -0700296 TestEncoder fake_encoder_;
perkj803d97f2016-11-01 11:45:46 -0700297 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
perkj26091b12016-09-01 01:17:40 -0700298 TestSink sink_;
perkja49cbd32016-09-16 07:53:41 -0700299 test::FrameForwarder video_source_;
perkj803d97f2016-11-01 11:45:46 -0700300 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
perkj26091b12016-09-01 01:17:40 -0700301};
302
303TEST_F(ViEEncoderTest, EncodeOneFrame) {
perkj26091b12016-09-01 01:17:40 -0700304 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
305 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700306 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
perkj26091b12016-09-01 01:17:40 -0700307 sink_.WaitForEncodedFrame(1);
perkja49cbd32016-09-16 07:53:41 -0700308 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700309 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 07:53:41 -0700315 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
316 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700317
perkj26091b12016-09-01 01:17:40 -0700318 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
319
perkja49cbd32016-09-16 07:53:41 -0700320 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700321 sink_.WaitForEncodedFrame(2);
322 vie_encoder_->Stop();
323}
324
325TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
perkj26091b12016-09-01 01:17:40 -0700326 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700327 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700328 sink_.WaitForEncodedFrame(1);
329
330 vie_encoder_->OnBitrateUpdated(0, 0, 0);
331 // Dropped since bitrate is zero.
perkja49cbd32016-09-16 07:53:41 -0700332 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700333
334 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700335 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700336 sink_.WaitForEncodedFrame(3);
337 vie_encoder_->Stop();
338}
339
340TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
perkj26091b12016-09-01 01:17:40 -0700341 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700342 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700343 sink_.WaitForEncodedFrame(1);
344
345 // This frame will be dropped since it has the same ntp timestamp.
perkja49cbd32016-09-16 07:53:41 -0700346 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700347
perkja49cbd32016-09-16 07:53:41 -0700348 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700349 sink_.WaitForEncodedFrame(2);
350 vie_encoder_->Stop();
351}
352
353TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
perkj26091b12016-09-01 01:17:40 -0700354 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
355
perkja49cbd32016-09-16 07:53:41 -0700356 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700357 sink_.WaitForEncodedFrame(1);
358
359 vie_encoder_->Stop();
360 sink_.SetExpectNoFrames();
361 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700362 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
363 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700364}
365
366TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
perkj26091b12016-09-01 01:17:40 -0700367 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
368
369 fake_encoder_.BlockNextEncode();
perkja49cbd32016-09-16 07:53:41 -0700370 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700371 sink_.WaitForEncodedFrame(1);
372 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
373 // call to ContinueEncode.
perkja49cbd32016-09-16 07:53:41 -0700374 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
375 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700376 fake_encoder_.ContinueEncode();
377 sink_.WaitForEncodedFrame(3);
378
379 vie_encoder_->Stop();
380}
381
Per512ecb32016-09-23 15:52:06 +0200382TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
Per512ecb32016-09-23 15:52:06 +0200383 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
Per21d45d22016-10-30 21:37:57 +0100384 EXPECT_EQ(0, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200385
386 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200387 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
Per512ecb32016-09-23 15:52:06 +0200388 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100389 // 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 15:52:06 +0200392
393 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700394 test::FillEncoderConfiguration(1, &video_encoder_config);
Per512ecb32016-09-23 15:52:06 +0200395 video_encoder_config.min_transmit_bitrate_bps = 9999;
asapersson5f7226f2016-11-25 04:37:00 -0800396 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
397 kMaxPayloadLength, true /* nack_enabled */);
Per512ecb32016-09-23 15:52:06 +0200398
399 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200400 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
Per512ecb32016-09-23 15:52:06 +0200401 sink_.WaitForEncodedFrame(2);
Per21d45d22016-10-30 21:37:57 +0100402 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkj3b703ed2016-09-29 23:25:40 -0700403 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
perkj26105b42016-09-29 22:39:10 -0700404
405 vie_encoder_->Stop();
406}
407
perkjfa10b552016-10-02 23:45:26 -0700408TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
perkjfa10b552016-10-02 23:45:26 -0700409 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 21:37:57 +0100414 // The encoder will have been configured once.
415 EXPECT_EQ(1, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700416 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 21:37:57 +0100427 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700428
429 vie_encoder_->Stop();
430}
431
asapersson5f7226f2016-11-25 04:37:00 -0800432TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor1S1TLWithNackEnabled) {
433 const bool kNackEnabled = true;
434 const size_t kNumStreams = 1;
435 const size_t kNumTl = 1;
asaperssona90799d2016-12-09 02:35:20 -0800436 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800437 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;
asaperssona90799d2016-12-09 02:35:20 -0800456 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800457 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;
asaperssona90799d2016-12-09 02:35:20 -0800476 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800477 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;
asaperssona90799d2016-12-09 02:35:20 -0800496 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800497 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 11:45:46 -0700512TEST_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 11:45:46 -0700531 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 01:44:11 -0800557 // Trigger CPU overuse one more time. This should not trigger a request for
perkj803d97f2016-11-01 11:45:46 -0700558 // 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 11:45:46 -0700580 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 03:59:51 -0800588 video_source_.IncomingCapturedFrame(
589 CreateFrame(1, frame_width, frame_height));
590 sink_.WaitForEncodedFrame(1);
perkj803d97f2016-11-01 11:45:46 -0700591 // Trigger CPU overuse.
592 vie_encoder_->TriggerCpuOveruse();
593
594 video_source_.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800595 CreateFrame(2, frame_width, frame_height));
596 sink_.WaitForEncodedFrame(2);
perkj803d97f2016-11-01 11:45:46 -0700597 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 03:59:51 -0800612 CreateFrame(3, frame_width, frame_height));
613 sink_.WaitForEncodedFrame(3);
perkj803d97f2016-11-01 11:45:46 -0700614 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 11:45:46 -0700629 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 01:44:11 -0800664TEST_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 11:45:46 -0700796TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
perkj803d97f2016-11-01 11:45:46 -0700797 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 16:41:30 +0100857TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) {
Erik Språng08127a92016-11-16 16:41:30 +0100858 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 01:44:11 -0800870TEST_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 01:44:11 -0800880 video_source_.IncomingCapturedFrame(
881 CreateFrame(1, frame_width, frame_height));
882 sink_.WaitForEncodedFrame(1);
883
kthelgason5e13d412016-12-01 03:59:51 -0800884 // 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 01:44:11 -0800891 // 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 03:59:51 -0800905 CreateFrame(3, frame_width, frame_height));
906 sink_.WaitForEncodedFrame(3);
kthelgason876222f2016-11-29 01:44:11 -0800907
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 03:59:51 -0800914 CreateFrame(4, frame_width, frame_height));
915 sink_.WaitForEncodedFrame(4);
kthelgason876222f2016-11-29 01:44:11 -0800916
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 03:59:51 -0800923TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) {
924 const int kTargetBitrateBps = 100000;
925 int frame_width = 1280;
926 int frame_height = 720;
kthelgason1cd0a0a2016-12-09 02:30:46 -0800927 // from vie_encoder.cc
928 const int kMinPixelsPerFrame = 120 * 90;
kthelgason5e13d412016-12-01 03:59:51 -0800929 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 11:45:46 -0700943TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
perkj803d97f2016-11-01 11:45:46 -0700944 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 01:17:40 -0700973} // namespace webrtc