1 /*
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
11 #include <limits>
12 #include <utility>
13
14 #include "webrtc/api/video/i420_buffer.h"
15 #include "webrtc/base/logging.h"
16 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h"
17 #include "webrtc/system_wrappers/include/metrics_default.h"
18 #include "webrtc/system_wrappers/include/sleep.h"
19 #include "webrtc/test/encoder_settings.h"
20 #include "webrtc/test/fake_encoder.h"
21 #include "webrtc/test/frame_generator.h"
22 #include "webrtc/test/gmock.h"
23 #include "webrtc/test/gtest.h"
24 #include "webrtc/video/send_statistics_proxy.h"
25 #include "webrtc/video/vie_encoder.h"
26
27 namespace {
28 #if defined(WEBRTC_ANDROID)
29 // TODO(kthelgason): Lower this limit when better testing
30 // on MediaCodec and fallback implementations are in place.
31 const int kMinPixelsPerFrame = 320 * 180;
32 #else
33 const int kMinPixelsPerFrame = 120 * 90;
34 #endif
35 }
36
37 namespace webrtc {
38
39 using DegredationPreference = VideoSendStream::DegradationPreference;
40 using ScaleReason = ScalingObserverInterface::ScaleReason;
41 using ::testing::_;
42 using ::testing::Return;
43
44 namespace {
45 const size_t kMaxPayloadLength = 1440;
46 const int kTargetBitrateBps = 100000;
47
48 class TestBuffer : public webrtc::I420Buffer {
49 public:
TestBuffer(rtc::Event * event,int width,int height)50 TestBuffer(rtc::Event* event, int width, int height)
51 : I420Buffer(width, height), event_(event) {}
52
53 private:
54 friend class rtc::RefCountedObject<TestBuffer>;
~TestBuffer()55 ~TestBuffer() override {
56 if (event_)
57 event_->Set();
58 }
59 rtc::Event* const event_;
60 };
61
62 class ViEEncoderUnderTest : public ViEEncoder {
63 public:
ViEEncoderUnderTest(SendStatisticsProxy * stats_proxy,const VideoSendStream::Config::EncoderSettings & settings)64 ViEEncoderUnderTest(SendStatisticsProxy* stats_proxy,
65 const VideoSendStream::Config::EncoderSettings& settings)
66 : ViEEncoder(1 /* number_of_cores */,
67 stats_proxy,
68 settings,
69 nullptr /* pre_encode_callback */,
70 nullptr /* encoder_timing */) {}
71
PostTaskAndWait(bool down,ScaleReason reason)72 void PostTaskAndWait(bool down, ScaleReason reason) {
73 rtc::Event event(false, false);
74 encoder_queue()->PostTask([this, &event, reason, down] {
75 down ? ScaleDown(reason) : ScaleUp(reason);
76 event.Set();
77 });
78 RTC_DCHECK(event.Wait(5000));
79 }
80
TriggerCpuOveruse()81 void TriggerCpuOveruse() { PostTaskAndWait(true, ScaleReason::kCpu); }
82
TriggerCpuNormalUsage()83 void TriggerCpuNormalUsage() { PostTaskAndWait(false, ScaleReason::kCpu); }
84
TriggerQualityLow()85 void TriggerQualityLow() { PostTaskAndWait(true, ScaleReason::kQuality); }
86
TriggerQualityHigh()87 void TriggerQualityHigh() { PostTaskAndWait(false, ScaleReason::kQuality); }
88 };
89
90 class VideoStreamFactory
91 : public VideoEncoderConfig::VideoStreamFactoryInterface {
92 public:
VideoStreamFactory(size_t num_temporal_layers)93 explicit VideoStreamFactory(size_t num_temporal_layers)
94 : num_temporal_layers_(num_temporal_layers) {
95 EXPECT_GT(num_temporal_layers, 0u);
96 }
97
98 private:
CreateEncoderStreams(int width,int height,const VideoEncoderConfig & encoder_config)99 std::vector<VideoStream> CreateEncoderStreams(
100 int width,
101 int height,
102 const VideoEncoderConfig& encoder_config) override {
103 std::vector<VideoStream> streams =
104 test::CreateVideoStreams(width, height, encoder_config);
105 for (VideoStream& stream : streams) {
106 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ - 1);
107 }
108 return streams;
109 }
110 const size_t num_temporal_layers_;
111 };
112
113 } // namespace
114
115 class ViEEncoderTest : public ::testing::Test {
116 public:
117 static const int kDefaultTimeoutMs = 30 * 1000;
118
ViEEncoderTest()119 ViEEncoderTest()
120 : video_send_config_(VideoSendStream::Config(nullptr)),
121 codec_width_(320),
122 codec_height_(240),
123 fake_encoder_(),
124 stats_proxy_(new SendStatisticsProxy(
125 Clock::GetRealTimeClock(),
126 video_send_config_,
127 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
128 sink_(&fake_encoder_) {}
129
SetUp()130 void SetUp() override {
131 metrics::Reset();
132 video_send_config_ = VideoSendStream::Config(nullptr);
133 video_send_config_.encoder_settings.encoder = &fake_encoder_;
134 video_send_config_.encoder_settings.payload_name = "FAKE";
135 video_send_config_.encoder_settings.payload_type = 125;
136
137 VideoEncoderConfig video_encoder_config;
138 test::FillEncoderConfiguration(1, &video_encoder_config);
139 video_encoder_config_ = video_encoder_config.Copy();
140 ConfigureEncoder(std::move(video_encoder_config), true /* nack_enabled */);
141 }
142
ConfigureEncoder(VideoEncoderConfig video_encoder_config,bool nack_enabled)143 void ConfigureEncoder(VideoEncoderConfig video_encoder_config,
144 bool nack_enabled) {
145 if (vie_encoder_)
146 vie_encoder_->Stop();
147 vie_encoder_.reset(new ViEEncoderUnderTest(
148 stats_proxy_.get(), video_send_config_.encoder_settings));
149 vie_encoder_->SetSink(&sink_, false /* rotation_applied */);
150 vie_encoder_->SetSource(&video_source_,
151 VideoSendStream::DegradationPreference::kBalanced);
152 vie_encoder_->SetStartBitrate(10000);
153 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
154 kMaxPayloadLength, nack_enabled);
155 }
156
ResetEncoder(const std::string & payload_name,size_t num_streams,size_t num_temporal_layers,bool nack_enabled)157 void ResetEncoder(const std::string& payload_name,
158 size_t num_streams,
159 size_t num_temporal_layers,
160 bool nack_enabled) {
161 video_send_config_.encoder_settings.payload_name = payload_name;
162
163 VideoEncoderConfig video_encoder_config;
164 video_encoder_config.number_of_streams = num_streams;
165 video_encoder_config.max_bitrate_bps = 1000000;
166 video_encoder_config.video_stream_factory =
167 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers);
168 ConfigureEncoder(std::move(video_encoder_config), nack_enabled);
169 }
170
CreateFrame(int64_t ntp_time_ms,rtc::Event * destruction_event) const171 VideoFrame CreateFrame(int64_t ntp_time_ms,
172 rtc::Event* destruction_event) const {
173 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>(
174 destruction_event, codec_width_, codec_height_),
175 99, 99, kVideoRotation_0);
176 frame.set_ntp_time_ms(ntp_time_ms);
177 return frame;
178 }
179
CreateFrame(int64_t ntp_time_ms,int width,int height) const180 VideoFrame CreateFrame(int64_t ntp_time_ms, int width, int height) const {
181 VideoFrame frame(
182 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height), 99, 99,
183 kVideoRotation_0);
184 frame.set_ntp_time_ms(ntp_time_ms);
185 return frame;
186 }
187
188 class TestEncoder : public test::FakeEncoder {
189 public:
TestEncoder()190 TestEncoder()
191 : FakeEncoder(Clock::GetRealTimeClock()),
192 continue_encode_event_(false, false) {}
193
codec_config()194 VideoCodec codec_config() {
195 rtc::CritScope lock(&crit_sect_);
196 return config_;
197 }
198
BlockNextEncode()199 void BlockNextEncode() {
200 rtc::CritScope lock(&local_crit_sect_);
201 block_next_encode_ = true;
202 }
203
GetScalingSettings() const204 VideoEncoder::ScalingSettings GetScalingSettings() const override {
205 return VideoEncoder::ScalingSettings(true, 1, 2);
206 }
207
ContinueEncode()208 void ContinueEncode() { continue_encode_event_.Set(); }
209
CheckLastTimeStampsMatch(int64_t ntp_time_ms,uint32_t timestamp) const210 void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
211 uint32_t timestamp) const {
212 rtc::CritScope lock(&local_crit_sect_);
213 EXPECT_EQ(timestamp_, timestamp);
214 EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
215 }
216
217 private:
Encode(const VideoFrame & input_image,const CodecSpecificInfo * codec_specific_info,const std::vector<FrameType> * frame_types)218 int32_t Encode(const VideoFrame& input_image,
219 const CodecSpecificInfo* codec_specific_info,
220 const std::vector<FrameType>* frame_types) override {
221 bool block_encode;
222 {
223 rtc::CritScope lock(&local_crit_sect_);
224 EXPECT_GT(input_image.timestamp(), timestamp_);
225 EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
226 EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
227
228 timestamp_ = input_image.timestamp();
229 ntp_time_ms_ = input_image.ntp_time_ms();
230 last_input_width_ = input_image.width();
231 last_input_height_ = input_image.height();
232 block_encode = block_next_encode_;
233 block_next_encode_ = false;
234 }
235 int32_t result =
236 FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
237 if (block_encode)
238 EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
239 return result;
240 }
241
242 rtc::CriticalSection local_crit_sect_;
243 bool block_next_encode_ = false;
244 rtc::Event continue_encode_event_;
245 uint32_t timestamp_ = 0;
246 int64_t ntp_time_ms_ = 0;
247 int last_input_width_ = 0;
248 int last_input_height_ = 0;
249 };
250
251 class TestSink : public ViEEncoder::EncoderSink {
252 public:
TestSink(TestEncoder * test_encoder)253 explicit TestSink(TestEncoder* test_encoder)
254 : test_encoder_(test_encoder), encoded_frame_event_(false, false) {}
255
WaitForEncodedFrame(int64_t expected_ntp_time)256 void WaitForEncodedFrame(int64_t expected_ntp_time) {
257 uint32_t timestamp = 0;
258 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
259 {
260 rtc::CritScope lock(&crit_);
261 timestamp = timestamp_;
262 }
263 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
264 }
265
SetExpectNoFrames()266 void SetExpectNoFrames() {
267 rtc::CritScope lock(&crit_);
268 expect_frames_ = false;
269 }
270
number_of_reconfigurations()271 int number_of_reconfigurations() {
272 rtc::CritScope lock(&crit_);
273 return number_of_reconfigurations_;
274 }
275
last_min_transmit_bitrate()276 int last_min_transmit_bitrate() {
277 rtc::CritScope lock(&crit_);
278 return min_transmit_bitrate_bps_;
279 }
280
281 private:
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)282 Result OnEncodedImage(
283 const EncodedImage& encoded_image,
284 const CodecSpecificInfo* codec_specific_info,
285 const RTPFragmentationHeader* fragmentation) override {
286 rtc::CritScope lock(&crit_);
287 EXPECT_TRUE(expect_frames_);
288 timestamp_ = encoded_image._timeStamp;
289 encoded_frame_event_.Set();
290 return Result(Result::OK, timestamp_);
291 }
292
OnEncoderConfigurationChanged(std::vector<VideoStream> streams,int min_transmit_bitrate_bps)293 void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
294 int min_transmit_bitrate_bps) override {
295 rtc::CriticalSection crit_;
296 ++number_of_reconfigurations_;
297 min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
298 }
299
300 rtc::CriticalSection crit_;
301 TestEncoder* test_encoder_;
302 rtc::Event encoded_frame_event_;
303 uint32_t timestamp_ = 0;
304 bool expect_frames_ = true;
305 int number_of_reconfigurations_ = 0;
306 int min_transmit_bitrate_bps_ = 0;
307 };
308
309 VideoSendStream::Config video_send_config_;
310 VideoEncoderConfig video_encoder_config_;
311 int codec_width_;
312 int codec_height_;
313 TestEncoder fake_encoder_;
314 std::unique_ptr<SendStatisticsProxy> stats_proxy_;
315 TestSink sink_;
316 test::FrameForwarder video_source_;
317 std::unique_ptr<ViEEncoderUnderTest> vie_encoder_;
318 };
319
TEST_F(ViEEncoderTest,EncodeOneFrame)320 TEST_F(ViEEncoderTest, EncodeOneFrame) {
321 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
322 rtc::Event frame_destroyed_event(false, false);
323 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
324 sink_.WaitForEncodedFrame(1);
325 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
326 vie_encoder_->Stop();
327 }
328
TEST_F(ViEEncoderTest,DropsFramesBeforeFirstOnBitrateUpdated)329 TEST_F(ViEEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
330 // Dropped since no target bitrate has been set.
331 rtc::Event frame_destroyed_event(false, false);
332 video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
333 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
334
335 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
336
337 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
338 sink_.WaitForEncodedFrame(2);
339 vie_encoder_->Stop();
340 }
341
TEST_F(ViEEncoderTest,DropsFramesWhenRateSetToZero)342 TEST_F(ViEEncoderTest, DropsFramesWhenRateSetToZero) {
343 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
344 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
345 sink_.WaitForEncodedFrame(1);
346
347 vie_encoder_->OnBitrateUpdated(0, 0, 0);
348 // Dropped since bitrate is zero.
349 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
350
351 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
352 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
353 sink_.WaitForEncodedFrame(3);
354 vie_encoder_->Stop();
355 }
356
TEST_F(ViEEncoderTest,DropsFramesWithSameOrOldNtpTimestamp)357 TEST_F(ViEEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
358 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
359 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
360 sink_.WaitForEncodedFrame(1);
361
362 // This frame will be dropped since it has the same ntp timestamp.
363 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
364
365 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
366 sink_.WaitForEncodedFrame(2);
367 vie_encoder_->Stop();
368 }
369
TEST_F(ViEEncoderTest,DropsFrameAfterStop)370 TEST_F(ViEEncoderTest, DropsFrameAfterStop) {
371 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
372
373 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
374 sink_.WaitForEncodedFrame(1);
375
376 vie_encoder_->Stop();
377 sink_.SetExpectNoFrames();
378 rtc::Event frame_destroyed_event(false, false);
379 video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
380 EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
381 }
382
TEST_F(ViEEncoderTest,DropsPendingFramesOnSlowEncode)383 TEST_F(ViEEncoderTest, DropsPendingFramesOnSlowEncode) {
384 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
385
386 fake_encoder_.BlockNextEncode();
387 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
388 sink_.WaitForEncodedFrame(1);
389 // Here, the encoder thread will be blocked in the TestEncoder waiting for a
390 // call to ContinueEncode.
391 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
392 video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
393 fake_encoder_.ContinueEncode();
394 sink_.WaitForEncodedFrame(3);
395
396 vie_encoder_->Stop();
397 }
398
TEST_F(ViEEncoderTest,ConfigureEncoderTriggersOnEncoderConfigurationChanged)399 TEST_F(ViEEncoderTest, ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
400 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
401 EXPECT_EQ(0, sink_.number_of_reconfigurations());
402
403 // Capture a frame and wait for it to synchronize with the encoder thread.
404 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
405 sink_.WaitForEncodedFrame(1);
406 // The encoder will have been configured once when the first frame is
407 // received.
408 EXPECT_EQ(1, sink_.number_of_reconfigurations());
409
410 VideoEncoderConfig video_encoder_config;
411 test::FillEncoderConfiguration(1, &video_encoder_config);
412 video_encoder_config.min_transmit_bitrate_bps = 9999;
413 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config),
414 kMaxPayloadLength, true /* nack_enabled */);
415
416 // Capture a frame and wait for it to synchronize with the encoder thread.
417 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
418 sink_.WaitForEncodedFrame(2);
419 EXPECT_EQ(2, sink_.number_of_reconfigurations());
420 EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
421
422 vie_encoder_->Stop();
423 }
424
TEST_F(ViEEncoderTest,FrameResolutionChangeReconfigureEncoder)425 TEST_F(ViEEncoderTest, FrameResolutionChangeReconfigureEncoder) {
426 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
427
428 // Capture a frame and wait for it to synchronize with the encoder thread.
429 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
430 sink_.WaitForEncodedFrame(1);
431 // The encoder will have been configured once.
432 EXPECT_EQ(1, sink_.number_of_reconfigurations());
433 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
434 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
435
436 codec_width_ *= 2;
437 codec_height_ *= 2;
438 // Capture a frame with a higher resolution and wait for it to synchronize
439 // with the encoder thread.
440 video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
441 sink_.WaitForEncodedFrame(2);
442 EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
443 EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
444 EXPECT_EQ(2, sink_.number_of_reconfigurations());
445
446 vie_encoder_->Stop();
447 }
448
TEST_F(ViEEncoderTest,Vp8ResilienceIsOffFor1S1TLWithNackEnabled)449 TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor1S1TLWithNackEnabled) {
450 const bool kNackEnabled = true;
451 const size_t kNumStreams = 1;
452 const size_t kNumTl = 1;
453 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
454 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
455
456 // Capture a frame and wait for it to synchronize with the encoder thread.
457 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
458 sink_.WaitForEncodedFrame(1);
459 // The encoder have been configured once when the first frame is received.
460 EXPECT_EQ(1, sink_.number_of_reconfigurations());
461 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
462 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
463 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
464 // Resilience is off for no temporal layers with nack on.
465 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
466 vie_encoder_->Stop();
467 }
468
TEST_F(ViEEncoderTest,Vp8ResilienceIsOffFor2S1TlWithNackEnabled)469 TEST_F(ViEEncoderTest, Vp8ResilienceIsOffFor2S1TlWithNackEnabled) {
470 const bool kNackEnabled = true;
471 const size_t kNumStreams = 2;
472 const size_t kNumTl = 1;
473 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
474 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
475
476 // Capture a frame and wait for it to synchronize with the encoder thread.
477 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
478 sink_.WaitForEncodedFrame(1);
479 // The encoder have been configured once when the first frame is received.
480 EXPECT_EQ(1, sink_.number_of_reconfigurations());
481 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
482 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
483 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
484 // Resilience is off for no temporal layers and >1 streams with nack on.
485 EXPECT_EQ(kResilienceOff, fake_encoder_.codec_config().VP8()->resilience);
486 vie_encoder_->Stop();
487 }
488
TEST_F(ViEEncoderTest,Vp8ResilienceIsOnFor1S1TLWithNackDisabled)489 TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S1TLWithNackDisabled) {
490 const bool kNackEnabled = false;
491 const size_t kNumStreams = 1;
492 const size_t kNumTl = 1;
493 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
494 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
495
496 // Capture a frame and wait for it to synchronize with the encoder thread.
497 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
498 sink_.WaitForEncodedFrame(1);
499 // The encoder have been configured once when the first frame is received.
500 EXPECT_EQ(1, sink_.number_of_reconfigurations());
501 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
502 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
503 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
504 // Resilience is on for no temporal layers with nack off.
505 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
506 vie_encoder_->Stop();
507 }
508
TEST_F(ViEEncoderTest,Vp8ResilienceIsOnFor1S2TlWithNackEnabled)509 TEST_F(ViEEncoderTest, Vp8ResilienceIsOnFor1S2TlWithNackEnabled) {
510 const bool kNackEnabled = true;
511 const size_t kNumStreams = 1;
512 const size_t kNumTl = 2;
513 ResetEncoder("VP8", kNumStreams, kNumTl, kNackEnabled);
514 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
515
516 // Capture a frame and wait for it to synchronize with the encoder thread.
517 video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
518 sink_.WaitForEncodedFrame(1);
519 // The encoder have been configured once when the first frame is received.
520 EXPECT_EQ(1, sink_.number_of_reconfigurations());
521 EXPECT_EQ(kVideoCodecVP8, fake_encoder_.codec_config().codecType);
522 EXPECT_EQ(kNumStreams, fake_encoder_.codec_config().numberOfSimulcastStreams);
523 EXPECT_EQ(kNumTl, fake_encoder_.codec_config().VP8()->numberOfTemporalLayers);
524 // Resilience is on for temporal layers.
525 EXPECT_EQ(kResilientStream, fake_encoder_.codec_config().VP8()->resilience);
526 vie_encoder_->Stop();
527 }
528
TEST_F(ViEEncoderTest,SwitchSourceDeregisterEncoderAsSink)529 TEST_F(ViEEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
530 EXPECT_TRUE(video_source_.has_sinks());
531 test::FrameForwarder new_video_source;
532 vie_encoder_->SetSource(&new_video_source,
533 VideoSendStream::DegradationPreference::kBalanced);
534 EXPECT_FALSE(video_source_.has_sinks());
535 EXPECT_TRUE(new_video_source.has_sinks());
536
537 vie_encoder_->Stop();
538 }
539
TEST_F(ViEEncoderTest,SinkWantsRotationApplied)540 TEST_F(ViEEncoderTest, SinkWantsRotationApplied) {
541 EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
542 vie_encoder_->SetSink(&sink_, true /*rotation_applied*/);
543 EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
544 vie_encoder_->Stop();
545 }
546
TEST_F(ViEEncoderTest,SinkWantsFromOveruseDetector)547 TEST_F(ViEEncoderTest, SinkWantsFromOveruseDetector) {
548 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
549
550 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
551 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
552
553 int frame_width = 1280;
554 int frame_height = 720;
555
556 // Trigger CPU overuse kMaxCpuDowngrades times. Every time, ViEEncoder should
557 // request lower resolution.
558 for (int i = 1; i <= ViEEncoder::kMaxCpuDowngrades; ++i) {
559 video_source_.IncomingCapturedFrame(
560 CreateFrame(i, frame_width, frame_height));
561 sink_.WaitForEncodedFrame(i);
562
563 vie_encoder_->TriggerCpuOveruse();
564
565 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
566 std::numeric_limits<int>::max()),
567 frame_width * frame_height);
568 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
569
570 frame_width /= 2;
571 frame_height /= 2;
572 }
573
574 // Trigger CPU overuse one more time. This should not trigger a request for
575 // lower resolution.
576 rtc::VideoSinkWants current_wants = video_source_.sink_wants();
577 video_source_.IncomingCapturedFrame(CreateFrame(
578 ViEEncoder::kMaxCpuDowngrades + 1, frame_width, frame_height));
579 sink_.WaitForEncodedFrame(ViEEncoder::kMaxCpuDowngrades + 1);
580 vie_encoder_->TriggerCpuOveruse();
581 EXPECT_EQ(video_source_.sink_wants().max_pixel_count,
582 current_wants.max_pixel_count);
583 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up,
584 current_wants.max_pixel_count_step_up);
585
586 // Trigger CPU normal use.
587 vie_encoder_->TriggerCpuNormalUsage();
588 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
589 EXPECT_EQ(video_source_.sink_wants().max_pixel_count_step_up.value_or(0),
590 frame_width * frame_height);
591
592 vie_encoder_->Stop();
593 }
594
TEST_F(ViEEncoderTest,ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling)595 TEST_F(ViEEncoderTest,
596 ResolutionSinkWantsResetOnSetSourceWithDisabledResolutionScaling) {
597 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
598
599 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
600 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
601
602 int frame_width = 1280;
603 int frame_height = 720;
604
605 video_source_.IncomingCapturedFrame(
606 CreateFrame(1, frame_width, frame_height));
607 sink_.WaitForEncodedFrame(1);
608 // Trigger CPU overuse.
609 vie_encoder_->TriggerCpuOveruse();
610
611 video_source_.IncomingCapturedFrame(
612 CreateFrame(2, frame_width, frame_height));
613 sink_.WaitForEncodedFrame(2);
614 EXPECT_LT(video_source_.sink_wants().max_pixel_count.value_or(
615 std::numeric_limits<int>::max()),
616 frame_width * frame_height);
617 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
618
619 // Set new source.
620 test::FrameForwarder new_video_source;
621 vie_encoder_->SetSource(
622 &new_video_source,
623 VideoSendStream::DegradationPreference::kMaintainResolution);
624
625 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 new_video_source.IncomingCapturedFrame(
629 CreateFrame(3, frame_width, frame_height));
630 sink_.WaitForEncodedFrame(3);
631 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
632 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
633
634 // Calling SetSource with resolution scaling enabled apply the old SinkWants.
635 vie_encoder_->SetSource(&new_video_source,
636 VideoSendStream::DegradationPreference::kBalanced);
637 EXPECT_LT(new_video_source.sink_wants().max_pixel_count.value_or(
638 std::numeric_limits<int>::max()),
639 frame_width * frame_height);
640 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count_step_up);
641
642 vie_encoder_->Stop();
643 }
644
TEST_F(ViEEncoderTest,StatsTracksAdaptationStats)645 TEST_F(ViEEncoderTest, StatsTracksAdaptationStats) {
646 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
647
648 int frame_width = 1280;
649 int frame_height = 720;
650
651 video_source_.IncomingCapturedFrame(
652 CreateFrame(1, frame_width, frame_height));
653 sink_.WaitForEncodedFrame(1);
654 VideoSendStream::Stats stats = stats_proxy_->GetStats();
655 EXPECT_FALSE(stats.cpu_limited_resolution);
656 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
657
658 // Trigger CPU overuse.
659 vie_encoder_->TriggerCpuOveruse();
660 video_source_.IncomingCapturedFrame(
661 CreateFrame(2, frame_width, frame_height));
662 sink_.WaitForEncodedFrame(2);
663
664 stats = stats_proxy_->GetStats();
665 EXPECT_TRUE(stats.cpu_limited_resolution);
666 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
667
668 // Trigger CPU normal use.
669 vie_encoder_->TriggerCpuNormalUsage();
670 video_source_.IncomingCapturedFrame(
671 CreateFrame(3, frame_width, frame_height));
672 sink_.WaitForEncodedFrame(3);
673
674 stats = stats_proxy_->GetStats();
675 EXPECT_FALSE(stats.cpu_limited_resolution);
676 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
677
678 vie_encoder_->Stop();
679 }
680
TEST_F(ViEEncoderTest,SwitchingSourceKeepsCpuAdaptation)681 TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
682 const int kTargetBitrateBps = 100000;
683 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
684
685 int frame_width = 1280;
686 int frame_height = 720;
687 video_source_.IncomingCapturedFrame(
688 CreateFrame(1, frame_width, frame_height));
689 sink_.WaitForEncodedFrame(1);
690
691 VideoSendStream::Stats stats = stats_proxy_->GetStats();
692 EXPECT_FALSE(stats.cpu_limited_resolution);
693 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
694
695 vie_encoder_->TriggerCpuOveruse();
696
697 video_source_.IncomingCapturedFrame(
698 CreateFrame(2, frame_width, frame_height));
699 sink_.WaitForEncodedFrame(2);
700 stats = stats_proxy_->GetStats();
701 EXPECT_TRUE(stats.cpu_limited_resolution);
702 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
703
704 // Set new source with adaptation still enabled.
705 test::FrameForwarder new_video_source;
706 vie_encoder_->SetSource(&new_video_source,
707 VideoSendStream::DegradationPreference::kBalanced);
708
709 new_video_source.IncomingCapturedFrame(
710 CreateFrame(3, frame_width, frame_height));
711 sink_.WaitForEncodedFrame(3);
712 stats = stats_proxy_->GetStats();
713 EXPECT_TRUE(stats.cpu_limited_resolution);
714 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
715
716 // Set adaptation disabled.
717 vie_encoder_->SetSource(
718 &new_video_source,
719 VideoSendStream::DegradationPreference::kMaintainResolution);
720
721 new_video_source.IncomingCapturedFrame(
722 CreateFrame(4, frame_width, frame_height));
723 sink_.WaitForEncodedFrame(4);
724 stats = stats_proxy_->GetStats();
725 EXPECT_FALSE(stats.cpu_limited_resolution);
726 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
727
728 // Set adaptation back to enabled.
729 vie_encoder_->SetSource(&new_video_source,
730 VideoSendStream::DegradationPreference::kBalanced);
731
732 new_video_source.IncomingCapturedFrame(
733 CreateFrame(5, frame_width, frame_height));
734 sink_.WaitForEncodedFrame(5);
735 stats = stats_proxy_->GetStats();
736 EXPECT_TRUE(stats.cpu_limited_resolution);
737 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
738
739 vie_encoder_->TriggerCpuNormalUsage();
740
741 new_video_source.IncomingCapturedFrame(
742 CreateFrame(6, frame_width, frame_height));
743 sink_.WaitForEncodedFrame(6);
744 stats = stats_proxy_->GetStats();
745 EXPECT_FALSE(stats.cpu_limited_resolution);
746 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
747
748 vie_encoder_->Stop();
749 }
750
TEST_F(ViEEncoderTest,SwitchingSourceKeepsQualityAdaptation)751 TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
752 const int kTargetBitrateBps = 100000;
753 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
754
755 int frame_width = 1280;
756 int frame_height = 720;
757 video_source_.IncomingCapturedFrame(
758 CreateFrame(1, frame_width, frame_height));
759 sink_.WaitForEncodedFrame(1);
760
761 VideoSendStream::Stats stats = stats_proxy_->GetStats();
762 EXPECT_FALSE(stats.cpu_limited_resolution);
763 EXPECT_FALSE(stats.bw_limited_resolution);
764 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
765
766 // Set new source with adaptation still enabled.
767 test::FrameForwarder new_video_source;
768 vie_encoder_->SetSource(&new_video_source,
769 VideoSendStream::DegradationPreference::kBalanced);
770
771 new_video_source.IncomingCapturedFrame(
772 CreateFrame(2, frame_width, frame_height));
773 sink_.WaitForEncodedFrame(2);
774 stats = stats_proxy_->GetStats();
775 EXPECT_FALSE(stats.cpu_limited_resolution);
776 EXPECT_FALSE(stats.bw_limited_resolution);
777 EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
778
779 vie_encoder_->TriggerQualityLow();
780
781 new_video_source.IncomingCapturedFrame(
782 CreateFrame(3, frame_width, frame_height));
783 sink_.WaitForEncodedFrame(3);
784 stats = stats_proxy_->GetStats();
785 EXPECT_FALSE(stats.cpu_limited_resolution);
786 EXPECT_TRUE(stats.bw_limited_resolution);
787
788 vie_encoder_->SetSource(&new_video_source,
789 VideoSendStream::DegradationPreference::kBalanced);
790
791 new_video_source.IncomingCapturedFrame(
792 CreateFrame(4, frame_width, frame_height));
793 sink_.WaitForEncodedFrame(4);
794 stats = stats_proxy_->GetStats();
795 EXPECT_FALSE(stats.cpu_limited_resolution);
796 EXPECT_TRUE(stats.bw_limited_resolution);
797
798 // Set adaptation disabled.
799 vie_encoder_->SetSource(
800 &new_video_source,
801 VideoSendStream::DegradationPreference::kMaintainResolution);
802
803 new_video_source.IncomingCapturedFrame(
804 CreateFrame(5, frame_width, frame_height));
805 sink_.WaitForEncodedFrame(5);
806 stats = stats_proxy_->GetStats();
807 EXPECT_FALSE(stats.cpu_limited_resolution);
808 EXPECT_FALSE(stats.bw_limited_resolution);
809
810 vie_encoder_->Stop();
811 }
812
TEST_F(ViEEncoderTest,StatsTracksAdaptationStatsWhenSwitchingSource)813 TEST_F(ViEEncoderTest, StatsTracksAdaptationStatsWhenSwitchingSource) {
814 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
815
816 // Trigger CPU overuse.
817 vie_encoder_->TriggerCpuOveruse();
818 int frame_width = 1280;
819 int frame_height = 720;
820
821 video_source_.IncomingCapturedFrame(
822 CreateFrame(1, frame_width, frame_height));
823 sink_.WaitForEncodedFrame(1);
824
825 VideoSendStream::Stats stats = stats_proxy_->GetStats();
826 EXPECT_TRUE(stats.cpu_limited_resolution);
827 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
828
829 // Set new source with adaptation still enabled.
830 test::FrameForwarder new_video_source;
831 vie_encoder_->SetSource(&new_video_source,
832 VideoSendStream::DegradationPreference::kBalanced);
833
834 new_video_source.IncomingCapturedFrame(
835 CreateFrame(2, frame_width, frame_height));
836 sink_.WaitForEncodedFrame(2);
837 stats = stats_proxy_->GetStats();
838 EXPECT_TRUE(stats.cpu_limited_resolution);
839 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
840
841 // Set adaptation disabled.
842 vie_encoder_->SetSource(
843 &new_video_source,
844 VideoSendStream::DegradationPreference::kMaintainResolution);
845 new_video_source.IncomingCapturedFrame(
846 CreateFrame(3, frame_width, frame_height));
847 sink_.WaitForEncodedFrame(3);
848 stats = stats_proxy_->GetStats();
849 EXPECT_FALSE(stats.cpu_limited_resolution);
850 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
851
852 // Switch back the source with adaptation enabled.
853 vie_encoder_->SetSource(&video_source_,
854 VideoSendStream::DegradationPreference::kBalanced);
855 video_source_.IncomingCapturedFrame(
856 CreateFrame(4, frame_width, frame_height));
857 sink_.WaitForEncodedFrame(4);
858 stats = stats_proxy_->GetStats();
859 EXPECT_TRUE(stats.cpu_limited_resolution);
860 EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
861
862 // Trigger CPU normal usage.
863 vie_encoder_->TriggerCpuNormalUsage();
864 video_source_.IncomingCapturedFrame(
865 CreateFrame(5, frame_width, frame_height));
866 sink_.WaitForEncodedFrame(5);
867 stats = stats_proxy_->GetStats();
868 EXPECT_FALSE(stats.cpu_limited_resolution);
869 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
870
871 vie_encoder_->Stop();
872 }
873
TEST_F(ViEEncoderTest,StatsTracksPreferredBitrate)874 TEST_F(ViEEncoderTest, StatsTracksPreferredBitrate) {
875 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
876
877 video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
878 sink_.WaitForEncodedFrame(1);
879
880 VideoSendStream::Stats stats = stats_proxy_->GetStats();
881 EXPECT_EQ(video_encoder_config_.max_bitrate_bps,
882 stats.preferred_media_bitrate_bps);
883
884 vie_encoder_->Stop();
885 }
886
TEST_F(ViEEncoderTest,ScalingUpAndDownDoesNothingWithMaintainResolution)887 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) {
888 const int kTargetBitrateBps = 100000;
889 int frame_width = 1280;
890 int frame_height = 720;
891 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
892
893 // Expect no scaling to begin with
894 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count);
895 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up);
896
897 video_source_.IncomingCapturedFrame(
898 CreateFrame(1, frame_width, frame_height));
899 sink_.WaitForEncodedFrame(1);
900
901 // Trigger scale down
902 vie_encoder_->TriggerQualityLow();
903
904 video_source_.IncomingCapturedFrame(
905 CreateFrame(2, frame_width, frame_height));
906 sink_.WaitForEncodedFrame(2);
907
908 // Expect a scale down.
909 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count);
910 EXPECT_LT(*video_source_.sink_wants().max_pixel_count,
911 frame_width * frame_height);
912
913 // Set adaptation disabled.
914 test::FrameForwarder new_video_source;
915 vie_encoder_->SetSource(
916 &new_video_source,
917 VideoSendStream::DegradationPreference::kMaintainResolution);
918
919 // Trigger scale down
920 vie_encoder_->TriggerQualityLow();
921 new_video_source.IncomingCapturedFrame(
922 CreateFrame(3, frame_width, frame_height));
923 sink_.WaitForEncodedFrame(3);
924
925 // Expect no scaling
926 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
927
928 // Trigger scale up
929 vie_encoder_->TriggerQualityHigh();
930 new_video_source.IncomingCapturedFrame(
931 CreateFrame(4, frame_width, frame_height));
932 sink_.WaitForEncodedFrame(4);
933
934 // Expect nothing to change, still no scaling
935 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count);
936
937 vie_encoder_->Stop();
938 }
939
TEST_F(ViEEncoderTest,DoesNotScaleBelowSetLimit)940 TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) {
941 const int kTargetBitrateBps = 100000;
942 int frame_width = 1280;
943 int frame_height = 720;
944 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
945
946 for (size_t i = 1; i <= 10; i++) {
947 video_source_.IncomingCapturedFrame(
948 CreateFrame(i, frame_width, frame_height));
949 sink_.WaitForEncodedFrame(i);
950 // Trigger scale down
951 vie_encoder_->TriggerQualityLow();
952 EXPECT_GE(*video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame);
953 }
954
955 vie_encoder_->Stop();
956 }
957
TEST_F(ViEEncoderTest,UMACpuLimitedResolutionInPercent)958 TEST_F(ViEEncoderTest, UMACpuLimitedResolutionInPercent) {
959 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
960
961 int frame_width = 640;
962 int frame_height = 360;
963
964 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
965 video_source_.IncomingCapturedFrame(
966 CreateFrame(i, frame_width, frame_height));
967 sink_.WaitForEncodedFrame(i);
968 }
969
970 vie_encoder_->TriggerCpuOveruse();
971 for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
972 video_source_.IncomingCapturedFrame(
973 CreateFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i,
974 frame_width, frame_height));
975 sink_.WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples +
976 i);
977 }
978
979 vie_encoder_->Stop();
980
981 stats_proxy_.reset();
982 EXPECT_EQ(1,
983 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
984 EXPECT_EQ(
985 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
986 }
987
TEST_F(ViEEncoderTest,CallsBitrateObserver)988 TEST_F(ViEEncoderTest, CallsBitrateObserver) {
989 class MockBitrateObserver : public VideoBitrateAllocationObserver {
990 public:
991 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const BitrateAllocation&));
992 } bitrate_observer;
993 vie_encoder_->SetBitrateObserver(&bitrate_observer);
994
995 const int kDefaultFps = 30;
996 const BitrateAllocation expected_bitrate =
997 DefaultVideoBitrateAllocator(fake_encoder_.codec_config())
998 .GetAllocation(kTargetBitrateBps, kDefaultFps);
999
1000 // First called on bitrate updated, then again on first frame.
1001 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
1002 .Times(2);
1003 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0);
1004
1005 const int64_t kStartTimeMs = 1;
1006 video_source_.IncomingCapturedFrame(
1007 CreateFrame(kStartTimeMs, codec_width_, codec_height_));
1008 sink_.WaitForEncodedFrame(kStartTimeMs);
1009
1010 // Not called on second frame.
1011 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
1012 .Times(0);
1013 video_source_.IncomingCapturedFrame(
1014 CreateFrame(kStartTimeMs + 1, codec_width_, codec_height_));
1015 sink_.WaitForEncodedFrame(kStartTimeMs + 1);
1016
1017 // Called after a process interval.
1018 const int64_t kProcessIntervalMs =
1019 vcm::VCMProcessTimer::kDefaultProcessIntervalMs;
1020 // TODO(sprang): ViEEncoder should die and/or get injectable clock.
1021 // Sleep for one processing interval plus one frame to avoid flakiness.
1022 SleepMs(kProcessIntervalMs + 1000 / kDefaultFps);
1023 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
1024 .Times(1);
1025 video_source_.IncomingCapturedFrame(CreateFrame(
1026 kStartTimeMs + kProcessIntervalMs, codec_width_, codec_height_));
1027 sink_.WaitForEncodedFrame(kStartTimeMs + kProcessIntervalMs);
1028
1029 vie_encoder_->Stop();
1030 }
1031
1032 } // namespace webrtc
1033