blob: da925e5224db403b29c4a7b4d53ddc49f01556e9 [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;
asapersson4eb03c72016-12-02 08:57:55 -080031const unsigned char kNumSlDummy = 0;
asapersson5f7226f2016-11-25 04:37:00 -080032
perkj803d97f2016-11-01 11:45:46 -070033class TestBuffer : public webrtc::I420Buffer {
34 public:
35 TestBuffer(rtc::Event* event, int width, int height)
36 : I420Buffer(width, height), event_(event) {}
37
38 private:
39 friend class rtc::RefCountedObject<TestBuffer>;
40 ~TestBuffer() override {
41 if (event_)
42 event_->Set();
43 }
44 rtc::Event* const event_;
45};
46
47class ViEEncoderUnderTest : public ViEEncoder {
48 public:
kthelgason876222f2016-11-29 01:44:11 -080049 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
50 const VideoSendStream::Config::EncoderSettings& settings)
perkj803d97f2016-11-01 11:45:46 -070051 : ViEEncoder(1 /* number_of_cores */,
52 stats_proxy,
53 settings,
54 nullptr /* pre_encode_callback */,
55 nullptr /* encoder_timing */) {}
56
kthelgason876222f2016-11-29 01:44:11 -080057 void PostTaskAndWait(bool down, ScaleReason reason) {
perkj803d97f2016-11-01 11:45:46 -070058 rtc::Event event(false, false);
kthelgason876222f2016-11-29 01:44:11 -080059 encoder_queue()->PostTask([this, &event, reason, down] {
60 down ? ScaleDown(reason) : ScaleUp(reason);
perkj803d97f2016-11-01 11:45:46 -070061 event.Set();
62 });
kthelgason876222f2016-11-29 01:44:11 -080063 RTC_DCHECK(event.Wait(5000));
perkj803d97f2016-11-01 11:45:46 -070064 }
65
kthelgason876222f2016-11-29 01:44:11 -080066 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); }
67
68 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); }
69
70 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); }
71
72 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); }
perkj803d97f2016-11-01 11:45:46 -070073};
74
asapersson5f7226f2016-11-25 04:37:00 -080075class VideoStreamFactory
76 : public VideoEncoderConfig::VideoStreamFactoryInterface {
77 public:
78 explicit VideoStreamFactory(size_t num_temporal_layers)
79 : num_temporal_layers_(num_temporal_layers) {
80 EXPECT_GT(num_temporal_layers, 0u);
81 }
82
83 private:
84 std::vector<VideoStream> CreateEncoderStreams(
85 int width,
86 int height,
87 const VideoEncoderConfig& encoder_config) override {
88 std::vector<VideoStream> streams =
89 test::CreateVideoStreams(width, height, encoder_config);
90 for (VideoStream& stream : streams) {
91 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ - 1);
92 }
93 return streams;
94 }
95 const size_t num_temporal_layers_;
96};
97
perkj803d97f2016-11-01 11:45:46 -070098} // namespace
99
perkj26091b12016-09-01 01:17:40 -0700100class ViEEncoderTest : public ::testing::Test {
101 public:
102 static const int kDefaultTimeoutMs = 30 * 1000;
103
104 ViEEncoderTest()
105 : video_send_config_(VideoSendStream::Config(nullptr)),
perkjfa10b552016-10-02 23:45:26 -0700106 codec_width_(320),
107 codec_height_(240),
perkj26091b12016-09-01 01:17:40 -0700108 fake_encoder_(),
perkj803d97f2016-11-01 11:45:46 -0700109 stats_proxy_(new SendStatisticsProxy(
110 Clock::GetRealTimeClock(),
111 video_send_config_,
112 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
perkj26091b12016-09-01 01:17:40 -0700113 sink_(&fake_encoder_) {}
114
115 void SetUp() override {
perkj803d97f2016-11-01 11:45:46 -0700116 metrics::Reset();
perkj26091b12016-09-01 01:17:40 -0700117 video_send_config_ = VideoSendStream::Config(nullptr);
118 video_send_config_.encoder_settings.encoder = &fake_encoder_;
119 video_send_config_.encoder_settings.payload_name = "FAKE";
120 video_send_config_.encoder_settings.payload_type = 125;
121
Per512ecb32016-09-23 15:52:06 +0200122 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700123 test::FillEncoderConfiguration(1, &video_encoder_config);
Erik Språng08127a92016-11-16 16:41:30 +0100124 video_encoder_config_ = video_encoder_config.Copy();
asapersson5f7226f2016-11-25 04:37:00 -0800125 ConfigureEncoder(std::move(video_encoder_config), true /* nack_enabled */);
126 }
127
128 void ConfigureEncoder(VideoEncoderConfig video_encoder_config,
129 bool nack_enabled) {
130 if (vie_encoder_)
131 vie_encoder_->Stop();
perkj803d97f2016-11-01 11:45:46 -0700132 vie_encoder_.reset(new ViEEncoderUnderTest(
133 stats_proxy_.get(), video_send_config_.encoder_settings));
134 vie_encoder_->SetSink(&sink_, false /* rotation_applied */);
135 vie_encoder_->SetSource(&video_source_,
136 VideoSendStream::DegradationPreference::kBalanced);
perkj26091b12016-09-01 01:17:40 -0700137 vie_encoder_->SetStartBitrate(10000);
asapersson5f7226f2016-11-25 04:37:00 -0800138 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
139 kMaxPayloadLength, nack_enabled);
140 }
141
142 void ResetEncoder(const std::string& payload_name,
143 size_t num_streams,
144 size_t num_temporal_layers,
asapersson4eb03c72016-12-02 08:57:55 -0800145 unsigned char num_spatial_layers,
asapersson5f7226f2016-11-25 04:37:00 -0800146 bool nack_enabled) {
147 video_send_config_.encoder_settings.payload_name = payload_name;
148
149 VideoEncoderConfig video_encoder_config;
150 video_encoder_config.number_of_streams = num_streams;
151 video_encoder_config.max_bitrate_bps = 1000000;
152 video_encoder_config.video_stream_factory =
153 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers);
asapersson4eb03c72016-12-02 08:57:55 -0800154 if (payload_name == "VP9") {
155 VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
156 vp9_settings.numberOfSpatialLayers = num_spatial_layers;
157 video_encoder_config.encoder_specific_settings =
158 new rtc::RefCountedObject<
159 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings);
160 }
asapersson5f7226f2016-11-25 04:37:00 -0800161 ConfigureEncoder(std::move(video_encoder_config), nack_enabled);
perkj26091b12016-09-01 01:17:40 -0700162 }
163
164 VideoFrame CreateFrame(int64_t ntp_ts, rtc::Event* destruction_event) const {
Per512ecb32016-09-23 15:52:06 +0200165 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
166 destruction_event, codec_width_, codec_height_),
167 99, 99, kVideoRotation_0);
perkj26091b12016-09-01 01:17:40 -0700168 frame.set_ntp_time_ms(ntp_ts);
169 return frame;
170 }
171
perkj803d97f2016-11-01 11:45:46 -0700172 VideoFrame CreateFrame(int64_t ntp_ts, int width, int height) const {
173 VideoFrame frame(
174 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99,
175 kVideoRotation_0);
176 frame.set_ntp_time_ms(ntp_ts);
177 return frame;
178 }
179
perkj26091b12016-09-01 01:17:40 -0700180 class TestEncoder : public test::FakeEncoder {
181 public:
182 TestEncoder()
183 : FakeEncoder(Clock::GetRealTimeClock()),
184 continue_encode_event_(false, false) {}
185
perkjfa10b552016-10-02 23:45:26 -0700186 VideoCodec codec_config() {
187 rtc::CritScope lock(&crit_);
188 return config_;
189 }
190
191 void BlockNextEncode() {
192 rtc::CritScope lock(&crit_);
193 block_next_encode_ = true;
194 }
195
kthelgason876222f2016-11-29 01:44:11 -0800196 VideoEncoder::ScalingSettings GetScalingSettings() const override {
197 return VideoEncoder::ScalingSettings(true, 1, 2);
198 }
199
perkjfa10b552016-10-02 23:45:26 -0700200 void ContinueEncode() { continue_encode_event_.Set(); }
201
202 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
203 uint32_t timestamp) const {
204 rtc::CritScope lock(&crit_);
205 EXPECT_EQ(timestamp_, timestamp);
206 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
207 }
208
209 private:
perkj26091b12016-09-01 01:17:40 -0700210 int32_t Encode(const VideoFrame& input_image,
211 const CodecSpecificInfo* codec_specific_info,
212 const std::vector<FrameType>* frame_types) override {
213 bool block_encode;
214 {
215 rtc::CritScope lock(&crit_);
216 EXPECT_GT(input_image.timestamp(), timestamp_);
217 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
218 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
219
220 timestamp_ = input_image.timestamp();
221 ntp_time_ms_ = input_image.ntp_time_ms();
perkj803d97f2016-11-01 11:45:46 -0700222 last_input_width_ = input_image.width();
223 last_input_height_ = input_image.height();
perkj26091b12016-09-01 01:17:40 -0700224 block_encode = block_next_encode_;
225 block_next_encode_ = false;
226 }
227 int32_t result =
228 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
229 if (block_encode)
perkja49cbd32016-09-16 07:53:41 -0700230 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700231 return result;
232 }
233
perkj26091b12016-09-01 01:17:40 -0700234 rtc::CriticalSection crit_;
235 bool block_next_encode_ = false;
236 rtc::Event continue_encode_event_;
237 uint32_t timestamp_ = 0;
238 int64_t ntp_time_ms_ = 0;
perkj803d97f2016-11-01 11:45:46 -0700239 int last_input_width_ = 0;
240 int last_input_height_ = 0;
perkj26091b12016-09-01 01:17:40 -0700241 };
242
Per512ecb32016-09-23 15:52:06 +0200243 class TestSink : public ViEEncoder::EncoderSink {
perkj26091b12016-09-01 01:17:40 -0700244 public:
245 explicit TestSink(TestEncoder* test_encoder)
246 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
247
perkj26091b12016-09-01 01:17:40 -0700248 void WaitForEncodedFrame(int64_t expected_ntp_time) {
249 uint32_t timestamp = 0;
perkja49cbd32016-09-16 07:53:41 -0700250 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700251 {
252 rtc::CritScope lock(&crit_);
253 timestamp = timestamp_;
254 }
255 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
256 }
257
258 void SetExpectNoFrames() {
259 rtc::CritScope lock(&crit_);
260 expect_frames_ = false;
261 }
262
Per512ecb32016-09-23 15:52:06 +0200263 int number_of_reconfigurations() {
264 rtc::CritScope lock(&crit_);
265 return number_of_reconfigurations_;
266 }
267
268 int last_min_transmit_bitrate() {
269 rtc::CritScope lock(&crit_);
270 return min_transmit_bitrate_bps_;
271 }
272
perkj26091b12016-09-01 01:17:40 -0700273 private:
sergeyu2cb155a2016-11-04 11:39:29 -0700274 Result OnEncodedImage(
275 const EncodedImage& encoded_image,
276 const CodecSpecificInfo* codec_specific_info,
277 const RTPFragmentationHeader* fragmentation) override {
Per512ecb32016-09-23 15:52:06 +0200278 rtc::CritScope lock(&crit_);
279 EXPECT_TRUE(expect_frames_);
280 timestamp_ = encoded_image._timeStamp;
281 encoded_frame_event_.Set();
sergeyu2cb155a2016-11-04 11:39:29 -0700282 return Result(Result::OK, timestamp_);
Per512ecb32016-09-23 15:52:06 +0200283 }
284
285 void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
286 int min_transmit_bitrate_bps) override {
287 rtc::CriticalSection crit_;
288 ++number_of_reconfigurations_;
289 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
290 }
291
perkj26091b12016-09-01 01:17:40 -0700292 rtc::CriticalSection crit_;
293 TestEncoder* test_encoder_;
294 rtc::Event encoded_frame_event_;
295 uint32_t timestamp_ = 0;
296 bool expect_frames_ = true;
Per512ecb32016-09-23 15:52:06 +0200297 int number_of_reconfigurations_ = 0;
298 int min_transmit_bitrate_bps_ = 0;
perkj26091b12016-09-01 01:17:40 -0700299 };
300
301 VideoSendStream::Config video_send_config_;
Erik Språng08127a92016-11-16 16:41:30 +0100302 VideoEncoderConfig video_encoder_config_;
Per512ecb32016-09-23 15:52:06 +0200303 int codec_width_;
304 int codec_height_;
perkj26091b12016-09-01 01:17:40 -0700305 TestEncoder fake_encoder_;
perkj803d97f2016-11-01 11:45:46 -0700306 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
perkj26091b12016-09-01 01:17:40 -0700307 TestSink sink_;
perkja49cbd32016-09-16 07:53:41 -0700308 test::FrameForwarder video_source_;
perkj803d97f2016-11-01 11:45:46 -0700309 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
perkj26091b12016-09-01 01:17:40 -0700310};
311
312TEST_F(ViEEncoderTest, EncodeOneFrame) {
perkj26091b12016-09-01 01:17:40 -0700313 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
314 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700315 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
perkj26091b12016-09-01 01:17:40 -0700316 sink_.WaitForEncodedFrame(1);
perkja49cbd32016-09-16 07:53:41 -0700317 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700318 vie_encoder_->Stop();
319}
320
321TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
322 // Dropped since no target bitrate has been set.
323 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700324 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
325 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700326
perkj26091b12016-09-01 01:17:40 -0700327 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
328
perkja49cbd32016-09-16 07:53:41 -0700329 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700330 sink_.WaitForEncodedFrame(2);
331 vie_encoder_->Stop();
332}
333
334TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
perkj26091b12016-09-01 01:17:40 -0700335 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700336 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700337 sink_.WaitForEncodedFrame(1);
338
339 vie_encoder_->OnBitrateUpdated(0, 0, 0);
340 // Dropped since bitrate is zero.
perkja49cbd32016-09-16 07:53:41 -0700341 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700342
343 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700344 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700345 sink_.WaitForEncodedFrame(3);
346 vie_encoder_->Stop();
347}
348
349TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
perkj26091b12016-09-01 01:17:40 -0700350 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
perkja49cbd32016-09-16 07:53:41 -0700351 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700352 sink_.WaitForEncodedFrame(1);
353
354 // This frame will be dropped since it has the same ntp timestamp.
perkja49cbd32016-09-16 07:53:41 -0700355 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700356
perkja49cbd32016-09-16 07:53:41 -0700357 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
perkj26091b12016-09-01 01:17:40 -0700358 sink_.WaitForEncodedFrame(2);
359 vie_encoder_->Stop();
360}
361
362TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
perkj26091b12016-09-01 01:17:40 -0700363 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
364
perkja49cbd32016-09-16 07:53:41 -0700365 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700366 sink_.WaitForEncodedFrame(1);
367
368 vie_encoder_->Stop();
369 sink_.SetExpectNoFrames();
370 rtc::Event frame_destroyed_event(false, false);
perkja49cbd32016-09-16 07:53:41 -0700371 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
372 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
perkj26091b12016-09-01 01:17:40 -0700373}
374
375TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
perkj26091b12016-09-01 01:17:40 -0700376 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
377
378 fake_encoder_.BlockNextEncode();
perkja49cbd32016-09-16 07:53:41 -0700379 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
perkj26091b12016-09-01 01:17:40 -0700380 sink_.WaitForEncodedFrame(1);
381 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
382 // call to ContinueEncode.
perkja49cbd32016-09-16 07:53:41 -0700383 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
384 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
perkj26091b12016-09-01 01:17:40 -0700385 fake_encoder_.ContinueEncode();
386 sink_.WaitForEncodedFrame(3);
387
388 vie_encoder_->Stop();
389}
390
Per512ecb32016-09-23 15:52:06 +0200391TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
Per512ecb32016-09-23 15:52:06 +0200392 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
Per21d45d22016-10-30 21:37:57 +0100393 EXPECT_EQ(0, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200394
395 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200396 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
Per512ecb32016-09-23 15:52:06 +0200397 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100398 // The encoder will have been configured once when the first frame is
399 // received.
400 EXPECT_EQ(1, sink_.number_of_reconfigurations());
Per512ecb32016-09-23 15:52:06 +0200401
402 VideoEncoderConfig video_encoder_config;
perkjfa10b552016-10-02 23:45:26 -0700403 test::FillEncoderConfiguration(1, &video_encoder_config);
Per512ecb32016-09-23 15:52:06 +0200404 video_encoder_config.min_transmit_bitrate_bps = 9999;
asapersson5f7226f2016-11-25 04:37:00 -0800405 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
406 kMaxPayloadLength, true /* nack_enabled */);
Per512ecb32016-09-23 15:52:06 +0200407
408 // Capture a frame and wait for it to synchronize with the encoder thread.
Perf8c5f2b2016-09-23 16:24:55 +0200409 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
Per512ecb32016-09-23 15:52:06 +0200410 sink_.WaitForEncodedFrame(2);
Per21d45d22016-10-30 21:37:57 +0100411 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkj3b703ed2016-09-29 23:25:40 -0700412 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
perkj26105b42016-09-29 22:39:10 -0700413
414 vie_encoder_->Stop();
415}
416
perkjfa10b552016-10-02 23:45:26 -0700417TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
perkjfa10b552016-10-02 23:45:26 -0700418 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
419
420 // Capture a frame and wait for it to synchronize with the encoder thread.
421 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
422 sink_.WaitForEncodedFrame(1);
Per21d45d22016-10-30 21:37:57 +0100423 // The encoder will have been configured once.
424 EXPECT_EQ(1, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700425 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
426 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
427
428 codec_width_ *= 2;
429 codec_height_ *= 2;
430 // Capture a frame with a higher resolution and wait for it to synchronize
431 // with the encoder thread.
432 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
433 sink_.WaitForEncodedFrame(2);
434 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
435 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
Per21d45d22016-10-30 21:37:57 +0100436 EXPECT_EQ(2, sink_.number_of_reconfigurations());
perkjfa10b552016-10-02 23:45:26 -0700437
438 vie_encoder_->Stop();
439}
440
asapersson5f7226f2016-11-25 04:37:00 -0800441TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor1S1TLWithNackEnabled) {
442 const bool kNackEnabled = true;
443 const size_t kNumStreams = 1;
444 const size_t kNumTl = 1;
asapersson4eb03c72016-12-02 08:57:55 -0800445 ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800446 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
447
448 // Capture a frame and wait for it to synchronize with the encoder thread.
449 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
450 sink_.WaitForEncodedFrame(1);
451 // The encoder have been configured once when the first frame is received.
452 EXPECT_EQ(1, sink_.number_of_reconfigurations());
453 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
454 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
455 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
456 // Resilience is off for no temporal layers with nack on.
457 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
458 vie_encoder_->Stop();
459}
460
461TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor2S1TlWithNackEnabled) {
462 const bool kNackEnabled = true;
463 const size_t kNumStreams = 2;
464 const size_t kNumTl = 1;
asapersson4eb03c72016-12-02 08:57:55 -0800465 ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800466 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
467
468 // Capture a frame and wait for it to synchronize with the encoder thread.
469 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
470 sink_.WaitForEncodedFrame(1);
471 // The encoder have been configured once when the first frame is received.
472 EXPECT_EQ(1, sink_.number_of_reconfigurations());
473 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
474 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
475 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
476 // Resilience is off for no temporal layers and >1 streams with nack on.
477 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
478 vie_encoder_->Stop();
479}
480
481TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S1TLWithNackDisabled) {
482 const bool kNackEnabled = false;
483 const size_t kNumStreams = 1;
484 const size_t kNumTl = 1;
asapersson4eb03c72016-12-02 08:57:55 -0800485 ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800486 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
487
488 // Capture a frame and wait for it to synchronize with the encoder thread.
489 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
490 sink_.WaitForEncodedFrame(1);
491 // The encoder have been configured once when the first frame is received.
492 EXPECT_EQ(1, sink_.number_of_reconfigurations());
493 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
494 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
495 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
496 // Resilience is on for no temporal layers with nack off.
497 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
498 vie_encoder_->Stop();
499}
500
501TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S2TlWithNackEnabled) {
502 const bool kNackEnabled = true;
503 const size_t kNumStreams = 1;
504 const size_t kNumTl = 2;
asapersson4eb03c72016-12-02 08:57:55 -0800505 ResetEncoder("VP8", kNumStreams, kNumTl, kNumSlDummy, kNackEnabled);
asapersson5f7226f2016-11-25 04:37:00 -0800506 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
507
508 // Capture a frame and wait for it to synchronize with the encoder thread.
509 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
510 sink_.WaitForEncodedFrame(1);
511 // The encoder have been configured once when the first frame is received.
512 EXPECT_EQ(1, sink_.number_of_reconfigurations());
513 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
514 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
515 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
516 // Resilience is on for temporal layers.
517 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
518 vie_encoder_->Stop();
519}
520
asapersson4eb03c72016-12-02 08:57:55 -0800521TEST_F(ViEEncoderTest, Vp9ResilienceIsOffFor1SL1TLWithNackEnabled) {
522 const bool kNackEnabled = true;
523 const size_t kNumStreams = 1;
524 const size_t kNumTl = 1;
525 const unsigned char kNumSl = 1;
526 ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled);
527 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
528
529 // Capture a frame and wait for it to synchronize with the encoder thread.
530 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
531 sink_.WaitForEncodedFrame(1);
532 // The encoder have been configured once when the first frame is received.
533 EXPECT_EQ(1, sink_.number_of_reconfigurations());
534 EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
535 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
536 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
537 EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
538 // Resilience is off for no spatial and temporal layers with nack on.
539 EXPECT_FALSE(fake_encoder_.codec_config().VP9()->resilienceOn);
540 vie_encoder_->Stop();
541}
542
543TEST_F(ViEEncoderTest, Vp9ResilienceIsOnFor1SL1TLWithNackDisabled) {
544 const bool kNackEnabled = false;
545 const size_t kNumStreams = 1;
546 const size_t kNumTl = 1;
547 const unsigned char kNumSl = 1;
548 ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled);
549 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
550
551 // Capture a frame and wait for it to synchronize with the encoder thread.
552 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
553 sink_.WaitForEncodedFrame(1);
554 // The encoder have been configured once when the first frame is received.
555 EXPECT_EQ(1, sink_.number_of_reconfigurations());
556 EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
557 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
558 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
559 EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
560 // Resilience is on if nack is off.
561 EXPECT_TRUE(fake_encoder_.codec_config().VP9()->resilienceOn);
562 vie_encoder_->Stop();
563}
564
565TEST_F(ViEEncoderTest, Vp9ResilienceIsOnFor2SL1TLWithNackEnabled) {
566 const bool kNackEnabled = true;
567 const size_t kNumStreams = 1;
568 const size_t kNumTl = 1;
569 const unsigned char kNumSl = 2;
570 ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled);
571 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
572
573 // Capture a frame and wait for it to synchronize with the encoder thread.
574 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
575 sink_.WaitForEncodedFrame(1);
576 // The encoder have been configured once when the first frame is received.
577 EXPECT_EQ(1, sink_.number_of_reconfigurations());
578 EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
579 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
580 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
581 EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
582 // Resilience is on for spatial layers.
583 EXPECT_TRUE(fake_encoder_.codec_config().VP9()->resilienceOn);
584 vie_encoder_->Stop();
585}
586
587TEST_F(ViEEncoderTest, Vp9ResilienceIsOnFor1SL2TLWithNackEnabled) {
588 const bool kNackEnabled = true;
589 const size_t kNumStreams = 1;
590 const size_t kNumTl = 2;
591 const unsigned char kNumSl = 1;
592 ResetEncoder("VP9", kNumStreams, kNumTl, kNumSl, kNackEnabled);
593 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
594
595 // Capture a frame and wait for it to synchronize with the encoder thread.
596 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
597 sink_.WaitForEncodedFrame(1);
598 // The encoder have been configured once when the first frame is received.
599 EXPECT_EQ(1, sink_.number_of_reconfigurations());
600 EXPECT_EQ(kVideoCodecVP9, fake_encoder_.codec_config().codecType);
601 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
602 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP9()->numberOfTemporalLayers);
603 EXPECT_EQ(kNumSl, fake_encoder_.codec_config().VP9()->numberOfSpatialLayers);
604 // Resilience is on for temporal layers.
605 EXPECT_TRUE(fake_encoder_.codec_config().VP9()->resilienceOn);
606 vie_encoder_->Stop();
607}
608
perkj803d97f2016-11-01 11:45:46 -0700609TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
610 EXPECT_TRUE(video_source_.has_sinks());
611 test::FrameForwarder new_video_source;
612 vie_encoder_->SetSource(&new_video_source,
613 VideoSendStream::DegradationPreference::kBalanced);
614 EXPECT_FALSE(video_source_.has_sinks());
615 EXPECT_TRUE(new_video_source.has_sinks());
616
617 vie_encoder_->Stop();
618}
619
620TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
621 EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
622 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/);
623 EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
624 vie_encoder_->Stop();
625}
626
627TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
perkj803d97f2016-11-01 11:45:46 -0700628 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
629
630 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
631 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
632
633 int frame_width = 1280;
634 int frame_height = 720;
635
636 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
637 // request lower resolution.
638 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) {
639 video_source_.IncomingCapturedFrame(
640 CreateFrame(i, frame_width, frame_height));
641 sink_.WaitForEncodedFrame(i);
642
643 vie_encoder_->TriggerCpuOveruse();
644
645 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
646 std::numeric_limits<int>::max()),
647 frame_width * frame_height);
648 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
649
650 frame_width /= 2;
651 frame_height /= 2;
652 }
653
kthelgason876222f2016-11-29 01:44:11 -0800654 // Trigger CPU overuse one more time. This should not trigger a request for
perkj803d97f2016-11-01 11:45:46 -0700655 // lower resolution.
656 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
657 video_source_.IncomingCapturedFrame(CreateFrame(
658 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
659 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
660 vie_encoder_->TriggerCpuOveruse();
661 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
662 current_wants.max_pixel_count);
663 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
664 current_wants.max_pixel_count_step_up);
665
666 // Trigger CPU normal use.
667 vie_encoder_->TriggerCpuNormalUsage();
668 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
669 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
670 frame_width * frame_height);
671
672 vie_encoder_->Stop();
673}
674
675TEST_F(ViEEncoderTest,
676 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) {
perkj803d97f2016-11-01 11:45:46 -0700677 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
678
679 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
680 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
681
682 int frame_width = 1280;
683 int frame_height = 720;
684
kthelgason5e13d412016-12-01 03:59:51 -0800685 video_source_.IncomingCapturedFrame(
686 CreateFrame(1, frame_width, frame_height));
687 sink_.WaitForEncodedFrame(1);
perkj803d97f2016-11-01 11:45:46 -0700688 // Trigger CPU overuse.
689 vie_encoder_->TriggerCpuOveruse();
690
691 video_source_.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800692 CreateFrame(2, frame_width, frame_height));
693 sink_.WaitForEncodedFrame(2);
perkj803d97f2016-11-01 11:45:46 -0700694 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
695 std::numeric_limits<int>::max()),
696 frame_width * frame_height);
697 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
698
699 // Set new source.
700 test::FrameForwarder new_video_source;
701 vie_encoder_->SetSource(
702 &new_video_source,
703 VideoSendStream::DegradationPreference::kMaintainResolution);
704
705 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
706 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
707
708 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -0800709 CreateFrame(3, frame_width, frame_height));
710 sink_.WaitForEncodedFrame(3);
perkj803d97f2016-11-01 11:45:46 -0700711 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
712 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
713
714 // Calling SetSource with resolution scaling enabled apply the old SinkWants.
715 vie_encoder_->SetSource(&new_video_source,
716 VideoSendStream::DegradationPreference::kBalanced);
717 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or(
718 std::numeric_limits<int>::max()),
719 frame_width * frame_height);
720 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
721
722 vie_encoder_->Stop();
723}
724
725TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -0700726 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
727
728 int frame_width = 1280;
729 int frame_height = 720;
730
731 video_source_.IncomingCapturedFrame(
732 CreateFrame(1, frame_width, frame_height));
733 sink_.WaitForEncodedFrame(1);
734 VideoSendStream::Stats stats = stats_proxy_->GetStats();
735 EXPECT_FALSE(stats.cpu_limited_resolution);
736 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
737
738 // Trigger CPU overuse.
739 vie_encoder_->TriggerCpuOveruse();
740 video_source_.IncomingCapturedFrame(
741 CreateFrame(2, frame_width, frame_height));
742 sink_.WaitForEncodedFrame(2);
743
744 stats = stats_proxy_->GetStats();
745 EXPECT_TRUE(stats.cpu_limited_resolution);
746 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
747
748 // Trigger CPU normal use.
749 vie_encoder_->TriggerCpuNormalUsage();
750 video_source_.IncomingCapturedFrame(
751 CreateFrame(3, frame_width, frame_height));
752 sink_.WaitForEncodedFrame(3);
753
754 stats = stats_proxy_->GetStats();
755 EXPECT_FALSE(stats.cpu_limited_resolution);
756 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
757
758 vie_encoder_->Stop();
759}
760
kthelgason876222f2016-11-29 01:44:11 -0800761TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
762 const int kTargetBitrateBps = 100000;
763 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
764
765 int frame_width = 1280;
766 int frame_height = 720;
767 video_source_.IncomingCapturedFrame(
768 CreateFrame(1, frame_width, frame_height));
769 sink_.WaitForEncodedFrame(1);
770
771 VideoSendStream::Stats stats = stats_proxy_->GetStats();
772 EXPECT_FALSE(stats.cpu_limited_resolution);
773 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
774
775 vie_encoder_->TriggerCpuOveruse();
776
777 video_source_.IncomingCapturedFrame(
778 CreateFrame(2, frame_width, frame_height));
779 sink_.WaitForEncodedFrame(2);
780 stats = stats_proxy_->GetStats();
781 EXPECT_TRUE(stats.cpu_limited_resolution);
782 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
783
784 // Set new source with adaptation still enabled.
785 test::FrameForwarder new_video_source;
786 vie_encoder_->SetSource(&new_video_source,
787 VideoSendStream::DegradationPreference::kBalanced);
788
789 new_video_source.IncomingCapturedFrame(
790 CreateFrame(3, frame_width, frame_height));
791 sink_.WaitForEncodedFrame(3);
792 stats = stats_proxy_->GetStats();
793 EXPECT_TRUE(stats.cpu_limited_resolution);
794 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
795
796 // Set adaptation disabled.
797 vie_encoder_->SetSource(
798 &new_video_source,
799 VideoSendStream::DegradationPreference::kMaintainResolution);
800
801 new_video_source.IncomingCapturedFrame(
802 CreateFrame(4, frame_width, frame_height));
803 sink_.WaitForEncodedFrame(4);
804 stats = stats_proxy_->GetStats();
805 EXPECT_FALSE(stats.cpu_limited_resolution);
806 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
807
808 // Set adaptation back to enabled.
809 vie_encoder_->SetSource(&new_video_source,
810 VideoSendStream::DegradationPreference::kBalanced);
811
812 new_video_source.IncomingCapturedFrame(
813 CreateFrame(5, frame_width, frame_height));
814 sink_.WaitForEncodedFrame(5);
815 stats = stats_proxy_->GetStats();
816 EXPECT_TRUE(stats.cpu_limited_resolution);
817 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
818
819 vie_encoder_->TriggerCpuNormalUsage();
820
821 new_video_source.IncomingCapturedFrame(
822 CreateFrame(6, frame_width, frame_height));
823 sink_.WaitForEncodedFrame(6);
824 stats = stats_proxy_->GetStats();
825 EXPECT_FALSE(stats.cpu_limited_resolution);
826 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
827
828 vie_encoder_->Stop();
829}
830
831TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
832 const int kTargetBitrateBps = 100000;
833 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
834
835 int frame_width = 1280;
836 int frame_height = 720;
837 video_source_.IncomingCapturedFrame(
838 CreateFrame(1, frame_width, frame_height));
839 sink_.WaitForEncodedFrame(1);
840
841 VideoSendStream::Stats stats = stats_proxy_->GetStats();
842 EXPECT_FALSE(stats.cpu_limited_resolution);
843 EXPECT_FALSE(stats.bw_limited_resolution);
844 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
845
846 // Set new source with adaptation still enabled.
847 test::FrameForwarder new_video_source;
848 vie_encoder_->SetSource(&new_video_source,
849 VideoSendStream::DegradationPreference::kBalanced);
850
851 new_video_source.IncomingCapturedFrame(
852 CreateFrame(2, frame_width, frame_height));
853 sink_.WaitForEncodedFrame(2);
854 stats = stats_proxy_->GetStats();
855 EXPECT_FALSE(stats.cpu_limited_resolution);
856 EXPECT_FALSE(stats.bw_limited_resolution);
857 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
858
859 vie_encoder_->TriggerQualityLow();
860
861 new_video_source.IncomingCapturedFrame(
862 CreateFrame(3, frame_width, frame_height));
863 sink_.WaitForEncodedFrame(3);
864 stats = stats_proxy_->GetStats();
865 EXPECT_FALSE(stats.cpu_limited_resolution);
866 EXPECT_TRUE(stats.bw_limited_resolution);
867
868 vie_encoder_->SetSource(&new_video_source,
869 VideoSendStream::DegradationPreference::kBalanced);
870
871 new_video_source.IncomingCapturedFrame(
872 CreateFrame(4, frame_width, frame_height));
873 sink_.WaitForEncodedFrame(4);
874 stats = stats_proxy_->GetStats();
875 EXPECT_FALSE(stats.cpu_limited_resolution);
876 EXPECT_TRUE(stats.bw_limited_resolution);
877
878 // Set adaptation disabled.
879 vie_encoder_->SetSource(
880 &new_video_source,
881 VideoSendStream::DegradationPreference::kMaintainResolution);
882
883 new_video_source.IncomingCapturedFrame(
884 CreateFrame(5, frame_width, frame_height));
885 sink_.WaitForEncodedFrame(5);
886 stats = stats_proxy_->GetStats();
887 EXPECT_FALSE(stats.cpu_limited_resolution);
888 EXPECT_FALSE(stats.bw_limited_resolution);
889
890 vie_encoder_->Stop();
891}
892
perkj803d97f2016-11-01 11:45:46 -0700893TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
perkj803d97f2016-11-01 11:45:46 -0700894 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
895
896 // Trigger CPU overuse.
897 vie_encoder_->TriggerCpuOveruse();
898 int frame_width = 1280;
899 int frame_height = 720;
900
901 video_source_.IncomingCapturedFrame(
902 CreateFrame(1, frame_width, frame_height));
903 sink_.WaitForEncodedFrame(1);
904
905 VideoSendStream::Stats stats = stats_proxy_->GetStats();
906 EXPECT_TRUE(stats.cpu_limited_resolution);
907 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
908
909 // Set new source with adaptation still enabled.
910 test::FrameForwarder new_video_source;
911 vie_encoder_->SetSource(&new_video_source,
912 VideoSendStream::DegradationPreference::kBalanced);
913
914 new_video_source.IncomingCapturedFrame(
915 CreateFrame(2, frame_width, frame_height));
916 sink_.WaitForEncodedFrame(2);
917 stats = stats_proxy_->GetStats();
918 EXPECT_TRUE(stats.cpu_limited_resolution);
919 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
920
921 // Set adaptation disabled.
922 vie_encoder_->SetSource(
923 &new_video_source,
924 VideoSendStream::DegradationPreference::kMaintainResolution);
925 new_video_source.IncomingCapturedFrame(
926 CreateFrame(3, frame_width, frame_height));
927 sink_.WaitForEncodedFrame(3);
928 stats = stats_proxy_->GetStats();
929 EXPECT_FALSE(stats.cpu_limited_resolution);
930 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
931
932 // Switch back the source with adaptation enabled.
933 vie_encoder_->SetSource(&video_source_,
934 VideoSendStream::DegradationPreference::kBalanced);
935 video_source_.IncomingCapturedFrame(
936 CreateFrame(4, frame_width, frame_height));
937 sink_.WaitForEncodedFrame(4);
938 stats = stats_proxy_->GetStats();
939 EXPECT_TRUE(stats.cpu_limited_resolution);
940 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
941
942 // Trigger CPU normal usage.
943 vie_encoder_->TriggerCpuNormalUsage();
944 video_source_.IncomingCapturedFrame(
945 CreateFrame(5, frame_width, frame_height));
946 sink_.WaitForEncodedFrame(5);
947 stats = stats_proxy_->GetStats();
948 EXPECT_FALSE(stats.cpu_limited_resolution);
949 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
950
951 vie_encoder_->Stop();
952}
953
Erik Språng08127a92016-11-16 16:41:30 +0100954TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) {
Erik Språng08127a92016-11-16 16:41:30 +0100955 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
956
957 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
958 sink_.WaitForEncodedFrame(1);
959
960 VideoSendStream::Stats stats = stats_proxy_->GetStats();
961 EXPECT_EQ(video_encoder_config_.max_bitrate_bps,
962 stats.preferred_media_bitrate_bps);
963
964 vie_encoder_->Stop();
965}
966
kthelgason876222f2016-11-29 01:44:11 -0800967TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) {
968 const int kTargetBitrateBps = 100000;
969 int frame_width = 1280;
970 int frame_height = 720;
971 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
972
973 // Expect no scaling to begin with
974 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
975 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
976
kthelgason876222f2016-11-29 01:44:11 -0800977 video_source_.IncomingCapturedFrame(
978 CreateFrame(1, frame_width, frame_height));
979 sink_.WaitForEncodedFrame(1);
980
kthelgason5e13d412016-12-01 03:59:51 -0800981 // Trigger scale down
982 vie_encoder_->TriggerQualityLow();
983
984 video_source_.IncomingCapturedFrame(
985 CreateFrame(2, frame_width, frame_height));
986 sink_.WaitForEncodedFrame(2);
987
kthelgason876222f2016-11-29 01:44:11 -0800988 // Expect a scale down.
989 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count);
990 EXPECT_LT(*video_source_.sink_wants().max_pixel_count,
991 frame_width * frame_height);
992
993 // Set adaptation disabled.
994 test::FrameForwarder new_video_source;
995 vie_encoder_->SetSource(
996 &new_video_source,
997 VideoSendStream::DegradationPreference::kMaintainResolution);
998
999 // Trigger scale down
1000 vie_encoder_->TriggerQualityLow();
1001 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -08001002 CreateFrame(3, frame_width, frame_height));
1003 sink_.WaitForEncodedFrame(3);
kthelgason876222f2016-11-29 01:44:11 -08001004
1005 // Expect no scaling
1006 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
1007
1008 // Trigger scale up
1009 vie_encoder_->TriggerQualityHigh();
1010 new_video_source.IncomingCapturedFrame(
kthelgason5e13d412016-12-01 03:59:51 -08001011 CreateFrame(4, frame_width, frame_height));
1012 sink_.WaitForEncodedFrame(4);
kthelgason876222f2016-11-29 01:44:11 -08001013
1014 // Expect nothing to change, still no scaling
1015 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
1016
1017 vie_encoder_->Stop();
1018}
1019
kthelgason5e13d412016-12-01 03:59:51 -08001020TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) {
1021 const int kTargetBitrateBps = 100000;
1022 int frame_width = 1280;
1023 int frame_height = 720;
kthelgason1cd0a0a2016-12-09 02:30:46 -08001024 // from vie_encoder.cc
1025 const int kMinPixelsPerFrame = 120 * 90;
kthelgason5e13d412016-12-01 03:59:51 -08001026 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
1027
1028 for (size_t i = 1; i <= 10; i++) {
1029 video_source_.IncomingCapturedFrame(
1030 CreateFrame(i, frame_width, frame_height));
1031 sink_.WaitForEncodedFrame(i);
1032 // Trigger scale down
1033 vie_encoder_->TriggerQualityLow();
1034 EXPECT_GE(*video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame);
1035 }
1036
1037 vie_encoder_->Stop();
1038}
1039
perkj803d97f2016-11-01 11:45:46 -07001040TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
perkj803d97f2016-11-01 11:45:46 -07001041 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
1042
1043 int frame_width = 640;
1044 int frame_height = 360;
1045
1046 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1047 video_source_.IncomingCapturedFrame(
1048 CreateFrame(i, frame_width, frame_height));
1049 sink_.WaitForEncodedFrame(i);
1050 }
1051
1052 vie_encoder_->TriggerCpuOveruse();
1053 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1054 video_source_.IncomingCapturedFrame(
1055 CreateFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i,
1056 frame_width, frame_height));
1057 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples +
1058 i);
1059 }
1060
1061 vie_encoder_->Stop();
1062
1063 stats_proxy_.reset();
1064 EXPECT_EQ(1,
1065 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
1066 EXPECT_EQ(
1067 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
1068}
1069
perkj26091b12016-09-01 01:17:40 -07001070} // namespace webrtc