• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "video/video_stream_encoder.h"
12 
13 #include <algorithm>
14 #include <limits>
15 #include <memory>
16 #include <utility>
17 
18 #include "absl/memory/memory.h"
19 #include "api/task_queue/default_task_queue_factory.h"
20 #include "api/test/mock_fec_controller_override.h"
21 #include "api/test/mock_video_encoder.h"
22 #include "api/video/builtin_video_bitrate_allocator_factory.h"
23 #include "api/video/i420_buffer.h"
24 #include "api/video/video_adaptation_reason.h"
25 #include "api/video/video_bitrate_allocation.h"
26 #include "api/video_codecs/video_encoder.h"
27 #include "api/video_codecs/vp8_temporal_layers.h"
28 #include "api/video_codecs/vp8_temporal_layers_factory.h"
29 #include "call/adaptation/test/fake_adaptation_constraint.h"
30 #include "call/adaptation/test/fake_adaptation_listener.h"
31 #include "call/adaptation/test/fake_resource.h"
32 #include "common_video/h264/h264_common.h"
33 #include "common_video/include/video_frame_buffer.h"
34 #include "media/base/video_adapter.h"
35 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
36 #include "modules/video_coding/utility/quality_scaler.h"
37 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
38 #include "rtc_base/fake_clock.h"
39 #include "rtc_base/gunit.h"
40 #include "rtc_base/logging.h"
41 #include "rtc_base/ref_counted_object.h"
42 #include "rtc_base/synchronization/mutex.h"
43 #include "system_wrappers/include/field_trial.h"
44 #include "system_wrappers/include/metrics.h"
45 #include "system_wrappers/include/sleep.h"
46 #include "test/encoder_settings.h"
47 #include "test/fake_encoder.h"
48 #include "test/field_trial.h"
49 #include "test/frame_forwarder.h"
50 #include "test/gmock.h"
51 #include "test/gtest.h"
52 #include "test/video_encoder_proxy_factory.h"
53 #include "video/send_statistics_proxy.h"
54 
55 namespace webrtc {
56 
57 using ::testing::_;
58 using ::testing::AllOf;
59 using ::testing::Eq;
60 using ::testing::Field;
61 using ::testing::Ge;
62 using ::testing::Gt;
63 using ::testing::Le;
64 using ::testing::Lt;
65 using ::testing::Matcher;
66 using ::testing::NiceMock;
67 using ::testing::Return;
68 using ::testing::StrictMock;
69 
70 namespace {
71 const int kMinPixelsPerFrame = 320 * 180;
72 const int kQpLow = 1;
73 const int kQpHigh = 2;
74 const int kMinFramerateFps = 2;
75 const int kMinBalancedFramerateFps = 7;
76 const int64_t kFrameTimeoutMs = 100;
77 const size_t kMaxPayloadLength = 1440;
78 const uint32_t kTargetBitrateBps = 1000000;
79 const uint32_t kStartBitrateBps = 600000;
80 const uint32_t kSimulcastTargetBitrateBps = 3150000;
81 const uint32_t kLowTargetBitrateBps = kTargetBitrateBps / 10;
82 const int kMaxInitialFramedrop = 4;
83 const int kDefaultFramerate = 30;
84 const int64_t kFrameIntervalMs = rtc::kNumMillisecsPerSec / kDefaultFramerate;
85 const int64_t kProcessIntervalMs = 1000;
86 const VideoEncoder::ResolutionBitrateLimits
87     kEncoderBitrateLimits540p(960 * 540, 100 * 1000, 100 * 1000, 2000 * 1000);
88 const VideoEncoder::ResolutionBitrateLimits
89     kEncoderBitrateLimits720p(1280 * 720, 200 * 1000, 200 * 1000, 4000 * 1000);
90 
91 uint8_t optimal_sps[] = {0,    0,    0,    1,    H264::NaluType::kSps,
92                          0x00, 0x00, 0x03, 0x03, 0xF4,
93                          0x05, 0x03, 0xC7, 0xE0, 0x1B,
94                          0x41, 0x10, 0x8D, 0x00};
95 
96 class TestBuffer : public webrtc::I420Buffer {
97  public:
TestBuffer(rtc::Event * event,int width,int height)98   TestBuffer(rtc::Event* event, int width, int height)
99       : I420Buffer(width, height), event_(event) {}
100 
101  private:
102   friend class rtc::RefCountedObject<TestBuffer>;
~TestBuffer()103   ~TestBuffer() override {
104     if (event_)
105       event_->Set();
106   }
107   rtc::Event* const event_;
108 };
109 
110 // A fake native buffer that can't be converted to I420.
111 class FakeNativeBuffer : public webrtc::VideoFrameBuffer {
112  public:
FakeNativeBuffer(rtc::Event * event,int width,int height)113   FakeNativeBuffer(rtc::Event* event, int width, int height)
114       : event_(event), width_(width), height_(height) {}
type() const115   webrtc::VideoFrameBuffer::Type type() const override { return Type::kNative; }
width() const116   int width() const override { return width_; }
height() const117   int height() const override { return height_; }
ToI420()118   rtc::scoped_refptr<webrtc::I420BufferInterface> ToI420() override {
119     return nullptr;
120   }
121 
122  private:
123   friend class rtc::RefCountedObject<FakeNativeBuffer>;
~FakeNativeBuffer()124   ~FakeNativeBuffer() override {
125     if (event_)
126       event_->Set();
127   }
128   rtc::Event* const event_;
129   const int width_;
130   const int height_;
131 };
132 
133 class CpuOveruseDetectorProxy : public OveruseFrameDetector {
134  public:
CpuOveruseDetectorProxy(CpuOveruseMetricsObserver * metrics_observer)135   explicit CpuOveruseDetectorProxy(CpuOveruseMetricsObserver* metrics_observer)
136       : OveruseFrameDetector(metrics_observer),
137         last_target_framerate_fps_(-1),
138         framerate_updated_event_(true /* manual_reset */,
139                                  false /* initially_signaled */) {}
~CpuOveruseDetectorProxy()140   virtual ~CpuOveruseDetectorProxy() {}
141 
OnTargetFramerateUpdated(int framerate_fps)142   void OnTargetFramerateUpdated(int framerate_fps) override {
143     MutexLock lock(&lock_);
144     last_target_framerate_fps_ = framerate_fps;
145     OveruseFrameDetector::OnTargetFramerateUpdated(framerate_fps);
146     framerate_updated_event_.Set();
147   }
148 
GetLastTargetFramerate()149   int GetLastTargetFramerate() {
150     MutexLock lock(&lock_);
151     return last_target_framerate_fps_;
152   }
153 
GetOptions()154   CpuOveruseOptions GetOptions() { return options_; }
155 
framerate_updated_event()156   rtc::Event* framerate_updated_event() { return &framerate_updated_event_; }
157 
158  private:
159   Mutex lock_;
160   int last_target_framerate_fps_ RTC_GUARDED_BY(lock_);
161   rtc::Event framerate_updated_event_;
162 };
163 
164 class FakeQualityScalerQpUsageHandlerCallback
165     : public QualityScalerQpUsageHandlerCallbackInterface {
166  public:
FakeQualityScalerQpUsageHandlerCallback()167   FakeQualityScalerQpUsageHandlerCallback()
168       : QualityScalerQpUsageHandlerCallbackInterface(),
169         qp_usage_handled_event_(/*manual_reset=*/true,
170                                 /*initially_signaled=*/false),
171         clear_qp_samples_result_(absl::nullopt) {}
~FakeQualityScalerQpUsageHandlerCallback()172   ~FakeQualityScalerQpUsageHandlerCallback() override {
173     RTC_DCHECK(clear_qp_samples_result_.has_value());
174   }
175 
OnQpUsageHandled(bool clear_qp_samples)176   void OnQpUsageHandled(bool clear_qp_samples) override {
177     clear_qp_samples_result_ = clear_qp_samples;
178     qp_usage_handled_event_.Set();
179   }
180 
WaitForQpUsageHandled()181   bool WaitForQpUsageHandled() { return qp_usage_handled_event_.Wait(5000); }
182 
clear_qp_samples_result() const183   absl::optional<bool> clear_qp_samples_result() const {
184     return clear_qp_samples_result_;
185   }
186 
187  private:
188   rtc::Event qp_usage_handled_event_;
189   absl::optional<bool> clear_qp_samples_result_;
190 };
191 
192 class FakeVideoSourceRestrictionsListener
193     : public VideoSourceRestrictionsListener {
194  public:
FakeVideoSourceRestrictionsListener()195   FakeVideoSourceRestrictionsListener()
196       : was_restrictions_updated_(false), restrictions_updated_event_() {}
~FakeVideoSourceRestrictionsListener()197   ~FakeVideoSourceRestrictionsListener() override {
198     RTC_DCHECK(was_restrictions_updated_);
199   }
200 
restrictions_updated_event()201   rtc::Event* restrictions_updated_event() {
202     return &restrictions_updated_event_;
203   }
204 
205   // VideoSourceRestrictionsListener implementation.
OnVideoSourceRestrictionsUpdated(VideoSourceRestrictions restrictions,const VideoAdaptationCounters & adaptation_counters,rtc::scoped_refptr<Resource> reason,const VideoSourceRestrictions & unfiltered_restrictions)206   void OnVideoSourceRestrictionsUpdated(
207       VideoSourceRestrictions restrictions,
208       const VideoAdaptationCounters& adaptation_counters,
209       rtc::scoped_refptr<Resource> reason,
210       const VideoSourceRestrictions& unfiltered_restrictions) override {
211     was_restrictions_updated_ = true;
212     restrictions_updated_event_.Set();
213   }
214 
215  private:
216   bool was_restrictions_updated_;
217   rtc::Event restrictions_updated_event_;
218 };
219 
WantsFps(Matcher<int> fps_matcher)220 auto WantsFps(Matcher<int> fps_matcher) {
221   return Field("max_framerate_fps", &rtc::VideoSinkWants::max_framerate_fps,
222                fps_matcher);
223 }
224 
WantsMaxPixels(Matcher<int> max_pixel_matcher)225 auto WantsMaxPixels(Matcher<int> max_pixel_matcher) {
226   return Field("max_pixel_count", &rtc::VideoSinkWants::max_pixel_count,
227                AllOf(max_pixel_matcher, Gt(0)));
228 }
229 
ResolutionMax()230 auto ResolutionMax() {
231   return AllOf(
232       WantsMaxPixels(Eq(std::numeric_limits<int>::max())),
233       Field("target_pixel_count", &rtc::VideoSinkWants::target_pixel_count,
234             Eq(absl::nullopt)));
235 }
236 
FpsMax()237 auto FpsMax() {
238   return WantsFps(Eq(kDefaultFramerate));
239 }
240 
FpsUnlimited()241 auto FpsUnlimited() {
242   return WantsFps(Eq(std::numeric_limits<int>::max()));
243 }
244 
FpsMatchesResolutionMax(Matcher<int> fps_matcher)245 auto FpsMatchesResolutionMax(Matcher<int> fps_matcher) {
246   return AllOf(WantsFps(fps_matcher), ResolutionMax());
247 }
248 
FpsMaxResolutionMatches(Matcher<int> pixel_matcher)249 auto FpsMaxResolutionMatches(Matcher<int> pixel_matcher) {
250   return AllOf(FpsMax(), WantsMaxPixels(pixel_matcher));
251 }
252 
FpsMaxResolutionMax()253 auto FpsMaxResolutionMax() {
254   return AllOf(FpsMax(), ResolutionMax());
255 }
256 
UnlimitedSinkWants()257 auto UnlimitedSinkWants() {
258   return AllOf(FpsUnlimited(), ResolutionMax());
259 }
260 
FpsInRangeForPixelsInBalanced(int last_frame_pixels)261 auto FpsInRangeForPixelsInBalanced(int last_frame_pixels) {
262   Matcher<int> fps_range_matcher;
263 
264   if (last_frame_pixels <= 320 * 240) {
265     fps_range_matcher = AllOf(Ge(7), Le(10));
266   } else if (last_frame_pixels <= 480 * 270) {
267     fps_range_matcher = AllOf(Ge(10), Le(15));
268   } else if (last_frame_pixels <= 640 * 480) {
269     fps_range_matcher = Ge(15);
270   } else {
271     fps_range_matcher = Eq(kDefaultFramerate);
272   }
273   return Field("max_framerate_fps", &rtc::VideoSinkWants::max_framerate_fps,
274                fps_range_matcher);
275 }
276 
FpsEqResolutionEqTo(const rtc::VideoSinkWants & other_wants)277 auto FpsEqResolutionEqTo(const rtc::VideoSinkWants& other_wants) {
278   return AllOf(WantsFps(Eq(other_wants.max_framerate_fps)),
279                WantsMaxPixels(Eq(other_wants.max_pixel_count)));
280 }
281 
FpsMaxResolutionLt(const rtc::VideoSinkWants & other_wants)282 auto FpsMaxResolutionLt(const rtc::VideoSinkWants& other_wants) {
283   return AllOf(FpsMax(), WantsMaxPixels(Lt(other_wants.max_pixel_count)));
284 }
285 
FpsMaxResolutionGt(const rtc::VideoSinkWants & other_wants)286 auto FpsMaxResolutionGt(const rtc::VideoSinkWants& other_wants) {
287   return AllOf(FpsMax(), WantsMaxPixels(Gt(other_wants.max_pixel_count)));
288 }
289 
FpsLtResolutionEq(const rtc::VideoSinkWants & other_wants)290 auto FpsLtResolutionEq(const rtc::VideoSinkWants& other_wants) {
291   return AllOf(WantsFps(Lt(other_wants.max_framerate_fps)),
292                WantsMaxPixels(Eq(other_wants.max_pixel_count)));
293 }
294 
FpsGtResolutionEq(const rtc::VideoSinkWants & other_wants)295 auto FpsGtResolutionEq(const rtc::VideoSinkWants& other_wants) {
296   return AllOf(WantsFps(Gt(other_wants.max_framerate_fps)),
297                WantsMaxPixels(Eq(other_wants.max_pixel_count)));
298 }
299 
FpsEqResolutionLt(const rtc::VideoSinkWants & other_wants)300 auto FpsEqResolutionLt(const rtc::VideoSinkWants& other_wants) {
301   return AllOf(WantsFps(Eq(other_wants.max_framerate_fps)),
302                WantsMaxPixels(Lt(other_wants.max_pixel_count)));
303 }
304 
FpsEqResolutionGt(const rtc::VideoSinkWants & other_wants)305 auto FpsEqResolutionGt(const rtc::VideoSinkWants& other_wants) {
306   return AllOf(WantsFps(Eq(other_wants.max_framerate_fps)),
307                WantsMaxPixels(Gt(other_wants.max_pixel_count)));
308 }
309 
310 class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
311  public:
VideoStreamEncoderUnderTest(SendStatisticsProxy * stats_proxy,const VideoStreamEncoderSettings & settings,TaskQueueFactory * task_queue_factory)312   VideoStreamEncoderUnderTest(SendStatisticsProxy* stats_proxy,
313                               const VideoStreamEncoderSettings& settings,
314                               TaskQueueFactory* task_queue_factory)
315       : VideoStreamEncoder(Clock::GetRealTimeClock(),
316                            1 /* number_of_cores */,
317                            stats_proxy,
318                            settings,
319                            std::unique_ptr<OveruseFrameDetector>(
320                                overuse_detector_proxy_ =
321                                    new CpuOveruseDetectorProxy(stats_proxy)),
322                            task_queue_factory),
323         fake_cpu_resource_(FakeResource::Create("FakeResource[CPU]")),
324         fake_quality_resource_(FakeResource::Create("FakeResource[QP]")),
325         fake_adaptation_constraint_("FakeAdaptationConstraint") {
326     InjectAdaptationResource(fake_quality_resource_,
327                              VideoAdaptationReason::kQuality);
328     InjectAdaptationResource(fake_cpu_resource_, VideoAdaptationReason::kCpu);
329     InjectAdaptationConstraint(&fake_adaptation_constraint_);
330   }
331 
SetSourceAndWaitForRestrictionsUpdated(rtc::VideoSourceInterface<VideoFrame> * source,const DegradationPreference & degradation_preference)332   void SetSourceAndWaitForRestrictionsUpdated(
333       rtc::VideoSourceInterface<VideoFrame>* source,
334       const DegradationPreference& degradation_preference) {
335     FakeVideoSourceRestrictionsListener listener;
336     AddRestrictionsListenerForTesting(&listener);
337     SetSource(source, degradation_preference);
338     listener.restrictions_updated_event()->Wait(5000);
339     RemoveRestrictionsListenerForTesting(&listener);
340   }
341 
SetSourceAndWaitForFramerateUpdated(rtc::VideoSourceInterface<VideoFrame> * source,const DegradationPreference & degradation_preference)342   void SetSourceAndWaitForFramerateUpdated(
343       rtc::VideoSourceInterface<VideoFrame>* source,
344       const DegradationPreference& degradation_preference) {
345     overuse_detector_proxy_->framerate_updated_event()->Reset();
346     SetSource(source, degradation_preference);
347     overuse_detector_proxy_->framerate_updated_event()->Wait(5000);
348   }
349 
OnBitrateUpdatedAndWaitForManagedResources(DataRate target_bitrate,DataRate stable_target_bitrate,DataRate link_allocation,uint8_t fraction_lost,int64_t round_trip_time_ms,double cwnd_reduce_ratio)350   void OnBitrateUpdatedAndWaitForManagedResources(
351       DataRate target_bitrate,
352       DataRate stable_target_bitrate,
353       DataRate link_allocation,
354       uint8_t fraction_lost,
355       int64_t round_trip_time_ms,
356       double cwnd_reduce_ratio) {
357     OnBitrateUpdated(target_bitrate, stable_target_bitrate, link_allocation,
358                      fraction_lost, round_trip_time_ms, cwnd_reduce_ratio);
359     // Bitrate is updated on the encoder queue.
360     WaitUntilTaskQueueIsIdle();
361     // Give the managed resources time to react to the new bitrate.
362     // TODO(hbos): Can we await an appropriate event instead?
363     WaitUntilAdaptationTaskQueueIsIdle();
364   }
365 
WaitUntilAdaptationTaskQueueIsIdle()366   void WaitUntilAdaptationTaskQueueIsIdle() {
367     rtc::Event event;
368     resource_adaptation_queue()->PostTask([&event] { event.Set(); });
369     ASSERT_TRUE(event.Wait(5000));
370   }
371 
372   // This is used as a synchronisation mechanism, to make sure that the
373   // encoder queue is not blocked before we start sending it frames.
WaitUntilTaskQueueIsIdle()374   void WaitUntilTaskQueueIsIdle() {
375     rtc::Event event;
376     encoder_queue()->PostTask([&event] { event.Set(); });
377     ASSERT_TRUE(event.Wait(5000));
378   }
379 
380   // Triggers resource usage measurements on the fake CPU resource.
TriggerCpuOveruse()381   void TriggerCpuOveruse() {
382     rtc::Event event;
383     resource_adaptation_queue()->PostTask([this, &event] {
384       fake_cpu_resource_->SetUsageState(ResourceUsageState::kOveruse);
385       event.Set();
386     });
387     ASSERT_TRUE(event.Wait(5000));
388   }
TriggerCpuUnderuse()389   void TriggerCpuUnderuse() {
390     rtc::Event event;
391     resource_adaptation_queue()->PostTask([this, &event] {
392       fake_cpu_resource_->SetUsageState(ResourceUsageState::kUnderuse);
393       event.Set();
394     });
395     ASSERT_TRUE(event.Wait(5000));
396   }
397 
398   // Triggers resource usage measurements on the fake quality resource.
TriggerQualityLow()399   void TriggerQualityLow() {
400     rtc::Event event;
401     resource_adaptation_queue()->PostTask([this, &event] {
402       fake_quality_resource_->SetUsageState(ResourceUsageState::kOveruse);
403       event.Set();
404     });
405     ASSERT_TRUE(event.Wait(5000));
406   }
TriggerQualityHigh()407   void TriggerQualityHigh() {
408     rtc::Event event;
409     resource_adaptation_queue()->PostTask([this, &event] {
410       fake_quality_resource_->SetUsageState(ResourceUsageState::kUnderuse);
411       event.Set();
412     });
413     ASSERT_TRUE(event.Wait(5000));
414   }
415 
416   // Fakes high QP resource usage measurements on the real
417   // QualityScalerResource. Returns whether or not QP samples would have been
418   // cleared if this had been a real signal from the QualityScaler.
TriggerQualityScalerHighQpAndReturnIfQpSamplesShouldBeCleared()419   bool TriggerQualityScalerHighQpAndReturnIfQpSamplesShouldBeCleared() {
420     rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback =
421         new FakeQualityScalerQpUsageHandlerCallback();
422     encoder_queue()->PostTask([this, callback] {
423       // This will cause a "ping" between adaptation task queue and encoder
424       // queue. When we have the result, the |callback| will be notified.
425       quality_scaler_resource_for_testing()->OnReportQpUsageHigh(callback);
426     });
427     EXPECT_TRUE(callback->WaitForQpUsageHandled());
428     EXPECT_TRUE(callback->clear_qp_samples_result().has_value());
429     return callback->clear_qp_samples_result().value();
430   }
431 
432   CpuOveruseDetectorProxy* overuse_detector_proxy_;
433   rtc::scoped_refptr<FakeResource> fake_cpu_resource_;
434   rtc::scoped_refptr<FakeResource> fake_quality_resource_;
435   FakeAdaptationConstraint fake_adaptation_constraint_;
436 };
437 
438 class VideoStreamFactory
439     : public VideoEncoderConfig::VideoStreamFactoryInterface {
440  public:
VideoStreamFactory(size_t num_temporal_layers,int framerate)441   explicit VideoStreamFactory(size_t num_temporal_layers, int framerate)
442       : num_temporal_layers_(num_temporal_layers), framerate_(framerate) {
443     EXPECT_GT(num_temporal_layers, 0u);
444     EXPECT_GT(framerate, 0);
445   }
446 
447  private:
CreateEncoderStreams(int width,int height,const VideoEncoderConfig & encoder_config)448   std::vector<VideoStream> CreateEncoderStreams(
449       int width,
450       int height,
451       const VideoEncoderConfig& encoder_config) override {
452     std::vector<VideoStream> streams =
453         test::CreateVideoStreams(width, height, encoder_config);
454     for (VideoStream& stream : streams) {
455       stream.num_temporal_layers = num_temporal_layers_;
456       stream.max_framerate = framerate_;
457     }
458     return streams;
459   }
460 
461   const size_t num_temporal_layers_;
462   const int framerate_;
463 };
464 
465 // Simulates simulcast behavior and makes highest stream resolutions divisible
466 // by 4.
467 class CroppingVideoStreamFactory
468     : public VideoEncoderConfig::VideoStreamFactoryInterface {
469  public:
CroppingVideoStreamFactory(size_t num_temporal_layers,int framerate)470   explicit CroppingVideoStreamFactory(size_t num_temporal_layers, int framerate)
471       : num_temporal_layers_(num_temporal_layers), framerate_(framerate) {
472     EXPECT_GT(num_temporal_layers, 0u);
473     EXPECT_GT(framerate, 0);
474   }
475 
476  private:
CreateEncoderStreams(int width,int height,const VideoEncoderConfig & encoder_config)477   std::vector<VideoStream> CreateEncoderStreams(
478       int width,
479       int height,
480       const VideoEncoderConfig& encoder_config) override {
481     std::vector<VideoStream> streams = test::CreateVideoStreams(
482         width - width % 4, height - height % 4, encoder_config);
483     for (VideoStream& stream : streams) {
484       stream.num_temporal_layers = num_temporal_layers_;
485       stream.max_framerate = framerate_;
486     }
487     return streams;
488   }
489 
490   const size_t num_temporal_layers_;
491   const int framerate_;
492 };
493 
494 class AdaptingFrameForwarder : public test::FrameForwarder {
495  public:
AdaptingFrameForwarder()496   AdaptingFrameForwarder() : adaptation_enabled_(false) {}
~AdaptingFrameForwarder()497   ~AdaptingFrameForwarder() override {}
498 
set_adaptation_enabled(bool enabled)499   void set_adaptation_enabled(bool enabled) {
500     MutexLock lock(&mutex_);
501     adaptation_enabled_ = enabled;
502   }
503 
adaption_enabled() const504   bool adaption_enabled() const {
505     MutexLock lock(&mutex_);
506     return adaptation_enabled_;
507   }
508 
last_wants() const509   rtc::VideoSinkWants last_wants() const {
510     MutexLock lock(&mutex_);
511     return last_wants_;
512   }
513 
last_sent_width() const514   absl::optional<int> last_sent_width() const { return last_width_; }
last_sent_height() const515   absl::optional<int> last_sent_height() const { return last_height_; }
516 
IncomingCapturedFrame(const VideoFrame & video_frame)517   void IncomingCapturedFrame(const VideoFrame& video_frame) override {
518     int cropped_width = 0;
519     int cropped_height = 0;
520     int out_width = 0;
521     int out_height = 0;
522     if (adaption_enabled()) {
523       if (adapter_.AdaptFrameResolution(
524               video_frame.width(), video_frame.height(),
525               video_frame.timestamp_us() * 1000, &cropped_width,
526               &cropped_height, &out_width, &out_height)) {
527         VideoFrame adapted_frame =
528             VideoFrame::Builder()
529                 .set_video_frame_buffer(new rtc::RefCountedObject<TestBuffer>(
530                     nullptr, out_width, out_height))
531                 .set_timestamp_rtp(99)
532                 .set_timestamp_ms(99)
533                 .set_rotation(kVideoRotation_0)
534                 .build();
535         adapted_frame.set_ntp_time_ms(video_frame.ntp_time_ms());
536         if (video_frame.has_update_rect()) {
537           adapted_frame.set_update_rect(
538               video_frame.update_rect().ScaleWithFrame(
539                   video_frame.width(), video_frame.height(), 0, 0,
540                   video_frame.width(), video_frame.height(), out_width,
541                   out_height));
542         }
543         test::FrameForwarder::IncomingCapturedFrame(adapted_frame);
544         last_width_.emplace(adapted_frame.width());
545         last_height_.emplace(adapted_frame.height());
546       } else {
547         last_width_ = absl::nullopt;
548         last_height_ = absl::nullopt;
549       }
550     } else {
551       test::FrameForwarder::IncomingCapturedFrame(video_frame);
552       last_width_.emplace(video_frame.width());
553       last_height_.emplace(video_frame.height());
554     }
555   }
556 
AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame> * sink,const rtc::VideoSinkWants & wants)557   void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
558                        const rtc::VideoSinkWants& wants) override {
559     MutexLock lock(&mutex_);
560     last_wants_ = sink_wants_locked();
561     adapter_.OnSinkWants(wants);
562     test::FrameForwarder::AddOrUpdateSinkLocked(sink, wants);
563   }
564   cricket::VideoAdapter adapter_;
565   bool adaptation_enabled_ RTC_GUARDED_BY(mutex_);
566   rtc::VideoSinkWants last_wants_ RTC_GUARDED_BY(mutex_);
567   absl::optional<int> last_width_;
568   absl::optional<int> last_height_;
569 };
570 
571 // TODO(nisse): Mock only VideoStreamEncoderObserver.
572 class MockableSendStatisticsProxy : public SendStatisticsProxy {
573  public:
MockableSendStatisticsProxy(Clock * clock,const VideoSendStream::Config & config,VideoEncoderConfig::ContentType content_type)574   MockableSendStatisticsProxy(Clock* clock,
575                               const VideoSendStream::Config& config,
576                               VideoEncoderConfig::ContentType content_type)
577       : SendStatisticsProxy(clock, config, content_type) {}
578 
GetStats()579   VideoSendStream::Stats GetStats() override {
580     MutexLock lock(&lock_);
581     if (mock_stats_)
582       return *mock_stats_;
583     return SendStatisticsProxy::GetStats();
584   }
585 
GetInputFrameRate() const586   int GetInputFrameRate() const override {
587     MutexLock lock(&lock_);
588     if (mock_stats_)
589       return mock_stats_->input_frame_rate;
590     return SendStatisticsProxy::GetInputFrameRate();
591   }
SetMockStats(const VideoSendStream::Stats & stats)592   void SetMockStats(const VideoSendStream::Stats& stats) {
593     MutexLock lock(&lock_);
594     mock_stats_.emplace(stats);
595   }
596 
ResetMockStats()597   void ResetMockStats() {
598     MutexLock lock(&lock_);
599     mock_stats_.reset();
600   }
601 
602  private:
603   mutable Mutex lock_;
604   absl::optional<VideoSendStream::Stats> mock_stats_ RTC_GUARDED_BY(lock_);
605 };
606 
607 class MockBitrateObserver : public VideoBitrateAllocationObserver {
608  public:
609   MOCK_METHOD(void,
610               OnBitrateAllocationUpdated,
611               (const VideoBitrateAllocation&),
612               (override));
613 };
614 
615 class MockEncoderSelector
616     : public VideoEncoderFactory::EncoderSelectorInterface {
617  public:
618   MOCK_METHOD(void,
619               OnCurrentEncoder,
620               (const SdpVideoFormat& format),
621               (override));
622   MOCK_METHOD(absl::optional<SdpVideoFormat>,
623               OnAvailableBitrate,
624               (const DataRate& rate),
625               (override));
626   MOCK_METHOD(absl::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
627 };
628 
629 }  // namespace
630 
631 class VideoStreamEncoderTest : public ::testing::Test {
632  public:
633   static const int kDefaultTimeoutMs = 30 * 1000;
634 
VideoStreamEncoderTest()635   VideoStreamEncoderTest()
636       : video_send_config_(VideoSendStream::Config(nullptr)),
637         codec_width_(320),
638         codec_height_(240),
639         max_framerate_(kDefaultFramerate),
640         task_queue_factory_(CreateDefaultTaskQueueFactory()),
641         fake_encoder_(),
642         encoder_factory_(&fake_encoder_),
643         stats_proxy_(new MockableSendStatisticsProxy(
644             Clock::GetRealTimeClock(),
645             video_send_config_,
646             webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo)),
647         sink_(&fake_encoder_) {}
648 
SetUp()649   void SetUp() override {
650     metrics::Reset();
651     video_send_config_ = VideoSendStream::Config(nullptr);
652     video_send_config_.encoder_settings.encoder_factory = &encoder_factory_;
653     video_send_config_.encoder_settings.bitrate_allocator_factory =
654         &bitrate_allocator_factory_;
655     video_send_config_.rtp.payload_name = "FAKE";
656     video_send_config_.rtp.payload_type = 125;
657 
658     VideoEncoderConfig video_encoder_config;
659     test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
660     video_encoder_config.video_stream_factory =
661         new rtc::RefCountedObject<VideoStreamFactory>(1, max_framerate_);
662     video_encoder_config_ = video_encoder_config.Copy();
663 
664     // Framerate limit is specified by the VideoStreamFactory.
665     std::vector<VideoStream> streams =
666         video_encoder_config.video_stream_factory->CreateEncoderStreams(
667             codec_width_, codec_height_, video_encoder_config);
668     max_framerate_ = streams[0].max_framerate;
669     fake_clock_.SetTime(Timestamp::Micros(1234));
670 
671     ConfigureEncoder(std::move(video_encoder_config));
672   }
673 
ConfigureEncoder(VideoEncoderConfig video_encoder_config)674   void ConfigureEncoder(VideoEncoderConfig video_encoder_config) {
675     if (video_stream_encoder_)
676       video_stream_encoder_->Stop();
677     video_stream_encoder_.reset(new VideoStreamEncoderUnderTest(
678         stats_proxy_.get(), video_send_config_.encoder_settings,
679         task_queue_factory_.get()));
680     video_stream_encoder_->SetSink(&sink_, false /* rotation_applied */);
681     video_stream_encoder_->SetSource(
682         &video_source_, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
683     video_stream_encoder_->SetStartBitrate(kTargetBitrateBps);
684     video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
685                                             kMaxPayloadLength);
686     video_stream_encoder_->WaitUntilTaskQueueIsIdle();
687   }
688 
ResetEncoder(const std::string & payload_name,size_t num_streams,size_t num_temporal_layers,unsigned char num_spatial_layers,bool screenshare)689   void ResetEncoder(const std::string& payload_name,
690                     size_t num_streams,
691                     size_t num_temporal_layers,
692                     unsigned char num_spatial_layers,
693                     bool screenshare) {
694     video_send_config_.rtp.payload_name = payload_name;
695 
696     VideoEncoderConfig video_encoder_config;
697     video_encoder_config.codec_type = PayloadStringToCodecType(payload_name);
698     video_encoder_config.number_of_streams = num_streams;
699     video_encoder_config.max_bitrate_bps =
700         num_streams == 1 ? kTargetBitrateBps : kSimulcastTargetBitrateBps;
701     video_encoder_config.video_stream_factory =
702         new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers,
703                                                       kDefaultFramerate);
704     video_encoder_config.content_type =
705         screenshare ? VideoEncoderConfig::ContentType::kScreen
706                     : VideoEncoderConfig::ContentType::kRealtimeVideo;
707     if (payload_name == "VP9") {
708       VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
709       vp9_settings.numberOfSpatialLayers = num_spatial_layers;
710       vp9_settings.automaticResizeOn = num_spatial_layers <= 1;
711       video_encoder_config.encoder_specific_settings =
712           new rtc::RefCountedObject<
713               VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings);
714     }
715     ConfigureEncoder(std::move(video_encoder_config));
716   }
717 
CreateFrame(int64_t ntp_time_ms,rtc::Event * destruction_event) const718   VideoFrame CreateFrame(int64_t ntp_time_ms,
719                          rtc::Event* destruction_event) const {
720     VideoFrame frame =
721         VideoFrame::Builder()
722             .set_video_frame_buffer(new rtc::RefCountedObject<TestBuffer>(
723                 destruction_event, codec_width_, codec_height_))
724             .set_timestamp_rtp(99)
725             .set_timestamp_ms(99)
726             .set_rotation(kVideoRotation_0)
727             .build();
728     frame.set_ntp_time_ms(ntp_time_ms);
729     return frame;
730   }
731 
CreateFrameWithUpdatedPixel(int64_t ntp_time_ms,rtc::Event * destruction_event,int offset_x) const732   VideoFrame CreateFrameWithUpdatedPixel(int64_t ntp_time_ms,
733                                          rtc::Event* destruction_event,
734                                          int offset_x) const {
735     VideoFrame frame =
736         VideoFrame::Builder()
737             .set_video_frame_buffer(new rtc::RefCountedObject<TestBuffer>(
738                 destruction_event, codec_width_, codec_height_))
739             .set_timestamp_rtp(99)
740             .set_timestamp_ms(99)
741             .set_rotation(kVideoRotation_0)
742             .set_update_rect(VideoFrame::UpdateRect{offset_x, 0, 1, 1})
743             .build();
744     frame.set_ntp_time_ms(ntp_time_ms);
745     return frame;
746   }
747 
CreateFrame(int64_t ntp_time_ms,int width,int height) const748   VideoFrame CreateFrame(int64_t ntp_time_ms, int width, int height) const {
749     VideoFrame frame =
750         VideoFrame::Builder()
751             .set_video_frame_buffer(
752                 new rtc::RefCountedObject<TestBuffer>(nullptr, width, height))
753             .set_timestamp_rtp(99)
754             .set_timestamp_ms(99)
755             .set_rotation(kVideoRotation_0)
756             .build();
757     frame.set_ntp_time_ms(ntp_time_ms);
758     frame.set_timestamp_us(ntp_time_ms * 1000);
759     return frame;
760   }
761 
CreateFakeNativeFrame(int64_t ntp_time_ms,rtc::Event * destruction_event,int width,int height) const762   VideoFrame CreateFakeNativeFrame(int64_t ntp_time_ms,
763                                    rtc::Event* destruction_event,
764                                    int width,
765                                    int height) const {
766     VideoFrame frame =
767         VideoFrame::Builder()
768             .set_video_frame_buffer(new rtc::RefCountedObject<FakeNativeBuffer>(
769                 destruction_event, width, height))
770             .set_timestamp_rtp(99)
771             .set_timestamp_ms(99)
772             .set_rotation(kVideoRotation_0)
773             .build();
774     frame.set_ntp_time_ms(ntp_time_ms);
775     return frame;
776   }
777 
CreateFakeNativeFrame(int64_t ntp_time_ms,rtc::Event * destruction_event) const778   VideoFrame CreateFakeNativeFrame(int64_t ntp_time_ms,
779                                    rtc::Event* destruction_event) const {
780     return CreateFakeNativeFrame(ntp_time_ms, destruction_event, codec_width_,
781                                  codec_height_);
782   }
783 
VerifyAllocatedBitrate(const VideoBitrateAllocation & expected_bitrate)784   void VerifyAllocatedBitrate(const VideoBitrateAllocation& expected_bitrate) {
785     MockBitrateObserver bitrate_observer;
786     video_stream_encoder_->SetBitrateAllocationObserver(&bitrate_observer);
787 
788     EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
789         .Times(1);
790     video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
791         DataRate::BitsPerSec(kTargetBitrateBps),
792         DataRate::BitsPerSec(kTargetBitrateBps),
793         DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
794 
795     video_source_.IncomingCapturedFrame(
796         CreateFrame(1, codec_width_, codec_height_));
797     WaitForEncodedFrame(1);
798   }
799 
WaitForEncodedFrame(int64_t expected_ntp_time)800   void WaitForEncodedFrame(int64_t expected_ntp_time) {
801     sink_.WaitForEncodedFrame(expected_ntp_time);
802     fake_clock_.AdvanceTime(TimeDelta::Seconds(1) / max_framerate_);
803   }
804 
TimedWaitForEncodedFrame(int64_t expected_ntp_time,int64_t timeout_ms)805   bool TimedWaitForEncodedFrame(int64_t expected_ntp_time, int64_t timeout_ms) {
806     bool ok = sink_.TimedWaitForEncodedFrame(expected_ntp_time, timeout_ms);
807     fake_clock_.AdvanceTime(TimeDelta::Seconds(1) / max_framerate_);
808     return ok;
809   }
810 
WaitForEncodedFrame(uint32_t expected_width,uint32_t expected_height)811   void WaitForEncodedFrame(uint32_t expected_width, uint32_t expected_height) {
812     sink_.WaitForEncodedFrame(expected_width, expected_height);
813     fake_clock_.AdvanceTime(TimeDelta::Seconds(1) / max_framerate_);
814   }
815 
ExpectDroppedFrame()816   void ExpectDroppedFrame() {
817     sink_.ExpectDroppedFrame();
818     fake_clock_.AdvanceTime(TimeDelta::Seconds(1) / max_framerate_);
819   }
820 
WaitForFrame(int64_t timeout_ms)821   bool WaitForFrame(int64_t timeout_ms) {
822     bool ok = sink_.WaitForFrame(timeout_ms);
823     fake_clock_.AdvanceTime(TimeDelta::Seconds(1) / max_framerate_);
824     return ok;
825   }
826 
827   class TestEncoder : public test::FakeEncoder {
828    public:
TestEncoder()829     TestEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {}
830 
codec_config() const831     VideoCodec codec_config() const {
832       MutexLock lock(&mutex_);
833       return config_;
834     }
835 
BlockNextEncode()836     void BlockNextEncode() {
837       MutexLock lock(&local_mutex_);
838       block_next_encode_ = true;
839     }
840 
GetEncoderInfo() const841     VideoEncoder::EncoderInfo GetEncoderInfo() const override {
842       MutexLock lock(&local_mutex_);
843       EncoderInfo info;
844       if (initialized_ == EncoderState::kInitialized) {
845         if (quality_scaling_) {
846           info.scaling_settings = VideoEncoder::ScalingSettings(
847               kQpLow, kQpHigh, kMinPixelsPerFrame);
848         }
849         info.is_hardware_accelerated = is_hardware_accelerated_;
850         for (int i = 0; i < kMaxSpatialLayers; ++i) {
851           if (temporal_layers_supported_[i]) {
852             int num_layers = temporal_layers_supported_[i].value() ? 2 : 1;
853             info.fps_allocation[i].resize(num_layers);
854           }
855         }
856       }
857 
858       info.resolution_bitrate_limits = resolution_bitrate_limits_;
859       info.requested_resolution_alignment = requested_resolution_alignment_;
860       return info;
861     }
862 
RegisterEncodeCompleteCallback(EncodedImageCallback * callback)863     int32_t RegisterEncodeCompleteCallback(
864         EncodedImageCallback* callback) override {
865       MutexLock lock(&local_mutex_);
866       encoded_image_callback_ = callback;
867       return FakeEncoder::RegisterEncodeCompleteCallback(callback);
868     }
869 
ContinueEncode()870     void ContinueEncode() { continue_encode_event_.Set(); }
871 
CheckLastTimeStampsMatch(int64_t ntp_time_ms,uint32_t timestamp) const872     void CheckLastTimeStampsMatch(int64_t ntp_time_ms,
873                                   uint32_t timestamp) const {
874       MutexLock lock(&local_mutex_);
875       EXPECT_EQ(timestamp_, timestamp);
876       EXPECT_EQ(ntp_time_ms_, ntp_time_ms);
877     }
878 
SetQualityScaling(bool b)879     void SetQualityScaling(bool b) {
880       MutexLock lock(&local_mutex_);
881       quality_scaling_ = b;
882     }
883 
SetRequestedResolutionAlignment(int requested_resolution_alignment)884     void SetRequestedResolutionAlignment(int requested_resolution_alignment) {
885       MutexLock lock(&local_mutex_);
886       requested_resolution_alignment_ = requested_resolution_alignment;
887     }
888 
SetIsHardwareAccelerated(bool is_hardware_accelerated)889     void SetIsHardwareAccelerated(bool is_hardware_accelerated) {
890       MutexLock lock(&local_mutex_);
891       is_hardware_accelerated_ = is_hardware_accelerated;
892     }
893 
SetTemporalLayersSupported(size_t spatial_idx,bool supported)894     void SetTemporalLayersSupported(size_t spatial_idx, bool supported) {
895       RTC_DCHECK_LT(spatial_idx, kMaxSpatialLayers);
896       MutexLock lock(&local_mutex_);
897       temporal_layers_supported_[spatial_idx] = supported;
898     }
899 
SetResolutionBitrateLimits(std::vector<ResolutionBitrateLimits> thresholds)900     void SetResolutionBitrateLimits(
901         std::vector<ResolutionBitrateLimits> thresholds) {
902       MutexLock lock(&local_mutex_);
903       resolution_bitrate_limits_ = thresholds;
904     }
905 
ForceInitEncodeFailure(bool force_failure)906     void ForceInitEncodeFailure(bool force_failure) {
907       MutexLock lock(&local_mutex_);
908       force_init_encode_failed_ = force_failure;
909     }
910 
SimulateOvershoot(double rate_factor)911     void SimulateOvershoot(double rate_factor) {
912       MutexLock lock(&local_mutex_);
913       rate_factor_ = rate_factor;
914     }
915 
GetLastFramerate() const916     uint32_t GetLastFramerate() const {
917       MutexLock lock(&local_mutex_);
918       return last_framerate_;
919     }
920 
GetLastUpdateRect() const921     VideoFrame::UpdateRect GetLastUpdateRect() const {
922       MutexLock lock(&local_mutex_);
923       return last_update_rect_;
924     }
925 
LastFrameTypes() const926     const std::vector<VideoFrameType>& LastFrameTypes() const {
927       MutexLock lock(&local_mutex_);
928       return last_frame_types_;
929     }
930 
InjectFrame(const VideoFrame & input_image,bool keyframe)931     void InjectFrame(const VideoFrame& input_image, bool keyframe) {
932       const std::vector<VideoFrameType> frame_type = {
933           keyframe ? VideoFrameType::kVideoFrameKey
934                    : VideoFrameType::kVideoFrameDelta};
935       {
936         MutexLock lock(&local_mutex_);
937         last_frame_types_ = frame_type;
938       }
939       FakeEncoder::Encode(input_image, &frame_type);
940     }
941 
InjectEncodedImage(const EncodedImage & image)942     void InjectEncodedImage(const EncodedImage& image) {
943       MutexLock lock(&local_mutex_);
944       encoded_image_callback_->OnEncodedImage(image, nullptr, nullptr);
945     }
946 
SetEncodedImageData(rtc::scoped_refptr<EncodedImageBufferInterface> encoded_image_data)947     void SetEncodedImageData(
948         rtc::scoped_refptr<EncodedImageBufferInterface> encoded_image_data) {
949       MutexLock lock(&local_mutex_);
950       encoded_image_data_ = encoded_image_data;
951     }
952 
ExpectNullFrame()953     void ExpectNullFrame() {
954       MutexLock lock(&local_mutex_);
955       expect_null_frame_ = true;
956     }
957 
958     absl::optional<VideoEncoder::RateControlParameters>
GetAndResetLastRateControlSettings()959     GetAndResetLastRateControlSettings() {
960       auto settings = last_rate_control_settings_;
961       last_rate_control_settings_.reset();
962       return settings;
963     }
964 
GetNumEncoderInitializations() const965     int GetNumEncoderInitializations() const {
966       MutexLock lock(&local_mutex_);
967       return num_encoder_initializations_;
968     }
969 
GetNumSetRates() const970     int GetNumSetRates() const {
971       MutexLock lock(&local_mutex_);
972       return num_set_rates_;
973     }
974 
975    private:
Encode(const VideoFrame & input_image,const std::vector<VideoFrameType> * frame_types)976     int32_t Encode(const VideoFrame& input_image,
977                    const std::vector<VideoFrameType>* frame_types) override {
978       bool block_encode;
979       {
980         MutexLock lock(&local_mutex_);
981         if (expect_null_frame_) {
982           EXPECT_EQ(input_image.timestamp(), 0u);
983           EXPECT_EQ(input_image.width(), 1);
984           last_frame_types_ = *frame_types;
985           expect_null_frame_ = false;
986         } else {
987           EXPECT_GT(input_image.timestamp(), timestamp_);
988           EXPECT_GT(input_image.ntp_time_ms(), ntp_time_ms_);
989           EXPECT_EQ(input_image.timestamp(), input_image.ntp_time_ms() * 90);
990         }
991 
992         timestamp_ = input_image.timestamp();
993         ntp_time_ms_ = input_image.ntp_time_ms();
994         last_input_width_ = input_image.width();
995         last_input_height_ = input_image.height();
996         block_encode = block_next_encode_;
997         block_next_encode_ = false;
998         last_update_rect_ = input_image.update_rect();
999         last_frame_types_ = *frame_types;
1000       }
1001       int32_t result = FakeEncoder::Encode(input_image, frame_types);
1002       if (block_encode)
1003         EXPECT_TRUE(continue_encode_event_.Wait(kDefaultTimeoutMs));
1004       return result;
1005     }
1006 
EncodeHook(EncodedImage * encoded_image,CodecSpecificInfo * codec_specific)1007     std::unique_ptr<RTPFragmentationHeader> EncodeHook(
1008         EncodedImage* encoded_image,
1009         CodecSpecificInfo* codec_specific) override {
1010       {
1011         MutexLock lock(&mutex_);
1012         codec_specific->codecType = config_.codecType;
1013       }
1014       MutexLock lock(&local_mutex_);
1015       if (encoded_image_data_) {
1016         encoded_image->SetEncodedData(encoded_image_data_);
1017         if (codec_specific->codecType == kVideoCodecH264) {
1018           auto fragmentation = std::make_unique<RTPFragmentationHeader>();
1019           fragmentation->VerifyAndAllocateFragmentationHeader(1);
1020           fragmentation->fragmentationOffset[0] = 4;
1021           fragmentation->fragmentationLength[0] = encoded_image->size() - 4;
1022           return fragmentation;
1023         }
1024       }
1025       return nullptr;
1026     }
1027 
InitEncode(const VideoCodec * config,const Settings & settings)1028     int32_t InitEncode(const VideoCodec* config,
1029                        const Settings& settings) override {
1030       int res = FakeEncoder::InitEncode(config, settings);
1031 
1032       MutexLock lock(&local_mutex_);
1033       EXPECT_EQ(initialized_, EncoderState::kUninitialized);
1034 
1035       ++num_encoder_initializations_;
1036 
1037       if (config->codecType == kVideoCodecVP8) {
1038         // Simulate setting up temporal layers, in order to validate the life
1039         // cycle of these objects.
1040         Vp8TemporalLayersFactory factory;
1041         frame_buffer_controller_ =
1042             factory.Create(*config, settings, &fec_controller_override_);
1043       }
1044       if (force_init_encode_failed_) {
1045         initialized_ = EncoderState::kInitializationFailed;
1046         return -1;
1047       }
1048 
1049       initialized_ = EncoderState::kInitialized;
1050       return res;
1051     }
1052 
Release()1053     int32_t Release() override {
1054       MutexLock lock(&local_mutex_);
1055       EXPECT_NE(initialized_, EncoderState::kUninitialized);
1056       initialized_ = EncoderState::kUninitialized;
1057       return FakeEncoder::Release();
1058     }
1059 
SetRates(const RateControlParameters & parameters)1060     void SetRates(const RateControlParameters& parameters) {
1061       MutexLock lock(&local_mutex_);
1062       num_set_rates_++;
1063       VideoBitrateAllocation adjusted_rate_allocation;
1064       for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
1065         for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
1066           if (parameters.bitrate.HasBitrate(si, ti)) {
1067             adjusted_rate_allocation.SetBitrate(
1068                 si, ti,
1069                 static_cast<uint32_t>(parameters.bitrate.GetBitrate(si, ti) *
1070                                       rate_factor_));
1071           }
1072         }
1073       }
1074       last_framerate_ = static_cast<uint32_t>(parameters.framerate_fps + 0.5);
1075       last_rate_control_settings_ = parameters;
1076       RateControlParameters adjusted_paramters = parameters;
1077       adjusted_paramters.bitrate = adjusted_rate_allocation;
1078       FakeEncoder::SetRates(adjusted_paramters);
1079     }
1080 
1081     mutable Mutex local_mutex_;
1082     enum class EncoderState {
1083       kUninitialized,
1084       kInitializationFailed,
1085       kInitialized
1086     } initialized_ RTC_GUARDED_BY(local_mutex_) = EncoderState::kUninitialized;
1087     bool block_next_encode_ RTC_GUARDED_BY(local_mutex_) = false;
1088     rtc::Event continue_encode_event_;
1089     uint32_t timestamp_ RTC_GUARDED_BY(local_mutex_) = 0;
1090     int64_t ntp_time_ms_ RTC_GUARDED_BY(local_mutex_) = 0;
1091     int last_input_width_ RTC_GUARDED_BY(local_mutex_) = 0;
1092     int last_input_height_ RTC_GUARDED_BY(local_mutex_) = 0;
1093     bool quality_scaling_ RTC_GUARDED_BY(local_mutex_) = true;
1094     int requested_resolution_alignment_ RTC_GUARDED_BY(local_mutex_) = 1;
1095     bool is_hardware_accelerated_ RTC_GUARDED_BY(local_mutex_) = false;
1096     rtc::scoped_refptr<EncodedImageBufferInterface> encoded_image_data_
1097         RTC_GUARDED_BY(local_mutex_);
1098     std::unique_ptr<Vp8FrameBufferController> frame_buffer_controller_
1099         RTC_GUARDED_BY(local_mutex_);
1100     absl::optional<bool>
1101         temporal_layers_supported_[kMaxSpatialLayers] RTC_GUARDED_BY(
1102             local_mutex_);
1103     bool force_init_encode_failed_ RTC_GUARDED_BY(local_mutex_) = false;
1104     double rate_factor_ RTC_GUARDED_BY(local_mutex_) = 1.0;
1105     uint32_t last_framerate_ RTC_GUARDED_BY(local_mutex_) = 0;
1106     absl::optional<VideoEncoder::RateControlParameters>
1107         last_rate_control_settings_;
1108     VideoFrame::UpdateRect last_update_rect_ RTC_GUARDED_BY(local_mutex_) = {
1109         0, 0, 0, 0};
1110     std::vector<VideoFrameType> last_frame_types_;
1111     bool expect_null_frame_ = false;
1112     EncodedImageCallback* encoded_image_callback_ RTC_GUARDED_BY(local_mutex_) =
1113         nullptr;
1114     NiceMock<MockFecControllerOverride> fec_controller_override_;
1115     int num_encoder_initializations_ RTC_GUARDED_BY(local_mutex_) = 0;
1116     std::vector<ResolutionBitrateLimits> resolution_bitrate_limits_
1117         RTC_GUARDED_BY(local_mutex_);
1118     int num_set_rates_ RTC_GUARDED_BY(local_mutex_) = 0;
1119   };
1120 
1121   class TestSink : public VideoStreamEncoder::EncoderSink {
1122    public:
TestSink(TestEncoder * test_encoder)1123     explicit TestSink(TestEncoder* test_encoder)
1124         : test_encoder_(test_encoder) {}
1125 
WaitForEncodedFrame(int64_t expected_ntp_time)1126     void WaitForEncodedFrame(int64_t expected_ntp_time) {
1127       EXPECT_TRUE(
1128           TimedWaitForEncodedFrame(expected_ntp_time, kDefaultTimeoutMs));
1129     }
1130 
TimedWaitForEncodedFrame(int64_t expected_ntp_time,int64_t timeout_ms)1131     bool TimedWaitForEncodedFrame(int64_t expected_ntp_time,
1132                                   int64_t timeout_ms) {
1133       uint32_t timestamp = 0;
1134       if (!encoded_frame_event_.Wait(timeout_ms))
1135         return false;
1136       {
1137         MutexLock lock(&mutex_);
1138         timestamp = last_timestamp_;
1139       }
1140       test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp);
1141       return true;
1142     }
1143 
WaitForEncodedFrame(uint32_t expected_width,uint32_t expected_height)1144     void WaitForEncodedFrame(uint32_t expected_width,
1145                              uint32_t expected_height) {
1146       EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs));
1147       CheckLastFrameSizeMatches(expected_width, expected_height);
1148     }
1149 
CheckLastFrameSizeMatches(uint32_t expected_width,uint32_t expected_height)1150     void CheckLastFrameSizeMatches(uint32_t expected_width,
1151                                    uint32_t expected_height) {
1152       uint32_t width = 0;
1153       uint32_t height = 0;
1154       {
1155         MutexLock lock(&mutex_);
1156         width = last_width_;
1157         height = last_height_;
1158       }
1159       EXPECT_EQ(expected_height, height);
1160       EXPECT_EQ(expected_width, width);
1161     }
1162 
CheckLastFrameSizeIsMultipleOf(int resolution_alignment)1163     void CheckLastFrameSizeIsMultipleOf(int resolution_alignment) {
1164       int width = 0;
1165       int height = 0;
1166       {
1167         MutexLock lock(&mutex_);
1168         width = last_width_;
1169         height = last_height_;
1170       }
1171       EXPECT_EQ(width % resolution_alignment, 0);
1172       EXPECT_EQ(height % resolution_alignment, 0);
1173     }
1174 
CheckLastFrameRotationMatches(VideoRotation expected_rotation)1175     void CheckLastFrameRotationMatches(VideoRotation expected_rotation) {
1176       VideoRotation rotation;
1177       {
1178         MutexLock lock(&mutex_);
1179         rotation = last_rotation_;
1180       }
1181       EXPECT_EQ(expected_rotation, rotation);
1182     }
1183 
ExpectDroppedFrame()1184     void ExpectDroppedFrame() { EXPECT_FALSE(encoded_frame_event_.Wait(100)); }
1185 
WaitForFrame(int64_t timeout_ms)1186     bool WaitForFrame(int64_t timeout_ms) {
1187       return encoded_frame_event_.Wait(timeout_ms);
1188     }
1189 
SetExpectNoFrames()1190     void SetExpectNoFrames() {
1191       MutexLock lock(&mutex_);
1192       expect_frames_ = false;
1193     }
1194 
number_of_reconfigurations() const1195     int number_of_reconfigurations() const {
1196       MutexLock lock(&mutex_);
1197       return number_of_reconfigurations_;
1198     }
1199 
last_min_transmit_bitrate() const1200     int last_min_transmit_bitrate() const {
1201       MutexLock lock(&mutex_);
1202       return min_transmit_bitrate_bps_;
1203     }
1204 
SetNumExpectedLayers(size_t num_layers)1205     void SetNumExpectedLayers(size_t num_layers) {
1206       MutexLock lock(&mutex_);
1207       num_expected_layers_ = num_layers;
1208     }
1209 
GetLastCaptureTimeMs() const1210     int64_t GetLastCaptureTimeMs() const {
1211       MutexLock lock(&mutex_);
1212       return last_capture_time_ms_;
1213     }
1214 
GetLastEncodedImageData()1215     std::vector<uint8_t> GetLastEncodedImageData() {
1216       MutexLock lock(&mutex_);
1217       return std::move(last_encoded_image_data_);
1218     }
1219 
GetLastFragmentation()1220     RTPFragmentationHeader GetLastFragmentation() {
1221       MutexLock lock(&mutex_);
1222       return std::move(last_fragmentation_);
1223     }
1224 
1225    private:
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)1226     Result OnEncodedImage(
1227         const EncodedImage& encoded_image,
1228         const CodecSpecificInfo* codec_specific_info,
1229         const RTPFragmentationHeader* fragmentation) override {
1230       MutexLock lock(&mutex_);
1231       EXPECT_TRUE(expect_frames_);
1232       last_encoded_image_data_ = std::vector<uint8_t>(
1233           encoded_image.data(), encoded_image.data() + encoded_image.size());
1234       if (fragmentation) {
1235         last_fragmentation_.CopyFrom(*fragmentation);
1236       }
1237       uint32_t timestamp = encoded_image.Timestamp();
1238       if (last_timestamp_ != timestamp) {
1239         num_received_layers_ = 1;
1240       } else {
1241         ++num_received_layers_;
1242       }
1243       last_timestamp_ = timestamp;
1244       last_capture_time_ms_ = encoded_image.capture_time_ms_;
1245       last_width_ = encoded_image._encodedWidth;
1246       last_height_ = encoded_image._encodedHeight;
1247       last_rotation_ = encoded_image.rotation_;
1248       if (num_received_layers_ == num_expected_layers_) {
1249         encoded_frame_event_.Set();
1250       }
1251       return Result(Result::OK, last_timestamp_);
1252     }
1253 
OnEncoderConfigurationChanged(std::vector<VideoStream> streams,bool is_svc,VideoEncoderConfig::ContentType content_type,int min_transmit_bitrate_bps)1254     void OnEncoderConfigurationChanged(
1255         std::vector<VideoStream> streams,
1256         bool is_svc,
1257         VideoEncoderConfig::ContentType content_type,
1258         int min_transmit_bitrate_bps) override {
1259       MutexLock lock(&mutex_);
1260       ++number_of_reconfigurations_;
1261       min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
1262     }
1263 
1264     mutable Mutex mutex_;
1265     TestEncoder* test_encoder_;
1266     rtc::Event encoded_frame_event_;
1267     std::vector<uint8_t> last_encoded_image_data_;
1268     RTPFragmentationHeader last_fragmentation_;
1269     uint32_t last_timestamp_ = 0;
1270     int64_t last_capture_time_ms_ = 0;
1271     uint32_t last_height_ = 0;
1272     uint32_t last_width_ = 0;
1273     VideoRotation last_rotation_ = kVideoRotation_0;
1274     size_t num_expected_layers_ = 1;
1275     size_t num_received_layers_ = 0;
1276     bool expect_frames_ = true;
1277     int number_of_reconfigurations_ = 0;
1278     int min_transmit_bitrate_bps_ = 0;
1279   };
1280 
1281   class VideoBitrateAllocatorProxyFactory
1282       : public VideoBitrateAllocatorFactory {
1283    public:
VideoBitrateAllocatorProxyFactory()1284     VideoBitrateAllocatorProxyFactory()
1285         : bitrate_allocator_factory_(
1286               CreateBuiltinVideoBitrateAllocatorFactory()) {}
1287 
CreateVideoBitrateAllocator(const VideoCodec & codec)1288     std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
1289         const VideoCodec& codec) override {
1290       MutexLock lock(&mutex_);
1291       codec_config_ = codec;
1292       return bitrate_allocator_factory_->CreateVideoBitrateAllocator(codec);
1293     }
1294 
codec_config() const1295     VideoCodec codec_config() const {
1296       MutexLock lock(&mutex_);
1297       return codec_config_;
1298     }
1299 
1300    private:
1301     std::unique_ptr<VideoBitrateAllocatorFactory> bitrate_allocator_factory_;
1302 
1303     mutable Mutex mutex_;
1304     VideoCodec codec_config_ RTC_GUARDED_BY(mutex_);
1305   };
1306 
1307   VideoSendStream::Config video_send_config_;
1308   VideoEncoderConfig video_encoder_config_;
1309   int codec_width_;
1310   int codec_height_;
1311   int max_framerate_;
1312   rtc::ScopedFakeClock fake_clock_;
1313   const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
1314   TestEncoder fake_encoder_;
1315   test::VideoEncoderProxyFactory encoder_factory_;
1316   VideoBitrateAllocatorProxyFactory bitrate_allocator_factory_;
1317   std::unique_ptr<MockableSendStatisticsProxy> stats_proxy_;
1318   TestSink sink_;
1319   AdaptingFrameForwarder video_source_;
1320   std::unique_ptr<VideoStreamEncoderUnderTest> video_stream_encoder_;
1321 };
1322 
TEST_F(VideoStreamEncoderTest,EncodeOneFrame)1323 TEST_F(VideoStreamEncoderTest, EncodeOneFrame) {
1324   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1325       DataRate::BitsPerSec(kTargetBitrateBps),
1326       DataRate::BitsPerSec(kTargetBitrateBps),
1327       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1328   rtc::Event frame_destroyed_event;
1329   video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
1330   WaitForEncodedFrame(1);
1331   EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
1332   video_stream_encoder_->Stop();
1333 }
1334 
TEST_F(VideoStreamEncoderTest,DropsFramesBeforeFirstOnBitrateUpdated)1335 TEST_F(VideoStreamEncoderTest, DropsFramesBeforeFirstOnBitrateUpdated) {
1336   // Dropped since no target bitrate has been set.
1337   rtc::Event frame_destroyed_event;
1338   // The encoder will cache up to one frame for a short duration. Adding two
1339   // frames means that the first frame will be dropped and the second frame will
1340   // be sent when the encoder is enabled.
1341   video_source_.IncomingCapturedFrame(CreateFrame(1, &frame_destroyed_event));
1342   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1343   EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
1344 
1345   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1346       DataRate::BitsPerSec(kTargetBitrateBps),
1347       DataRate::BitsPerSec(kTargetBitrateBps),
1348       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1349 
1350   // The pending frame should be received.
1351   WaitForEncodedFrame(2);
1352   video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
1353 
1354   WaitForEncodedFrame(3);
1355   video_stream_encoder_->Stop();
1356 }
1357 
TEST_F(VideoStreamEncoderTest,DropsFramesWhenRateSetToZero)1358 TEST_F(VideoStreamEncoderTest, DropsFramesWhenRateSetToZero) {
1359   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1360       DataRate::BitsPerSec(kTargetBitrateBps),
1361       DataRate::BitsPerSec(kTargetBitrateBps),
1362       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1363   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1364   WaitForEncodedFrame(1);
1365 
1366   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1367       DataRate::BitsPerSec(0), DataRate::BitsPerSec(0), DataRate::BitsPerSec(0),
1368       0, 0, 0);
1369   // The encoder will cache up to one frame for a short duration. Adding two
1370   // frames means that the first frame will be dropped and the second frame will
1371   // be sent when the encoder is resumed.
1372   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1373   video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
1374 
1375   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1376       DataRate::BitsPerSec(kTargetBitrateBps),
1377       DataRate::BitsPerSec(kTargetBitrateBps),
1378       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1379   WaitForEncodedFrame(3);
1380   video_source_.IncomingCapturedFrame(CreateFrame(4, nullptr));
1381   WaitForEncodedFrame(4);
1382   video_stream_encoder_->Stop();
1383 }
1384 
TEST_F(VideoStreamEncoderTest,DropsFramesWithSameOrOldNtpTimestamp)1385 TEST_F(VideoStreamEncoderTest, DropsFramesWithSameOrOldNtpTimestamp) {
1386   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1387       DataRate::BitsPerSec(kTargetBitrateBps),
1388       DataRate::BitsPerSec(kTargetBitrateBps),
1389       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1390   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1391   WaitForEncodedFrame(1);
1392 
1393   // This frame will be dropped since it has the same ntp timestamp.
1394   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1395 
1396   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1397   WaitForEncodedFrame(2);
1398   video_stream_encoder_->Stop();
1399 }
1400 
TEST_F(VideoStreamEncoderTest,DropsFrameAfterStop)1401 TEST_F(VideoStreamEncoderTest, DropsFrameAfterStop) {
1402   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1403       DataRate::BitsPerSec(kTargetBitrateBps),
1404       DataRate::BitsPerSec(kTargetBitrateBps),
1405       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1406 
1407   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1408   WaitForEncodedFrame(1);
1409 
1410   video_stream_encoder_->Stop();
1411   sink_.SetExpectNoFrames();
1412   rtc::Event frame_destroyed_event;
1413   video_source_.IncomingCapturedFrame(CreateFrame(2, &frame_destroyed_event));
1414   EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
1415 }
1416 
TEST_F(VideoStreamEncoderTest,DropsPendingFramesOnSlowEncode)1417 TEST_F(VideoStreamEncoderTest, DropsPendingFramesOnSlowEncode) {
1418   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1419       DataRate::BitsPerSec(kTargetBitrateBps),
1420       DataRate::BitsPerSec(kTargetBitrateBps),
1421       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1422 
1423   fake_encoder_.BlockNextEncode();
1424   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1425   WaitForEncodedFrame(1);
1426   // Here, the encoder thread will be blocked in the TestEncoder waiting for a
1427   // call to ContinueEncode.
1428   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1429   video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
1430   fake_encoder_.ContinueEncode();
1431   WaitForEncodedFrame(3);
1432 
1433   video_stream_encoder_->Stop();
1434 }
1435 
TEST_F(VideoStreamEncoderTest,DropFrameWithFailedI420Conversion)1436 TEST_F(VideoStreamEncoderTest, DropFrameWithFailedI420Conversion) {
1437   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1438       DataRate::BitsPerSec(kTargetBitrateBps),
1439       DataRate::BitsPerSec(kTargetBitrateBps),
1440       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1441 
1442   rtc::Event frame_destroyed_event;
1443   video_source_.IncomingCapturedFrame(
1444       CreateFakeNativeFrame(1, &frame_destroyed_event));
1445   ExpectDroppedFrame();
1446   EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
1447   video_stream_encoder_->Stop();
1448 }
1449 
TEST_F(VideoStreamEncoderTest,DropFrameWithFailedI420ConversionWithCrop)1450 TEST_F(VideoStreamEncoderTest, DropFrameWithFailedI420ConversionWithCrop) {
1451   // Use the cropping factory.
1452   video_encoder_config_.video_stream_factory =
1453       new rtc::RefCountedObject<CroppingVideoStreamFactory>(1, 30);
1454   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config_),
1455                                           kMaxPayloadLength);
1456   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
1457 
1458   // Capture a frame at codec_width_/codec_height_.
1459   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1460       DataRate::BitsPerSec(kTargetBitrateBps),
1461       DataRate::BitsPerSec(kTargetBitrateBps),
1462       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1463   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1464   WaitForEncodedFrame(1);
1465   // The encoder will have been configured once.
1466   EXPECT_EQ(1, sink_.number_of_reconfigurations());
1467   EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
1468   EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
1469 
1470   // Now send in a fake frame that needs to be cropped as the width/height
1471   // aren't divisible by 4 (see CreateEncoderStreams above).
1472   rtc::Event frame_destroyed_event;
1473   video_source_.IncomingCapturedFrame(CreateFakeNativeFrame(
1474       2, &frame_destroyed_event, codec_width_ + 1, codec_height_ + 1));
1475   ExpectDroppedFrame();
1476   EXPECT_TRUE(frame_destroyed_event.Wait(kDefaultTimeoutMs));
1477   video_stream_encoder_->Stop();
1478 }
1479 
TEST_F(VideoStreamEncoderTest,DropsFramesWhenCongestionWindowPushbackSet)1480 TEST_F(VideoStreamEncoderTest, DropsFramesWhenCongestionWindowPushbackSet) {
1481   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1482       DataRate::BitsPerSec(kTargetBitrateBps),
1483       DataRate::BitsPerSec(kTargetBitrateBps),
1484       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1485   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1486   WaitForEncodedFrame(1);
1487 
1488   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1489       DataRate::BitsPerSec(kTargetBitrateBps),
1490       DataRate::BitsPerSec(kTargetBitrateBps),
1491       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0.5);
1492   // The congestion window pushback is set to 0.5, which will drop 1/2 of
1493   // frames. Adding two frames means that the first frame will be dropped and
1494   // the second frame will be sent to the encoder.
1495   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1496   video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
1497   WaitForEncodedFrame(3);
1498   video_source_.IncomingCapturedFrame(CreateFrame(4, nullptr));
1499   video_source_.IncomingCapturedFrame(CreateFrame(5, nullptr));
1500   WaitForEncodedFrame(5);
1501   EXPECT_EQ(2u, stats_proxy_->GetStats().frames_dropped_by_congestion_window);
1502   video_stream_encoder_->Stop();
1503 }
1504 
TEST_F(VideoStreamEncoderTest,ConfigureEncoderTriggersOnEncoderConfigurationChanged)1505 TEST_F(VideoStreamEncoderTest,
1506        ConfigureEncoderTriggersOnEncoderConfigurationChanged) {
1507   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1508       DataRate::BitsPerSec(kTargetBitrateBps),
1509       DataRate::BitsPerSec(kTargetBitrateBps),
1510       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1511   EXPECT_EQ(0, sink_.number_of_reconfigurations());
1512 
1513   // Capture a frame and wait for it to synchronize with the encoder thread.
1514   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1515   WaitForEncodedFrame(1);
1516   // The encoder will have been configured once when the first frame is
1517   // received.
1518   EXPECT_EQ(1, sink_.number_of_reconfigurations());
1519 
1520   VideoEncoderConfig video_encoder_config;
1521   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1522   video_encoder_config.min_transmit_bitrate_bps = 9999;
1523   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
1524                                           kMaxPayloadLength);
1525 
1526   // Capture a frame and wait for it to synchronize with the encoder thread.
1527   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1528   WaitForEncodedFrame(2);
1529   EXPECT_EQ(2, sink_.number_of_reconfigurations());
1530   EXPECT_EQ(9999, sink_.last_min_transmit_bitrate());
1531 
1532   video_stream_encoder_->Stop();
1533 }
1534 
TEST_F(VideoStreamEncoderTest,FrameResolutionChangeReconfigureEncoder)1535 TEST_F(VideoStreamEncoderTest, FrameResolutionChangeReconfigureEncoder) {
1536   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1537       DataRate::BitsPerSec(kTargetBitrateBps),
1538       DataRate::BitsPerSec(kTargetBitrateBps),
1539       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1540 
1541   // Capture a frame and wait for it to synchronize with the encoder thread.
1542   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1543   WaitForEncodedFrame(1);
1544   // The encoder will have been configured once.
1545   EXPECT_EQ(1, sink_.number_of_reconfigurations());
1546   EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
1547   EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
1548 
1549   codec_width_ *= 2;
1550   codec_height_ *= 2;
1551   // Capture a frame with a higher resolution and wait for it to synchronize
1552   // with the encoder thread.
1553   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1554   WaitForEncodedFrame(2);
1555   EXPECT_EQ(codec_width_, fake_encoder_.codec_config().width);
1556   EXPECT_EQ(codec_height_, fake_encoder_.codec_config().height);
1557   EXPECT_EQ(2, sink_.number_of_reconfigurations());
1558 
1559   video_stream_encoder_->Stop();
1560 }
1561 
TEST_F(VideoStreamEncoderTest,EncoderInstanceDestroyedBeforeAnotherInstanceCreated)1562 TEST_F(VideoStreamEncoderTest,
1563        EncoderInstanceDestroyedBeforeAnotherInstanceCreated) {
1564   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1565       DataRate::BitsPerSec(kTargetBitrateBps),
1566       DataRate::BitsPerSec(kTargetBitrateBps),
1567       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1568 
1569   // Capture a frame and wait for it to synchronize with the encoder thread.
1570   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1571   WaitForEncodedFrame(1);
1572 
1573   VideoEncoderConfig video_encoder_config;
1574   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1575   // Changing the max payload data length recreates encoder.
1576   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
1577                                           kMaxPayloadLength / 2);
1578 
1579   // Capture a frame and wait for it to synchronize with the encoder thread.
1580   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1581   WaitForEncodedFrame(2);
1582   EXPECT_EQ(1, encoder_factory_.GetMaxNumberOfSimultaneousEncoderInstances());
1583 
1584   video_stream_encoder_->Stop();
1585 }
1586 
TEST_F(VideoStreamEncoderTest,BitrateLimitsChangeReconfigureRateAllocator)1587 TEST_F(VideoStreamEncoderTest, BitrateLimitsChangeReconfigureRateAllocator) {
1588   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1589       DataRate::BitsPerSec(kTargetBitrateBps),
1590       DataRate::BitsPerSec(kTargetBitrateBps),
1591       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1592 
1593   VideoEncoderConfig video_encoder_config;
1594   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1595   video_encoder_config.max_bitrate_bps = kTargetBitrateBps;
1596   video_stream_encoder_->SetStartBitrate(kStartBitrateBps);
1597   video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
1598                                           kMaxPayloadLength);
1599 
1600   // Capture a frame and wait for it to synchronize with the encoder thread.
1601   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1602   WaitForEncodedFrame(1);
1603   // The encoder will have been configured once when the first frame is
1604   // received.
1605   EXPECT_EQ(1, sink_.number_of_reconfigurations());
1606   EXPECT_EQ(kTargetBitrateBps,
1607             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1608   EXPECT_EQ(kStartBitrateBps,
1609             bitrate_allocator_factory_.codec_config().startBitrate * 1000);
1610 
1611   test::FillEncoderConfiguration(kVideoCodecVP8, 1,
1612                                  &video_encoder_config);  //???
1613   video_encoder_config.max_bitrate_bps = kTargetBitrateBps * 2;
1614   video_stream_encoder_->SetStartBitrate(kStartBitrateBps * 2);
1615   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
1616                                           kMaxPayloadLength);
1617 
1618   // Capture a frame and wait for it to synchronize with the encoder thread.
1619   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1620   WaitForEncodedFrame(2);
1621   EXPECT_EQ(2, sink_.number_of_reconfigurations());
1622   // Bitrate limits have changed - rate allocator should be reconfigured,
1623   // encoder should not be reconfigured.
1624   EXPECT_EQ(kTargetBitrateBps * 2,
1625             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1626   EXPECT_EQ(kStartBitrateBps * 2,
1627             bitrate_allocator_factory_.codec_config().startBitrate * 1000);
1628   EXPECT_EQ(1, fake_encoder_.GetNumEncoderInitializations());
1629 
1630   video_stream_encoder_->Stop();
1631 }
1632 
TEST_F(VideoStreamEncoderTest,IntersectionOfEncoderAndAppBitrateLimitsUsedWhenBothProvided)1633 TEST_F(VideoStreamEncoderTest,
1634        IntersectionOfEncoderAndAppBitrateLimitsUsedWhenBothProvided) {
1635   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1636       DataRate::BitsPerSec(kTargetBitrateBps),
1637       DataRate::BitsPerSec(kTargetBitrateBps),
1638       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1639 
1640   const uint32_t kMinEncBitrateKbps = 100;
1641   const uint32_t kMaxEncBitrateKbps = 1000;
1642   const VideoEncoder::ResolutionBitrateLimits encoder_bitrate_limits(
1643       /*frame_size_pixels=*/codec_width_ * codec_height_,
1644       /*min_start_bitrate_bps=*/0,
1645       /*min_bitrate_bps=*/kMinEncBitrateKbps * 1000,
1646       /*max_bitrate_bps=*/kMaxEncBitrateKbps * 1000);
1647   fake_encoder_.SetResolutionBitrateLimits({encoder_bitrate_limits});
1648 
1649   VideoEncoderConfig video_encoder_config;
1650   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1651   video_encoder_config.max_bitrate_bps = (kMaxEncBitrateKbps + 1) * 1000;
1652   video_encoder_config.simulcast_layers[0].min_bitrate_bps =
1653       (kMinEncBitrateKbps + 1) * 1000;
1654   video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
1655                                           kMaxPayloadLength);
1656 
1657   // When both encoder and app provide bitrate limits, the intersection of
1658   // provided sets should be used.
1659   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1660   WaitForEncodedFrame(1);
1661   EXPECT_EQ(kMaxEncBitrateKbps,
1662             bitrate_allocator_factory_.codec_config().maxBitrate);
1663   EXPECT_EQ(kMinEncBitrateKbps + 1,
1664             bitrate_allocator_factory_.codec_config().minBitrate);
1665 
1666   video_encoder_config.max_bitrate_bps = (kMaxEncBitrateKbps - 1) * 1000;
1667   video_encoder_config.simulcast_layers[0].min_bitrate_bps =
1668       (kMinEncBitrateKbps - 1) * 1000;
1669   video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
1670                                           kMaxPayloadLength);
1671   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
1672   WaitForEncodedFrame(2);
1673   EXPECT_EQ(kMaxEncBitrateKbps - 1,
1674             bitrate_allocator_factory_.codec_config().maxBitrate);
1675   EXPECT_EQ(kMinEncBitrateKbps,
1676             bitrate_allocator_factory_.codec_config().minBitrate);
1677 
1678   video_stream_encoder_->Stop();
1679 }
1680 
TEST_F(VideoStreamEncoderTest,EncoderAndAppLimitsDontIntersectEncoderLimitsIgnored)1681 TEST_F(VideoStreamEncoderTest,
1682        EncoderAndAppLimitsDontIntersectEncoderLimitsIgnored) {
1683   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1684       DataRate::BitsPerSec(kTargetBitrateBps),
1685       DataRate::BitsPerSec(kTargetBitrateBps),
1686       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1687 
1688   const uint32_t kMinAppBitrateKbps = 100;
1689   const uint32_t kMaxAppBitrateKbps = 200;
1690   const uint32_t kMinEncBitrateKbps = kMaxAppBitrateKbps + 1;
1691   const uint32_t kMaxEncBitrateKbps = kMaxAppBitrateKbps * 2;
1692   const VideoEncoder::ResolutionBitrateLimits encoder_bitrate_limits(
1693       /*frame_size_pixels=*/codec_width_ * codec_height_,
1694       /*min_start_bitrate_bps=*/0,
1695       /*min_bitrate_bps=*/kMinEncBitrateKbps * 1000,
1696       /*max_bitrate_bps=*/kMaxEncBitrateKbps * 1000);
1697   fake_encoder_.SetResolutionBitrateLimits({encoder_bitrate_limits});
1698 
1699   VideoEncoderConfig video_encoder_config;
1700   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1701   video_encoder_config.max_bitrate_bps = kMaxAppBitrateKbps * 1000;
1702   video_encoder_config.simulcast_layers[0].min_bitrate_bps =
1703       kMinAppBitrateKbps * 1000;
1704   video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
1705                                           kMaxPayloadLength);
1706 
1707   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
1708   WaitForEncodedFrame(1);
1709   EXPECT_EQ(kMaxAppBitrateKbps,
1710             bitrate_allocator_factory_.codec_config().maxBitrate);
1711   EXPECT_EQ(kMinAppBitrateKbps,
1712             bitrate_allocator_factory_.codec_config().minBitrate);
1713 
1714   video_stream_encoder_->Stop();
1715 }
1716 
TEST_F(VideoStreamEncoderTest,EncoderRecommendedMaxAndMinBitratesUsedForGivenResolution)1717 TEST_F(VideoStreamEncoderTest,
1718        EncoderRecommendedMaxAndMinBitratesUsedForGivenResolution) {
1719   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1720       DataRate::BitsPerSec(kTargetBitrateBps),
1721       DataRate::BitsPerSec(kTargetBitrateBps),
1722       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1723 
1724   const VideoEncoder::ResolutionBitrateLimits encoder_bitrate_limits_270p(
1725       480 * 270, 34 * 1000, 12 * 1000, 1234 * 1000);
1726   const VideoEncoder::ResolutionBitrateLimits encoder_bitrate_limits_360p(
1727       640 * 360, 43 * 1000, 21 * 1000, 2345 * 1000);
1728   fake_encoder_.SetResolutionBitrateLimits(
1729       {encoder_bitrate_limits_270p, encoder_bitrate_limits_360p});
1730 
1731   VideoEncoderConfig video_encoder_config;
1732   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1733   video_encoder_config.max_bitrate_bps = 0;
1734   video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
1735                                           kMaxPayloadLength);
1736 
1737   // 270p. The bitrate limits recommended by encoder for 270p should be used.
1738   video_source_.IncomingCapturedFrame(CreateFrame(1, 480, 270));
1739   WaitForEncodedFrame(1);
1740   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_270p.min_bitrate_bps),
1741             bitrate_allocator_factory_.codec_config().minBitrate * 1000);
1742   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_270p.max_bitrate_bps),
1743             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1744 
1745   // 360p. The bitrate limits recommended by encoder for 360p should be used.
1746   video_source_.IncomingCapturedFrame(CreateFrame(2, 640, 360));
1747   WaitForEncodedFrame(2);
1748   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_360p.min_bitrate_bps),
1749             bitrate_allocator_factory_.codec_config().minBitrate * 1000);
1750   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_360p.max_bitrate_bps),
1751             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1752 
1753   // Resolution between 270p and 360p. The bitrate limits recommended by
1754   // encoder for 360p should be used.
1755   video_source_.IncomingCapturedFrame(
1756       CreateFrame(3, (640 + 480) / 2, (360 + 270) / 2));
1757   WaitForEncodedFrame(3);
1758   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_360p.min_bitrate_bps),
1759             bitrate_allocator_factory_.codec_config().minBitrate * 1000);
1760   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_360p.max_bitrate_bps),
1761             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1762 
1763   // Resolution higher than 360p. The caps recommended by encoder should be
1764   // ignored.
1765   video_source_.IncomingCapturedFrame(CreateFrame(4, 960, 540));
1766   WaitForEncodedFrame(4);
1767   EXPECT_NE(static_cast<uint32_t>(encoder_bitrate_limits_270p.min_bitrate_bps),
1768             bitrate_allocator_factory_.codec_config().minBitrate * 1000);
1769   EXPECT_NE(static_cast<uint32_t>(encoder_bitrate_limits_270p.max_bitrate_bps),
1770             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1771   EXPECT_NE(static_cast<uint32_t>(encoder_bitrate_limits_360p.min_bitrate_bps),
1772             bitrate_allocator_factory_.codec_config().minBitrate * 1000);
1773   EXPECT_NE(static_cast<uint32_t>(encoder_bitrate_limits_360p.max_bitrate_bps),
1774             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1775 
1776   // Resolution lower than 270p. The max bitrate limit recommended by encoder
1777   // for 270p should be used.
1778   video_source_.IncomingCapturedFrame(CreateFrame(5, 320, 180));
1779   WaitForEncodedFrame(5);
1780   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_270p.min_bitrate_bps),
1781             bitrate_allocator_factory_.codec_config().minBitrate * 1000);
1782   EXPECT_EQ(static_cast<uint32_t>(encoder_bitrate_limits_270p.max_bitrate_bps),
1783             bitrate_allocator_factory_.codec_config().maxBitrate * 1000);
1784 
1785   video_stream_encoder_->Stop();
1786 }
1787 
TEST_F(VideoStreamEncoderTest,EncoderRecommendedMaxBitrateCapsTargetBitrate)1788 TEST_F(VideoStreamEncoderTest, EncoderRecommendedMaxBitrateCapsTargetBitrate) {
1789   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1790       DataRate::BitsPerSec(kTargetBitrateBps),
1791       DataRate::BitsPerSec(kTargetBitrateBps),
1792       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1793 
1794   VideoEncoderConfig video_encoder_config;
1795   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
1796   video_encoder_config.max_bitrate_bps = 0;
1797   video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
1798                                           kMaxPayloadLength);
1799 
1800   // Encode 720p frame to get the default encoder target bitrate.
1801   video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
1802   WaitForEncodedFrame(1);
1803   const uint32_t kDefaultTargetBitrateFor720pKbps =
1804       bitrate_allocator_factory_.codec_config()
1805           .simulcastStream[0]
1806           .targetBitrate;
1807 
1808   // Set the max recommended encoder bitrate to something lower than the default
1809   // target bitrate.
1810   const VideoEncoder::ResolutionBitrateLimits encoder_bitrate_limits(
1811       1280 * 720, 10 * 1000, 10 * 1000,
1812       kDefaultTargetBitrateFor720pKbps / 2 * 1000);
1813   fake_encoder_.SetResolutionBitrateLimits({encoder_bitrate_limits});
1814 
1815   // Change resolution to trigger encoder reinitialization.
1816   video_source_.IncomingCapturedFrame(CreateFrame(2, 640, 360));
1817   WaitForEncodedFrame(2);
1818   video_source_.IncomingCapturedFrame(CreateFrame(3, 1280, 720));
1819   WaitForEncodedFrame(3);
1820 
1821   // Ensure the target bitrate is capped by the max bitrate.
1822   EXPECT_EQ(bitrate_allocator_factory_.codec_config().maxBitrate * 1000,
1823             static_cast<uint32_t>(encoder_bitrate_limits.max_bitrate_bps));
1824   EXPECT_EQ(bitrate_allocator_factory_.codec_config()
1825                     .simulcastStream[0]
1826                     .targetBitrate *
1827                 1000,
1828             static_cast<uint32_t>(encoder_bitrate_limits.max_bitrate_bps));
1829 
1830   video_stream_encoder_->Stop();
1831 }
1832 
TEST_F(VideoStreamEncoderTest,SwitchSourceDeregisterEncoderAsSink)1833 TEST_F(VideoStreamEncoderTest, SwitchSourceDeregisterEncoderAsSink) {
1834   EXPECT_TRUE(video_source_.has_sinks());
1835   test::FrameForwarder new_video_source;
1836   video_stream_encoder_->SetSource(
1837       &new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
1838   EXPECT_FALSE(video_source_.has_sinks());
1839   EXPECT_TRUE(new_video_source.has_sinks());
1840 
1841   video_stream_encoder_->Stop();
1842 }
1843 
TEST_F(VideoStreamEncoderTest,SinkWantsRotationApplied)1844 TEST_F(VideoStreamEncoderTest, SinkWantsRotationApplied) {
1845   EXPECT_FALSE(video_source_.sink_wants().rotation_applied);
1846   video_stream_encoder_->SetSink(&sink_, true /*rotation_applied*/);
1847   EXPECT_TRUE(video_source_.sink_wants().rotation_applied);
1848   video_stream_encoder_->Stop();
1849 }
1850 
TEST_F(VideoStreamEncoderTest,SinkWantsResolutionAlignment)1851 TEST_F(VideoStreamEncoderTest, SinkWantsResolutionAlignment) {
1852   constexpr int kRequestedResolutionAlignment = 7;
1853   video_source_.set_adaptation_enabled(true);
1854   fake_encoder_.SetRequestedResolutionAlignment(kRequestedResolutionAlignment);
1855   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1856       DataRate::BitsPerSec(kTargetBitrateBps),
1857       DataRate::BitsPerSec(kTargetBitrateBps),
1858       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1859 
1860   // On the 1st frame, we should have initialized the encoder and
1861   // asked for its resolution requirements.
1862   video_source_.IncomingCapturedFrame(
1863       CreateFrame(1, codec_width_, codec_height_));
1864   WaitForEncodedFrame(1);
1865   EXPECT_EQ(video_source_.sink_wants().resolution_alignment,
1866             kRequestedResolutionAlignment);
1867 
1868   // On the 2nd frame, we should be receiving a correctly aligned resolution.
1869   // (It's up the to the encoder to potentially drop the previous frame,
1870   // to avoid coding back-to-back keyframes.)
1871   video_source_.IncomingCapturedFrame(
1872       CreateFrame(2, codec_width_, codec_height_));
1873   WaitForEncodedFrame(2);
1874   sink_.CheckLastFrameSizeIsMultipleOf(kRequestedResolutionAlignment);
1875 
1876   video_stream_encoder_->Stop();
1877 }
1878 
TEST_F(VideoStreamEncoderTest,TestCpuDowngrades_BalancedMode)1879 TEST_F(VideoStreamEncoderTest, TestCpuDowngrades_BalancedMode) {
1880   const int kFramerateFps = 30;
1881   const int kWidth = 1280;
1882   const int kHeight = 720;
1883 
1884   // We rely on the automatic resolution adaptation, but we handle framerate
1885   // adaptation manually by mocking the stats proxy.
1886   video_source_.set_adaptation_enabled(true);
1887 
1888   // Enable BALANCED preference, no initial limitation.
1889   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
1890       DataRate::BitsPerSec(kTargetBitrateBps),
1891       DataRate::BitsPerSec(kTargetBitrateBps),
1892       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1893   video_stream_encoder_->SetSource(&video_source_,
1894                                    webrtc::DegradationPreference::BALANCED);
1895   EXPECT_THAT(video_source_.sink_wants(), UnlimitedSinkWants());
1896   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
1897   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
1898   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
1899 
1900   // Adapt down as far as possible.
1901   rtc::VideoSinkWants last_wants;
1902   int64_t t = 1;
1903   int loop_count = 0;
1904   do {
1905     ++loop_count;
1906     last_wants = video_source_.sink_wants();
1907 
1908     // Simulate the framerate we've been asked to adapt to.
1909     const int fps = std::min(kFramerateFps, last_wants.max_framerate_fps);
1910     const int frame_interval_ms = rtc::kNumMillisecsPerSec / fps;
1911     VideoSendStream::Stats mock_stats = stats_proxy_->GetStats();
1912     mock_stats.input_frame_rate = fps;
1913     stats_proxy_->SetMockStats(mock_stats);
1914 
1915     video_source_.IncomingCapturedFrame(CreateFrame(t, kWidth, kHeight));
1916     sink_.WaitForEncodedFrame(t);
1917     t += frame_interval_ms;
1918 
1919     video_stream_encoder_->TriggerCpuOveruse();
1920     EXPECT_THAT(
1921         video_source_.sink_wants(),
1922         FpsInRangeForPixelsInBalanced(*video_source_.last_sent_width() *
1923                                       *video_source_.last_sent_height()));
1924   } while (video_source_.sink_wants().max_pixel_count <
1925                last_wants.max_pixel_count ||
1926            video_source_.sink_wants().max_framerate_fps <
1927                last_wants.max_framerate_fps);
1928 
1929   // Verify that we've adapted all the way down.
1930   stats_proxy_->ResetMockStats();
1931   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
1932   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_framerate);
1933   EXPECT_EQ(loop_count - 1,
1934             stats_proxy_->GetStats().number_of_cpu_adapt_changes);
1935   EXPECT_EQ(kMinPixelsPerFrame, *video_source_.last_sent_width() *
1936                                     *video_source_.last_sent_height());
1937   EXPECT_EQ(kMinBalancedFramerateFps,
1938             video_source_.sink_wants().max_framerate_fps);
1939 
1940   // Adapt back up the same number of times we adapted down.
1941   for (int i = 0; i < loop_count - 1; ++i) {
1942     last_wants = video_source_.sink_wants();
1943 
1944     // Simulate the framerate we've been asked to adapt to.
1945     const int fps = std::min(kFramerateFps, last_wants.max_framerate_fps);
1946     const int frame_interval_ms = rtc::kNumMillisecsPerSec / fps;
1947     VideoSendStream::Stats mock_stats = stats_proxy_->GetStats();
1948     mock_stats.input_frame_rate = fps;
1949     stats_proxy_->SetMockStats(mock_stats);
1950 
1951     video_source_.IncomingCapturedFrame(CreateFrame(t, kWidth, kHeight));
1952     sink_.WaitForEncodedFrame(t);
1953     t += frame_interval_ms;
1954 
1955     video_stream_encoder_->TriggerCpuUnderuse();
1956     EXPECT_THAT(
1957         video_source_.sink_wants(),
1958         FpsInRangeForPixelsInBalanced(*video_source_.last_sent_width() *
1959                                       *video_source_.last_sent_height()));
1960     EXPECT_TRUE(video_source_.sink_wants().max_pixel_count >
1961                     last_wants.max_pixel_count ||
1962                 video_source_.sink_wants().max_framerate_fps >
1963                     last_wants.max_framerate_fps);
1964   }
1965 
1966   EXPECT_THAT(video_source_.sink_wants(), FpsMaxResolutionMax());
1967   stats_proxy_->ResetMockStats();
1968   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
1969   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
1970   EXPECT_EQ((loop_count - 1) * 2,
1971             stats_proxy_->GetStats().number_of_cpu_adapt_changes);
1972 
1973   video_stream_encoder_->Stop();
1974 }
1975 
TEST_F(VideoStreamEncoderTest,SinkWantsNotChangedByResourceLimitedBeforeDegradationPreferenceChange)1976 TEST_F(VideoStreamEncoderTest,
1977        SinkWantsNotChangedByResourceLimitedBeforeDegradationPreferenceChange) {
1978   video_stream_encoder_->OnBitrateUpdated(
1979       DataRate::BitsPerSec(kTargetBitrateBps),
1980       DataRate::BitsPerSec(kTargetBitrateBps),
1981       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
1982   EXPECT_THAT(video_source_.sink_wants(), UnlimitedSinkWants());
1983 
1984   const int kFrameWidth = 1280;
1985   const int kFrameHeight = 720;
1986 
1987   int64_t ntp_time = kFrameIntervalMs;
1988 
1989   // Force an input frame rate to be available, or the adaptation call won't
1990   // know what framerate to adapt form.
1991   const int kInputFps = 30;
1992   VideoSendStream::Stats stats = stats_proxy_->GetStats();
1993   stats.input_frame_rate = kInputFps;
1994   stats_proxy_->SetMockStats(stats);
1995 
1996   video_source_.set_adaptation_enabled(true);
1997   video_stream_encoder_->SetSource(
1998       &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
1999   EXPECT_THAT(video_source_.sink_wants(), UnlimitedSinkWants());
2000   video_source_.IncomingCapturedFrame(
2001       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2002   sink_.WaitForEncodedFrame(ntp_time);
2003   ntp_time += kFrameIntervalMs;
2004 
2005   // Trigger CPU overuse.
2006   video_stream_encoder_->TriggerCpuOveruse();
2007   video_source_.IncomingCapturedFrame(
2008       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2009   sink_.WaitForEncodedFrame(ntp_time);
2010   ntp_time += kFrameIntervalMs;
2011 
2012   EXPECT_FALSE(video_source_.sink_wants().target_pixel_count);
2013   EXPECT_EQ(std::numeric_limits<int>::max(),
2014             video_source_.sink_wants().max_pixel_count);
2015   // Some framerate constraint should be set.
2016   int restricted_fps = video_source_.sink_wants().max_framerate_fps;
2017   EXPECT_LT(restricted_fps, kInputFps);
2018   video_source_.IncomingCapturedFrame(
2019       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2020   sink_.WaitForEncodedFrame(ntp_time);
2021   ntp_time += 100;
2022 
2023   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2024       &video_source_, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2025   // Give the encoder queue time to process the change in degradation preference
2026   // by waiting for an encoded frame.
2027   video_source_.IncomingCapturedFrame(
2028       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2029   sink_.WaitForEncodedFrame(ntp_time);
2030   ntp_time += kFrameIntervalMs;
2031 
2032   video_stream_encoder_->TriggerQualityLow();
2033   video_source_.IncomingCapturedFrame(
2034       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2035   sink_.WaitForEncodedFrame(ntp_time);
2036   ntp_time += kFrameIntervalMs;
2037 
2038   // Some resolution constraint should be set.
2039   EXPECT_FALSE(video_source_.sink_wants().target_pixel_count);
2040   EXPECT_LT(video_source_.sink_wants().max_pixel_count,
2041             kFrameWidth * kFrameHeight);
2042   EXPECT_EQ(video_source_.sink_wants().max_framerate_fps, kInputFps);
2043 
2044   int pixel_count = video_source_.sink_wants().max_pixel_count;
2045   // Triggering a CPU underuse should not change the sink wants since it has
2046   // not been overused for resolution since we changed degradation preference.
2047   video_stream_encoder_->TriggerCpuUnderuse();
2048   video_source_.IncomingCapturedFrame(
2049       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2050   sink_.WaitForEncodedFrame(ntp_time);
2051   ntp_time += kFrameIntervalMs;
2052   EXPECT_EQ(video_source_.sink_wants().max_pixel_count, pixel_count);
2053   EXPECT_EQ(video_source_.sink_wants().max_framerate_fps, kInputFps);
2054 
2055   // Change the degradation preference back. CPU underuse should not adapt since
2056   // QP is most limited.
2057   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2058       &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2059   video_source_.IncomingCapturedFrame(
2060       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2061   sink_.WaitForEncodedFrame(ntp_time);
2062   ntp_time += 100;
2063   // Resolution adaptations is gone after changing degradation preference.
2064   EXPECT_FALSE(video_source_.sink_wants().target_pixel_count);
2065   EXPECT_EQ(std::numeric_limits<int>::max(),
2066             video_source_.sink_wants().max_pixel_count);
2067   // The fps adaptation from above is now back.
2068   EXPECT_EQ(video_source_.sink_wants().max_framerate_fps, restricted_fps);
2069 
2070   // Trigger CPU underuse.
2071   video_stream_encoder_->TriggerCpuUnderuse();
2072   video_source_.IncomingCapturedFrame(
2073       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2074   sink_.WaitForEncodedFrame(ntp_time);
2075   ntp_time += kFrameIntervalMs;
2076   EXPECT_EQ(video_source_.sink_wants().max_framerate_fps, restricted_fps);
2077 
2078   // Trigger QP underuse, fps should return to normal.
2079   video_stream_encoder_->TriggerQualityHigh();
2080   video_source_.IncomingCapturedFrame(
2081       CreateFrame(ntp_time, kFrameWidth, kFrameHeight));
2082   sink_.WaitForEncodedFrame(ntp_time);
2083   ntp_time += kFrameIntervalMs;
2084   EXPECT_THAT(video_source_.sink_wants(), FpsMax());
2085 
2086   video_stream_encoder_->Stop();
2087 }
2088 
TEST_F(VideoStreamEncoderTest,SinkWantsStoredByDegradationPreference)2089 TEST_F(VideoStreamEncoderTest, SinkWantsStoredByDegradationPreference) {
2090   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2091       DataRate::BitsPerSec(kTargetBitrateBps),
2092       DataRate::BitsPerSec(kTargetBitrateBps),
2093       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2094   EXPECT_THAT(video_source_.sink_wants(), UnlimitedSinkWants());
2095 
2096   const int kFrameWidth = 1280;
2097   const int kFrameHeight = 720;
2098 
2099   int64_t frame_timestamp = 1;
2100 
2101   video_source_.IncomingCapturedFrame(
2102       CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight));
2103   WaitForEncodedFrame(frame_timestamp);
2104   frame_timestamp += kFrameIntervalMs;
2105 
2106   // Trigger CPU overuse.
2107   video_stream_encoder_->TriggerCpuOveruse();
2108   video_source_.IncomingCapturedFrame(
2109       CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight));
2110   WaitForEncodedFrame(frame_timestamp);
2111   frame_timestamp += kFrameIntervalMs;
2112 
2113   // Default degradation preference is maintain-framerate, so will lower max
2114   // wanted resolution.
2115   EXPECT_FALSE(video_source_.sink_wants().target_pixel_count);
2116   EXPECT_LT(video_source_.sink_wants().max_pixel_count,
2117             kFrameWidth * kFrameHeight);
2118   EXPECT_EQ(kDefaultFramerate, video_source_.sink_wants().max_framerate_fps);
2119 
2120   // Set new source, switch to maintain-resolution.
2121   test::FrameForwarder new_video_source;
2122   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2123       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2124   // Give the encoder queue time to process the change in degradation preference
2125   // by waiting for an encoded frame.
2126   new_video_source.IncomingCapturedFrame(
2127       CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
2128   sink_.WaitForEncodedFrame(frame_timestamp);
2129   frame_timestamp += kFrameIntervalMs;
2130   // Initially no degradation registered.
2131   EXPECT_THAT(new_video_source.sink_wants(), FpsMaxResolutionMax());
2132 
2133   // Force an input frame rate to be available, or the adaptation call won't
2134   // know what framerate to adapt form.
2135   const int kInputFps = 30;
2136   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2137   stats.input_frame_rate = kInputFps;
2138   stats_proxy_->SetMockStats(stats);
2139 
2140   video_stream_encoder_->TriggerCpuOveruse();
2141   new_video_source.IncomingCapturedFrame(
2142       CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight));
2143   WaitForEncodedFrame(frame_timestamp);
2144   frame_timestamp += kFrameIntervalMs;
2145 
2146   // Some framerate constraint should be set.
2147   EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
2148   EXPECT_EQ(std::numeric_limits<int>::max(),
2149             new_video_source.sink_wants().max_pixel_count);
2150   EXPECT_LT(new_video_source.sink_wants().max_framerate_fps, kInputFps);
2151 
2152   // Turn off degradation completely.
2153   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2154       &new_video_source, webrtc::DegradationPreference::DISABLED);
2155   // Give the encoder queue time to process the change in degradation preference
2156   // by waiting for an encoded frame.
2157   new_video_source.IncomingCapturedFrame(
2158       CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
2159   sink_.WaitForEncodedFrame(frame_timestamp);
2160   frame_timestamp += kFrameIntervalMs;
2161   EXPECT_THAT(new_video_source.sink_wants(), FpsMaxResolutionMax());
2162 
2163   video_stream_encoder_->TriggerCpuOveruse();
2164   new_video_source.IncomingCapturedFrame(
2165       CreateFrame(frame_timestamp, kFrameWidth, kFrameHeight));
2166   WaitForEncodedFrame(frame_timestamp);
2167   frame_timestamp += kFrameIntervalMs;
2168 
2169   // Still no degradation.
2170   EXPECT_THAT(new_video_source.sink_wants(), FpsMaxResolutionMax());
2171 
2172   // Calling SetSource with resolution scaling enabled apply the old SinkWants.
2173   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2174       &new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2175   // Give the encoder queue time to process the change in degradation preference
2176   // by waiting for an encoded frame.
2177   new_video_source.IncomingCapturedFrame(
2178       CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
2179   sink_.WaitForEncodedFrame(frame_timestamp);
2180   frame_timestamp += kFrameIntervalMs;
2181   EXPECT_LT(new_video_source.sink_wants().max_pixel_count,
2182             kFrameWidth * kFrameHeight);
2183   EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
2184   EXPECT_EQ(kDefaultFramerate, new_video_source.sink_wants().max_framerate_fps);
2185 
2186   // Calling SetSource with framerate scaling enabled apply the old SinkWants.
2187   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2188       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2189   // Give the encoder queue time to process the change in degradation preference
2190   // by waiting for an encoded frame.
2191   new_video_source.IncomingCapturedFrame(
2192       CreateFrame(frame_timestamp, kFrameWidth, kFrameWidth));
2193   sink_.WaitForEncodedFrame(frame_timestamp);
2194   frame_timestamp += kFrameIntervalMs;
2195   EXPECT_FALSE(new_video_source.sink_wants().target_pixel_count);
2196   EXPECT_EQ(std::numeric_limits<int>::max(),
2197             new_video_source.sink_wants().max_pixel_count);
2198   EXPECT_LT(new_video_source.sink_wants().max_framerate_fps, kInputFps);
2199 
2200   video_stream_encoder_->Stop();
2201 }
2202 
TEST_F(VideoStreamEncoderTest,StatsTracksQualityAdaptationStats)2203 TEST_F(VideoStreamEncoderTest, StatsTracksQualityAdaptationStats) {
2204   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2205       DataRate::BitsPerSec(kTargetBitrateBps),
2206       DataRate::BitsPerSec(kTargetBitrateBps),
2207       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2208 
2209   const int kWidth = 1280;
2210   const int kHeight = 720;
2211   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2212   WaitForEncodedFrame(1);
2213   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2214   EXPECT_FALSE(stats.bw_limited_resolution);
2215   EXPECT_EQ(0, stats.number_of_quality_adapt_changes);
2216 
2217   // Trigger adapt down.
2218   video_stream_encoder_->TriggerQualityLow();
2219   video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2220   WaitForEncodedFrame(2);
2221 
2222   stats = stats_proxy_->GetStats();
2223   EXPECT_TRUE(stats.bw_limited_resolution);
2224   EXPECT_EQ(1, stats.number_of_quality_adapt_changes);
2225 
2226   // Trigger adapt up.
2227   video_stream_encoder_->TriggerQualityHigh();
2228   video_source_.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
2229   WaitForEncodedFrame(3);
2230 
2231   stats = stats_proxy_->GetStats();
2232   EXPECT_FALSE(stats.bw_limited_resolution);
2233   EXPECT_EQ(2, stats.number_of_quality_adapt_changes);
2234   EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
2235 
2236   video_stream_encoder_->Stop();
2237 }
2238 
TEST_F(VideoStreamEncoderTest,StatsTracksCpuAdaptationStats)2239 TEST_F(VideoStreamEncoderTest, StatsTracksCpuAdaptationStats) {
2240   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2241       DataRate::BitsPerSec(kTargetBitrateBps),
2242       DataRate::BitsPerSec(kTargetBitrateBps),
2243       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2244 
2245   const int kWidth = 1280;
2246   const int kHeight = 720;
2247   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2248   WaitForEncodedFrame(1);
2249   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2250   EXPECT_FALSE(stats.cpu_limited_resolution);
2251   EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
2252 
2253   // Trigger CPU overuse.
2254   video_stream_encoder_->TriggerCpuOveruse();
2255   video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2256   WaitForEncodedFrame(2);
2257 
2258   stats = stats_proxy_->GetStats();
2259   EXPECT_TRUE(stats.cpu_limited_resolution);
2260   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2261 
2262   // Trigger CPU normal use.
2263   video_stream_encoder_->TriggerCpuUnderuse();
2264   video_source_.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
2265   WaitForEncodedFrame(3);
2266 
2267   stats = stats_proxy_->GetStats();
2268   EXPECT_FALSE(stats.cpu_limited_resolution);
2269   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2270   EXPECT_EQ(0, stats.number_of_quality_adapt_changes);
2271 
2272   video_stream_encoder_->Stop();
2273 }
2274 
TEST_F(VideoStreamEncoderTest,SwitchingSourceKeepsCpuAdaptation)2275 TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsCpuAdaptation) {
2276   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2277       DataRate::BitsPerSec(kTargetBitrateBps),
2278       DataRate::BitsPerSec(kTargetBitrateBps),
2279       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2280 
2281   const int kWidth = 1280;
2282   const int kHeight = 720;
2283   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2284   WaitForEncodedFrame(1);
2285   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2286   EXPECT_FALSE(stats.bw_limited_resolution);
2287   EXPECT_FALSE(stats.cpu_limited_resolution);
2288   EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
2289 
2290   // Trigger CPU overuse.
2291   video_stream_encoder_->TriggerCpuOveruse();
2292   video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2293   WaitForEncodedFrame(2);
2294   stats = stats_proxy_->GetStats();
2295   EXPECT_FALSE(stats.bw_limited_resolution);
2296   EXPECT_TRUE(stats.cpu_limited_resolution);
2297   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2298 
2299   // Set new source with adaptation still enabled.
2300   test::FrameForwarder new_video_source;
2301   video_stream_encoder_->SetSource(
2302       &new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2303 
2304   new_video_source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
2305   WaitForEncodedFrame(3);
2306   stats = stats_proxy_->GetStats();
2307   EXPECT_FALSE(stats.bw_limited_resolution);
2308   EXPECT_TRUE(stats.cpu_limited_resolution);
2309   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2310 
2311   // Set adaptation disabled.
2312   video_stream_encoder_->SetSource(&new_video_source,
2313                                    webrtc::DegradationPreference::DISABLED);
2314 
2315   new_video_source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
2316   WaitForEncodedFrame(4);
2317   stats = stats_proxy_->GetStats();
2318   EXPECT_FALSE(stats.bw_limited_resolution);
2319   EXPECT_FALSE(stats.cpu_limited_resolution);
2320   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2321 
2322   // Set adaptation back to enabled.
2323   video_stream_encoder_->SetSource(
2324       &new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2325 
2326   new_video_source.IncomingCapturedFrame(CreateFrame(5, kWidth, kHeight));
2327   WaitForEncodedFrame(5);
2328   stats = stats_proxy_->GetStats();
2329   EXPECT_FALSE(stats.bw_limited_resolution);
2330   EXPECT_TRUE(stats.cpu_limited_resolution);
2331   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2332 
2333   // Trigger CPU normal use.
2334   video_stream_encoder_->TriggerCpuUnderuse();
2335   new_video_source.IncomingCapturedFrame(CreateFrame(6, kWidth, kHeight));
2336   WaitForEncodedFrame(6);
2337   stats = stats_proxy_->GetStats();
2338   EXPECT_FALSE(stats.bw_limited_resolution);
2339   EXPECT_FALSE(stats.cpu_limited_resolution);
2340   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2341   EXPECT_EQ(0, stats.number_of_quality_adapt_changes);
2342 
2343   video_stream_encoder_->Stop();
2344 }
2345 
TEST_F(VideoStreamEncoderTest,SwitchingSourceKeepsQualityAdaptation)2346 TEST_F(VideoStreamEncoderTest, SwitchingSourceKeepsQualityAdaptation) {
2347   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2348       DataRate::BitsPerSec(kTargetBitrateBps),
2349       DataRate::BitsPerSec(kTargetBitrateBps),
2350       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2351 
2352   const int kWidth = 1280;
2353   const int kHeight = 720;
2354   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2355   WaitForEncodedFrame(1);
2356   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2357   EXPECT_FALSE(stats.bw_limited_resolution);
2358   EXPECT_FALSE(stats.bw_limited_framerate);
2359   EXPECT_EQ(0, stats.number_of_quality_adapt_changes);
2360 
2361   // Set new source with adaptation still enabled.
2362   test::FrameForwarder new_video_source;
2363   video_stream_encoder_->SetSource(&new_video_source,
2364                                    webrtc::DegradationPreference::BALANCED);
2365 
2366   new_video_source.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2367   WaitForEncodedFrame(2);
2368   stats = stats_proxy_->GetStats();
2369   EXPECT_FALSE(stats.bw_limited_resolution);
2370   EXPECT_FALSE(stats.bw_limited_framerate);
2371   EXPECT_EQ(0, stats.number_of_quality_adapt_changes);
2372 
2373   // Trigger adapt down.
2374   video_stream_encoder_->TriggerQualityLow();
2375   new_video_source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
2376   WaitForEncodedFrame(3);
2377   stats = stats_proxy_->GetStats();
2378   EXPECT_TRUE(stats.bw_limited_resolution);
2379   EXPECT_FALSE(stats.bw_limited_framerate);
2380   EXPECT_EQ(1, stats.number_of_quality_adapt_changes);
2381 
2382   // Set new source with adaptation still enabled.
2383   video_stream_encoder_->SetSource(&new_video_source,
2384                                    webrtc::DegradationPreference::BALANCED);
2385 
2386   new_video_source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
2387   WaitForEncodedFrame(4);
2388   stats = stats_proxy_->GetStats();
2389   EXPECT_TRUE(stats.bw_limited_resolution);
2390   EXPECT_FALSE(stats.bw_limited_framerate);
2391   EXPECT_EQ(1, stats.number_of_quality_adapt_changes);
2392 
2393   // Disable resolution scaling.
2394   video_stream_encoder_->SetSource(
2395       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2396 
2397   new_video_source.IncomingCapturedFrame(CreateFrame(5, kWidth, kHeight));
2398   WaitForEncodedFrame(5);
2399   stats = stats_proxy_->GetStats();
2400   EXPECT_FALSE(stats.bw_limited_resolution);
2401   EXPECT_FALSE(stats.bw_limited_framerate);
2402   EXPECT_EQ(1, stats.number_of_quality_adapt_changes);
2403   EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
2404 
2405   video_stream_encoder_->Stop();
2406 }
2407 
TEST_F(VideoStreamEncoderTest,QualityAdaptationStatsAreResetWhenScalerIsDisabled)2408 TEST_F(VideoStreamEncoderTest,
2409        QualityAdaptationStatsAreResetWhenScalerIsDisabled) {
2410   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2411       DataRate::BitsPerSec(kTargetBitrateBps),
2412       DataRate::BitsPerSec(kTargetBitrateBps),
2413       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2414 
2415   const int kWidth = 1280;
2416   const int kHeight = 720;
2417   int64_t timestamp_ms = kFrameIntervalMs;
2418   video_source_.set_adaptation_enabled(true);
2419   video_source_.IncomingCapturedFrame(
2420       CreateFrame(timestamp_ms, kWidth, kHeight));
2421   WaitForEncodedFrame(timestamp_ms);
2422   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
2423   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2424   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2425 
2426   // Trigger adapt down.
2427   video_stream_encoder_->TriggerQualityLow();
2428   timestamp_ms += kFrameIntervalMs;
2429   video_source_.IncomingCapturedFrame(
2430       CreateFrame(timestamp_ms, kWidth, kHeight));
2431   WaitForEncodedFrame(timestamp_ms);
2432   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
2433   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
2434   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2435 
2436   // Trigger overuse.
2437   video_stream_encoder_->TriggerCpuOveruse();
2438   timestamp_ms += kFrameIntervalMs;
2439   video_source_.IncomingCapturedFrame(
2440       CreateFrame(timestamp_ms, kWidth, kHeight));
2441   WaitForEncodedFrame(timestamp_ms);
2442   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
2443   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
2444   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2445 
2446   // Leave source unchanged, but disable quality scaler.
2447   fake_encoder_.SetQualityScaling(false);
2448 
2449   VideoEncoderConfig video_encoder_config;
2450   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
2451   // Make format different, to force recreation of encoder.
2452   video_encoder_config.video_format.parameters["foo"] = "foo";
2453   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
2454                                           kMaxPayloadLength);
2455   timestamp_ms += kFrameIntervalMs;
2456   video_source_.IncomingCapturedFrame(
2457       CreateFrame(timestamp_ms, kWidth, kHeight));
2458   WaitForEncodedFrame(timestamp_ms);
2459   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
2460   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2461   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2462 
2463   video_stream_encoder_->Stop();
2464 }
2465 
TEST_F(VideoStreamEncoderTest,StatsTracksCpuAdaptationStatsWhenSwitchingSource_Balanced)2466 TEST_F(VideoStreamEncoderTest,
2467        StatsTracksCpuAdaptationStatsWhenSwitchingSource_Balanced) {
2468   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2469       DataRate::BitsPerSec(kTargetBitrateBps),
2470       DataRate::BitsPerSec(kTargetBitrateBps),
2471       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2472 
2473   const int kWidth = 1280;
2474   const int kHeight = 720;
2475   int sequence = 1;
2476 
2477   // Enable BALANCED preference, no initial limitation.
2478   test::FrameForwarder source;
2479   video_stream_encoder_->SetSource(&source,
2480                                    webrtc::DegradationPreference::BALANCED);
2481   source.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2482   WaitForEncodedFrame(sequence++);
2483   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2484   EXPECT_FALSE(stats.cpu_limited_resolution);
2485   EXPECT_FALSE(stats.cpu_limited_framerate);
2486   EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
2487 
2488   // Trigger CPU overuse, should now adapt down.
2489   video_stream_encoder_->TriggerCpuOveruse();
2490   source.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2491   WaitForEncodedFrame(sequence++);
2492   stats = stats_proxy_->GetStats();
2493   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2494 
2495   // Set new degradation preference should clear restrictions since we changed
2496   // from BALANCED.
2497   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2498       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2499   source.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2500   WaitForEncodedFrame(sequence++);
2501   stats = stats_proxy_->GetStats();
2502   EXPECT_FALSE(stats.cpu_limited_resolution);
2503   EXPECT_FALSE(stats.cpu_limited_framerate);
2504   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2505 
2506   // Force an input frame rate to be available, or the adaptation call won't
2507   // know what framerate to adapt from.
2508   VideoSendStream::Stats mock_stats = stats_proxy_->GetStats();
2509   mock_stats.input_frame_rate = 30;
2510   stats_proxy_->SetMockStats(mock_stats);
2511   video_stream_encoder_->TriggerCpuOveruse();
2512   stats_proxy_->ResetMockStats();
2513   source.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2514   WaitForEncodedFrame(sequence++);
2515 
2516   // We have now adapted once.
2517   stats = stats_proxy_->GetStats();
2518   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2519 
2520   // Back to BALANCED, should clear the restrictions again.
2521   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2522       &source, webrtc::DegradationPreference::BALANCED);
2523   source.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2524   WaitForEncodedFrame(sequence++);
2525   stats = stats_proxy_->GetStats();
2526   EXPECT_FALSE(stats.cpu_limited_resolution);
2527   EXPECT_FALSE(stats.cpu_limited_framerate);
2528   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2529 
2530   video_stream_encoder_->Stop();
2531 }
2532 
TEST_F(VideoStreamEncoderTest,StatsTracksCpuAdaptationStatsWhenSwitchingSource)2533 TEST_F(VideoStreamEncoderTest,
2534        StatsTracksCpuAdaptationStatsWhenSwitchingSource) {
2535   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2536       DataRate::BitsPerSec(kTargetBitrateBps),
2537       DataRate::BitsPerSec(kTargetBitrateBps),
2538       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2539 
2540   const int kWidth = 1280;
2541   const int kHeight = 720;
2542   int sequence = 1;
2543 
2544   video_source_.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2545   WaitForEncodedFrame(sequence++);
2546   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2547   EXPECT_FALSE(stats.cpu_limited_resolution);
2548   EXPECT_FALSE(stats.cpu_limited_framerate);
2549   EXPECT_EQ(0, stats.number_of_cpu_adapt_changes);
2550 
2551   // Trigger CPU overuse, should now adapt down.
2552   video_stream_encoder_->TriggerCpuOveruse();
2553   video_source_.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2554   WaitForEncodedFrame(sequence++);
2555   stats = stats_proxy_->GetStats();
2556   EXPECT_TRUE(stats.cpu_limited_resolution);
2557   EXPECT_FALSE(stats.cpu_limited_framerate);
2558   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2559 
2560   // Set new source with adaptation still enabled.
2561   test::FrameForwarder new_video_source;
2562   video_stream_encoder_->SetSource(
2563       &new_video_source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2564 
2565   new_video_source.IncomingCapturedFrame(
2566       CreateFrame(sequence, kWidth, kHeight));
2567   WaitForEncodedFrame(sequence++);
2568   stats = stats_proxy_->GetStats();
2569   EXPECT_TRUE(stats.cpu_limited_resolution);
2570   EXPECT_FALSE(stats.cpu_limited_framerate);
2571   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2572 
2573   // Set cpu adaptation by frame dropping.
2574   video_stream_encoder_->SetSource(
2575       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2576   new_video_source.IncomingCapturedFrame(
2577       CreateFrame(sequence, kWidth, kHeight));
2578   WaitForEncodedFrame(sequence++);
2579   stats = stats_proxy_->GetStats();
2580   // Not adapted at first.
2581   EXPECT_FALSE(stats.cpu_limited_resolution);
2582   EXPECT_FALSE(stats.cpu_limited_framerate);
2583   EXPECT_EQ(1, stats.number_of_cpu_adapt_changes);
2584 
2585   // Force an input frame rate to be available, or the adaptation call won't
2586   // know what framerate to adapt from.
2587   VideoSendStream::Stats mock_stats = stats_proxy_->GetStats();
2588   mock_stats.input_frame_rate = 30;
2589   stats_proxy_->SetMockStats(mock_stats);
2590   video_stream_encoder_->TriggerCpuOveruse();
2591   stats_proxy_->ResetMockStats();
2592 
2593   new_video_source.IncomingCapturedFrame(
2594       CreateFrame(sequence, kWidth, kHeight));
2595   WaitForEncodedFrame(sequence++);
2596 
2597   // Framerate now adapted.
2598   stats = stats_proxy_->GetStats();
2599   EXPECT_FALSE(stats.cpu_limited_resolution);
2600   EXPECT_TRUE(stats.cpu_limited_framerate);
2601   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2602 
2603   // Disable CPU adaptation.
2604   video_stream_encoder_->SetSource(&new_video_source,
2605                                    webrtc::DegradationPreference::DISABLED);
2606   new_video_source.IncomingCapturedFrame(
2607       CreateFrame(sequence, kWidth, kHeight));
2608   WaitForEncodedFrame(sequence++);
2609 
2610   stats = stats_proxy_->GetStats();
2611   EXPECT_FALSE(stats.cpu_limited_resolution);
2612   EXPECT_FALSE(stats.cpu_limited_framerate);
2613   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2614 
2615   // Try to trigger overuse. Should not succeed.
2616   stats_proxy_->SetMockStats(mock_stats);
2617   video_stream_encoder_->TriggerCpuOveruse();
2618   stats_proxy_->ResetMockStats();
2619 
2620   stats = stats_proxy_->GetStats();
2621   EXPECT_FALSE(stats.cpu_limited_resolution);
2622   EXPECT_FALSE(stats.cpu_limited_framerate);
2623   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2624 
2625   // Switch back the source with resolution adaptation enabled.
2626   video_stream_encoder_->SetSource(
2627       &video_source_, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2628   video_source_.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2629   WaitForEncodedFrame(sequence++);
2630   stats = stats_proxy_->GetStats();
2631   EXPECT_TRUE(stats.cpu_limited_resolution);
2632   EXPECT_FALSE(stats.cpu_limited_framerate);
2633   EXPECT_EQ(2, stats.number_of_cpu_adapt_changes);
2634 
2635   // Trigger CPU normal usage.
2636   video_stream_encoder_->TriggerCpuUnderuse();
2637   video_source_.IncomingCapturedFrame(CreateFrame(sequence, kWidth, kHeight));
2638   WaitForEncodedFrame(sequence++);
2639   stats = stats_proxy_->GetStats();
2640   EXPECT_FALSE(stats.cpu_limited_resolution);
2641   EXPECT_FALSE(stats.cpu_limited_framerate);
2642   EXPECT_EQ(3, stats.number_of_cpu_adapt_changes);
2643 
2644   // Back to the source with adaptation off, set it back to maintain-resolution.
2645   video_stream_encoder_->SetSource(
2646       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2647   new_video_source.IncomingCapturedFrame(
2648       CreateFrame(sequence, kWidth, kHeight));
2649   WaitForEncodedFrame(sequence++);
2650   stats = stats_proxy_->GetStats();
2651   // Disabled, since we previously switched the source to disabled.
2652   EXPECT_FALSE(stats.cpu_limited_resolution);
2653   EXPECT_TRUE(stats.cpu_limited_framerate);
2654   EXPECT_EQ(3, stats.number_of_cpu_adapt_changes);
2655 
2656   // Trigger CPU normal usage.
2657   video_stream_encoder_->TriggerCpuUnderuse();
2658   new_video_source.IncomingCapturedFrame(
2659       CreateFrame(sequence, kWidth, kHeight));
2660   WaitForEncodedFrame(sequence++);
2661   stats = stats_proxy_->GetStats();
2662   EXPECT_FALSE(stats.cpu_limited_resolution);
2663   EXPECT_FALSE(stats.cpu_limited_framerate);
2664   EXPECT_EQ(4, stats.number_of_cpu_adapt_changes);
2665   EXPECT_EQ(0, stats.number_of_quality_adapt_changes);
2666 
2667   video_stream_encoder_->Stop();
2668 }
2669 
TEST_F(VideoStreamEncoderTest,ScalingUpAndDownDoesNothingWithMaintainResolution)2670 TEST_F(VideoStreamEncoderTest,
2671        ScalingUpAndDownDoesNothingWithMaintainResolution) {
2672   const int kWidth = 1280;
2673   const int kHeight = 720;
2674   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2675       DataRate::BitsPerSec(kTargetBitrateBps),
2676       DataRate::BitsPerSec(kTargetBitrateBps),
2677       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2678 
2679   // Expect no scaling to begin with.
2680   EXPECT_THAT(video_source_.sink_wants(), UnlimitedSinkWants());
2681 
2682   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2683   WaitForEncodedFrame(1);
2684 
2685   // Trigger scale down.
2686   video_stream_encoder_->TriggerQualityLow();
2687 
2688   video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2689   WaitForEncodedFrame(2);
2690 
2691   // Expect a scale down.
2692   EXPECT_TRUE(video_source_.sink_wants().max_pixel_count);
2693   EXPECT_LT(video_source_.sink_wants().max_pixel_count, kWidth * kHeight);
2694 
2695   // Set resolution scaling disabled.
2696   test::FrameForwarder new_video_source;
2697   video_stream_encoder_->SetSource(
2698       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2699 
2700   // Trigger scale down.
2701   video_stream_encoder_->TriggerQualityLow();
2702   new_video_source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
2703   WaitForEncodedFrame(3);
2704 
2705   // Expect no scaling.
2706   EXPECT_EQ(std::numeric_limits<int>::max(),
2707             new_video_source.sink_wants().max_pixel_count);
2708 
2709   // Trigger scale up.
2710   video_stream_encoder_->TriggerQualityHigh();
2711   new_video_source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
2712   WaitForEncodedFrame(4);
2713 
2714   // Expect nothing to change, still no scaling.
2715   EXPECT_EQ(std::numeric_limits<int>::max(),
2716             new_video_source.sink_wants().max_pixel_count);
2717 
2718   video_stream_encoder_->Stop();
2719 }
2720 
TEST_F(VideoStreamEncoderTest,SkipsSameAdaptDownRequest_MaintainFramerateMode)2721 TEST_F(VideoStreamEncoderTest,
2722        SkipsSameAdaptDownRequest_MaintainFramerateMode) {
2723   const int kWidth = 1280;
2724   const int kHeight = 720;
2725   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2726       DataRate::BitsPerSec(kTargetBitrateBps),
2727       DataRate::BitsPerSec(kTargetBitrateBps),
2728       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2729 
2730   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
2731   test::FrameForwarder source;
2732   video_stream_encoder_->SetSource(
2733       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2734 
2735   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2736   WaitForEncodedFrame(1);
2737   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2738   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
2739   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2740 
2741   // Trigger adapt down, expect scaled down resolution.
2742   video_stream_encoder_->TriggerCpuOveruse();
2743   EXPECT_THAT(source.sink_wants(),
2744               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
2745   const int kLastMaxPixelCount = source.sink_wants().max_pixel_count;
2746   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
2747   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2748 
2749   // Trigger adapt down for same input resolution, expect no change.
2750   video_stream_encoder_->TriggerCpuOveruse();
2751   EXPECT_EQ(kLastMaxPixelCount, source.sink_wants().max_pixel_count);
2752   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
2753   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2754 
2755   video_stream_encoder_->Stop();
2756 }
2757 
TEST_F(VideoStreamEncoderTest,SkipsSameOrLargerAdaptDownRequest_BalancedMode)2758 TEST_F(VideoStreamEncoderTest, SkipsSameOrLargerAdaptDownRequest_BalancedMode) {
2759   const int kWidth = 1280;
2760   const int kHeight = 720;
2761   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2762       DataRate::BitsPerSec(kTargetBitrateBps),
2763       DataRate::BitsPerSec(kTargetBitrateBps),
2764       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2765 
2766   // Enable BALANCED preference, no initial limitation.
2767   test::FrameForwarder source;
2768   video_stream_encoder_->SetSource(&source,
2769                                    webrtc::DegradationPreference::BALANCED);
2770   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2771   sink_.WaitForEncodedFrame(1);
2772   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2773 
2774   // Trigger adapt down, expect scaled down resolution.
2775   video_stream_encoder_->TriggerQualityLow();
2776   EXPECT_THAT(source.sink_wants(),
2777               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
2778   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
2779   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2780   const int kLastMaxPixelCount = source.sink_wants().max_pixel_count;
2781 
2782   // Trigger adapt down for same input resolution, expect no change.
2783   source.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2784   sink_.WaitForEncodedFrame(2);
2785   video_stream_encoder_->TriggerQualityLow();
2786   EXPECT_EQ(kLastMaxPixelCount, source.sink_wants().max_pixel_count);
2787   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
2788   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2789 
2790   // Trigger adapt down for larger input resolution, expect no change.
2791   source.IncomingCapturedFrame(CreateFrame(3, kWidth + 1, kHeight + 1));
2792   sink_.WaitForEncodedFrame(3);
2793   video_stream_encoder_->TriggerQualityLow();
2794   EXPECT_EQ(kLastMaxPixelCount, source.sink_wants().max_pixel_count);
2795   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
2796   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2797 
2798   video_stream_encoder_->Stop();
2799 }
2800 
TEST_F(VideoStreamEncoderTest,NoChangeForInitialNormalUsage_MaintainFramerateMode)2801 TEST_F(VideoStreamEncoderTest,
2802        NoChangeForInitialNormalUsage_MaintainFramerateMode) {
2803   const int kWidth = 1280;
2804   const int kHeight = 720;
2805   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2806       DataRate::BitsPerSec(kTargetBitrateBps),
2807       DataRate::BitsPerSec(kTargetBitrateBps),
2808       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2809 
2810   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
2811   test::FrameForwarder source;
2812   video_stream_encoder_->SetSource(
2813       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2814 
2815   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2816   WaitForEncodedFrame(kWidth, kHeight);
2817   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2818   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
2819   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2820 
2821   // Trigger adapt up, expect no change.
2822   video_stream_encoder_->TriggerCpuUnderuse();
2823   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2824   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
2825   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2826 
2827   video_stream_encoder_->Stop();
2828 }
2829 
TEST_F(VideoStreamEncoderTest,NoChangeForInitialNormalUsage_MaintainResolutionMode)2830 TEST_F(VideoStreamEncoderTest,
2831        NoChangeForInitialNormalUsage_MaintainResolutionMode) {
2832   const int kWidth = 1280;
2833   const int kHeight = 720;
2834   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2835       DataRate::BitsPerSec(kTargetBitrateBps),
2836       DataRate::BitsPerSec(kTargetBitrateBps),
2837       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2838 
2839   // Enable MAINTAIN_RESOLUTION preference, no initial limitation.
2840   test::FrameForwarder source;
2841   video_stream_encoder_->SetSource(
2842       &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2843 
2844   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2845   WaitForEncodedFrame(kWidth, kHeight);
2846   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2847   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
2848   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2849 
2850   // Trigger adapt up, expect no change.
2851   video_stream_encoder_->TriggerCpuUnderuse();
2852   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2853   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
2854   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2855 
2856   video_stream_encoder_->Stop();
2857 }
2858 
TEST_F(VideoStreamEncoderTest,NoChangeForInitialNormalUsage_BalancedMode)2859 TEST_F(VideoStreamEncoderTest, NoChangeForInitialNormalUsage_BalancedMode) {
2860   const int kWidth = 1280;
2861   const int kHeight = 720;
2862   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2863       DataRate::BitsPerSec(kTargetBitrateBps),
2864       DataRate::BitsPerSec(kTargetBitrateBps),
2865       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2866 
2867   // Enable BALANCED preference, no initial limitation.
2868   test::FrameForwarder source;
2869   video_stream_encoder_->SetSource(&source,
2870                                    webrtc::DegradationPreference::BALANCED);
2871 
2872   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2873   sink_.WaitForEncodedFrame(kWidth, kHeight);
2874   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2875   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2876   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
2877   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2878 
2879   // Trigger adapt up, expect no change.
2880   video_stream_encoder_->TriggerQualityHigh();
2881   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2882   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2883   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
2884   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2885 
2886   video_stream_encoder_->Stop();
2887 }
2888 
TEST_F(VideoStreamEncoderTest,NoChangeForInitialNormalUsage_DisabledMode)2889 TEST_F(VideoStreamEncoderTest, NoChangeForInitialNormalUsage_DisabledMode) {
2890   const int kWidth = 1280;
2891   const int kHeight = 720;
2892   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2893       DataRate::BitsPerSec(kTargetBitrateBps),
2894       DataRate::BitsPerSec(kTargetBitrateBps),
2895       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2896 
2897   // Enable DISABLED preference, no initial limitation.
2898   test::FrameForwarder source;
2899   video_stream_encoder_->SetSource(&source,
2900                                    webrtc::DegradationPreference::DISABLED);
2901 
2902   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2903   sink_.WaitForEncodedFrame(kWidth, kHeight);
2904   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2905   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2906   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
2907   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2908 
2909   // Trigger adapt up, expect no change.
2910   video_stream_encoder_->TriggerQualityHigh();
2911   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2912   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2913   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
2914   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2915 
2916   video_stream_encoder_->Stop();
2917 }
2918 
TEST_F(VideoStreamEncoderTest,AdaptsResolutionForLowQuality_MaintainFramerateMode)2919 TEST_F(VideoStreamEncoderTest,
2920        AdaptsResolutionForLowQuality_MaintainFramerateMode) {
2921   const int kWidth = 1280;
2922   const int kHeight = 720;
2923   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2924       DataRate::BitsPerSec(kTargetBitrateBps),
2925       DataRate::BitsPerSec(kTargetBitrateBps),
2926       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2927 
2928   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
2929   AdaptingFrameForwarder source;
2930   source.set_adaptation_enabled(true);
2931   video_stream_encoder_->SetSource(
2932       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
2933 
2934   source.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2935   WaitForEncodedFrame(1);
2936   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2937   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2938   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2939 
2940   // Trigger adapt down, expect scaled down resolution.
2941   video_stream_encoder_->TriggerQualityLow();
2942   source.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2943   WaitForEncodedFrame(2);
2944   EXPECT_THAT(source.sink_wants(),
2945               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
2946   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
2947   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2948 
2949   // Trigger adapt up, expect no restriction.
2950   video_stream_encoder_->TriggerQualityHigh();
2951   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
2952   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
2953   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
2954   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
2955 
2956   video_stream_encoder_->Stop();
2957 }
2958 
TEST_F(VideoStreamEncoderTest,AdaptsFramerateForLowQuality_MaintainResolutionMode)2959 TEST_F(VideoStreamEncoderTest,
2960        AdaptsFramerateForLowQuality_MaintainResolutionMode) {
2961   const int kWidth = 1280;
2962   const int kHeight = 720;
2963   const int kInputFps = 30;
2964   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
2965       DataRate::BitsPerSec(kTargetBitrateBps),
2966       DataRate::BitsPerSec(kTargetBitrateBps),
2967       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
2968 
2969   VideoSendStream::Stats stats = stats_proxy_->GetStats();
2970   stats.input_frame_rate = kInputFps;
2971   stats_proxy_->SetMockStats(stats);
2972 
2973   // Expect no scaling to begin with (preference: MAINTAIN_FRAMERATE).
2974   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
2975   sink_.WaitForEncodedFrame(1);
2976   EXPECT_THAT(video_source_.sink_wants(), FpsMaxResolutionMax());
2977 
2978   // Trigger adapt down, expect scaled down resolution.
2979   video_stream_encoder_->TriggerQualityLow();
2980   video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
2981   sink_.WaitForEncodedFrame(2);
2982   EXPECT_THAT(video_source_.sink_wants(),
2983               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
2984 
2985   // Enable MAINTAIN_RESOLUTION preference.
2986   test::FrameForwarder new_video_source;
2987   video_stream_encoder_->SetSourceAndWaitForRestrictionsUpdated(
2988       &new_video_source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
2989   // Give the encoder queue time to process the change in degradation preference
2990   // by waiting for an encoded frame.
2991   new_video_source.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
2992   sink_.WaitForEncodedFrame(3);
2993   EXPECT_THAT(new_video_source.sink_wants(), FpsMaxResolutionMax());
2994 
2995   // Trigger adapt down, expect reduced framerate.
2996   video_stream_encoder_->TriggerQualityLow();
2997   new_video_source.IncomingCapturedFrame(CreateFrame(4, kWidth, kHeight));
2998   sink_.WaitForEncodedFrame(4);
2999   EXPECT_THAT(new_video_source.sink_wants(),
3000               FpsMatchesResolutionMax(Lt(kInputFps)));
3001 
3002   // Trigger adapt up, expect no restriction.
3003   video_stream_encoder_->TriggerQualityHigh();
3004   EXPECT_THAT(new_video_source.sink_wants(), FpsMaxResolutionMax());
3005 
3006   video_stream_encoder_->Stop();
3007 }
3008 
TEST_F(VideoStreamEncoderTest,DoesNotScaleBelowSetResolutionLimit)3009 TEST_F(VideoStreamEncoderTest, DoesNotScaleBelowSetResolutionLimit) {
3010   const int kWidth = 1280;
3011   const int kHeight = 720;
3012   const size_t kNumFrames = 10;
3013 
3014   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3015       DataRate::BitsPerSec(kTargetBitrateBps),
3016       DataRate::BitsPerSec(kTargetBitrateBps),
3017       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3018 
3019   // Enable adapter, expected input resolutions when downscaling:
3020   // 1280x720 -> 960x540 -> 640x360 -> 480x270 -> 320x180 (kMinPixelsPerFrame)
3021   video_source_.set_adaptation_enabled(true);
3022 
3023   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3024   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3025 
3026   int downscales = 0;
3027   for (size_t i = 1; i <= kNumFrames; i++) {
3028     video_source_.IncomingCapturedFrame(
3029         CreateFrame(i * kFrameIntervalMs, kWidth, kHeight));
3030     WaitForEncodedFrame(i * kFrameIntervalMs);
3031 
3032     // Trigger scale down.
3033     rtc::VideoSinkWants last_wants = video_source_.sink_wants();
3034     video_stream_encoder_->TriggerQualityLow();
3035     EXPECT_GE(video_source_.sink_wants().max_pixel_count, kMinPixelsPerFrame);
3036 
3037     if (video_source_.sink_wants().max_pixel_count < last_wants.max_pixel_count)
3038       ++downscales;
3039 
3040     EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3041     EXPECT_EQ(downscales,
3042               stats_proxy_->GetStats().number_of_quality_adapt_changes);
3043     EXPECT_GT(downscales, 0);
3044   }
3045   video_stream_encoder_->Stop();
3046 }
3047 
TEST_F(VideoStreamEncoderTest,AdaptsResolutionUpAndDownTwiceOnOveruse_MaintainFramerateMode)3048 TEST_F(VideoStreamEncoderTest,
3049        AdaptsResolutionUpAndDownTwiceOnOveruse_MaintainFramerateMode) {
3050   const int kWidth = 1280;
3051   const int kHeight = 720;
3052   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3053       DataRate::BitsPerSec(kTargetBitrateBps),
3054       DataRate::BitsPerSec(kTargetBitrateBps),
3055       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3056 
3057   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
3058   AdaptingFrameForwarder source;
3059   source.set_adaptation_enabled(true);
3060   video_stream_encoder_->SetSource(
3061       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
3062 
3063   int64_t timestamp_ms = kFrameIntervalMs;
3064   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3065   WaitForEncodedFrame(kWidth, kHeight);
3066   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3067   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
3068   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3069 
3070   // Trigger adapt down, expect scaled down resolution.
3071   video_stream_encoder_->TriggerCpuOveruse();
3072   timestamp_ms += kFrameIntervalMs;
3073   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3074   WaitForEncodedFrame(timestamp_ms);
3075   EXPECT_THAT(source.sink_wants(),
3076               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
3077   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3078   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3079 
3080   // Trigger adapt up, expect no restriction.
3081   video_stream_encoder_->TriggerCpuUnderuse();
3082   timestamp_ms += kFrameIntervalMs;
3083   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3084   WaitForEncodedFrame(kWidth, kHeight);
3085   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3086   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
3087   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3088 
3089   // Trigger adapt down, expect scaled down resolution.
3090   video_stream_encoder_->TriggerCpuOveruse();
3091   timestamp_ms += kFrameIntervalMs;
3092   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3093   WaitForEncodedFrame(timestamp_ms);
3094   EXPECT_THAT(source.sink_wants(),
3095               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
3096   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3097   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3098 
3099   // Trigger adapt up, expect no restriction.
3100   video_stream_encoder_->TriggerCpuUnderuse();
3101   timestamp_ms += kFrameIntervalMs;
3102   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3103   sink_.WaitForEncodedFrame(kWidth, kHeight);
3104   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3105   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
3106   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3107 
3108   video_stream_encoder_->Stop();
3109 }
3110 
TEST_F(VideoStreamEncoderTest,AdaptsResolutionUpAndDownTwiceForLowQuality_BalancedMode_NoFpsLimit)3111 TEST_F(VideoStreamEncoderTest,
3112        AdaptsResolutionUpAndDownTwiceForLowQuality_BalancedMode_NoFpsLimit) {
3113   const int kWidth = 1280;
3114   const int kHeight = 720;
3115   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3116       DataRate::BitsPerSec(kTargetBitrateBps),
3117       DataRate::BitsPerSec(kTargetBitrateBps),
3118       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3119 
3120   // Enable BALANCED preference, no initial limitation.
3121   AdaptingFrameForwarder source;
3122   source.set_adaptation_enabled(true);
3123   video_stream_encoder_->SetSource(&source,
3124                                    webrtc::DegradationPreference::BALANCED);
3125 
3126   int64_t timestamp_ms = kFrameIntervalMs;
3127   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3128   sink_.WaitForEncodedFrame(kWidth, kHeight);
3129   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3130   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3131   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3132 
3133   // Trigger adapt down, expect scaled down resolution.
3134   video_stream_encoder_->TriggerQualityLow();
3135   timestamp_ms += kFrameIntervalMs;
3136   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3137   sink_.WaitForEncodedFrame(timestamp_ms);
3138   EXPECT_THAT(source.sink_wants(),
3139               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
3140   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3141   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3142 
3143   // Trigger adapt up, expect no restriction.
3144   video_stream_encoder_->TriggerQualityHigh();
3145   timestamp_ms += kFrameIntervalMs;
3146   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3147   sink_.WaitForEncodedFrame(kWidth, kHeight);
3148   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3149   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3150   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3151 
3152   // Trigger adapt down, expect scaled down resolution.
3153   video_stream_encoder_->TriggerQualityLow();
3154   timestamp_ms += kFrameIntervalMs;
3155   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3156   sink_.WaitForEncodedFrame(timestamp_ms);
3157   EXPECT_THAT(source.sink_wants(),
3158               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
3159   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3160   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3161 
3162   // Trigger adapt up, expect no restriction.
3163   video_stream_encoder_->TriggerQualityHigh();
3164   timestamp_ms += kFrameIntervalMs;
3165   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3166   sink_.WaitForEncodedFrame(kWidth, kHeight);
3167   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3168   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3169   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3170 
3171   video_stream_encoder_->Stop();
3172 }
3173 
TEST_F(VideoStreamEncoderTest,AdaptUpIfBwEstimateIsHigherThanMinBitrate)3174 TEST_F(VideoStreamEncoderTest, AdaptUpIfBwEstimateIsHigherThanMinBitrate) {
3175   fake_encoder_.SetResolutionBitrateLimits(
3176       {kEncoderBitrateLimits540p, kEncoderBitrateLimits720p});
3177 
3178   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3179       DataRate::BitsPerSec(kEncoderBitrateLimits720p.min_start_bitrate_bps),
3180       DataRate::BitsPerSec(kEncoderBitrateLimits720p.min_start_bitrate_bps),
3181       DataRate::BitsPerSec(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0,
3182       0, 0);
3183 
3184   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
3185   AdaptingFrameForwarder source;
3186   source.set_adaptation_enabled(true);
3187   video_stream_encoder_->SetSource(
3188       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
3189 
3190   // Insert 720p frame.
3191   int64_t timestamp_ms = kFrameIntervalMs;
3192   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
3193   WaitForEncodedFrame(1280, 720);
3194 
3195   // Reduce bitrate and trigger adapt down.
3196   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3197       DataRate::BitsPerSec(kEncoderBitrateLimits540p.min_start_bitrate_bps),
3198       DataRate::BitsPerSec(kEncoderBitrateLimits540p.min_start_bitrate_bps),
3199       DataRate::BitsPerSec(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0,
3200       0, 0);
3201   video_stream_encoder_->TriggerQualityLow();
3202 
3203   // Insert 720p frame. It should be downscaled and encoded.
3204   timestamp_ms += kFrameIntervalMs;
3205   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
3206   WaitForEncodedFrame(960, 540);
3207 
3208   // Trigger adapt up. Higher resolution should not be requested duo to lack
3209   // of bitrate.
3210   video_stream_encoder_->TriggerQualityHigh();
3211   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMatches(Lt(1280 * 720)));
3212 
3213   // Increase bitrate.
3214   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3215       DataRate::BitsPerSec(kEncoderBitrateLimits720p.min_start_bitrate_bps),
3216       DataRate::BitsPerSec(kEncoderBitrateLimits720p.min_start_bitrate_bps),
3217       DataRate::BitsPerSec(kEncoderBitrateLimits720p.min_start_bitrate_bps), 0,
3218       0, 0);
3219 
3220   // Trigger adapt up. Higher resolution should be requested.
3221   video_stream_encoder_->TriggerQualityHigh();
3222   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3223 
3224   video_stream_encoder_->Stop();
3225 }
3226 
TEST_F(VideoStreamEncoderTest,DropFirstFramesIfBwEstimateIsTooLow)3227 TEST_F(VideoStreamEncoderTest, DropFirstFramesIfBwEstimateIsTooLow) {
3228   fake_encoder_.SetResolutionBitrateLimits(
3229       {kEncoderBitrateLimits540p, kEncoderBitrateLimits720p});
3230 
3231   // Set bitrate equal to min bitrate of 540p.
3232   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3233       DataRate::BitsPerSec(kEncoderBitrateLimits540p.min_start_bitrate_bps),
3234       DataRate::BitsPerSec(kEncoderBitrateLimits540p.min_start_bitrate_bps),
3235       DataRate::BitsPerSec(kEncoderBitrateLimits540p.min_start_bitrate_bps), 0,
3236       0, 0);
3237 
3238   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
3239   AdaptingFrameForwarder source;
3240   source.set_adaptation_enabled(true);
3241   video_stream_encoder_->SetSource(
3242       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
3243 
3244   // Insert 720p frame. It should be dropped and lower resolution should be
3245   // requested.
3246   int64_t timestamp_ms = kFrameIntervalMs;
3247   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
3248   ExpectDroppedFrame();
3249   EXPECT_TRUE_WAIT(source.sink_wants().max_pixel_count < 1280 * 720, 5000);
3250 
3251   // Insert 720p frame. It should be downscaled and encoded.
3252   timestamp_ms += kFrameIntervalMs;
3253   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, 1280, 720));
3254   WaitForEncodedFrame(960, 540);
3255 
3256   video_stream_encoder_->Stop();
3257 }
3258 
3259 class BalancedDegradationTest : public VideoStreamEncoderTest {
3260  protected:
SetupTest()3261   void SetupTest() {
3262     // Reset encoder for field trials to take effect.
3263     ConfigureEncoder(video_encoder_config_.Copy());
3264     OnBitrateUpdated(kTargetBitrateBps);
3265 
3266     // Enable BALANCED preference.
3267     source_.set_adaptation_enabled(true);
3268     video_stream_encoder_->SetSource(&source_, DegradationPreference::BALANCED);
3269   }
3270 
OnBitrateUpdated(int bitrate_bps)3271   void OnBitrateUpdated(int bitrate_bps) {
3272     video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3273         DataRate::BitsPerSec(bitrate_bps), DataRate::BitsPerSec(bitrate_bps),
3274         DataRate::BitsPerSec(bitrate_bps), 0, 0, 0);
3275   }
3276 
InsertFrame()3277   void InsertFrame() {
3278     timestamp_ms_ += kFrameIntervalMs;
3279     source_.IncomingCapturedFrame(CreateFrame(timestamp_ms_, kWidth, kHeight));
3280   }
3281 
InsertFrameAndWaitForEncoded()3282   void InsertFrameAndWaitForEncoded() {
3283     InsertFrame();
3284     sink_.WaitForEncodedFrame(timestamp_ms_);
3285   }
3286 
3287   const int kWidth = 640;  // pixels:640x360=230400
3288   const int kHeight = 360;
3289   const int64_t kFrameIntervalMs = 150;  // Use low fps to not drop any frame.
3290   int64_t timestamp_ms_ = 0;
3291   AdaptingFrameForwarder source_;
3292 };
3293 
TEST_F(BalancedDegradationTest,AdaptDownReturnsFalseIfFpsDiffLtThreshold)3294 TEST_F(BalancedDegradationTest, AdaptDownReturnsFalseIfFpsDiffLtThreshold) {
3295   test::ScopedFieldTrials field_trials(
3296       "WebRTC-Video-BalancedDegradationSettings/"
3297       "pixels:57600|129600|230400,fps:7|10|24,fps_diff:1|1|1/");
3298   SetupTest();
3299 
3300   // Force input frame rate.
3301   const int kInputFps = 24;
3302   VideoSendStream::Stats stats = stats_proxy_->GetStats();
3303   stats.input_frame_rate = kInputFps;
3304   stats_proxy_->SetMockStats(stats);
3305 
3306   InsertFrameAndWaitForEncoded();
3307   EXPECT_THAT(source_.sink_wants(), FpsMaxResolutionMax());
3308 
3309   // Trigger adapt down, expect scaled down framerate (640x360@24fps).
3310   // Fps diff (input-requested:0) < threshold, expect adapting down not to clear
3311   // QP samples.
3312   EXPECT_FALSE(
3313       video_stream_encoder_
3314           ->TriggerQualityScalerHighQpAndReturnIfQpSamplesShouldBeCleared());
3315   EXPECT_THAT(source_.sink_wants(), FpsMatchesResolutionMax(Eq(24)));
3316 
3317   video_stream_encoder_->Stop();
3318 }
3319 
TEST_F(BalancedDegradationTest,AdaptDownReturnsTrueIfFpsDiffGeThreshold)3320 TEST_F(BalancedDegradationTest, AdaptDownReturnsTrueIfFpsDiffGeThreshold) {
3321   test::ScopedFieldTrials field_trials(
3322       "WebRTC-Video-BalancedDegradationSettings/"
3323       "pixels:57600|129600|230400,fps:7|10|24,fps_diff:1|1|1/");
3324   SetupTest();
3325 
3326   // Force input frame rate.
3327   const int kInputFps = 25;
3328   VideoSendStream::Stats stats = stats_proxy_->GetStats();
3329   stats.input_frame_rate = kInputFps;
3330   stats_proxy_->SetMockStats(stats);
3331 
3332   InsertFrameAndWaitForEncoded();
3333   EXPECT_THAT(source_.sink_wants(), FpsMaxResolutionMax());
3334 
3335   // Trigger adapt down, expect scaled down framerate (640x360@24fps).
3336   // Fps diff (input-requested:1) == threshold, expect adapting down to clear QP
3337   // samples.
3338   EXPECT_TRUE(
3339       video_stream_encoder_
3340           ->TriggerQualityScalerHighQpAndReturnIfQpSamplesShouldBeCleared());
3341   EXPECT_THAT(source_.sink_wants(), FpsMatchesResolutionMax(Eq(24)));
3342 
3343   video_stream_encoder_->Stop();
3344 }
3345 
TEST_F(BalancedDegradationTest,AdaptDownUsesCodecSpecificFps)3346 TEST_F(BalancedDegradationTest, AdaptDownUsesCodecSpecificFps) {
3347   test::ScopedFieldTrials field_trials(
3348       "WebRTC-Video-BalancedDegradationSettings/"
3349       "pixels:57600|129600|230400,fps:7|10|24,vp8_fps:8|11|22/");
3350   SetupTest();
3351 
3352   EXPECT_EQ(kVideoCodecVP8, video_encoder_config_.codec_type);
3353 
3354   InsertFrameAndWaitForEncoded();
3355   EXPECT_THAT(source_.sink_wants(), FpsMaxResolutionMax());
3356 
3357   // Trigger adapt down, expect scaled down framerate (640x360@22fps).
3358   video_stream_encoder_->TriggerQualityLow();
3359   EXPECT_THAT(source_.sink_wants(), FpsMatchesResolutionMax(Eq(22)));
3360 
3361   video_stream_encoder_->Stop();
3362 }
3363 
TEST_F(BalancedDegradationTest,NoAdaptUpIfBwEstimateIsLessThanMinBitrate)3364 TEST_F(BalancedDegradationTest, NoAdaptUpIfBwEstimateIsLessThanMinBitrate) {
3365   test::ScopedFieldTrials field_trials(
3366       "WebRTC-Video-BalancedDegradationSettings/"
3367       "pixels:57600|129600|230400,fps:7|10|14,kbps:0|0|425/");
3368   SetupTest();
3369 
3370   const int kMinBitrateBps = 425000;
3371   const int kTooLowMinBitrateBps = 424000;
3372   OnBitrateUpdated(kTooLowMinBitrateBps);
3373 
3374   InsertFrameAndWaitForEncoded();
3375   EXPECT_THAT(source_.sink_wants(), FpsMaxResolutionMax());
3376   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3377 
3378   // Trigger adapt down, expect scaled down framerate (640x360@14fps).
3379   video_stream_encoder_->TriggerQualityLow();
3380   InsertFrameAndWaitForEncoded();
3381   EXPECT_THAT(source_.sink_wants(), FpsMatchesResolutionMax(Eq(14)));
3382   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3383 
3384   // Trigger adapt down, expect scaled down resolution (480x270@14fps).
3385   video_stream_encoder_->TriggerQualityLow();
3386   InsertFrameAndWaitForEncoded();
3387   EXPECT_THAT(source_.sink_wants(), FpsEqResolutionLt(source_.last_wants()));
3388   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3389 
3390   // Trigger adapt down, expect scaled down framerate (480x270@10fps).
3391   video_stream_encoder_->TriggerQualityLow();
3392   InsertFrameAndWaitForEncoded();
3393   EXPECT_THAT(source_.sink_wants(), FpsLtResolutionEq(source_.last_wants()));
3394   EXPECT_EQ(source_.sink_wants().max_framerate_fps, 10);
3395   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3396 
3397   // Trigger adapt up, expect no upscale in fps (target bitrate < min bitrate).
3398   video_stream_encoder_->TriggerQualityHigh();
3399   InsertFrameAndWaitForEncoded();
3400   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3401 
3402   // Trigger adapt up, expect upscaled fps (target bitrate == min bitrate).
3403   OnBitrateUpdated(kMinBitrateBps);
3404   video_stream_encoder_->TriggerQualityHigh();
3405   InsertFrameAndWaitForEncoded();
3406   EXPECT_EQ(source_.sink_wants().max_framerate_fps, 14);
3407   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3408 
3409   video_stream_encoder_->Stop();
3410 }
3411 
TEST_F(BalancedDegradationTest,InitialFrameDropAdaptsFpsAndResolutionInOneStep)3412 TEST_F(BalancedDegradationTest,
3413        InitialFrameDropAdaptsFpsAndResolutionInOneStep) {
3414   test::ScopedFieldTrials field_trials(
3415       "WebRTC-Video-BalancedDegradationSettings/"
3416       "pixels:57600|129600|230400,fps:7|24|24/");
3417   SetupTest();
3418   OnBitrateUpdated(kLowTargetBitrateBps);
3419 
3420   EXPECT_THAT(source_.sink_wants(), UnlimitedSinkWants());
3421 
3422   // Insert frame, expect scaled down:
3423   // framerate (640x360@24fps) -> resolution (480x270@24fps).
3424   InsertFrame();
3425   EXPECT_FALSE(WaitForFrame(1000));
3426   EXPECT_LT(source_.sink_wants().max_pixel_count, kWidth * kHeight);
3427   EXPECT_EQ(source_.sink_wants().max_framerate_fps, 24);
3428 
3429   // Insert frame, expect scaled down:
3430   // resolution (320x180@24fps).
3431   InsertFrame();
3432   EXPECT_FALSE(WaitForFrame(1000));
3433   EXPECT_LT(source_.sink_wants().max_pixel_count,
3434             source_.last_wants().max_pixel_count);
3435   EXPECT_EQ(source_.sink_wants().max_framerate_fps, 24);
3436 
3437   // Frame should not be dropped (min pixels per frame reached).
3438   InsertFrameAndWaitForEncoded();
3439 
3440   video_stream_encoder_->Stop();
3441 }
3442 
TEST_F(BalancedDegradationTest,NoAdaptUpInResolutionIfBwEstimateIsLessThanMinBitrate)3443 TEST_F(BalancedDegradationTest,
3444        NoAdaptUpInResolutionIfBwEstimateIsLessThanMinBitrate) {
3445   test::ScopedFieldTrials field_trials(
3446       "WebRTC-Video-BalancedDegradationSettings/"
3447       "pixels:57600|129600|230400,fps:7|10|14,kbps_res:0|0|435/");
3448   SetupTest();
3449 
3450   const int kResolutionMinBitrateBps = 435000;
3451   const int kTooLowMinResolutionBitrateBps = 434000;
3452   OnBitrateUpdated(kTooLowMinResolutionBitrateBps);
3453 
3454   InsertFrameAndWaitForEncoded();
3455   EXPECT_THAT(source_.sink_wants(), FpsMaxResolutionMax());
3456   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3457 
3458   // Trigger adapt down, expect scaled down framerate (640x360@14fps).
3459   video_stream_encoder_->TriggerQualityLow();
3460   InsertFrameAndWaitForEncoded();
3461   EXPECT_THAT(source_.sink_wants(), FpsMatchesResolutionMax(Eq(14)));
3462   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3463 
3464   // Trigger adapt down, expect scaled down resolution (480x270@14fps).
3465   video_stream_encoder_->TriggerQualityLow();
3466   InsertFrameAndWaitForEncoded();
3467   EXPECT_THAT(source_.sink_wants(), FpsEqResolutionLt(source_.last_wants()));
3468   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3469 
3470   // Trigger adapt down, expect scaled down framerate (480x270@10fps).
3471   video_stream_encoder_->TriggerQualityLow();
3472   InsertFrameAndWaitForEncoded();
3473   EXPECT_THAT(source_.sink_wants(), FpsLtResolutionEq(source_.last_wants()));
3474   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3475 
3476   // Trigger adapt up, expect upscaled fps (no bitrate limit) (480x270@14fps).
3477   video_stream_encoder_->TriggerQualityHigh();
3478   InsertFrameAndWaitForEncoded();
3479   EXPECT_THAT(source_.sink_wants(), FpsGtResolutionEq(source_.last_wants()));
3480   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3481 
3482   // Trigger adapt up, expect no upscale in res (target bitrate < min bitrate).
3483   video_stream_encoder_->TriggerQualityHigh();
3484   InsertFrameAndWaitForEncoded();
3485   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3486 
3487   // Trigger adapt up, expect upscaled res (target bitrate == min bitrate).
3488   OnBitrateUpdated(kResolutionMinBitrateBps);
3489   video_stream_encoder_->TriggerQualityHigh();
3490   InsertFrameAndWaitForEncoded();
3491   EXPECT_THAT(source_.sink_wants(), FpsEqResolutionGt(source_.last_wants()));
3492   EXPECT_EQ(5, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3493 
3494   video_stream_encoder_->Stop();
3495 }
3496 
TEST_F(BalancedDegradationTest,NoAdaptUpInFpsAndResolutionIfBwEstimateIsLessThanMinBitrate)3497 TEST_F(BalancedDegradationTest,
3498        NoAdaptUpInFpsAndResolutionIfBwEstimateIsLessThanMinBitrate) {
3499   test::ScopedFieldTrials field_trials(
3500       "WebRTC-Video-BalancedDegradationSettings/"
3501       "pixels:57600|129600|230400,fps:7|10|14,kbps:0|0|425,kbps_res:0|0|435/");
3502   SetupTest();
3503 
3504   const int kMinBitrateBps = 425000;
3505   const int kTooLowMinBitrateBps = 424000;
3506   const int kResolutionMinBitrateBps = 435000;
3507   const int kTooLowMinResolutionBitrateBps = 434000;
3508   OnBitrateUpdated(kTooLowMinBitrateBps);
3509 
3510   InsertFrameAndWaitForEncoded();
3511   EXPECT_THAT(source_.sink_wants(), FpsMaxResolutionMax());
3512   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3513 
3514   // Trigger adapt down, expect scaled down framerate (640x360@14fps).
3515   video_stream_encoder_->TriggerQualityLow();
3516   InsertFrameAndWaitForEncoded();
3517   EXPECT_THAT(source_.sink_wants(), FpsMatchesResolutionMax(Eq(14)));
3518   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3519 
3520   // Trigger adapt down, expect scaled down resolution (480x270@14fps).
3521   video_stream_encoder_->TriggerQualityLow();
3522   InsertFrameAndWaitForEncoded();
3523   EXPECT_THAT(source_.sink_wants(), FpsEqResolutionLt(source_.last_wants()));
3524   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3525 
3526   // Trigger adapt down, expect scaled down framerate (480x270@10fps).
3527   video_stream_encoder_->TriggerQualityLow();
3528   InsertFrameAndWaitForEncoded();
3529   EXPECT_THAT(source_.sink_wants(), FpsLtResolutionEq(source_.last_wants()));
3530   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3531 
3532   // Trigger adapt up, expect no upscale (target bitrate < min bitrate).
3533   video_stream_encoder_->TriggerQualityHigh();
3534   InsertFrameAndWaitForEncoded();
3535   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3536 
3537   // Trigger adapt up, expect upscaled fps (target bitrate == min bitrate).
3538   OnBitrateUpdated(kMinBitrateBps);
3539   video_stream_encoder_->TriggerQualityHigh();
3540   InsertFrameAndWaitForEncoded();
3541   EXPECT_THAT(source_.sink_wants(), FpsGtResolutionEq(source_.last_wants()));
3542   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3543 
3544   // Trigger adapt up, expect no upscale in res (target bitrate < min bitrate).
3545   OnBitrateUpdated(kTooLowMinResolutionBitrateBps);
3546   video_stream_encoder_->TriggerQualityHigh();
3547   InsertFrameAndWaitForEncoded();
3548   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3549 
3550   // Trigger adapt up, expect upscaled res (target bitrate == min bitrate).
3551   OnBitrateUpdated(kResolutionMinBitrateBps);
3552   video_stream_encoder_->TriggerQualityHigh();
3553   InsertFrameAndWaitForEncoded();
3554   EXPECT_THAT(source_.sink_wants(), FpsEqResolutionGt(source_.last_wants()));
3555   EXPECT_EQ(5, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3556 
3557   video_stream_encoder_->Stop();
3558 }
3559 
TEST_F(VideoStreamEncoderTest,AdaptsResolutionOnOveruseAndLowQuality_MaintainFramerateMode)3560 TEST_F(VideoStreamEncoderTest,
3561        AdaptsResolutionOnOveruseAndLowQuality_MaintainFramerateMode) {
3562   const int kWidth = 1280;
3563   const int kHeight = 720;
3564   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3565       DataRate::BitsPerSec(kTargetBitrateBps),
3566       DataRate::BitsPerSec(kTargetBitrateBps),
3567       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3568 
3569   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
3570   AdaptingFrameForwarder source;
3571   source.set_adaptation_enabled(true);
3572   video_stream_encoder_->SetSource(
3573       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
3574 
3575   int64_t timestamp_ms = kFrameIntervalMs;
3576   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3577   WaitForEncodedFrame(kWidth, kHeight);
3578   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3579   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
3580   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3581   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3582   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3583 
3584   // Trigger cpu adapt down, expect scaled down resolution (960x540).
3585   video_stream_encoder_->TriggerCpuOveruse();
3586   timestamp_ms += kFrameIntervalMs;
3587   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3588   WaitForEncodedFrame(timestamp_ms);
3589   EXPECT_THAT(source.sink_wants(),
3590               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
3591   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3592   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3593   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3594   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3595 
3596   // Trigger cpu adapt down, expect scaled down resolution (640x360).
3597   video_stream_encoder_->TriggerCpuOveruse();
3598   timestamp_ms += kFrameIntervalMs;
3599   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3600   WaitForEncodedFrame(timestamp_ms);
3601   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionLt(source.last_wants()));
3602   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3603   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3604   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3605   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3606 
3607   // Trigger cpu adapt down, expect scaled down resolution (480x270).
3608   video_stream_encoder_->TriggerCpuOveruse();
3609   timestamp_ms += kFrameIntervalMs;
3610   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3611   WaitForEncodedFrame(timestamp_ms);
3612   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionLt(source.last_wants()));
3613   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3614   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3615   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3616   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3617 
3618   // Trigger quality adapt down, expect scaled down resolution (320x180).
3619   video_stream_encoder_->TriggerQualityLow();
3620   timestamp_ms += kFrameIntervalMs;
3621   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3622   WaitForEncodedFrame(timestamp_ms);
3623   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionLt(source.last_wants()));
3624   rtc::VideoSinkWants last_wants = source.sink_wants();
3625   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3626   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3627   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3628   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3629 
3630   // Trigger quality adapt down, expect no change (min resolution reached).
3631   video_stream_encoder_->TriggerQualityLow();
3632   timestamp_ms += kFrameIntervalMs;
3633   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3634   WaitForEncodedFrame(timestamp_ms);
3635   EXPECT_THAT(source.sink_wants(), FpsMax());
3636   EXPECT_EQ(source.sink_wants().max_pixel_count, last_wants.max_pixel_count);
3637   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3638   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3639   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3640   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3641 
3642   // Trigger quality adapt up, expect upscaled resolution (480x270).
3643   video_stream_encoder_->TriggerQualityHigh();
3644   timestamp_ms += kFrameIntervalMs;
3645   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3646   WaitForEncodedFrame(timestamp_ms);
3647   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
3648   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3649   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3650   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3651   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3652 
3653   // Trigger quality and cpu adapt up since both are most limited, expect
3654   // upscaled resolution (640x360).
3655   video_stream_encoder_->TriggerCpuUnderuse();
3656   video_stream_encoder_->TriggerQualityHigh();
3657   timestamp_ms += kFrameIntervalMs;
3658   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3659   WaitForEncodedFrame(timestamp_ms);
3660   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
3661   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3662   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3663   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3664   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3665 
3666   // Trigger quality and cpu adapt up since both are most limited, expect
3667   // upscaled resolution (960x540).
3668   video_stream_encoder_->TriggerCpuUnderuse();
3669   video_stream_encoder_->TriggerQualityHigh();
3670   timestamp_ms += kFrameIntervalMs;
3671   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3672   WaitForEncodedFrame(timestamp_ms);
3673   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
3674   last_wants = source.sink_wants();
3675   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
3676   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3677   EXPECT_EQ(5, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3678   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3679 
3680   // Trigger cpu adapt up, expect no change since not most limited (960x540).
3681   // However the stats will change since the CPU resource is no longer limited.
3682   video_stream_encoder_->TriggerCpuUnderuse();
3683   timestamp_ms += kFrameIntervalMs;
3684   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3685   WaitForEncodedFrame(timestamp_ms);
3686   EXPECT_THAT(source.sink_wants(), FpsEqResolutionEqTo(last_wants));
3687   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
3688   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
3689   EXPECT_EQ(6, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3690   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3691 
3692   // Trigger quality adapt up, expect no restriction (1280x720).
3693   video_stream_encoder_->TriggerQualityHigh();
3694   timestamp_ms += kFrameIntervalMs;
3695   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
3696   WaitForEncodedFrame(kWidth, kHeight);
3697   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
3698   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
3699   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
3700   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
3701   EXPECT_EQ(6, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
3702   EXPECT_EQ(5, stats_proxy_->GetStats().number_of_quality_adapt_changes);
3703 
3704   video_stream_encoder_->Stop();
3705 }
3706 
TEST_F(VideoStreamEncoderTest,CpuLimitedHistogramIsReported)3707 TEST_F(VideoStreamEncoderTest, CpuLimitedHistogramIsReported) {
3708   const int kWidth = 640;
3709   const int kHeight = 360;
3710 
3711   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3712       DataRate::BitsPerSec(kTargetBitrateBps),
3713       DataRate::BitsPerSec(kTargetBitrateBps),
3714       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3715 
3716   for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
3717     video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight));
3718     WaitForEncodedFrame(i);
3719   }
3720 
3721   video_stream_encoder_->TriggerCpuOveruse();
3722   for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
3723     video_source_.IncomingCapturedFrame(CreateFrame(
3724         SendStatisticsProxy::kMinRequiredMetricsSamples + i, kWidth, kHeight));
3725     WaitForEncodedFrame(SendStatisticsProxy::kMinRequiredMetricsSamples + i);
3726   }
3727 
3728   video_stream_encoder_->Stop();
3729   video_stream_encoder_.reset();
3730   stats_proxy_.reset();
3731 
3732   EXPECT_METRIC_EQ(
3733       1, metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
3734   EXPECT_METRIC_EQ(
3735       1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
3736 }
3737 
TEST_F(VideoStreamEncoderTest,CpuLimitedHistogramIsNotReportedForDisabledDegradation)3738 TEST_F(VideoStreamEncoderTest,
3739        CpuLimitedHistogramIsNotReportedForDisabledDegradation) {
3740   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3741       DataRate::BitsPerSec(kTargetBitrateBps),
3742       DataRate::BitsPerSec(kTargetBitrateBps),
3743       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3744   const int kWidth = 640;
3745   const int kHeight = 360;
3746 
3747   video_stream_encoder_->SetSource(&video_source_,
3748                                    webrtc::DegradationPreference::DISABLED);
3749 
3750   for (int i = 1; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
3751     video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight));
3752     WaitForEncodedFrame(i);
3753   }
3754 
3755   video_stream_encoder_->Stop();
3756   video_stream_encoder_.reset();
3757   stats_proxy_.reset();
3758 
3759   EXPECT_EQ(0,
3760             metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
3761 }
3762 
TEST_F(VideoStreamEncoderTest,CallsBitrateObserver)3763 TEST_F(VideoStreamEncoderTest, CallsBitrateObserver) {
3764   MockBitrateObserver bitrate_observer;
3765   video_stream_encoder_->SetBitrateAllocationObserver(&bitrate_observer);
3766 
3767   const int kDefaultFps = 30;
3768   const VideoBitrateAllocation expected_bitrate =
3769       SimulcastRateAllocator(fake_encoder_.codec_config())
3770           .Allocate(VideoBitrateAllocationParameters(kLowTargetBitrateBps,
3771                                                      kDefaultFps));
3772 
3773   EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
3774       .Times(1);
3775   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3776       DataRate::BitsPerSec(kLowTargetBitrateBps),
3777       DataRate::BitsPerSec(kLowTargetBitrateBps),
3778       DataRate::BitsPerSec(kLowTargetBitrateBps), 0, 0, 0);
3779 
3780   video_source_.IncomingCapturedFrame(
3781       CreateFrame(rtc::TimeMillis(), codec_width_, codec_height_));
3782   WaitForEncodedFrame(rtc::TimeMillis());
3783   VideoBitrateAllocation bitrate_allocation =
3784       fake_encoder_.GetAndResetLastRateControlSettings()->bitrate;
3785   // Check that encoder has been updated too, not just allocation observer.
3786   EXPECT_EQ(bitrate_allocation.get_sum_bps(), kLowTargetBitrateBps);
3787   // TODO(srte): The use of millisecs here looks like an error, but the tests
3788   // fails using seconds, this should be investigated.
3789   fake_clock_.AdvanceTime(TimeDelta::Millis(1) / kDefaultFps);
3790 
3791   // Not called on second frame.
3792   EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
3793       .Times(0);
3794   video_source_.IncomingCapturedFrame(
3795       CreateFrame(rtc::TimeMillis(), codec_width_, codec_height_));
3796   WaitForEncodedFrame(rtc::TimeMillis());
3797   fake_clock_.AdvanceTime(TimeDelta::Millis(1) / kDefaultFps);
3798 
3799   // Called after a process interval.
3800   EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate))
3801       .Times(1);
3802   const int64_t start_time_ms = rtc::TimeMillis();
3803   while (rtc::TimeMillis() - start_time_ms < kProcessIntervalMs) {
3804     video_source_.IncomingCapturedFrame(
3805         CreateFrame(rtc::TimeMillis(), codec_width_, codec_height_));
3806     WaitForEncodedFrame(rtc::TimeMillis());
3807     fake_clock_.AdvanceTime(TimeDelta::Millis(1) / kDefaultFps);
3808   }
3809 
3810   // Since rates are unchanged, encoder should not be reconfigured.
3811   EXPECT_FALSE(fake_encoder_.GetAndResetLastRateControlSettings().has_value());
3812 
3813   video_stream_encoder_->Stop();
3814 }
3815 
TEST_F(VideoStreamEncoderTest,TemporalLayersNotDisabledIfSupported)3816 TEST_F(VideoStreamEncoderTest, TemporalLayersNotDisabledIfSupported) {
3817   // 2 TLs configured, temporal layers supported by encoder.
3818   const int kNumTemporalLayers = 2;
3819   ResetEncoder("VP8", 1, kNumTemporalLayers, 1, /*screenshare*/ false);
3820   fake_encoder_.SetTemporalLayersSupported(0, true);
3821 
3822   // Bitrate allocated across temporal layers.
3823   const int kTl0Bps = kTargetBitrateBps *
3824                       webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
3825                           kNumTemporalLayers, /*temporal_id*/ 0,
3826                           /*base_heavy_tl3_alloc*/ false);
3827   const int kTl1Bps = kTargetBitrateBps *
3828                       webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
3829                           kNumTemporalLayers, /*temporal_id*/ 1,
3830                           /*base_heavy_tl3_alloc*/ false);
3831   VideoBitrateAllocation expected_bitrate;
3832   expected_bitrate.SetBitrate(/*si*/ 0, /*ti*/ 0, kTl0Bps);
3833   expected_bitrate.SetBitrate(/*si*/ 0, /*ti*/ 1, kTl1Bps - kTl0Bps);
3834 
3835   VerifyAllocatedBitrate(expected_bitrate);
3836   video_stream_encoder_->Stop();
3837 }
3838 
TEST_F(VideoStreamEncoderTest,TemporalLayersDisabledIfNotSupported)3839 TEST_F(VideoStreamEncoderTest, TemporalLayersDisabledIfNotSupported) {
3840   // 2 TLs configured, temporal layers not supported by encoder.
3841   ResetEncoder("VP8", 1, /*num_temporal_layers*/ 2, 1, /*screenshare*/ false);
3842   fake_encoder_.SetTemporalLayersSupported(0, false);
3843 
3844   // Temporal layers not supported by the encoder.
3845   // Total bitrate should be at ti:0.
3846   VideoBitrateAllocation expected_bitrate;
3847   expected_bitrate.SetBitrate(/*si*/ 0, /*ti*/ 0, kTargetBitrateBps);
3848 
3849   VerifyAllocatedBitrate(expected_bitrate);
3850   video_stream_encoder_->Stop();
3851 }
3852 
TEST_F(VideoStreamEncoderTest,VerifyBitrateAllocationForTwoStreams)3853 TEST_F(VideoStreamEncoderTest, VerifyBitrateAllocationForTwoStreams) {
3854   // 2 TLs configured, temporal layers only supported for first stream.
3855   ResetEncoder("VP8", 2, /*num_temporal_layers*/ 2, 1, /*screenshare*/ false);
3856   fake_encoder_.SetTemporalLayersSupported(0, true);
3857   fake_encoder_.SetTemporalLayersSupported(1, false);
3858 
3859   const int kS0Bps = 150000;
3860   const int kS0Tl0Bps =
3861       kS0Bps *
3862       webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
3863           /*num_layers*/ 2, /*temporal_id*/ 0, /*base_heavy_tl3_alloc*/ false);
3864   const int kS0Tl1Bps =
3865       kS0Bps *
3866       webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(
3867           /*num_layers*/ 2, /*temporal_id*/ 1, /*base_heavy_tl3_alloc*/ false);
3868   const int kS1Bps = kTargetBitrateBps - kS0Tl1Bps;
3869   // Temporal layers not supported by si:1.
3870   VideoBitrateAllocation expected_bitrate;
3871   expected_bitrate.SetBitrate(/*si*/ 0, /*ti*/ 0, kS0Tl0Bps);
3872   expected_bitrate.SetBitrate(/*si*/ 0, /*ti*/ 1, kS0Tl1Bps - kS0Tl0Bps);
3873   expected_bitrate.SetBitrate(/*si*/ 1, /*ti*/ 0, kS1Bps);
3874 
3875   VerifyAllocatedBitrate(expected_bitrate);
3876   video_stream_encoder_->Stop();
3877 }
3878 
TEST_F(VideoStreamEncoderTest,OveruseDetectorUpdatedOnReconfigureAndAdaption)3879 TEST_F(VideoStreamEncoderTest, OveruseDetectorUpdatedOnReconfigureAndAdaption) {
3880   const int kFrameWidth = 1280;
3881   const int kFrameHeight = 720;
3882   const int kFramerate = 24;
3883 
3884   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3885       DataRate::BitsPerSec(kTargetBitrateBps),
3886       DataRate::BitsPerSec(kTargetBitrateBps),
3887       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3888   test::FrameForwarder source;
3889   video_stream_encoder_->SetSource(
3890       &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
3891 
3892   // Insert a single frame, triggering initial configuration.
3893   source.IncomingCapturedFrame(CreateFrame(1, kFrameWidth, kFrameHeight));
3894   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3895 
3896   EXPECT_EQ(
3897       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
3898       kDefaultFramerate);
3899 
3900   // Trigger reconfigure encoder (without resetting the entire instance).
3901   VideoEncoderConfig video_encoder_config;
3902   video_encoder_config.codec_type = kVideoCodecVP8;
3903   video_encoder_config.max_bitrate_bps = kTargetBitrateBps;
3904   video_encoder_config.number_of_streams = 1;
3905   video_encoder_config.video_stream_factory =
3906       new rtc::RefCountedObject<VideoStreamFactory>(1, kFramerate);
3907   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
3908                                           kMaxPayloadLength);
3909   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3910 
3911   // Detector should be updated with fps limit from codec config.
3912   EXPECT_EQ(
3913       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
3914       kFramerate);
3915 
3916   // Trigger overuse, max framerate should be reduced.
3917   VideoSendStream::Stats stats = stats_proxy_->GetStats();
3918   stats.input_frame_rate = kFramerate;
3919   stats_proxy_->SetMockStats(stats);
3920   video_stream_encoder_->TriggerCpuOveruse();
3921   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3922   int adapted_framerate =
3923       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate();
3924   EXPECT_LT(adapted_framerate, kFramerate);
3925 
3926   // Trigger underuse, max framerate should go back to codec configured fps.
3927   // Set extra low fps, to make sure it's actually reset, not just incremented.
3928   stats = stats_proxy_->GetStats();
3929   stats.input_frame_rate = adapted_framerate / 2;
3930   stats_proxy_->SetMockStats(stats);
3931   video_stream_encoder_->TriggerCpuUnderuse();
3932   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3933   EXPECT_EQ(
3934       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
3935       kFramerate);
3936 
3937   video_stream_encoder_->Stop();
3938 }
3939 
TEST_F(VideoStreamEncoderTest,OveruseDetectorUpdatedRespectsFramerateAfterUnderuse)3940 TEST_F(VideoStreamEncoderTest,
3941        OveruseDetectorUpdatedRespectsFramerateAfterUnderuse) {
3942   const int kFrameWidth = 1280;
3943   const int kFrameHeight = 720;
3944   const int kLowFramerate = 15;
3945   const int kHighFramerate = 25;
3946 
3947   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
3948       DataRate::BitsPerSec(kTargetBitrateBps),
3949       DataRate::BitsPerSec(kTargetBitrateBps),
3950       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
3951   test::FrameForwarder source;
3952   video_stream_encoder_->SetSource(
3953       &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
3954 
3955   // Trigger initial configuration.
3956   VideoEncoderConfig video_encoder_config;
3957   video_encoder_config.codec_type = kVideoCodecVP8;
3958   video_encoder_config.max_bitrate_bps = kTargetBitrateBps;
3959   video_encoder_config.number_of_streams = 1;
3960   video_encoder_config.video_stream_factory =
3961       new rtc::RefCountedObject<VideoStreamFactory>(1, kLowFramerate);
3962   source.IncomingCapturedFrame(CreateFrame(1, kFrameWidth, kFrameHeight));
3963   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
3964                                           kMaxPayloadLength);
3965   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3966 
3967   EXPECT_EQ(
3968       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
3969       kLowFramerate);
3970 
3971   // Trigger overuse, max framerate should be reduced.
3972   VideoSendStream::Stats stats = stats_proxy_->GetStats();
3973   stats.input_frame_rate = kLowFramerate;
3974   stats_proxy_->SetMockStats(stats);
3975   video_stream_encoder_->TriggerCpuOveruse();
3976   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3977   int adapted_framerate =
3978       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate();
3979   EXPECT_LT(adapted_framerate, kLowFramerate);
3980 
3981   // Reconfigure the encoder with a new (higher max framerate), max fps should
3982   // still respect the adaptation.
3983   video_encoder_config.video_stream_factory =
3984       new rtc::RefCountedObject<VideoStreamFactory>(1, kHighFramerate);
3985   source.IncomingCapturedFrame(CreateFrame(1, kFrameWidth, kFrameHeight));
3986   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
3987                                           kMaxPayloadLength);
3988   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
3989 
3990   EXPECT_EQ(
3991       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
3992       adapted_framerate);
3993 
3994   // Trigger underuse, max framerate should go back to codec configured fps.
3995   stats = stats_proxy_->GetStats();
3996   stats.input_frame_rate = adapted_framerate;
3997   stats_proxy_->SetMockStats(stats);
3998   video_stream_encoder_->TriggerCpuUnderuse();
3999   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
4000   EXPECT_EQ(
4001       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
4002       kHighFramerate);
4003 
4004   video_stream_encoder_->Stop();
4005 }
4006 
TEST_F(VideoStreamEncoderTest,OveruseDetectorUpdatedOnDegradationPreferenceChange)4007 TEST_F(VideoStreamEncoderTest,
4008        OveruseDetectorUpdatedOnDegradationPreferenceChange) {
4009   const int kFrameWidth = 1280;
4010   const int kFrameHeight = 720;
4011   const int kFramerate = 24;
4012 
4013   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4014       DataRate::BitsPerSec(kTargetBitrateBps),
4015       DataRate::BitsPerSec(kTargetBitrateBps),
4016       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4017   test::FrameForwarder source;
4018   video_stream_encoder_->SetSource(
4019       &source, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
4020 
4021   // Trigger initial configuration.
4022   VideoEncoderConfig video_encoder_config;
4023   video_encoder_config.codec_type = kVideoCodecVP8;
4024   video_encoder_config.max_bitrate_bps = kTargetBitrateBps;
4025   video_encoder_config.number_of_streams = 1;
4026   video_encoder_config.video_stream_factory =
4027       new rtc::RefCountedObject<VideoStreamFactory>(1, kFramerate);
4028   source.IncomingCapturedFrame(CreateFrame(1, kFrameWidth, kFrameHeight));
4029   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
4030                                           kMaxPayloadLength);
4031   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
4032 
4033   EXPECT_EQ(
4034       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
4035       kFramerate);
4036 
4037   // Trigger overuse, max framerate should be reduced.
4038   VideoSendStream::Stats stats = stats_proxy_->GetStats();
4039   stats.input_frame_rate = kFramerate;
4040   stats_proxy_->SetMockStats(stats);
4041   video_stream_encoder_->TriggerCpuOveruse();
4042   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
4043   int adapted_framerate =
4044       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate();
4045   EXPECT_LT(adapted_framerate, kFramerate);
4046 
4047   // Change degradation preference to not enable framerate scaling. Target
4048   // framerate should be changed to codec defined limit.
4049   video_stream_encoder_->SetSourceAndWaitForFramerateUpdated(
4050       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
4051   EXPECT_EQ(
4052       video_stream_encoder_->overuse_detector_proxy_->GetLastTargetFramerate(),
4053       kFramerate);
4054 
4055   video_stream_encoder_->Stop();
4056 }
4057 
TEST_F(VideoStreamEncoderTest,DropsFramesAndScalesWhenBitrateIsTooLow)4058 TEST_F(VideoStreamEncoderTest, DropsFramesAndScalesWhenBitrateIsTooLow) {
4059   const int kTooLowBitrateForFrameSizeBps = 10000;
4060   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4061       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps),
4062       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps),
4063       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps), 0, 0, 0);
4064   const int kWidth = 640;
4065   const int kHeight = 360;
4066 
4067   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
4068 
4069   // Expect to drop this frame, the wait should time out.
4070   ExpectDroppedFrame();
4071 
4072   // Expect the sink_wants to specify a scaled frame.
4073   EXPECT_TRUE_WAIT(
4074       video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000);
4075 
4076   int last_pixel_count = video_source_.sink_wants().max_pixel_count;
4077 
4078   // Next frame is scaled.
4079   video_source_.IncomingCapturedFrame(
4080       CreateFrame(2, kWidth * 3 / 4, kHeight * 3 / 4));
4081 
4082   // Expect to drop this frame, the wait should time out.
4083   ExpectDroppedFrame();
4084 
4085   EXPECT_TRUE_WAIT(
4086       video_source_.sink_wants().max_pixel_count < last_pixel_count, 5000);
4087 
4088   video_stream_encoder_->Stop();
4089 }
4090 
TEST_F(VideoStreamEncoderTest,NumberOfDroppedFramesLimitedWhenBitrateIsTooLow)4091 TEST_F(VideoStreamEncoderTest,
4092        NumberOfDroppedFramesLimitedWhenBitrateIsTooLow) {
4093   const int kTooLowBitrateForFrameSizeBps = 10000;
4094   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4095       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps),
4096       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps),
4097       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps), 0, 0, 0);
4098   const int kWidth = 640;
4099   const int kHeight = 360;
4100 
4101   // We expect the n initial frames to get dropped.
4102   int i;
4103   for (i = 1; i <= kMaxInitialFramedrop; ++i) {
4104     video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight));
4105     ExpectDroppedFrame();
4106   }
4107   // The n+1th frame should not be dropped, even though it's size is too large.
4108   video_source_.IncomingCapturedFrame(CreateFrame(i, kWidth, kHeight));
4109   WaitForEncodedFrame(i);
4110 
4111   // Expect the sink_wants to specify a scaled frame.
4112   EXPECT_LT(video_source_.sink_wants().max_pixel_count, kWidth * kHeight);
4113 
4114   video_stream_encoder_->Stop();
4115 }
4116 
TEST_F(VideoStreamEncoderTest,InitialFrameDropOffWithMaintainResolutionPreference)4117 TEST_F(VideoStreamEncoderTest,
4118        InitialFrameDropOffWithMaintainResolutionPreference) {
4119   const int kWidth = 640;
4120   const int kHeight = 360;
4121   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4122       DataRate::BitsPerSec(kLowTargetBitrateBps),
4123       DataRate::BitsPerSec(kLowTargetBitrateBps),
4124       DataRate::BitsPerSec(kLowTargetBitrateBps), 0, 0, 0);
4125 
4126   // Set degradation preference.
4127   video_stream_encoder_->SetSource(
4128       &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
4129 
4130   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
4131   // Frame should not be dropped, even if it's too large.
4132   WaitForEncodedFrame(1);
4133 
4134   video_stream_encoder_->Stop();
4135 }
4136 
TEST_F(VideoStreamEncoderTest,InitialFrameDropOffWhenEncoderDisabledScaling)4137 TEST_F(VideoStreamEncoderTest, InitialFrameDropOffWhenEncoderDisabledScaling) {
4138   const int kWidth = 640;
4139   const int kHeight = 360;
4140   fake_encoder_.SetQualityScaling(false);
4141 
4142   VideoEncoderConfig video_encoder_config;
4143   test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
4144   // Make format different, to force recreation of encoder.
4145   video_encoder_config.video_format.parameters["foo"] = "foo";
4146   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
4147                                           kMaxPayloadLength);
4148   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4149       DataRate::BitsPerSec(kLowTargetBitrateBps),
4150       DataRate::BitsPerSec(kLowTargetBitrateBps),
4151       DataRate::BitsPerSec(kLowTargetBitrateBps), 0, 0, 0);
4152 
4153   // Force quality scaler reconfiguration by resetting the source.
4154   video_stream_encoder_->SetSource(&video_source_,
4155                                    webrtc::DegradationPreference::BALANCED);
4156 
4157   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
4158   // Frame should not be dropped, even if it's too large.
4159   WaitForEncodedFrame(1);
4160 
4161   video_stream_encoder_->Stop();
4162   fake_encoder_.SetQualityScaling(true);
4163 }
4164 
TEST_F(VideoStreamEncoderTest,InitialFrameDropActivatesWhenBweDrops)4165 TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenBweDrops) {
4166   webrtc::test::ScopedFieldTrials field_trials(
4167       "WebRTC-Video-QualityScalerSettings/"
4168       "initial_bitrate_interval_ms:1000,initial_bitrate_factor:0.2/");
4169   // Reset encoder for field trials to take effect.
4170   ConfigureEncoder(video_encoder_config_.Copy());
4171   const int kNotTooLowBitrateForFrameSizeBps = kTargetBitrateBps * 0.2;
4172   const int kTooLowBitrateForFrameSizeBps = kTargetBitrateBps * 0.19;
4173   const int kWidth = 640;
4174   const int kHeight = 360;
4175 
4176   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4177       DataRate::BitsPerSec(kTargetBitrateBps),
4178       DataRate::BitsPerSec(kTargetBitrateBps),
4179       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4180   video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
4181   // Frame should not be dropped.
4182   WaitForEncodedFrame(1);
4183 
4184   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4185       DataRate::BitsPerSec(kNotTooLowBitrateForFrameSizeBps),
4186       DataRate::BitsPerSec(kNotTooLowBitrateForFrameSizeBps),
4187       DataRate::BitsPerSec(kNotTooLowBitrateForFrameSizeBps), 0, 0, 0);
4188   video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
4189   // Frame should not be dropped.
4190   WaitForEncodedFrame(2);
4191 
4192   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4193       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps),
4194       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps),
4195       DataRate::BitsPerSec(kTooLowBitrateForFrameSizeBps), 0, 0, 0);
4196   video_source_.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
4197   // Expect to drop this frame, the wait should time out.
4198   ExpectDroppedFrame();
4199 
4200   // Expect the sink_wants to specify a scaled frame.
4201   EXPECT_TRUE_WAIT(
4202       video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000);
4203   video_stream_encoder_->Stop();
4204 }
4205 
TEST_F(VideoStreamEncoderTest,RampsUpInQualityWhenBwIsHigh)4206 TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) {
4207   webrtc::test::ScopedFieldTrials field_trials(
4208       "WebRTC-Video-QualityRampupSettings/min_pixels:1,min_duration_ms:2000/");
4209 
4210   // Reset encoder for field trials to take effect.
4211   VideoEncoderConfig config = video_encoder_config_.Copy();
4212   config.max_bitrate_bps = kTargetBitrateBps;
4213   DataRate max_bitrate = DataRate::BitsPerSec(config.max_bitrate_bps);
4214   ConfigureEncoder(std::move(config));
4215   fake_encoder_.SetQp(kQpLow);
4216 
4217   // Enable MAINTAIN_FRAMERATE preference.
4218   AdaptingFrameForwarder source;
4219   source.set_adaptation_enabled(true);
4220   video_stream_encoder_->SetSource(&source,
4221                                    DegradationPreference::MAINTAIN_FRAMERATE);
4222 
4223   // Start at low bitrate.
4224   const int kLowBitrateBps = 200000;
4225   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4226       DataRate::BitsPerSec(kLowBitrateBps),
4227       DataRate::BitsPerSec(kLowBitrateBps),
4228       DataRate::BitsPerSec(kLowBitrateBps), 0, 0, 0);
4229 
4230   // Expect first frame to be dropped and resolution to be limited.
4231   const int kWidth = 1280;
4232   const int kHeight = 720;
4233   const int64_t kFrameIntervalMs = 100;
4234   int64_t timestamp_ms = kFrameIntervalMs;
4235   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4236   ExpectDroppedFrame();
4237   EXPECT_TRUE_WAIT(source.sink_wants().max_pixel_count < kWidth * kHeight,
4238                    5000);
4239 
4240   // Increase bitrate to encoder max.
4241   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4242       max_bitrate, max_bitrate, max_bitrate, 0, 0, 0);
4243 
4244   // Insert frames and advance |min_duration_ms|.
4245   for (size_t i = 1; i <= 10; i++) {
4246     timestamp_ms += kFrameIntervalMs;
4247     source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4248     WaitForEncodedFrame(timestamp_ms);
4249   }
4250   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4251   EXPECT_LT(source.sink_wants().max_pixel_count, kWidth * kHeight);
4252 
4253   fake_clock_.AdvanceTime(TimeDelta::Millis(2000));
4254 
4255   // Insert frame should trigger high BW and release quality limitation.
4256   timestamp_ms += kFrameIntervalMs;
4257   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4258   WaitForEncodedFrame(timestamp_ms);
4259   // The ramp-up code involves the adaptation queue, give it time to execute.
4260   // TODO(hbos): Can we await an appropriate event instead?
4261   video_stream_encoder_->WaitUntilAdaptationTaskQueueIsIdle();
4262   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4263 
4264   // Frame should not be adapted.
4265   timestamp_ms += kFrameIntervalMs;
4266   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4267   WaitForEncodedFrame(kWidth, kHeight);
4268   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4269 
4270   video_stream_encoder_->Stop();
4271 }
4272 
TEST_F(VideoStreamEncoderTest,ResolutionNotAdaptedForTooSmallFrame_MaintainFramerateMode)4273 TEST_F(VideoStreamEncoderTest,
4274        ResolutionNotAdaptedForTooSmallFrame_MaintainFramerateMode) {
4275   const int kTooSmallWidth = 10;
4276   const int kTooSmallHeight = 10;
4277   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4278       DataRate::BitsPerSec(kTargetBitrateBps),
4279       DataRate::BitsPerSec(kTargetBitrateBps),
4280       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4281 
4282   // Enable MAINTAIN_FRAMERATE preference, no initial limitation.
4283   test::FrameForwarder source;
4284   video_stream_encoder_->SetSource(
4285       &source, webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
4286   EXPECT_THAT(source.sink_wants(), UnlimitedSinkWants());
4287   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4288 
4289   // Trigger adapt down, too small frame, expect no change.
4290   source.IncomingCapturedFrame(CreateFrame(1, kTooSmallWidth, kTooSmallHeight));
4291   WaitForEncodedFrame(1);
4292   video_stream_encoder_->TriggerCpuOveruse();
4293   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4294   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4295   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4296 
4297   video_stream_encoder_->Stop();
4298 }
4299 
TEST_F(VideoStreamEncoderTest,ResolutionNotAdaptedForTooSmallFrame_BalancedMode)4300 TEST_F(VideoStreamEncoderTest,
4301        ResolutionNotAdaptedForTooSmallFrame_BalancedMode) {
4302   const int kTooSmallWidth = 10;
4303   const int kTooSmallHeight = 10;
4304   const int kFpsLimit = 7;
4305   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4306       DataRate::BitsPerSec(kTargetBitrateBps),
4307       DataRate::BitsPerSec(kTargetBitrateBps),
4308       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4309 
4310   // Enable BALANCED preference, no initial limitation.
4311   test::FrameForwarder source;
4312   video_stream_encoder_->SetSource(&source,
4313                                    webrtc::DegradationPreference::BALANCED);
4314   EXPECT_THAT(source.sink_wants(), UnlimitedSinkWants());
4315   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4316   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4317 
4318   // Trigger adapt down, expect limited framerate.
4319   source.IncomingCapturedFrame(CreateFrame(1, kTooSmallWidth, kTooSmallHeight));
4320   WaitForEncodedFrame(1);
4321   video_stream_encoder_->TriggerQualityLow();
4322   EXPECT_THAT(source.sink_wants(), FpsMatchesResolutionMax(Eq(kFpsLimit)));
4323   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4324   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4325   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4326 
4327   // Trigger adapt down, too small frame, expect no change.
4328   source.IncomingCapturedFrame(CreateFrame(2, kTooSmallWidth, kTooSmallHeight));
4329   WaitForEncodedFrame(2);
4330   video_stream_encoder_->TriggerQualityLow();
4331   EXPECT_THAT(source.sink_wants(), FpsMatchesResolutionMax(Eq(kFpsLimit)));
4332   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4333   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4334   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4335 
4336   video_stream_encoder_->Stop();
4337 }
4338 
TEST_F(VideoStreamEncoderTest,FailingInitEncodeDoesntCauseCrash)4339 TEST_F(VideoStreamEncoderTest, FailingInitEncodeDoesntCauseCrash) {
4340   fake_encoder_.ForceInitEncodeFailure(true);
4341   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4342       DataRate::BitsPerSec(kTargetBitrateBps),
4343       DataRate::BitsPerSec(kTargetBitrateBps),
4344       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4345   ResetEncoder("VP8", 2, 1, 1, false);
4346   const int kFrameWidth = 1280;
4347   const int kFrameHeight = 720;
4348   video_source_.IncomingCapturedFrame(
4349       CreateFrame(1, kFrameWidth, kFrameHeight));
4350   ExpectDroppedFrame();
4351   video_stream_encoder_->Stop();
4352 }
4353 
4354 // TODO(sprang): Extend this with fps throttling and any "balanced" extensions.
TEST_F(VideoStreamEncoderTest,AdaptsResolutionOnOveruse_MaintainFramerateMode)4355 TEST_F(VideoStreamEncoderTest,
4356        AdaptsResolutionOnOveruse_MaintainFramerateMode) {
4357   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4358       DataRate::BitsPerSec(kTargetBitrateBps),
4359       DataRate::BitsPerSec(kTargetBitrateBps),
4360       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4361 
4362   const int kFrameWidth = 1280;
4363   const int kFrameHeight = 720;
4364   // Enabled default VideoAdapter downscaling. First step is 3/4, not 3/5 as
4365   // requested by
4366   // VideoStreamEncoder::VideoSourceProxy::RequestResolutionLowerThan().
4367   video_source_.set_adaptation_enabled(true);
4368 
4369   video_source_.IncomingCapturedFrame(
4370       CreateFrame(1 * kFrameIntervalMs, kFrameWidth, kFrameHeight));
4371   WaitForEncodedFrame(kFrameWidth, kFrameHeight);
4372 
4373   // Trigger CPU overuse, downscale by 3/4.
4374   video_stream_encoder_->TriggerCpuOveruse();
4375   video_source_.IncomingCapturedFrame(
4376       CreateFrame(2 * kFrameIntervalMs, kFrameWidth, kFrameHeight));
4377   WaitForEncodedFrame((kFrameWidth * 3) / 4, (kFrameHeight * 3) / 4);
4378 
4379   // Trigger CPU normal use, return to original resolution.
4380   video_stream_encoder_->TriggerCpuUnderuse();
4381   video_source_.IncomingCapturedFrame(
4382       CreateFrame(3 * kFrameIntervalMs, kFrameWidth, kFrameHeight));
4383   WaitForEncodedFrame(kFrameWidth, kFrameHeight);
4384 
4385   video_stream_encoder_->Stop();
4386 }
4387 
TEST_F(VideoStreamEncoderTest,AdaptsFramerateOnOveruse_MaintainResolutionMode)4388 TEST_F(VideoStreamEncoderTest,
4389        AdaptsFramerateOnOveruse_MaintainResolutionMode) {
4390   const int kFrameWidth = 1280;
4391   const int kFrameHeight = 720;
4392 
4393   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4394       DataRate::BitsPerSec(kTargetBitrateBps),
4395       DataRate::BitsPerSec(kTargetBitrateBps),
4396       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4397   video_stream_encoder_->SetSource(
4398       &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
4399   video_source_.set_adaptation_enabled(true);
4400 
4401   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
4402 
4403   video_source_.IncomingCapturedFrame(
4404       CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4405   WaitForEncodedFrame(timestamp_ms);
4406 
4407   // Try to trigger overuse. No fps estimate available => no effect.
4408   video_stream_encoder_->TriggerCpuOveruse();
4409 
4410   // Insert frames for one second to get a stable estimate.
4411   for (int i = 0; i < max_framerate_; ++i) {
4412     timestamp_ms += kFrameIntervalMs;
4413     video_source_.IncomingCapturedFrame(
4414         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4415     WaitForEncodedFrame(timestamp_ms);
4416   }
4417 
4418   // Trigger CPU overuse, reduce framerate by 2/3.
4419   video_stream_encoder_->TriggerCpuOveruse();
4420   int num_frames_dropped = 0;
4421   for (int i = 0; i < max_framerate_; ++i) {
4422     timestamp_ms += kFrameIntervalMs;
4423     video_source_.IncomingCapturedFrame(
4424         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4425     if (!WaitForFrame(kFrameTimeoutMs)) {
4426       ++num_frames_dropped;
4427     } else {
4428       sink_.CheckLastFrameSizeMatches(kFrameWidth, kFrameHeight);
4429     }
4430   }
4431 
4432   // Add some slack to account for frames dropped by the frame dropper.
4433   const int kErrorMargin = 1;
4434   EXPECT_NEAR(num_frames_dropped, max_framerate_ - (max_framerate_ * 2 / 3),
4435               kErrorMargin);
4436 
4437   // Trigger CPU overuse, reduce framerate by 2/3 again.
4438   video_stream_encoder_->TriggerCpuOveruse();
4439   num_frames_dropped = 0;
4440   for (int i = 0; i <= max_framerate_; ++i) {
4441     timestamp_ms += kFrameIntervalMs;
4442     video_source_.IncomingCapturedFrame(
4443         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4444     if (!WaitForFrame(kFrameTimeoutMs)) {
4445       ++num_frames_dropped;
4446     } else {
4447       sink_.CheckLastFrameSizeMatches(kFrameWidth, kFrameHeight);
4448     }
4449   }
4450   EXPECT_NEAR(num_frames_dropped, max_framerate_ - (max_framerate_ * 4 / 9),
4451               kErrorMargin);
4452 
4453   // Go back up one step.
4454   video_stream_encoder_->TriggerCpuUnderuse();
4455   num_frames_dropped = 0;
4456   for (int i = 0; i < max_framerate_; ++i) {
4457     timestamp_ms += kFrameIntervalMs;
4458     video_source_.IncomingCapturedFrame(
4459         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4460     if (!WaitForFrame(kFrameTimeoutMs)) {
4461       ++num_frames_dropped;
4462     } else {
4463       sink_.CheckLastFrameSizeMatches(kFrameWidth, kFrameHeight);
4464     }
4465   }
4466   EXPECT_NEAR(num_frames_dropped, max_framerate_ - (max_framerate_ * 2 / 3),
4467               kErrorMargin);
4468 
4469   // Go back up to original mode.
4470   video_stream_encoder_->TriggerCpuUnderuse();
4471   num_frames_dropped = 0;
4472   for (int i = 0; i < max_framerate_; ++i) {
4473     timestamp_ms += kFrameIntervalMs;
4474     video_source_.IncomingCapturedFrame(
4475         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4476     if (!WaitForFrame(kFrameTimeoutMs)) {
4477       ++num_frames_dropped;
4478     } else {
4479       sink_.CheckLastFrameSizeMatches(kFrameWidth, kFrameHeight);
4480     }
4481   }
4482   EXPECT_NEAR(num_frames_dropped, 0, kErrorMargin);
4483 
4484   video_stream_encoder_->Stop();
4485 }
4486 
TEST_F(VideoStreamEncoderTest,DoesntAdaptDownPastMinFramerate)4487 TEST_F(VideoStreamEncoderTest, DoesntAdaptDownPastMinFramerate) {
4488   const int kFramerateFps = 5;
4489   const int kFrameIntervalMs = rtc::kNumMillisecsPerSec / kFramerateFps;
4490   const int kFrameWidth = 1280;
4491   const int kFrameHeight = 720;
4492 
4493   // Reconfigure encoder with two temporal layers and screensharing, which will
4494   // disable frame dropping and make testing easier.
4495   ResetEncoder("VP8", 1, 2, 1, true);
4496 
4497   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4498       DataRate::BitsPerSec(kTargetBitrateBps),
4499       DataRate::BitsPerSec(kTargetBitrateBps),
4500       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4501   video_stream_encoder_->SetSource(
4502       &video_source_, webrtc::DegradationPreference::MAINTAIN_RESOLUTION);
4503   video_source_.set_adaptation_enabled(true);
4504 
4505   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
4506 
4507   // Trigger overuse as much as we can.
4508   rtc::VideoSinkWants last_wants;
4509   do {
4510     last_wants = video_source_.sink_wants();
4511 
4512     // Insert frames to get a new fps estimate...
4513     for (int j = 0; j < kFramerateFps; ++j) {
4514       video_source_.IncomingCapturedFrame(
4515           CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
4516       if (video_source_.last_sent_width()) {
4517         sink_.WaitForEncodedFrame(timestamp_ms);
4518       }
4519       timestamp_ms += kFrameIntervalMs;
4520       fake_clock_.AdvanceTime(TimeDelta::Millis(kFrameIntervalMs));
4521     }
4522     // ...and then try to adapt again.
4523     video_stream_encoder_->TriggerCpuOveruse();
4524   } while (video_source_.sink_wants().max_framerate_fps <
4525            last_wants.max_framerate_fps);
4526 
4527   EXPECT_THAT(video_source_.sink_wants(),
4528               FpsMatchesResolutionMax(Eq(kMinFramerateFps)));
4529 
4530   video_stream_encoder_->Stop();
4531 }
4532 
TEST_F(VideoStreamEncoderTest,AdaptsResolutionAndFramerateForLowQuality_BalancedMode)4533 TEST_F(VideoStreamEncoderTest,
4534        AdaptsResolutionAndFramerateForLowQuality_BalancedMode) {
4535   const int kWidth = 1280;
4536   const int kHeight = 720;
4537   const int64_t kFrameIntervalMs = 150;
4538   int64_t timestamp_ms = kFrameIntervalMs;
4539   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4540       DataRate::BitsPerSec(kTargetBitrateBps),
4541       DataRate::BitsPerSec(kTargetBitrateBps),
4542       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4543 
4544   // Enable BALANCED preference, no initial limitation.
4545   AdaptingFrameForwarder source;
4546   source.set_adaptation_enabled(true);
4547   video_stream_encoder_->SetSource(&source,
4548                                    webrtc::DegradationPreference::BALANCED);
4549   timestamp_ms += kFrameIntervalMs;
4550   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4551   WaitForEncodedFrame(kWidth, kHeight);
4552   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4553   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4554   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4555   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4556 
4557   // Trigger adapt down, expect scaled down resolution (960x540@30fps).
4558   video_stream_encoder_->TriggerQualityLow();
4559   timestamp_ms += kFrameIntervalMs;
4560   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4561   WaitForEncodedFrame(timestamp_ms);
4562   EXPECT_THAT(source.sink_wants(),
4563               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
4564   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4565   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4566   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4567 
4568   // Trigger adapt down, expect scaled down resolution (640x360@30fps).
4569   video_stream_encoder_->TriggerQualityLow();
4570   timestamp_ms += kFrameIntervalMs;
4571   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4572   WaitForEncodedFrame(timestamp_ms);
4573   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionLt(source.last_wants()));
4574   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4575   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4576   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4577 
4578   // Trigger adapt down, expect reduced fps (640x360@15fps).
4579   video_stream_encoder_->TriggerQualityLow();
4580   timestamp_ms += kFrameIntervalMs;
4581   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4582   WaitForEncodedFrame(timestamp_ms);
4583   EXPECT_THAT(source.sink_wants(), FpsLtResolutionEq(source.last_wants()));
4584   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4585   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4586   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4587 
4588   // Trigger adapt down, expect scaled down resolution (480x270@15fps).
4589   video_stream_encoder_->TriggerQualityLow();
4590   timestamp_ms += kFrameIntervalMs;
4591   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4592   WaitForEncodedFrame(timestamp_ms);
4593   EXPECT_THAT(source.sink_wants(), FpsEqResolutionLt(source.last_wants()));
4594   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4595   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4596   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4597 
4598   // Restrict bitrate, trigger adapt down, expect reduced fps (480x270@10fps).
4599   video_stream_encoder_->TriggerQualityLow();
4600   timestamp_ms += kFrameIntervalMs;
4601   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4602   WaitForEncodedFrame(timestamp_ms);
4603   EXPECT_THAT(source.sink_wants(), FpsLtResolutionEq(source.last_wants()));
4604   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4605   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4606   EXPECT_EQ(5, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4607 
4608   // Trigger adapt down, expect scaled down resolution (320x180@10fps).
4609   video_stream_encoder_->TriggerQualityLow();
4610   timestamp_ms += kFrameIntervalMs;
4611   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4612   WaitForEncodedFrame(timestamp_ms);
4613   EXPECT_THAT(source.sink_wants(), FpsEqResolutionLt(source.last_wants()));
4614   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4615   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4616   EXPECT_EQ(6, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4617 
4618   // Trigger adapt down, expect reduced fps (320x180@7fps).
4619   video_stream_encoder_->TriggerQualityLow();
4620   timestamp_ms += kFrameIntervalMs;
4621   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4622   WaitForEncodedFrame(timestamp_ms);
4623   EXPECT_THAT(source.sink_wants(), FpsLtResolutionEq(source.last_wants()));
4624   rtc::VideoSinkWants last_wants = source.sink_wants();
4625   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4626   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4627   EXPECT_EQ(7, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4628 
4629   // Trigger adapt down, min resolution reached, expect no change.
4630   video_stream_encoder_->TriggerQualityLow();
4631   timestamp_ms += kFrameIntervalMs;
4632   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4633   WaitForEncodedFrame(timestamp_ms);
4634   EXPECT_THAT(source.sink_wants(), FpsEqResolutionEqTo(last_wants));
4635   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4636   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4637   EXPECT_EQ(7, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4638 
4639   // Trigger adapt up, expect expect increased fps (320x180@10fps).
4640   video_stream_encoder_->TriggerQualityHigh();
4641   timestamp_ms += kFrameIntervalMs;
4642   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4643   WaitForEncodedFrame(timestamp_ms);
4644   EXPECT_THAT(source.sink_wants(), FpsGtResolutionEq(source.last_wants()));
4645   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4646   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4647   EXPECT_EQ(8, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4648 
4649   // Trigger adapt up, expect upscaled resolution (480x270@10fps).
4650   video_stream_encoder_->TriggerQualityHigh();
4651   timestamp_ms += kFrameIntervalMs;
4652   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4653   WaitForEncodedFrame(timestamp_ms);
4654   EXPECT_THAT(source.sink_wants(), FpsEqResolutionGt(source.last_wants()));
4655   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4656   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4657   EXPECT_EQ(9, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4658 
4659   // Increase bitrate, trigger adapt up, expect increased fps (480x270@15fps).
4660   video_stream_encoder_->TriggerQualityHigh();
4661   timestamp_ms += kFrameIntervalMs;
4662   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4663   WaitForEncodedFrame(timestamp_ms);
4664   EXPECT_THAT(source.sink_wants(), FpsGtResolutionEq(source.last_wants()));
4665   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4666   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4667   EXPECT_EQ(10, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4668 
4669   // Trigger adapt up, expect upscaled resolution (640x360@15fps).
4670   video_stream_encoder_->TriggerQualityHigh();
4671   timestamp_ms += kFrameIntervalMs;
4672   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4673   WaitForEncodedFrame(timestamp_ms);
4674   EXPECT_THAT(source.sink_wants(), FpsEqResolutionGt(source.last_wants()));
4675   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4676   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4677   EXPECT_EQ(11, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4678 
4679   // Trigger adapt up, expect increased fps (640x360@30fps).
4680   video_stream_encoder_->TriggerQualityHigh();
4681   timestamp_ms += kFrameIntervalMs;
4682   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4683   WaitForEncodedFrame(timestamp_ms);
4684   EXPECT_THAT(source.sink_wants(), FpsMax());
4685   EXPECT_EQ(source.sink_wants().max_pixel_count,
4686             source.last_wants().max_pixel_count);
4687   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4688   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4689   EXPECT_EQ(12, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4690 
4691   // Trigger adapt up, expect upscaled resolution (960x540@30fps).
4692   video_stream_encoder_->TriggerQualityHigh();
4693   timestamp_ms += kFrameIntervalMs;
4694   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4695   WaitForEncodedFrame(timestamp_ms);
4696   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
4697   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4698   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4699   EXPECT_EQ(13, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4700 
4701   // Trigger adapt up, expect no restriction (1280x720fps@30fps).
4702   video_stream_encoder_->TriggerQualityHigh();
4703   timestamp_ms += kFrameIntervalMs;
4704   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4705   WaitForEncodedFrame(kWidth, kHeight);
4706   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
4707   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4708   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4709   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4710   EXPECT_EQ(14, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4711 
4712   // Trigger adapt up, expect no change.
4713   video_stream_encoder_->TriggerQualityHigh();
4714   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4715   EXPECT_EQ(14, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4716 
4717   video_stream_encoder_->Stop();
4718 }
4719 
TEST_F(VideoStreamEncoderTest,AdaptWithTwoReasonsAndDifferentOrder_Framerate)4720 TEST_F(VideoStreamEncoderTest, AdaptWithTwoReasonsAndDifferentOrder_Framerate) {
4721   const int kWidth = 1280;
4722   const int kHeight = 720;
4723   const int64_t kFrameIntervalMs = 150;
4724   int64_t timestamp_ms = kFrameIntervalMs;
4725   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4726       DataRate::BitsPerSec(kTargetBitrateBps),
4727       DataRate::BitsPerSec(kTargetBitrateBps),
4728       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4729 
4730   // Enable BALANCED preference, no initial limitation.
4731   AdaptingFrameForwarder source;
4732   source.set_adaptation_enabled(true);
4733   video_stream_encoder_->SetSource(&source,
4734                                    webrtc::DegradationPreference::BALANCED);
4735   timestamp_ms += kFrameIntervalMs;
4736   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4737   WaitForEncodedFrame(kWidth, kHeight);
4738   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4739   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4740   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4741   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4742   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4743   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4744   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4745 
4746   // Trigger cpu adapt down, expect scaled down resolution (960x540@30fps).
4747   video_stream_encoder_->TriggerCpuOveruse();
4748   timestamp_ms += kFrameIntervalMs;
4749   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4750   WaitForEncodedFrame(timestamp_ms);
4751   EXPECT_THAT(source.sink_wants(),
4752               FpsMaxResolutionMatches(Lt(kWidth * kHeight)));
4753   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4754   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4755   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
4756   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4757   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4758   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4759 
4760   // Trigger cpu adapt down, expect scaled down resolution (640x360@30fps).
4761   video_stream_encoder_->TriggerCpuOveruse();
4762   timestamp_ms += kFrameIntervalMs;
4763   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4764   WaitForEncodedFrame(timestamp_ms);
4765   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionLt(source.last_wants()));
4766   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4767   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4768   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
4769   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4770   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4771   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4772 
4773   // Trigger quality adapt down, expect reduced fps (640x360@15fps).
4774   video_stream_encoder_->TriggerQualityLow();
4775   timestamp_ms += kFrameIntervalMs;
4776   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4777   WaitForEncodedFrame(timestamp_ms);
4778   EXPECT_THAT(source.sink_wants(), FpsLtResolutionEq(source.last_wants()));
4779   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4780   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4781   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
4782   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4783   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4784   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4785 
4786   // Trigger cpu adapt up, expect no change since QP is most limited.
4787   {
4788     // Store current sink wants since we expect no change and if there is no
4789     // change then last_wants() is not updated.
4790     auto previous_sink_wants = source.sink_wants();
4791     video_stream_encoder_->TriggerCpuUnderuse();
4792     timestamp_ms += kFrameIntervalMs;
4793     source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4794     WaitForEncodedFrame(timestamp_ms);
4795     EXPECT_THAT(source.sink_wants(), FpsEqResolutionEqTo(previous_sink_wants));
4796     EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4797     EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4798   }
4799 
4800   // Trigger quality adapt up, expect increased fps (640x360@30fps).
4801   video_stream_encoder_->TriggerQualityHigh();
4802   timestamp_ms += kFrameIntervalMs;
4803   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4804   WaitForEncodedFrame(timestamp_ms);
4805   EXPECT_THAT(source.sink_wants(), FpsGtResolutionEq(source.last_wants()));
4806   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4807   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4808   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
4809   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4810   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4811   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4812 
4813   // Trigger quality adapt up and Cpu adapt up since both are most limited,
4814   // expect increased resolution (960x540@30fps).
4815   video_stream_encoder_->TriggerQualityHigh();
4816   video_stream_encoder_->TriggerCpuUnderuse();
4817   timestamp_ms += kFrameIntervalMs;
4818   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4819   WaitForEncodedFrame(timestamp_ms);
4820   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
4821   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4822   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4823   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_resolution);
4824   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4825   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4826   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4827 
4828   // Trigger quality adapt up and Cpu adapt up since both are most limited,
4829   // expect no restriction (1280x720fps@30fps).
4830   video_stream_encoder_->TriggerQualityHigh();
4831   video_stream_encoder_->TriggerCpuUnderuse();
4832   timestamp_ms += kFrameIntervalMs;
4833   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4834   WaitForEncodedFrame(kWidth, kHeight);
4835   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionGt(source.last_wants()));
4836   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4837   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4838   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4839   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4840   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4841   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4842   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4843 
4844   // Trigger adapt up, expect no change.
4845   video_stream_encoder_->TriggerQualityHigh();
4846   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4847   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4848   EXPECT_EQ(4, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4849 
4850   video_stream_encoder_->Stop();
4851 }
4852 
TEST_F(VideoStreamEncoderTest,AdaptWithTwoReasonsAndDifferentOrder_Resolution)4853 TEST_F(VideoStreamEncoderTest,
4854        AdaptWithTwoReasonsAndDifferentOrder_Resolution) {
4855   const int kWidth = 640;
4856   const int kHeight = 360;
4857   const int kFpsLimit = 15;
4858   const int64_t kFrameIntervalMs = 150;
4859   int64_t timestamp_ms = kFrameIntervalMs;
4860   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4861       DataRate::BitsPerSec(kTargetBitrateBps),
4862       DataRate::BitsPerSec(kTargetBitrateBps),
4863       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4864 
4865   // Enable BALANCED preference, no initial limitation.
4866   AdaptingFrameForwarder source;
4867   source.set_adaptation_enabled(true);
4868   video_stream_encoder_->SetSource(&source,
4869                                    webrtc::DegradationPreference::BALANCED);
4870   timestamp_ms += kFrameIntervalMs;
4871   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4872   WaitForEncodedFrame(kWidth, kHeight);
4873   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4874   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4875   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4876   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4877   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4878   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4879   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4880 
4881   // Trigger cpu adapt down, expect scaled down framerate (640x360@15fps).
4882   video_stream_encoder_->TriggerCpuOveruse();
4883   timestamp_ms += kFrameIntervalMs;
4884   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4885   WaitForEncodedFrame(timestamp_ms);
4886   EXPECT_THAT(source.sink_wants(), FpsMatchesResolutionMax(Eq(kFpsLimit)));
4887   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4888   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4889   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4890   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_framerate);
4891   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4892   EXPECT_EQ(0, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4893 
4894   // Trigger quality adapt down, expect scaled down resolution (480x270@15fps).
4895   video_stream_encoder_->TriggerQualityLow();
4896   timestamp_ms += kFrameIntervalMs;
4897   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4898   WaitForEncodedFrame(timestamp_ms);
4899   EXPECT_THAT(source.sink_wants(), FpsEqResolutionLt(source.last_wants()));
4900   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_resolution);
4901   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4902   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4903   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_framerate);
4904   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4905   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4906 
4907   // Trigger cpu adapt up, expect no change because quality is most limited.
4908   {
4909     auto previous_sink_wants = source.sink_wants();
4910     // Store current sink wants since we expect no change ind if there is no
4911     // change then last__wants() is not updated.
4912     video_stream_encoder_->TriggerCpuUnderuse();
4913     timestamp_ms += kFrameIntervalMs;
4914     source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4915     WaitForEncodedFrame(timestamp_ms);
4916     EXPECT_THAT(source.sink_wants(), FpsEqResolutionEqTo(previous_sink_wants));
4917     EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4918     EXPECT_EQ(1, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4919   }
4920 
4921   // Trigger quality adapt up, expect upscaled resolution (640x360@15fps).
4922   video_stream_encoder_->TriggerQualityHigh();
4923   timestamp_ms += kFrameIntervalMs;
4924   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4925   WaitForEncodedFrame(timestamp_ms);
4926   EXPECT_THAT(source.sink_wants(), FpsEqResolutionGt(source.last_wants()));
4927   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4928   EXPECT_TRUE(stats_proxy_->GetStats().bw_limited_framerate);
4929   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4930   EXPECT_TRUE(stats_proxy_->GetStats().cpu_limited_framerate);
4931   EXPECT_EQ(1, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4932   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4933 
4934   // Trigger quality and cpu adapt up, expect increased fps (640x360@30fps).
4935   video_stream_encoder_->TriggerQualityHigh();
4936   video_stream_encoder_->TriggerCpuUnderuse();
4937   timestamp_ms += kFrameIntervalMs;
4938   source.IncomingCapturedFrame(CreateFrame(timestamp_ms, kWidth, kHeight));
4939   WaitForEncodedFrame(timestamp_ms);
4940   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4941   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_resolution);
4942   EXPECT_FALSE(stats_proxy_->GetStats().bw_limited_framerate);
4943   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_resolution);
4944   EXPECT_FALSE(stats_proxy_->GetStats().cpu_limited_framerate);
4945   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4946   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4947 
4948   // Trigger adapt up, expect no change.
4949   video_stream_encoder_->TriggerQualityHigh();
4950   EXPECT_THAT(source.sink_wants(), FpsMaxResolutionMax());
4951   EXPECT_EQ(2, stats_proxy_->GetStats().number_of_cpu_adapt_changes);
4952   EXPECT_EQ(3, stats_proxy_->GetStats().number_of_quality_adapt_changes);
4953 
4954   video_stream_encoder_->Stop();
4955 }
4956 
TEST_F(VideoStreamEncoderTest,AcceptsFullHdAdaptedDownSimulcastFrames)4957 TEST_F(VideoStreamEncoderTest, AcceptsFullHdAdaptedDownSimulcastFrames) {
4958   const int kFrameWidth = 1920;
4959   const int kFrameHeight = 1080;
4960   // 3/4 of 1920.
4961   const int kAdaptedFrameWidth = 1440;
4962   // 3/4 of 1080 rounded down to multiple of 4.
4963   const int kAdaptedFrameHeight = 808;
4964   const int kFramerate = 24;
4965 
4966   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
4967       DataRate::BitsPerSec(kTargetBitrateBps),
4968       DataRate::BitsPerSec(kTargetBitrateBps),
4969       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
4970   // Trigger reconfigure encoder (without resetting the entire instance).
4971   VideoEncoderConfig video_encoder_config;
4972   video_encoder_config.codec_type = kVideoCodecVP8;
4973   video_encoder_config.max_bitrate_bps = kTargetBitrateBps;
4974   video_encoder_config.number_of_streams = 1;
4975   video_encoder_config.video_stream_factory =
4976       new rtc::RefCountedObject<CroppingVideoStreamFactory>(1, kFramerate);
4977   video_stream_encoder_->ConfigureEncoder(std::move(video_encoder_config),
4978                                           kMaxPayloadLength);
4979   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
4980 
4981   video_source_.set_adaptation_enabled(true);
4982 
4983   video_source_.IncomingCapturedFrame(
4984       CreateFrame(1, kFrameWidth, kFrameHeight));
4985   WaitForEncodedFrame(kFrameWidth, kFrameHeight);
4986 
4987   // Trigger CPU overuse, downscale by 3/4.
4988   video_stream_encoder_->TriggerCpuOveruse();
4989   video_source_.IncomingCapturedFrame(
4990       CreateFrame(2, kFrameWidth, kFrameHeight));
4991   WaitForEncodedFrame(kAdaptedFrameWidth, kAdaptedFrameHeight);
4992 
4993   video_stream_encoder_->Stop();
4994 }
4995 
TEST_F(VideoStreamEncoderTest,PeriodicallyUpdatesChannelParameters)4996 TEST_F(VideoStreamEncoderTest, PeriodicallyUpdatesChannelParameters) {
4997   const int kFrameWidth = 1280;
4998   const int kFrameHeight = 720;
4999   const int kLowFps = 2;
5000   const int kHighFps = 30;
5001 
5002   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5003       DataRate::BitsPerSec(kTargetBitrateBps),
5004       DataRate::BitsPerSec(kTargetBitrateBps),
5005       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5006 
5007   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5008   max_framerate_ = kLowFps;
5009 
5010   // Insert 2 seconds of 2fps video.
5011   for (int i = 0; i < kLowFps * 2; ++i) {
5012     video_source_.IncomingCapturedFrame(
5013         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5014     WaitForEncodedFrame(timestamp_ms);
5015     timestamp_ms += 1000 / kLowFps;
5016   }
5017 
5018   // Make sure encoder is updated with new target.
5019   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5020       DataRate::BitsPerSec(kTargetBitrateBps),
5021       DataRate::BitsPerSec(kTargetBitrateBps),
5022       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5023   video_source_.IncomingCapturedFrame(
5024       CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5025   WaitForEncodedFrame(timestamp_ms);
5026   timestamp_ms += 1000 / kLowFps;
5027 
5028   EXPECT_EQ(kLowFps, fake_encoder_.GetConfiguredInputFramerate());
5029 
5030   // Insert 30fps frames for just a little more than the forced update period.
5031   const int kVcmTimerIntervalFrames = (kProcessIntervalMs * kHighFps) / 1000;
5032   const int kFrameIntervalMs = 1000 / kHighFps;
5033   max_framerate_ = kHighFps;
5034   for (int i = 0; i < kVcmTimerIntervalFrames + 2; ++i) {
5035     video_source_.IncomingCapturedFrame(
5036         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5037     // Wait for encoded frame, but skip ahead if it doesn't arrive as it might
5038     // be dropped if the encoder hans't been updated with the new higher target
5039     // framerate yet, causing it to overshoot the target bitrate and then
5040     // suffering the wrath of the media optimizer.
5041     TimedWaitForEncodedFrame(timestamp_ms, 2 * kFrameIntervalMs);
5042     timestamp_ms += kFrameIntervalMs;
5043   }
5044 
5045   // Don expect correct measurement just yet, but it should be higher than
5046   // before.
5047   EXPECT_GT(fake_encoder_.GetConfiguredInputFramerate(), kLowFps);
5048 
5049   video_stream_encoder_->Stop();
5050 }
5051 
TEST_F(VideoStreamEncoderTest,DoesNotUpdateBitrateAllocationWhenSuspended)5052 TEST_F(VideoStreamEncoderTest, DoesNotUpdateBitrateAllocationWhenSuspended) {
5053   const int kFrameWidth = 1280;
5054   const int kFrameHeight = 720;
5055   const int kTargetBitrateBps = 1000000;
5056 
5057   MockBitrateObserver bitrate_observer;
5058   video_stream_encoder_->SetBitrateAllocationObserver(&bitrate_observer);
5059   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5060       DataRate::BitsPerSec(kTargetBitrateBps),
5061       DataRate::BitsPerSec(kTargetBitrateBps),
5062       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5063   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5064 
5065   // Insert a first video frame, causes another bitrate update.
5066   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5067   EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(_)).Times(1);
5068   video_source_.IncomingCapturedFrame(
5069       CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5070   WaitForEncodedFrame(timestamp_ms);
5071 
5072   // Next, simulate video suspension due to pacer queue overrun.
5073   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5074       DataRate::BitsPerSec(0), DataRate::BitsPerSec(0), DataRate::BitsPerSec(0),
5075       0, 1, 0);
5076 
5077   // Skip ahead until a new periodic parameter update should have occured.
5078   timestamp_ms += kProcessIntervalMs;
5079   fake_clock_.AdvanceTime(TimeDelta::Millis(kProcessIntervalMs));
5080 
5081   // Bitrate observer should not be called.
5082   EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(_)).Times(0);
5083   video_source_.IncomingCapturedFrame(
5084       CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5085   ExpectDroppedFrame();
5086 
5087   video_stream_encoder_->Stop();
5088 }
5089 
TEST_F(VideoStreamEncoderTest,DefaultCpuAdaptationThresholdsForSoftwareEncoder)5090 TEST_F(VideoStreamEncoderTest,
5091        DefaultCpuAdaptationThresholdsForSoftwareEncoder) {
5092   const int kFrameWidth = 1280;
5093   const int kFrameHeight = 720;
5094   const CpuOveruseOptions default_options;
5095   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5096       DataRate::BitsPerSec(kTargetBitrateBps),
5097       DataRate::BitsPerSec(kTargetBitrateBps),
5098       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5099   video_source_.IncomingCapturedFrame(
5100       CreateFrame(1, kFrameWidth, kFrameHeight));
5101   WaitForEncodedFrame(1);
5102   EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
5103                 .low_encode_usage_threshold_percent,
5104             default_options.low_encode_usage_threshold_percent);
5105   EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
5106                 .high_encode_usage_threshold_percent,
5107             default_options.high_encode_usage_threshold_percent);
5108   video_stream_encoder_->Stop();
5109 }
5110 
TEST_F(VideoStreamEncoderTest,HigherCpuAdaptationThresholdsForHardwareEncoder)5111 TEST_F(VideoStreamEncoderTest,
5112        HigherCpuAdaptationThresholdsForHardwareEncoder) {
5113   const int kFrameWidth = 1280;
5114   const int kFrameHeight = 720;
5115   CpuOveruseOptions hardware_options;
5116   hardware_options.low_encode_usage_threshold_percent = 150;
5117   hardware_options.high_encode_usage_threshold_percent = 200;
5118   fake_encoder_.SetIsHardwareAccelerated(true);
5119 
5120   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5121       DataRate::BitsPerSec(kTargetBitrateBps),
5122       DataRate::BitsPerSec(kTargetBitrateBps),
5123       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5124   video_source_.IncomingCapturedFrame(
5125       CreateFrame(1, kFrameWidth, kFrameHeight));
5126   WaitForEncodedFrame(1);
5127   EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
5128                 .low_encode_usage_threshold_percent,
5129             hardware_options.low_encode_usage_threshold_percent);
5130   EXPECT_EQ(video_stream_encoder_->overuse_detector_proxy_->GetOptions()
5131                 .high_encode_usage_threshold_percent,
5132             hardware_options.high_encode_usage_threshold_percent);
5133   video_stream_encoder_->Stop();
5134 }
5135 
TEST_F(VideoStreamEncoderTest,DropsFramesWhenEncoderOvershoots)5136 TEST_F(VideoStreamEncoderTest, DropsFramesWhenEncoderOvershoots) {
5137   const int kFrameWidth = 320;
5138   const int kFrameHeight = 240;
5139   const int kFps = 30;
5140   const int kTargetBitrateBps = 120000;
5141   const int kNumFramesInRun = kFps * 5;  // Runs of five seconds.
5142 
5143   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5144       DataRate::BitsPerSec(kTargetBitrateBps),
5145       DataRate::BitsPerSec(kTargetBitrateBps),
5146       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5147 
5148   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5149   max_framerate_ = kFps;
5150 
5151   // Insert 3 seconds of video, verify number of drops with normal bitrate.
5152   fake_encoder_.SimulateOvershoot(1.0);
5153   int num_dropped = 0;
5154   for (int i = 0; i < kNumFramesInRun; ++i) {
5155     video_source_.IncomingCapturedFrame(
5156         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5157     // Wait up to two frame durations for a frame to arrive.
5158     if (!TimedWaitForEncodedFrame(timestamp_ms, 2 * 1000 / kFps)) {
5159       ++num_dropped;
5160     }
5161     timestamp_ms += 1000 / kFps;
5162   }
5163 
5164   // Framerate should be measured to be near the expected target rate.
5165   EXPECT_NEAR(fake_encoder_.GetLastFramerate(), kFps, 1);
5166 
5167   // Frame drops should be within 5% of expected 0%.
5168   EXPECT_NEAR(num_dropped, 0, 5 * kNumFramesInRun / 100);
5169 
5170   // Make encoder produce frames at double the expected bitrate during 3 seconds
5171   // of video, verify number of drops. Rate needs to be slightly changed in
5172   // order to force the rate to be reconfigured.
5173   double overshoot_factor = 2.0;
5174   if (RateControlSettings::ParseFromFieldTrials().UseEncoderBitrateAdjuster()) {
5175     // With bitrate adjuster, when need to overshoot even more to trigger
5176     // frame dropping.
5177     overshoot_factor *= 2;
5178   }
5179   fake_encoder_.SimulateOvershoot(overshoot_factor);
5180   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5181       DataRate::BitsPerSec(kTargetBitrateBps + 1000),
5182       DataRate::BitsPerSec(kTargetBitrateBps + 1000),
5183       DataRate::BitsPerSec(kTargetBitrateBps + 1000), 0, 0, 0);
5184   num_dropped = 0;
5185   for (int i = 0; i < kNumFramesInRun; ++i) {
5186     video_source_.IncomingCapturedFrame(
5187         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5188     // Wait up to two frame durations for a frame to arrive.
5189     if (!TimedWaitForEncodedFrame(timestamp_ms, 2 * 1000 / kFps)) {
5190       ++num_dropped;
5191     }
5192     timestamp_ms += 1000 / kFps;
5193   }
5194 
5195   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5196       DataRate::BitsPerSec(kTargetBitrateBps),
5197       DataRate::BitsPerSec(kTargetBitrateBps),
5198       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5199 
5200   // Target framerate should be still be near the expected target, despite
5201   // the frame drops.
5202   EXPECT_NEAR(fake_encoder_.GetLastFramerate(), kFps, 1);
5203 
5204   // Frame drops should be within 5% of expected 50%.
5205   EXPECT_NEAR(num_dropped, kNumFramesInRun / 2, 5 * kNumFramesInRun / 100);
5206 
5207   video_stream_encoder_->Stop();
5208 }
5209 
TEST_F(VideoStreamEncoderTest,ConfiguresCorrectFrameRate)5210 TEST_F(VideoStreamEncoderTest, ConfiguresCorrectFrameRate) {
5211   const int kFrameWidth = 320;
5212   const int kFrameHeight = 240;
5213   const int kActualInputFps = 24;
5214   const int kTargetBitrateBps = 120000;
5215 
5216   ASSERT_GT(max_framerate_, kActualInputFps);
5217 
5218   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5219   max_framerate_ = kActualInputFps;
5220   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5221       DataRate::BitsPerSec(kTargetBitrateBps),
5222       DataRate::BitsPerSec(kTargetBitrateBps),
5223       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5224 
5225   // Insert 3 seconds of video, with an input fps lower than configured max.
5226   for (int i = 0; i < kActualInputFps * 3; ++i) {
5227     video_source_.IncomingCapturedFrame(
5228         CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight));
5229     // Wait up to two frame durations for a frame to arrive.
5230     WaitForEncodedFrame(timestamp_ms);
5231     timestamp_ms += 1000 / kActualInputFps;
5232   }
5233 
5234   EXPECT_NEAR(kActualInputFps, fake_encoder_.GetLastFramerate(), 1);
5235 
5236   video_stream_encoder_->Stop();
5237 }
5238 
TEST_F(VideoStreamEncoderTest,AccumulatesUpdateRectOnDroppedFrames)5239 TEST_F(VideoStreamEncoderTest, AccumulatesUpdateRectOnDroppedFrames) {
5240   VideoFrame::UpdateRect rect;
5241   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5242       DataRate::BitsPerSec(kTargetBitrateBps),
5243       DataRate::BitsPerSec(kTargetBitrateBps),
5244       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5245 
5246   fake_encoder_.BlockNextEncode();
5247   video_source_.IncomingCapturedFrame(
5248       CreateFrameWithUpdatedPixel(1, nullptr, 0));
5249   WaitForEncodedFrame(1);
5250   // On the very first frame full update should be forced.
5251   rect = fake_encoder_.GetLastUpdateRect();
5252   EXPECT_EQ(rect.offset_x, 0);
5253   EXPECT_EQ(rect.offset_y, 0);
5254   EXPECT_EQ(rect.height, codec_height_);
5255   EXPECT_EQ(rect.width, codec_width_);
5256   // Here, the encoder thread will be blocked in the TestEncoder waiting for a
5257   // call to ContinueEncode.
5258   video_source_.IncomingCapturedFrame(
5259       CreateFrameWithUpdatedPixel(2, nullptr, 1));
5260   ExpectDroppedFrame();
5261   video_source_.IncomingCapturedFrame(
5262       CreateFrameWithUpdatedPixel(3, nullptr, 10));
5263   ExpectDroppedFrame();
5264   fake_encoder_.ContinueEncode();
5265   WaitForEncodedFrame(3);
5266   // Updates to pixels 1 and 10 should be accumulated to one 10x1 rect.
5267   rect = fake_encoder_.GetLastUpdateRect();
5268   EXPECT_EQ(rect.offset_x, 1);
5269   EXPECT_EQ(rect.offset_y, 0);
5270   EXPECT_EQ(rect.width, 10);
5271   EXPECT_EQ(rect.height, 1);
5272 
5273   video_source_.IncomingCapturedFrame(
5274       CreateFrameWithUpdatedPixel(4, nullptr, 0));
5275   WaitForEncodedFrame(4);
5276   // Previous frame was encoded, so no accumulation should happen.
5277   rect = fake_encoder_.GetLastUpdateRect();
5278   EXPECT_EQ(rect.offset_x, 0);
5279   EXPECT_EQ(rect.offset_y, 0);
5280   EXPECT_EQ(rect.width, 1);
5281   EXPECT_EQ(rect.height, 1);
5282 
5283   video_stream_encoder_->Stop();
5284 }
5285 
TEST_F(VideoStreamEncoderTest,SetsFrameTypes)5286 TEST_F(VideoStreamEncoderTest, SetsFrameTypes) {
5287   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5288       DataRate::BitsPerSec(kTargetBitrateBps),
5289       DataRate::BitsPerSec(kTargetBitrateBps),
5290       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5291 
5292   // First frame is always keyframe.
5293   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
5294   WaitForEncodedFrame(1);
5295   EXPECT_THAT(
5296       fake_encoder_.LastFrameTypes(),
5297       ::testing::ElementsAre(VideoFrameType{VideoFrameType::kVideoFrameKey}));
5298 
5299   // Insert delta frame.
5300   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
5301   WaitForEncodedFrame(2);
5302   EXPECT_THAT(
5303       fake_encoder_.LastFrameTypes(),
5304       ::testing::ElementsAre(VideoFrameType{VideoFrameType::kVideoFrameDelta}));
5305 
5306   // Request next frame be a key-frame.
5307   video_stream_encoder_->SendKeyFrame();
5308   video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
5309   WaitForEncodedFrame(3);
5310   EXPECT_THAT(
5311       fake_encoder_.LastFrameTypes(),
5312       ::testing::ElementsAre(VideoFrameType{VideoFrameType::kVideoFrameKey}));
5313 
5314   video_stream_encoder_->Stop();
5315 }
5316 
TEST_F(VideoStreamEncoderTest,SetsFrameTypesSimulcast)5317 TEST_F(VideoStreamEncoderTest, SetsFrameTypesSimulcast) {
5318   // Setup simulcast with three streams.
5319   ResetEncoder("VP8", 3, 1, 1, false);
5320   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5321       DataRate::BitsPerSec(kSimulcastTargetBitrateBps),
5322       DataRate::BitsPerSec(kSimulcastTargetBitrateBps),
5323       DataRate::BitsPerSec(kSimulcastTargetBitrateBps), 0, 0, 0);
5324   // Wait for all three layers before triggering event.
5325   sink_.SetNumExpectedLayers(3);
5326 
5327   // First frame is always keyframe.
5328   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
5329   WaitForEncodedFrame(1);
5330   EXPECT_THAT(fake_encoder_.LastFrameTypes(),
5331               ::testing::ElementsAreArray({VideoFrameType::kVideoFrameKey,
5332                                            VideoFrameType::kVideoFrameKey,
5333                                            VideoFrameType::kVideoFrameKey}));
5334 
5335   // Insert delta frame.
5336   video_source_.IncomingCapturedFrame(CreateFrame(2, nullptr));
5337   WaitForEncodedFrame(2);
5338   EXPECT_THAT(fake_encoder_.LastFrameTypes(),
5339               ::testing::ElementsAreArray({VideoFrameType::kVideoFrameDelta,
5340                                            VideoFrameType::kVideoFrameDelta,
5341                                            VideoFrameType::kVideoFrameDelta}));
5342 
5343   // Request next frame be a key-frame.
5344   // Only first stream is configured to produce key-frame.
5345   video_stream_encoder_->SendKeyFrame();
5346   video_source_.IncomingCapturedFrame(CreateFrame(3, nullptr));
5347   WaitForEncodedFrame(3);
5348 
5349   // TODO(webrtc:10615): Map keyframe request to spatial layer. Currently
5350   // keyframe request on any layer triggers keyframe on all layers.
5351   EXPECT_THAT(fake_encoder_.LastFrameTypes(),
5352               ::testing::ElementsAreArray({VideoFrameType::kVideoFrameKey,
5353                                            VideoFrameType::kVideoFrameKey,
5354                                            VideoFrameType::kVideoFrameKey}));
5355 
5356   video_stream_encoder_->Stop();
5357 }
5358 
TEST_F(VideoStreamEncoderTest,RequestKeyframeInternalSource)5359 TEST_F(VideoStreamEncoderTest, RequestKeyframeInternalSource) {
5360   // Configure internal source factory and setup test again.
5361   encoder_factory_.SetHasInternalSource(true);
5362   ResetEncoder("VP8", 1, 1, 1, false);
5363   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5364       DataRate::BitsPerSec(kTargetBitrateBps),
5365       DataRate::BitsPerSec(kTargetBitrateBps),
5366       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5367 
5368   // Call encoder directly, simulating internal source where encoded frame
5369   // callback in VideoStreamEncoder is called despite no OnFrame().
5370   fake_encoder_.InjectFrame(CreateFrame(1, nullptr), true);
5371   EXPECT_TRUE(WaitForFrame(kDefaultTimeoutMs));
5372   EXPECT_THAT(
5373       fake_encoder_.LastFrameTypes(),
5374       ::testing::ElementsAre(VideoFrameType{VideoFrameType::kVideoFrameKey}));
5375 
5376   const std::vector<VideoFrameType> kDeltaFrame = {
5377       VideoFrameType::kVideoFrameDelta};
5378   // Need to set timestamp manually since manually for injected frame.
5379   VideoFrame frame = CreateFrame(101, nullptr);
5380   frame.set_timestamp(101);
5381   fake_encoder_.InjectFrame(frame, false);
5382   EXPECT_TRUE(WaitForFrame(kDefaultTimeoutMs));
5383   EXPECT_THAT(
5384       fake_encoder_.LastFrameTypes(),
5385       ::testing::ElementsAre(VideoFrameType{VideoFrameType::kVideoFrameDelta}));
5386 
5387   // Request key-frame. The forces a dummy frame down into the encoder.
5388   fake_encoder_.ExpectNullFrame();
5389   video_stream_encoder_->SendKeyFrame();
5390   EXPECT_TRUE(WaitForFrame(kDefaultTimeoutMs));
5391   EXPECT_THAT(
5392       fake_encoder_.LastFrameTypes(),
5393       ::testing::ElementsAre(VideoFrameType{VideoFrameType::kVideoFrameKey}));
5394 
5395   video_stream_encoder_->Stop();
5396 }
5397 
TEST_F(VideoStreamEncoderTest,AdjustsTimestampInternalSource)5398 TEST_F(VideoStreamEncoderTest, AdjustsTimestampInternalSource) {
5399   // Configure internal source factory and setup test again.
5400   encoder_factory_.SetHasInternalSource(true);
5401   ResetEncoder("VP8", 1, 1, 1, false);
5402   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5403       DataRate::BitsPerSec(kTargetBitrateBps),
5404       DataRate::BitsPerSec(kTargetBitrateBps),
5405       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5406 
5407   int64_t timestamp = 1;
5408   EncodedImage image;
5409   image.SetEncodedData(
5410       EncodedImageBuffer::Create(kTargetBitrateBps / kDefaultFramerate / 8));
5411   image.capture_time_ms_ = ++timestamp;
5412   image.SetTimestamp(static_cast<uint32_t>(timestamp * 90));
5413   const int64_t kEncodeFinishDelayMs = 10;
5414   image.timing_.encode_start_ms = timestamp;
5415   image.timing_.encode_finish_ms = timestamp + kEncodeFinishDelayMs;
5416   fake_encoder_.InjectEncodedImage(image);
5417   // Wait for frame without incrementing clock.
5418   EXPECT_TRUE(sink_.WaitForFrame(kDefaultTimeoutMs));
5419   // Frame is captured kEncodeFinishDelayMs before it's encoded, so restored
5420   // capture timestamp should be kEncodeFinishDelayMs in the past.
5421   EXPECT_EQ(sink_.GetLastCaptureTimeMs(),
5422             fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec -
5423                 kEncodeFinishDelayMs);
5424 
5425   video_stream_encoder_->Stop();
5426 }
5427 
TEST_F(VideoStreamEncoderTest,DoesNotRewriteH264BitstreamWithOptimalSps)5428 TEST_F(VideoStreamEncoderTest, DoesNotRewriteH264BitstreamWithOptimalSps) {
5429   // SPS contains VUI with restrictions on the maximum number of reordered
5430   // pictures, there is no need to rewrite the bitstream to enable faster
5431   // decoding.
5432   ResetEncoder("H264", 1, 1, 1, false);
5433 
5434   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5435       DataRate::BitsPerSec(kTargetBitrateBps),
5436       DataRate::BitsPerSec(kTargetBitrateBps),
5437       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5438   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5439 
5440   fake_encoder_.SetEncodedImageData(
5441       EncodedImageBuffer::Create(optimal_sps, sizeof(optimal_sps)));
5442 
5443   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
5444   WaitForEncodedFrame(1);
5445 
5446   EXPECT_THAT(sink_.GetLastEncodedImageData(),
5447               testing::ElementsAreArray(optimal_sps));
5448   RTPFragmentationHeader last_fragmentation = sink_.GetLastFragmentation();
5449   ASSERT_THAT(last_fragmentation.fragmentationVectorSize, 1U);
5450   EXPECT_EQ(last_fragmentation.fragmentationOffset[0], 4U);
5451   EXPECT_EQ(last_fragmentation.fragmentationLength[0], sizeof(optimal_sps) - 4);
5452 
5453   video_stream_encoder_->Stop();
5454 }
5455 
TEST_F(VideoStreamEncoderTest,RewritesH264BitstreamWithNonOptimalSps)5456 TEST_F(VideoStreamEncoderTest, RewritesH264BitstreamWithNonOptimalSps) {
5457   // SPS does not contain VUI, the bitstream is will be rewritten with added
5458   // VUI with restrictions on the maximum number of reordered pictures to
5459   // enable faster decoding.
5460   uint8_t original_sps[] = {0,    0,    0,    1,    H264::NaluType::kSps,
5461                             0x00, 0x00, 0x03, 0x03, 0xF4,
5462                             0x05, 0x03, 0xC7, 0xC0};
5463   ResetEncoder("H264", 1, 1, 1, false);
5464 
5465   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5466       DataRate::BitsPerSec(kTargetBitrateBps),
5467       DataRate::BitsPerSec(kTargetBitrateBps),
5468       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5469   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5470 
5471   fake_encoder_.SetEncodedImageData(
5472       EncodedImageBuffer::Create(original_sps, sizeof(original_sps)));
5473 
5474   video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
5475   WaitForEncodedFrame(1);
5476 
5477   EXPECT_THAT(sink_.GetLastEncodedImageData(),
5478               testing::ElementsAreArray(optimal_sps));
5479   RTPFragmentationHeader last_fragmentation = sink_.GetLastFragmentation();
5480   ASSERT_THAT(last_fragmentation.fragmentationVectorSize, 1U);
5481   EXPECT_EQ(last_fragmentation.fragmentationOffset[0], 4U);
5482   EXPECT_EQ(last_fragmentation.fragmentationLength[0], sizeof(optimal_sps) - 4);
5483 
5484   video_stream_encoder_->Stop();
5485 }
5486 
TEST_F(VideoStreamEncoderTest,CopiesVideoFrameMetadataAfterDownscale)5487 TEST_F(VideoStreamEncoderTest, CopiesVideoFrameMetadataAfterDownscale) {
5488   const int kFrameWidth = 1280;
5489   const int kFrameHeight = 720;
5490   const int kTargetBitrateBps = 300000;  // To low for HD resolution.
5491 
5492   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5493       DataRate::BitsPerSec(kTargetBitrateBps),
5494       DataRate::BitsPerSec(kTargetBitrateBps),
5495       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5496   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5497 
5498   // Insert a first video frame. It should be dropped because of downscale in
5499   // resolution.
5500   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5501   VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight);
5502   frame.set_rotation(kVideoRotation_270);
5503   video_source_.IncomingCapturedFrame(frame);
5504 
5505   ExpectDroppedFrame();
5506 
5507   // Second frame is downscaled.
5508   timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5509   frame = CreateFrame(timestamp_ms, kFrameWidth / 2, kFrameHeight / 2);
5510   frame.set_rotation(kVideoRotation_90);
5511   video_source_.IncomingCapturedFrame(frame);
5512 
5513   WaitForEncodedFrame(timestamp_ms);
5514   sink_.CheckLastFrameRotationMatches(kVideoRotation_90);
5515 
5516   // Insert another frame, also downscaled.
5517   timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5518   frame = CreateFrame(timestamp_ms, kFrameWidth / 2, kFrameHeight / 2);
5519   frame.set_rotation(kVideoRotation_180);
5520   video_source_.IncomingCapturedFrame(frame);
5521 
5522   WaitForEncodedFrame(timestamp_ms);
5523   sink_.CheckLastFrameRotationMatches(kVideoRotation_180);
5524 
5525   video_stream_encoder_->Stop();
5526 }
5527 
TEST_F(VideoStreamEncoderTest,BandwidthAllocationLowerBound)5528 TEST_F(VideoStreamEncoderTest, BandwidthAllocationLowerBound) {
5529   const int kFrameWidth = 320;
5530   const int kFrameHeight = 180;
5531 
5532   // Initial rate.
5533   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5534       /*target_bitrate=*/DataRate::KilobitsPerSec(300),
5535       /*stable_target_bitrate=*/DataRate::KilobitsPerSec(300),
5536       /*link_allocation=*/DataRate::KilobitsPerSec(300),
5537       /*fraction_lost=*/0,
5538       /*rtt_ms=*/0,
5539       /*cwnd_reduce_ratio=*/0);
5540 
5541   // Insert a first video frame so that encoder gets configured.
5542   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5543   VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight);
5544   frame.set_rotation(kVideoRotation_270);
5545   video_source_.IncomingCapturedFrame(frame);
5546   WaitForEncodedFrame(timestamp_ms);
5547 
5548   // Set a target rate below the minimum allowed by the codec settings.
5549   VideoCodec codec_config = fake_encoder_.codec_config();
5550   DataRate min_rate = DataRate::KilobitsPerSec(codec_config.minBitrate);
5551   DataRate target_rate = min_rate - DataRate::KilobitsPerSec(1);
5552   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5553       /*target_bitrate=*/target_rate,
5554       /*stable_target_bitrate=*/target_rate,
5555       /*link_allocation=*/target_rate,
5556       /*fraction_lost=*/0,
5557       /*rtt_ms=*/0,
5558       /*cwnd_reduce_ratio=*/0);
5559   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5560 
5561   // Target bitrate and bandwidth allocation should both be capped at min_rate.
5562   auto rate_settings = fake_encoder_.GetAndResetLastRateControlSettings();
5563   ASSERT_TRUE(rate_settings.has_value());
5564   DataRate allocation_sum =
5565       DataRate::BitsPerSec(rate_settings->bitrate.get_sum_bps());
5566   EXPECT_EQ(min_rate, allocation_sum);
5567   EXPECT_EQ(rate_settings->bandwidth_allocation, min_rate);
5568 
5569   video_stream_encoder_->Stop();
5570 }
5571 
TEST_F(VideoStreamEncoderTest,EncoderRatesPropagatedOnReconfigure)5572 TEST_F(VideoStreamEncoderTest, EncoderRatesPropagatedOnReconfigure) {
5573   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5574       DataRate::BitsPerSec(kTargetBitrateBps),
5575       DataRate::BitsPerSec(kTargetBitrateBps),
5576       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5577   // Capture a frame and wait for it to synchronize with the encoder thread.
5578   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5579   video_source_.IncomingCapturedFrame(CreateFrame(timestamp_ms, nullptr));
5580   WaitForEncodedFrame(1);
5581 
5582   auto prev_rate_settings = fake_encoder_.GetAndResetLastRateControlSettings();
5583   ASSERT_TRUE(prev_rate_settings.has_value());
5584   EXPECT_EQ(static_cast<int>(prev_rate_settings->framerate_fps),
5585             kDefaultFramerate);
5586 
5587   // Send 1s of video to ensure the framerate is stable at kDefaultFramerate.
5588   for (int i = 0; i < 2 * kDefaultFramerate; i++) {
5589     timestamp_ms += 1000 / kDefaultFramerate;
5590     video_source_.IncomingCapturedFrame(CreateFrame(timestamp_ms, nullptr));
5591     WaitForEncodedFrame(timestamp_ms);
5592   }
5593   EXPECT_EQ(static_cast<int>(fake_encoder_.GetLastFramerate()),
5594             kDefaultFramerate);
5595   // Capture larger frame to trigger a reconfigure.
5596   codec_height_ *= 2;
5597   codec_width_ *= 2;
5598   timestamp_ms += 1000 / kDefaultFramerate;
5599   video_source_.IncomingCapturedFrame(CreateFrame(timestamp_ms, nullptr));
5600   WaitForEncodedFrame(timestamp_ms);
5601 
5602   EXPECT_EQ(2, sink_.number_of_reconfigurations());
5603   auto current_rate_settings =
5604       fake_encoder_.GetAndResetLastRateControlSettings();
5605   // Ensure we have actually reconfigured twice
5606   // The rate settings should have been set again even though
5607   // they haven't changed.
5608   ASSERT_TRUE(current_rate_settings.has_value());
5609   EXPECT_EQ(prev_rate_settings, current_rate_settings);
5610 
5611   video_stream_encoder_->Stop();
5612 }
5613 
5614 struct MockEncoderSwitchRequestCallback : public EncoderSwitchRequestCallback {
5615   MOCK_METHOD(void, RequestEncoderFallback, (), (override));
5616   MOCK_METHOD(void, RequestEncoderSwitch, (const Config& conf), (override));
5617   MOCK_METHOD(void,
5618               RequestEncoderSwitch,
5619               (const webrtc::SdpVideoFormat& format),
5620               (override));
5621 };
5622 
TEST_F(VideoStreamEncoderTest,BitrateEncoderSwitch)5623 TEST_F(VideoStreamEncoderTest, BitrateEncoderSwitch) {
5624   constexpr int kDontCare = 100;
5625 
5626   StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
5627   video_send_config_.encoder_settings.encoder_switch_request_callback =
5628       &switch_callback;
5629   VideoEncoderConfig encoder_config = video_encoder_config_.Copy();
5630   encoder_config.codec_type = kVideoCodecVP8;
5631   webrtc::test::ScopedFieldTrials field_trial(
5632       "WebRTC-NetworkCondition-EncoderSwitch/"
5633       "codec_thresholds:VP8;100;-1|H264;-1;30000,"
5634       "to_codec:AV1,to_param:ping,to_value:pong,window:2.0/");
5635 
5636   // Reset encoder for new configuration to take effect.
5637   ConfigureEncoder(std::move(encoder_config));
5638 
5639   // Send one frame to trigger ReconfigureEncoder.
5640   video_source_.IncomingCapturedFrame(
5641       CreateFrame(kDontCare, kDontCare, kDontCare));
5642 
5643   using Config = EncoderSwitchRequestCallback::Config;
5644   EXPECT_CALL(switch_callback, RequestEncoderSwitch(Matcher<const Config&>(
5645                                    AllOf(Field(&Config::codec_name, "AV1"),
5646                                          Field(&Config::param, "ping"),
5647                                          Field(&Config::value, "pong")))));
5648 
5649   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5650       /*target_bitrate=*/DataRate::KilobitsPerSec(50),
5651       /*stable_target_bitrate=*/DataRate::KilobitsPerSec(kDontCare),
5652       /*link_allocation=*/DataRate::KilobitsPerSec(kDontCare),
5653       /*fraction_lost=*/0,
5654       /*rtt_ms=*/0,
5655       /*cwnd_reduce_ratio=*/0);
5656 
5657   video_stream_encoder_->Stop();
5658 }
5659 
TEST_F(VideoStreamEncoderTest,VideoSuspendedNoEncoderSwitch)5660 TEST_F(VideoStreamEncoderTest, VideoSuspendedNoEncoderSwitch) {
5661   constexpr int kDontCare = 100;
5662 
5663   StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
5664   video_send_config_.encoder_settings.encoder_switch_request_callback =
5665       &switch_callback;
5666   VideoEncoderConfig encoder_config = video_encoder_config_.Copy();
5667   encoder_config.codec_type = kVideoCodecVP8;
5668   webrtc::test::ScopedFieldTrials field_trial(
5669       "WebRTC-NetworkCondition-EncoderSwitch/"
5670       "codec_thresholds:VP8;100;-1|H264;-1;30000,"
5671       "to_codec:AV1,to_param:ping,to_value:pong,window:2.0/");
5672 
5673   // Reset encoder for new configuration to take effect.
5674   ConfigureEncoder(std::move(encoder_config));
5675 
5676   // Send one frame to trigger ReconfigureEncoder.
5677   video_source_.IncomingCapturedFrame(
5678       CreateFrame(kDontCare, kDontCare, kDontCare));
5679 
5680   using Config = EncoderSwitchRequestCallback::Config;
5681   EXPECT_CALL(switch_callback, RequestEncoderSwitch(Matcher<const Config&>(_)))
5682       .Times(0);
5683 
5684   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5685       /*target_bitrate=*/DataRate::KilobitsPerSec(0),
5686       /*stable_target_bitrate=*/DataRate::KilobitsPerSec(0),
5687       /*link_allocation=*/DataRate::KilobitsPerSec(kDontCare),
5688       /*fraction_lost=*/0,
5689       /*rtt_ms=*/0,
5690       /*cwnd_reduce_ratio=*/0);
5691 
5692   video_stream_encoder_->Stop();
5693 }
5694 
TEST_F(VideoStreamEncoderTest,ResolutionEncoderSwitch)5695 TEST_F(VideoStreamEncoderTest, ResolutionEncoderSwitch) {
5696   constexpr int kSufficientBitrateToNotDrop = 1000;
5697   constexpr int kHighRes = 500;
5698   constexpr int kLowRes = 100;
5699 
5700   StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
5701   video_send_config_.encoder_settings.encoder_switch_request_callback =
5702       &switch_callback;
5703   webrtc::test::ScopedFieldTrials field_trial(
5704       "WebRTC-NetworkCondition-EncoderSwitch/"
5705       "codec_thresholds:VP8;120;-1|H264;-1;30000,"
5706       "to_codec:AV1,to_param:ping,to_value:pong,window:2.0/");
5707   VideoEncoderConfig encoder_config = video_encoder_config_.Copy();
5708   encoder_config.codec_type = kVideoCodecH264;
5709 
5710   // Reset encoder for new configuration to take effect.
5711   ConfigureEncoder(std::move(encoder_config));
5712 
5713   // The VideoStreamEncoder needs some bitrate before it can start encoding,
5714   // setting some bitrate so that subsequent calls to WaitForEncodedFrame does
5715   // not fail.
5716   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5717       /*target_bitrate=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
5718       /*stable_target_bitrate=*/
5719       DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
5720       /*link_allocation=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
5721       /*fraction_lost=*/0,
5722       /*rtt_ms=*/0,
5723       /*cwnd_reduce_ratio=*/0);
5724 
5725   // Send one frame to trigger ReconfigureEncoder.
5726   video_source_.IncomingCapturedFrame(CreateFrame(1, kHighRes, kHighRes));
5727   WaitForEncodedFrame(1);
5728 
5729   using Config = EncoderSwitchRequestCallback::Config;
5730   EXPECT_CALL(switch_callback, RequestEncoderSwitch(Matcher<const Config&>(
5731                                    AllOf(Field(&Config::codec_name, "AV1"),
5732                                          Field(&Config::param, "ping"),
5733                                          Field(&Config::value, "pong")))));
5734 
5735   video_source_.IncomingCapturedFrame(CreateFrame(2, kLowRes, kLowRes));
5736   WaitForEncodedFrame(2);
5737 
5738   video_stream_encoder_->Stop();
5739 }
5740 
TEST_F(VideoStreamEncoderTest,EncoderSelectorCurrentEncoderIsSignaled)5741 TEST_F(VideoStreamEncoderTest, EncoderSelectorCurrentEncoderIsSignaled) {
5742   constexpr int kDontCare = 100;
5743   StrictMock<MockEncoderSelector> encoder_selector;
5744   auto encoder_factory = std::make_unique<test::VideoEncoderProxyFactory>(
5745       &fake_encoder_, &encoder_selector);
5746   video_send_config_.encoder_settings.encoder_factory = encoder_factory.get();
5747 
5748   // Reset encoder for new configuration to take effect.
5749   ConfigureEncoder(video_encoder_config_.Copy());
5750 
5751   EXPECT_CALL(encoder_selector, OnCurrentEncoder(_));
5752 
5753   video_source_.IncomingCapturedFrame(
5754       CreateFrame(kDontCare, kDontCare, kDontCare));
5755   video_stream_encoder_->Stop();
5756 
5757   // The encoders produces by the VideoEncoderProxyFactory have a pointer back
5758   // to it's factory, so in order for the encoder instance in the
5759   // |video_stream_encoder_| to be destroyed before the |encoder_factory| we
5760   // reset the |video_stream_encoder_| here.
5761   video_stream_encoder_.reset();
5762 }
5763 
TEST_F(VideoStreamEncoderTest,EncoderSelectorBitrateSwitch)5764 TEST_F(VideoStreamEncoderTest, EncoderSelectorBitrateSwitch) {
5765   constexpr int kDontCare = 100;
5766 
5767   NiceMock<MockEncoderSelector> encoder_selector;
5768   StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
5769   video_send_config_.encoder_settings.encoder_switch_request_callback =
5770       &switch_callback;
5771   auto encoder_factory = std::make_unique<test::VideoEncoderProxyFactory>(
5772       &fake_encoder_, &encoder_selector);
5773   video_send_config_.encoder_settings.encoder_factory = encoder_factory.get();
5774 
5775   // Reset encoder for new configuration to take effect.
5776   ConfigureEncoder(video_encoder_config_.Copy());
5777 
5778   ON_CALL(encoder_selector, OnAvailableBitrate(_))
5779       .WillByDefault(Return(SdpVideoFormat("AV1")));
5780   EXPECT_CALL(switch_callback,
5781               RequestEncoderSwitch(Matcher<const SdpVideoFormat&>(
5782                   Field(&SdpVideoFormat::name, "AV1"))));
5783 
5784   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5785       /*target_bitrate=*/DataRate::KilobitsPerSec(50),
5786       /*stable_target_bitrate=*/DataRate::KilobitsPerSec(kDontCare),
5787       /*link_allocation=*/DataRate::KilobitsPerSec(kDontCare),
5788       /*fraction_lost=*/0,
5789       /*rtt_ms=*/0,
5790       /*cwnd_reduce_ratio=*/0);
5791 
5792   video_stream_encoder_->Stop();
5793 }
5794 
TEST_F(VideoStreamEncoderTest,EncoderSelectorBrokenEncoderSwitch)5795 TEST_F(VideoStreamEncoderTest, EncoderSelectorBrokenEncoderSwitch) {
5796   constexpr int kSufficientBitrateToNotDrop = 1000;
5797   constexpr int kDontCare = 100;
5798 
5799   NiceMock<MockVideoEncoder> video_encoder;
5800   NiceMock<MockEncoderSelector> encoder_selector;
5801   StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
5802   video_send_config_.encoder_settings.encoder_switch_request_callback =
5803       &switch_callback;
5804   auto encoder_factory = std::make_unique<test::VideoEncoderProxyFactory>(
5805       &video_encoder, &encoder_selector);
5806   video_send_config_.encoder_settings.encoder_factory = encoder_factory.get();
5807 
5808   // Reset encoder for new configuration to take effect.
5809   ConfigureEncoder(video_encoder_config_.Copy());
5810 
5811   // The VideoStreamEncoder needs some bitrate before it can start encoding,
5812   // setting some bitrate so that subsequent calls to WaitForEncodedFrame does
5813   // not fail.
5814   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5815       /*target_bitrate=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
5816       /*stable_target_bitrate=*/
5817       DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
5818       /*link_allocation=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
5819       /*fraction_lost=*/0,
5820       /*rtt_ms=*/0,
5821       /*cwnd_reduce_ratio=*/0);
5822 
5823   ON_CALL(video_encoder, Encode(_, _))
5824       .WillByDefault(Return(WEBRTC_VIDEO_CODEC_ENCODER_FAILURE));
5825   ON_CALL(encoder_selector, OnEncoderBroken())
5826       .WillByDefault(Return(SdpVideoFormat("AV2")));
5827 
5828   rtc::Event encode_attempted;
5829   EXPECT_CALL(switch_callback,
5830               RequestEncoderSwitch(Matcher<const SdpVideoFormat&>(_)))
5831       .WillOnce([&encode_attempted](const SdpVideoFormat& format) {
5832         EXPECT_EQ(format.name, "AV2");
5833         encode_attempted.Set();
5834       });
5835 
5836   video_source_.IncomingCapturedFrame(CreateFrame(1, kDontCare, kDontCare));
5837   encode_attempted.Wait(3000);
5838 
5839   video_stream_encoder_->Stop();
5840 
5841   // The encoders produces by the VideoEncoderProxyFactory have a pointer back
5842   // to it's factory, so in order for the encoder instance in the
5843   // |video_stream_encoder_| to be destroyed before the |encoder_factory| we
5844   // reset the |video_stream_encoder_| here.
5845   video_stream_encoder_.reset();
5846 }
5847 
TEST_F(VideoStreamEncoderTest,AllocationPropagatedToEncoderWhenTargetRateChanged)5848 TEST_F(VideoStreamEncoderTest,
5849        AllocationPropagatedToEncoderWhenTargetRateChanged) {
5850   const int kFrameWidth = 320;
5851   const int kFrameHeight = 180;
5852 
5853   // Set initial rate.
5854   auto rate = DataRate::KilobitsPerSec(100);
5855   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5856       /*target_bitrate=*/rate,
5857       /*stable_target_bitrate=*/rate,
5858       /*link_allocation=*/rate,
5859       /*fraction_lost=*/0,
5860       /*rtt_ms=*/0,
5861       /*cwnd_reduce_ratio=*/0);
5862 
5863   // Insert a first video frame so that encoder gets configured.
5864   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5865   VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight);
5866   frame.set_rotation(kVideoRotation_270);
5867   video_source_.IncomingCapturedFrame(frame);
5868   WaitForEncodedFrame(timestamp_ms);
5869   EXPECT_EQ(1, fake_encoder_.GetNumSetRates());
5870 
5871   // Change of target bitrate propagates to the encoder.
5872   auto new_stable_rate = rate - DataRate::KilobitsPerSec(5);
5873   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5874       /*target_bitrate=*/new_stable_rate,
5875       /*stable_target_bitrate=*/new_stable_rate,
5876       /*link_allocation=*/rate,
5877       /*fraction_lost=*/0,
5878       /*rtt_ms=*/0,
5879       /*cwnd_reduce_ratio=*/0);
5880   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5881   EXPECT_EQ(2, fake_encoder_.GetNumSetRates());
5882   video_stream_encoder_->Stop();
5883 }
5884 
TEST_F(VideoStreamEncoderTest,AllocationNotPropagatedToEncoderWhenTargetRateUnchanged)5885 TEST_F(VideoStreamEncoderTest,
5886        AllocationNotPropagatedToEncoderWhenTargetRateUnchanged) {
5887   const int kFrameWidth = 320;
5888   const int kFrameHeight = 180;
5889 
5890   // Set initial rate.
5891   auto rate = DataRate::KilobitsPerSec(100);
5892   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5893       /*target_bitrate=*/rate,
5894       /*stable_target_bitrate=*/rate,
5895       /*link_allocation=*/rate,
5896       /*fraction_lost=*/0,
5897       /*rtt_ms=*/0,
5898       /*cwnd_reduce_ratio=*/0);
5899 
5900   // Insert a first video frame so that encoder gets configured.
5901   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5902   VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight);
5903   frame.set_rotation(kVideoRotation_270);
5904   video_source_.IncomingCapturedFrame(frame);
5905   WaitForEncodedFrame(timestamp_ms);
5906   EXPECT_EQ(1, fake_encoder_.GetNumSetRates());
5907 
5908   // Set a higher target rate without changing the link_allocation. Should not
5909   // reset encoder's rate.
5910   auto new_stable_rate = rate - DataRate::KilobitsPerSec(5);
5911   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5912       /*target_bitrate=*/rate,
5913       /*stable_target_bitrate=*/new_stable_rate,
5914       /*link_allocation=*/rate,
5915       /*fraction_lost=*/0,
5916       /*rtt_ms=*/0,
5917       /*cwnd_reduce_ratio=*/0);
5918   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
5919   EXPECT_EQ(1, fake_encoder_.GetNumSetRates());
5920   video_stream_encoder_->Stop();
5921 }
5922 
TEST_F(VideoStreamEncoderTest,AutomaticAnimationDetection)5923 TEST_F(VideoStreamEncoderTest, AutomaticAnimationDetection) {
5924   test::ScopedFieldTrials field_trials(
5925       "WebRTC-AutomaticAnimationDetectionScreenshare/"
5926       "enabled:true,min_fps:20,min_duration_ms:1000,min_area_ratio:0.8/");
5927   const int kFramerateFps = 30;
5928   const int kWidth = 1920;
5929   const int kHeight = 1080;
5930   const int kNumFrames = 2 * kFramerateFps;  // >1 seconds of frames.
5931   // Works on screenshare mode.
5932   ResetEncoder("VP8", 1, 1, 1, /*screenshare*/ true);
5933   // We rely on the automatic resolution adaptation, but we handle framerate
5934   // adaptation manually by mocking the stats proxy.
5935   video_source_.set_adaptation_enabled(true);
5936 
5937   // BALANCED degradation preference is required for this feature.
5938   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5939       DataRate::BitsPerSec(kTargetBitrateBps),
5940       DataRate::BitsPerSec(kTargetBitrateBps),
5941       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5942   video_stream_encoder_->SetSource(&video_source_,
5943                                    webrtc::DegradationPreference::BALANCED);
5944   EXPECT_THAT(video_source_.sink_wants(), UnlimitedSinkWants());
5945 
5946   VideoFrame frame = CreateFrame(1, kWidth, kHeight);
5947   frame.set_update_rect(VideoFrame::UpdateRect{0, 0, kWidth, kHeight});
5948 
5949   // Pass enough frames with the full update to trigger animation detection.
5950   for (int i = 0; i < kNumFrames; ++i) {
5951     int64_t timestamp_ms =
5952         fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5953     frame.set_ntp_time_ms(timestamp_ms);
5954     frame.set_timestamp_us(timestamp_ms * 1000);
5955     video_source_.IncomingCapturedFrame(frame);
5956     WaitForEncodedFrame(timestamp_ms);
5957   }
5958 
5959   // Resolution should be limited.
5960   rtc::VideoSinkWants expected;
5961   expected.max_framerate_fps = kFramerateFps;
5962   expected.max_pixel_count = 1280 * 720 + 1;
5963   EXPECT_THAT(video_source_.sink_wants(), FpsEqResolutionLt(expected));
5964 
5965   // Pass one frame with no known update.
5966   //  Resolution cap should be removed immediately.
5967   int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
5968   frame.set_ntp_time_ms(timestamp_ms);
5969   frame.set_timestamp_us(timestamp_ms * 1000);
5970   frame.clear_update_rect();
5971 
5972   video_source_.IncomingCapturedFrame(frame);
5973   WaitForEncodedFrame(timestamp_ms);
5974 
5975   // Resolution should be unlimited now.
5976   EXPECT_THAT(video_source_.sink_wants(),
5977               FpsMatchesResolutionMax(Eq(kFramerateFps)));
5978 
5979   video_stream_encoder_->Stop();
5980 }
5981 
TEST_F(VideoStreamEncoderTest,ConfiguresVp9SvcAtOddResolutions)5982 TEST_F(VideoStreamEncoderTest, ConfiguresVp9SvcAtOddResolutions) {
5983   const int kWidth = 720;  // 540p adapted down.
5984   const int kHeight = 405;
5985   const int kNumFrames = 3;
5986   // Works on screenshare mode.
5987   ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1,
5988                /*num_spatial_layers=*/2, /*screenshare=*/true);
5989 
5990   video_source_.set_adaptation_enabled(true);
5991 
5992   video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
5993       DataRate::BitsPerSec(kTargetBitrateBps),
5994       DataRate::BitsPerSec(kTargetBitrateBps),
5995       DataRate::BitsPerSec(kTargetBitrateBps), 0, 0, 0);
5996 
5997   VideoFrame frame = CreateFrame(1, kWidth, kHeight);
5998 
5999   // Pass enough frames with the full update to trigger animation detection.
6000   for (int i = 0; i < kNumFrames; ++i) {
6001     int64_t timestamp_ms =
6002         fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec;
6003     frame.set_ntp_time_ms(timestamp_ms);
6004     frame.set_timestamp_us(timestamp_ms * 1000);
6005     video_source_.IncomingCapturedFrame(frame);
6006     WaitForEncodedFrame(timestamp_ms);
6007   }
6008 
6009   video_stream_encoder_->Stop();
6010 }
6011 
6012 }  // namespace webrtc
6013