1 /*
2  *  Copyright (c) 2013 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 "modules/video_coding/codecs/vp8/screenshare_layers.h"
12 
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include <cstdint>
17 #include <memory>
18 #include <vector>
19 
20 #include "api/video_codecs/vp8_frame_config.h"
21 #include "modules/video_coding/codecs/interface/common_constants.h"
22 #include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
23 #include "modules/video_coding/include/video_codec_interface.h"
24 #include "rtc_base/checks.h"
25 #include "rtc_base/fake_clock.h"
26 #include "system_wrappers/include/metrics.h"
27 #include "test/gmock.h"
28 #include "test/gtest.h"
29 #include "vpx/vp8cx.h"
30 
31 using ::testing::_;
32 using ::testing::ElementsAre;
33 using ::testing::NiceMock;
34 
35 namespace webrtc {
36 namespace {
37 // 5 frames per second at 90 kHz.
38 const uint32_t kTimestampDelta5Fps = 90000 / 5;
39 const int kDefaultQp = 54;
40 const int kDefaultTl0BitrateKbps = 200;
41 const int kDefaultTl1BitrateKbps = 2000;
42 const int kFrameRate = 5;
43 const int kSyncPeriodSeconds = 2;
44 const int kMaxSyncPeriodSeconds = 4;
45 
46 // Expected flags for corresponding temporal layers.
47 const int kTl0Flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
48                       VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
49 const int kTl1Flags =
50     VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
51 const int kTl1SyncFlags = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF |
52                           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
53 const std::vector<uint32_t> kDefault2TlBitratesBps = {
54     kDefaultTl0BitrateKbps * 1000,
55     (kDefaultTl1BitrateKbps - kDefaultTl0BitrateKbps) * 1000};
56 
57 }  // namespace
58 
59 class ScreenshareLayerTest : public ::testing::Test {
60  protected:
ScreenshareLayerTest()61   ScreenshareLayerTest()
62       : min_qp_(2),
63         max_qp_(kDefaultQp),
64         frame_size_(-1),
65         timestamp_(90),
66         config_updated_(false) {}
~ScreenshareLayerTest()67   virtual ~ScreenshareLayerTest() {}
68 
SetUp()69   void SetUp() override {
70     layers_.reset(new ScreenshareLayers(2));
71     cfg_ = ConfigureBitrates();
72   }
73 
EncodeFrame(bool base_sync,CodecSpecificInfo * info=nullptr)74   int EncodeFrame(bool base_sync, CodecSpecificInfo* info = nullptr) {
75     CodecSpecificInfo ignored_info;
76     if (!info) {
77       info = &ignored_info;
78     }
79 
80     int flags = ConfigureFrame(base_sync);
81     if (flags != -1)
82       layers_->OnEncodeDone(0, timestamp_, frame_size_, base_sync, kDefaultQp,
83                             info);
84     return flags;
85   }
86 
ConfigureFrame(bool key_frame)87   int ConfigureFrame(bool key_frame) {
88     tl_config_ = NextFrameConfig(0, timestamp_);
89     EXPECT_EQ(0, tl_config_.encoder_layer_id)
90         << "ScreenshareLayers always encodes using the bitrate allocator for "
91            "layer 0, but may reference different buffers and packetize "
92            "differently.";
93     if (tl_config_.drop_frame) {
94       return -1;
95     }
96     const uint32_t prev_rc_target_bitrate = cfg_.rc_target_bitrate.value_or(-1);
97     const uint32_t prev_rc_max_quantizer = cfg_.rc_max_quantizer.value_or(-1);
98 
99     cfg_ = layers_->UpdateConfiguration(0);
100 
101     config_updated_ =
102         cfg_.temporal_layer_config.has_value() ||
103         (cfg_.rc_target_bitrate.has_value() &&
104          cfg_.rc_target_bitrate.value() != prev_rc_target_bitrate) ||
105         (cfg_.rc_max_quantizer.has_value() &&
106          cfg_.rc_max_quantizer.value() != prev_rc_max_quantizer) ||
107         cfg_.g_error_resilient.has_value();
108 
109     int flags = LibvpxVp8Encoder::EncodeFlags(tl_config_);
110     EXPECT_NE(-1, frame_size_);
111     return flags;
112   }
113 
NextFrameConfig(size_t stream_index,uint32_t timestamp)114   Vp8FrameConfig NextFrameConfig(size_t stream_index, uint32_t timestamp) {
115     int64_t timestamp_ms = timestamp / 90;
116     clock_.AdvanceTime(TimeDelta::Millis(timestamp_ms - rtc::TimeMillis()));
117     return layers_->NextFrameConfig(stream_index, timestamp);
118   }
119 
FrameSizeForBitrate(int bitrate_kbps)120   int FrameSizeForBitrate(int bitrate_kbps) {
121     return ((bitrate_kbps * 1000) / 8) / kFrameRate;
122   }
123 
ConfigureBitrates()124   Vp8EncoderConfig ConfigureBitrates() {
125     layers_->SetQpLimits(0, min_qp_, max_qp_);
126     layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, kFrameRate);
127     const Vp8EncoderConfig vp8_cfg = layers_->UpdateConfiguration(0);
128     EXPECT_TRUE(vp8_cfg.rc_target_bitrate.has_value());
129     frame_size_ = FrameSizeForBitrate(vp8_cfg.rc_target_bitrate.value());
130     return vp8_cfg;
131   }
132 
WithQpLimits(int min_qp,int max_qp)133   void WithQpLimits(int min_qp, int max_qp) {
134     min_qp_ = min_qp;
135     max_qp_ = max_qp;
136   }
137 
138   // Runs a few initial frames and makes sure we have seen frames on both
139   // temporal layers, including sync and non-sync frames.
RunGracePeriod()140   bool RunGracePeriod() {
141     bool got_tl0 = false;
142     bool got_tl1 = false;
143     bool got_tl1_sync = false;
144     for (int i = 0; i < 10; ++i) {
145       CodecSpecificInfo info;
146       EXPECT_NE(-1, EncodeFrame(false, &info));
147       timestamp_ += kTimestampDelta5Fps;
148       if (info.codecSpecific.VP8.temporalIdx == 0) {
149         got_tl0 = true;
150       } else if (info.codecSpecific.VP8.layerSync) {
151         got_tl1_sync = true;
152       } else {
153         got_tl1 = true;
154       }
155       if (got_tl0 && got_tl1 && got_tl1_sync)
156         return true;
157     }
158     return false;
159   }
160 
161   // Adds frames until we get one in the specified temporal layer. The last
162   // FrameEncoded() call will be omitted and needs to be done by the caller.
163   // Returns the flags for the last frame.
SkipUntilTl(int layer)164   int SkipUntilTl(int layer) {
165     return SkipUntilTlAndSync(layer, absl::nullopt);
166   }
167 
168   // Same as SkipUntilTl, but also waits until the sync bit condition is met.
SkipUntilTlAndSync(int layer,absl::optional<bool> sync)169   int SkipUntilTlAndSync(int layer, absl::optional<bool> sync) {
170     int flags = 0;
171     const int kMaxFramesToSkip =
172         1 + (sync.value_or(false) ? kMaxSyncPeriodSeconds : 1) * kFrameRate;
173     for (int i = 0; i < kMaxFramesToSkip; ++i) {
174       flags = ConfigureFrame(false);
175       if (tl_config_.packetizer_temporal_idx != layer ||
176           (sync && *sync != tl_config_.layer_sync)) {
177         if (flags != -1) {
178           // If flags do not request a frame drop, report some default values
179           // for frame size etc.
180           CodecSpecificInfo info;
181           layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
182                                 &info);
183         }
184         timestamp_ += kTimestampDelta5Fps;
185       } else {
186         // Found frame from sought after layer.
187         return flags;
188       }
189     }
190     ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time.";
191     return -1;
192   }
193 
194   int min_qp_;
195   uint32_t max_qp_;
196   int frame_size_;
197   rtc::ScopedFakeClock clock_;
198   std::unique_ptr<ScreenshareLayers> layers_;
199 
200   uint32_t timestamp_;
201   Vp8FrameConfig tl_config_;
202   Vp8EncoderConfig cfg_;
203   bool config_updated_;
204 
IgnoredCodecSpecificInfo()205   CodecSpecificInfo* IgnoredCodecSpecificInfo() {
206     ignored_codec_specific_info_ = std::make_unique<CodecSpecificInfo>();
207     return ignored_codec_specific_info_.get();
208   }
209 
210  private:
211   std::unique_ptr<CodecSpecificInfo> ignored_codec_specific_info_;
212 };
213 
214 TEST_F(ScreenshareLayerTest, 1Layer) {
215   layers_.reset(new ScreenshareLayers(1));
216   ConfigureBitrates();
217   // One layer screenshare should not use the frame dropper as all frames will
218   // belong to the base layer.
219   const int kSingleLayerFlags = 0;
220   auto info = std::make_unique<CodecSpecificInfo>();
221   int flags = EncodeFrame(false, info.get());
222   timestamp_ += kTimestampDelta5Fps;
223   EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx),
224             info->codecSpecific.VP8.temporalIdx);
225   EXPECT_FALSE(info->codecSpecific.VP8.layerSync);
226 
227   info = std::make_unique<CodecSpecificInfo>();
228   flags = EncodeFrame(false, info.get());
229   EXPECT_EQ(kSingleLayerFlags, flags);
230   EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx),
231             info->codecSpecific.VP8.temporalIdx);
232   EXPECT_FALSE(info->codecSpecific.VP8.layerSync);
233 }
234 
235 TEST_F(ScreenshareLayerTest, 2LayersPeriodicSync) {
236   std::vector<int> sync_times;
237   const int kNumFrames = kSyncPeriodSeconds * kFrameRate * 2 - 1;
238   for (int i = 0; i < kNumFrames; ++i) {
239     CodecSpecificInfo info;
240     EncodeFrame(false, &info);
241     timestamp_ += kTimestampDelta5Fps;
242     if (info.codecSpecific.VP8.temporalIdx == 1 &&
243         info.codecSpecific.VP8.layerSync) {
244       sync_times.push_back(timestamp_);
245     }
246   }
247 
248   ASSERT_EQ(2u, sync_times.size());
249   EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kSyncPeriodSeconds);
250 }
251 
252 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) {
253   std::vector<int> sync_times;
254   const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1;
255   for (int i = 0; i < kNumFrames; ++i) {
256     CodecSpecificInfo info;
257 
258     tl_config_ = NextFrameConfig(0, timestamp_);
259     cfg_ = layers_->UpdateConfiguration(0);
260 
261     // Simulate TL1 being at least 8 qp steps better.
262     if (tl_config_.packetizer_temporal_idx == 0) {
263       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
264                             &info);
265     } else {
266       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp - 8,
267                             &info);
268     }
269 
270     if (info.codecSpecific.VP8.temporalIdx == 1 &&
271         info.codecSpecific.VP8.layerSync)
272       sync_times.push_back(timestamp_);
273 
274     timestamp_ += kTimestampDelta5Fps;
275   }
276 
277   ASSERT_EQ(2u, sync_times.size());
278   EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds);
279 }
280 
281 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) {
282   std::vector<int> sync_times;
283 
284   const int kNumFrames = (kSyncPeriodSeconds +
285                           ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) *
286                          kFrameRate;
287   for (int i = 0; i < kNumFrames; ++i) {
288     CodecSpecificInfo info;
289 
290     ConfigureFrame(false);
291 
292     // Simulate TL1 being at least 8 qp steps better.
293     if (tl_config_.packetizer_temporal_idx == 0) {
294       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
295                             &info);
296     } else {
297       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp - 8,
298                             &info);
299     }
300 
301     if (info.codecSpecific.VP8.temporalIdx == 1 &&
302         info.codecSpecific.VP8.layerSync)
303       sync_times.push_back(timestamp_);
304 
305     timestamp_ += kTimestampDelta5Fps;
306   }
307 
308   ASSERT_EQ(1u, sync_times.size());
309 
310   bool bumped_tl0_quality = false;
311   for (int i = 0; i < 3; ++i) {
312     CodecSpecificInfo info;
313 
314     int flags = ConfigureFrame(false);
315     layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp - 8,
316                           &info);
317     if (info.codecSpecific.VP8.temporalIdx == 0) {
318       // Bump TL0 to same quality as TL1.
319       bumped_tl0_quality = true;
320     } else {
321       if (bumped_tl0_quality) {
322         EXPECT_TRUE(info.codecSpecific.VP8.layerSync);
323         EXPECT_EQ(kTl1SyncFlags, flags);
324         return;
325       }
326     }
327     timestamp_ += kTimestampDelta5Fps;
328   }
329   ADD_FAILURE() << "No TL1 frame arrived within time limit.";
330 }
331 
332 TEST_F(ScreenshareLayerTest, 2LayersToggling) {
333   EXPECT_TRUE(RunGracePeriod());
334 
335   // Insert 50 frames. 2/5 should be TL0.
336   int tl0_frames = 0;
337   int tl1_frames = 0;
338   for (int i = 0; i < 50; ++i) {
339     CodecSpecificInfo info;
340     EncodeFrame(false, &info);
341     timestamp_ += kTimestampDelta5Fps;
342     switch (info.codecSpecific.VP8.temporalIdx) {
343       case 0:
344         ++tl0_frames;
345         break;
346       case 1:
347         ++tl1_frames;
348         break;
349       default:
350         abort();
351     }
352   }
353   EXPECT_EQ(20, tl0_frames);
354   EXPECT_EQ(30, tl1_frames);
355 }
356 
TEST_F(ScreenshareLayerTest,AllFitsLayer0)357 TEST_F(ScreenshareLayerTest, AllFitsLayer0) {
358   frame_size_ = FrameSizeForBitrate(kDefaultTl0BitrateKbps);
359 
360   // Insert 50 frames, small enough that all fits in TL0.
361   for (int i = 0; i < 50; ++i) {
362     CodecSpecificInfo info;
363     int flags = EncodeFrame(false, &info);
364     timestamp_ += kTimestampDelta5Fps;
365     EXPECT_EQ(kTl0Flags, flags);
366     EXPECT_EQ(0, info.codecSpecific.VP8.temporalIdx);
367   }
368 }
369 
TEST_F(ScreenshareLayerTest,TooHighBitrate)370 TEST_F(ScreenshareLayerTest, TooHighBitrate) {
371   frame_size_ = 2 * FrameSizeForBitrate(kDefaultTl1BitrateKbps);
372 
373   // Insert 100 frames. Half should be dropped.
374   int tl0_frames = 0;
375   int tl1_frames = 0;
376   int dropped_frames = 0;
377   for (int i = 0; i < 100; ++i) {
378     CodecSpecificInfo info;
379     int flags = EncodeFrame(false, &info);
380     timestamp_ += kTimestampDelta5Fps;
381     if (flags == -1) {
382       ++dropped_frames;
383     } else {
384       switch (info.codecSpecific.VP8.temporalIdx) {
385         case 0:
386           ++tl0_frames;
387           break;
388         case 1:
389           ++tl1_frames;
390           break;
391         default:
392           ADD_FAILURE() << "Unexpected temporal id";
393       }
394     }
395   }
396 
397   EXPECT_NEAR(50, tl0_frames + tl1_frames, 1);
398   EXPECT_NEAR(50, dropped_frames, 1);
399 }
400 
TEST_F(ScreenshareLayerTest,TargetBitrateCappedByTL0)401 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL0) {
402   const int kTl0_kbps = 100;
403   const int kTl1_kbps = 1000;
404   const std::vector<uint32_t> layer_rates = {kTl0_kbps * 1000,
405                                              (kTl1_kbps - kTl0_kbps) * 1000};
406   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
407   cfg_ = layers_->UpdateConfiguration(0);
408 
409   EXPECT_EQ(static_cast<unsigned int>(
410                 ScreenshareLayers::kMaxTL0FpsReduction * kTl0_kbps + 0.5),
411             cfg_.rc_target_bitrate);
412 }
413 
TEST_F(ScreenshareLayerTest,TargetBitrateCappedByTL1)414 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL1) {
415   const int kTl0_kbps = 100;
416   const int kTl1_kbps = 450;
417   const std::vector<uint32_t> layer_rates = {kTl0_kbps * 1000,
418                                              (kTl1_kbps - kTl0_kbps) * 1000};
419   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
420   cfg_ = layers_->UpdateConfiguration(0);
421 
422   EXPECT_EQ(static_cast<unsigned int>(
423                 kTl1_kbps / ScreenshareLayers::kAcceptableTargetOvershoot),
424             cfg_.rc_target_bitrate);
425 }
426 
TEST_F(ScreenshareLayerTest,TargetBitrateBelowTL0)427 TEST_F(ScreenshareLayerTest, TargetBitrateBelowTL0) {
428   const int kTl0_kbps = 100;
429   const std::vector<uint32_t> layer_rates = {kTl0_kbps * 1000};
430   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
431   cfg_ = layers_->UpdateConfiguration(0);
432 
433   EXPECT_EQ(static_cast<uint32_t>(kTl0_kbps), cfg_.rc_target_bitrate);
434 }
435 
TEST_F(ScreenshareLayerTest,EncoderDrop)436 TEST_F(ScreenshareLayerTest, EncoderDrop) {
437   EXPECT_TRUE(RunGracePeriod());
438   SkipUntilTl(0);
439 
440   // Size 0 indicates dropped frame.
441   layers_->OnEncodeDone(0, timestamp_, 0, false, 0, IgnoredCodecSpecificInfo());
442 
443   // Re-encode frame (so don't advance timestamp).
444   int flags = EncodeFrame(false);
445   timestamp_ += kTimestampDelta5Fps;
446   EXPECT_FALSE(config_updated_);
447   EXPECT_EQ(kTl0Flags, flags);
448 
449   // Next frame should have boosted quality...
450   SkipUntilTl(0);
451   EXPECT_TRUE(config_updated_);
452   EXPECT_LT(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
453   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
454                         IgnoredCodecSpecificInfo());
455   timestamp_ += kTimestampDelta5Fps;
456 
457   // ...then back to standard setup.
458   SkipUntilTl(0);
459   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
460                         IgnoredCodecSpecificInfo());
461   timestamp_ += kTimestampDelta5Fps;
462   EXPECT_EQ(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
463 
464   // Next drop in TL1.
465   SkipUntilTl(1);
466   layers_->OnEncodeDone(0, timestamp_, 0, false, 0, IgnoredCodecSpecificInfo());
467 
468   // Re-encode frame (so don't advance timestamp).
469   flags = EncodeFrame(false);
470   timestamp_ += kTimestampDelta5Fps;
471   EXPECT_FALSE(config_updated_);
472   EXPECT_EQ(kTl1Flags, flags);
473 
474   // Next frame should have boosted QP.
475   SkipUntilTl(1);
476   EXPECT_TRUE(config_updated_);
477   EXPECT_LT(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
478   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
479                         IgnoredCodecSpecificInfo());
480   timestamp_ += kTimestampDelta5Fps;
481 
482   // ...and back to normal.
483   SkipUntilTl(1);
484   EXPECT_EQ(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
485   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
486                         IgnoredCodecSpecificInfo());
487   timestamp_ += kTimestampDelta5Fps;
488 }
489 
TEST_F(ScreenshareLayerTest,RespectsMaxIntervalBetweenFrames)490 TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) {
491   const int kLowBitrateKbps = 50;
492   const int kLargeFrameSizeBytes = 100000;
493   const uint32_t kStartTimestamp = 1234;
494 
495   const std::vector<uint32_t> layer_rates = {kLowBitrateKbps * 1000};
496   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
497   cfg_ = layers_->UpdateConfiguration(0);
498 
499   EXPECT_EQ(kTl0Flags,
500             LibvpxVp8Encoder::EncodeFlags(NextFrameConfig(0, kStartTimestamp)));
501   layers_->OnEncodeDone(0, kStartTimestamp, kLargeFrameSizeBytes, false,
502                         kDefaultQp, IgnoredCodecSpecificInfo());
503 
504   const uint32_t kTwoSecondsLater =
505       kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90);
506 
507   // Sanity check, repayment time should exceed kMaxFrameIntervalMs.
508   ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps,
509             kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90));
510 
511   // Expect drop one frame interval before the two second timeout. If we try
512   // any later, the frame will be dropped anyway by the frame rate throttling
513   // logic.
514   EXPECT_TRUE(
515       NextFrameConfig(0, kTwoSecondsLater - kTimestampDelta5Fps).drop_frame);
516 
517   // More than two seconds has passed since last frame, one should be emitted
518   // even if bitrate target is then exceeded.
519   EXPECT_EQ(kTl0Flags, LibvpxVp8Encoder::EncodeFlags(
520                            NextFrameConfig(0, kTwoSecondsLater + 90)));
521 }
522 
TEST_F(ScreenshareLayerTest,UpdatesHistograms)523 TEST_F(ScreenshareLayerTest, UpdatesHistograms) {
524   metrics::Reset();
525   bool trigger_drop = false;
526   bool dropped_frame = false;
527   bool overshoot = false;
528   const int kTl0Qp = 35;
529   const int kTl1Qp = 30;
530   for (int64_t timestamp = 0;
531        timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds;
532        timestamp += kTimestampDelta5Fps) {
533     tl_config_ = NextFrameConfig(0, timestamp);
534     if (tl_config_.drop_frame) {
535       dropped_frame = true;
536       continue;
537     }
538     int flags = LibvpxVp8Encoder::EncodeFlags(tl_config_);
539     if (flags != -1)
540       cfg_ = layers_->UpdateConfiguration(0);
541 
542     if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) {
543       // Simulate one overshoot.
544       layers_->OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
545       overshoot = true;
546     }
547 
548     if (flags == kTl0Flags) {
549       if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) {
550         // Simulate a too large frame, to cause frame drop.
551         layers_->OnEncodeDone(0, timestamp, frame_size_ * 10, false, kTl0Qp,
552                               IgnoredCodecSpecificInfo());
553         trigger_drop = true;
554       } else {
555         layers_->OnEncodeDone(0, timestamp, frame_size_, false, kTl0Qp,
556                               IgnoredCodecSpecificInfo());
557       }
558     } else if (flags == kTl1Flags || flags == kTl1SyncFlags) {
559       layers_->OnEncodeDone(0, timestamp, frame_size_, false, kTl1Qp,
560                             IgnoredCodecSpecificInfo());
561     } else if (flags == -1) {
562       dropped_frame = true;
563     } else {
564       RTC_NOTREACHED() << "Unexpected flags";
565     }
566     clock_.AdvanceTime(TimeDelta::Millis(1000 / 5));
567   }
568 
569   EXPECT_TRUE(overshoot);
570   EXPECT_TRUE(dropped_frame);
571 
572   layers_.reset();  // Histograms are reported on destruction.
573 
574   EXPECT_METRIC_EQ(
575       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer0.FrameRate"));
576   EXPECT_METRIC_EQ(
577       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer1.FrameRate"));
578   EXPECT_METRIC_EQ(
579       1, metrics::NumSamples("WebRTC.Video.Screenshare.FramesPerDrop"));
580   EXPECT_METRIC_EQ(
581       1, metrics::NumSamples("WebRTC.Video.Screenshare.FramesPerOvershoot"));
582   EXPECT_METRIC_EQ(1,
583                    metrics::NumSamples("WebRTC.Video.Screenshare.Layer0.Qp"));
584   EXPECT_METRIC_EQ(1,
585                    metrics::NumSamples("WebRTC.Video.Screenshare.Layer1.Qp"));
586   EXPECT_METRIC_EQ(
587       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer0.TargetBitrate"));
588   EXPECT_METRIC_EQ(
589       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer1.TargetBitrate"));
590 
591   EXPECT_METRIC_GT(
592       metrics::MinSample("WebRTC.Video.Screenshare.Layer0.FrameRate"), 1);
593   EXPECT_METRIC_GT(
594       metrics::MinSample("WebRTC.Video.Screenshare.Layer1.FrameRate"), 1);
595   EXPECT_METRIC_GT(metrics::MinSample("WebRTC.Video.Screenshare.FramesPerDrop"),
596                    1);
597   EXPECT_METRIC_GT(
598       metrics::MinSample("WebRTC.Video.Screenshare.FramesPerOvershoot"), 1);
599   EXPECT_METRIC_EQ(
600       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer0.Qp", kTl0Qp));
601   EXPECT_METRIC_EQ(
602       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer1.Qp", kTl1Qp));
603   EXPECT_METRIC_EQ(
604       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer0.TargetBitrate",
605                             kDefaultTl0BitrateKbps));
606   EXPECT_METRIC_EQ(
607       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer1.TargetBitrate",
608                             kDefaultTl1BitrateKbps));
609 }
610 
TEST_F(ScreenshareLayerTest,RespectsConfiguredFramerate)611 TEST_F(ScreenshareLayerTest, RespectsConfiguredFramerate) {
612   int64_t kTestSpanMs = 2000;
613   int64_t kFrameIntervalsMs = 1000 / kFrameRate;
614 
615   uint32_t timestamp = 1234;
616   int num_input_frames = 0;
617   int num_discarded_frames = 0;
618 
619   // Send at regular rate - no drops expected.
620   for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) {
621     if (NextFrameConfig(0, timestamp).drop_frame) {
622       ++num_discarded_frames;
623     } else {
624       size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
625       layers_->OnEncodeDone(0, timestamp, frame_size_bytes, false, kDefaultQp,
626                             IgnoredCodecSpecificInfo());
627     }
628     timestamp += kFrameIntervalsMs * 90;
629     clock_.AdvanceTime(TimeDelta::Millis(kFrameIntervalsMs));
630 
631     ++num_input_frames;
632   }
633   EXPECT_EQ(0, num_discarded_frames);
634 
635   // Send at twice the configured rate - drop every other frame.
636   num_input_frames = 0;
637   num_discarded_frames = 0;
638   for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) {
639     if (NextFrameConfig(0, timestamp).drop_frame) {
640       ++num_discarded_frames;
641     } else {
642       size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
643       layers_->OnEncodeDone(0, timestamp, frame_size_bytes, false, kDefaultQp,
644                             IgnoredCodecSpecificInfo());
645     }
646     timestamp += kFrameIntervalsMs * 90 / 2;
647     clock_.AdvanceTime(TimeDelta::Millis(kFrameIntervalsMs));
648     ++num_input_frames;
649   }
650 
651   // Allow for some rounding errors in the measurements.
652   EXPECT_NEAR(num_discarded_frames, num_input_frames / 2, 2);
653 }
654 
655 TEST_F(ScreenshareLayerTest, 2LayersSyncAtOvershootDrop) {
656   // Run grace period so we have existing frames in both TL0 and Tl1.
657   EXPECT_TRUE(RunGracePeriod());
658 
659   // Move ahead until we have a sync frame in TL1.
660   EXPECT_EQ(kTl1SyncFlags, SkipUntilTlAndSync(1, true));
661   ASSERT_TRUE(tl_config_.layer_sync);
662 
663   // Simulate overshoot of this frame.
664   layers_->OnEncodeDone(0, timestamp_, 0, false, 0, nullptr);
665 
666   cfg_ = layers_->UpdateConfiguration(0);
667   EXPECT_EQ(kTl1SyncFlags, LibvpxVp8Encoder::EncodeFlags(tl_config_));
668 
669   CodecSpecificInfo new_info;
670   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
671                         &new_info);
672   EXPECT_TRUE(new_info.codecSpecific.VP8.layerSync);
673 }
674 
TEST_F(ScreenshareLayerTest,DropOnTooShortFrameInterval)675 TEST_F(ScreenshareLayerTest, DropOnTooShortFrameInterval) {
676   // Run grace period so we have existing frames in both TL0 and Tl1.
677   EXPECT_TRUE(RunGracePeriod());
678 
679   // Add a large gap, so there's plenty of room in the rate tracker.
680   timestamp_ += kTimestampDelta5Fps * 3;
681   EXPECT_FALSE(NextFrameConfig(0, timestamp_).drop_frame);
682   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
683                         IgnoredCodecSpecificInfo());
684 
685   // Frame interval below 90% if desired time is not allowed, try inserting
686   // frame just before this limit.
687   const int64_t kMinFrameInterval = (kTimestampDelta5Fps * 85) / 100;
688   timestamp_ += kMinFrameInterval - 90;
689   EXPECT_TRUE(NextFrameConfig(0, timestamp_).drop_frame);
690 
691   // Try again at the limit, now it should pass.
692   timestamp_ += 90;
693   EXPECT_FALSE(NextFrameConfig(0, timestamp_).drop_frame);
694 }
695 
TEST_F(ScreenshareLayerTest,AdjustsBitrateWhenDroppingFrames)696 TEST_F(ScreenshareLayerTest, AdjustsBitrateWhenDroppingFrames) {
697   const uint32_t kTimestampDelta10Fps = kTimestampDelta5Fps / 2;
698   const int kNumFrames = 30;
699   ASSERT_TRUE(cfg_.rc_target_bitrate.has_value());
700   const uint32_t default_bitrate = cfg_.rc_target_bitrate.value();
701   layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, 10);
702 
703   int num_dropped_frames = 0;
704   for (int i = 0; i < kNumFrames; ++i) {
705     if (EncodeFrame(false) == -1)
706       ++num_dropped_frames;
707     timestamp_ += kTimestampDelta10Fps;
708   }
709   cfg_ = layers_->UpdateConfiguration(0);
710 
711   EXPECT_EQ(num_dropped_frames, kNumFrames / 2);
712   EXPECT_EQ(cfg_.rc_target_bitrate, default_bitrate * 2);
713 }
714 
TEST_F(ScreenshareLayerTest,UpdatesConfigurationAfterRateChange)715 TEST_F(ScreenshareLayerTest, UpdatesConfigurationAfterRateChange) {
716   // Set inital rate again, no need to update configuration.
717   layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, kFrameRate);
718   cfg_ = layers_->UpdateConfiguration(0);
719 
720   // Rate changed, now update config.
721   std::vector<uint32_t> bitrates = kDefault2TlBitratesBps;
722   bitrates[1] -= 100000;
723   layers_->OnRatesUpdated(0, bitrates, 5);
724   cfg_ = layers_->UpdateConfiguration(0);
725 
726   // Changed rate, but then set changed rate again before trying to update
727   // configuration, update should still apply.
728   bitrates[1] -= 100000;
729   layers_->OnRatesUpdated(0, bitrates, 5);
730   layers_->OnRatesUpdated(0, bitrates, 5);
731   cfg_ = layers_->UpdateConfiguration(0);
732 }
733 
TEST_F(ScreenshareLayerTest,MaxQpRestoredAfterDoubleDrop)734 TEST_F(ScreenshareLayerTest, MaxQpRestoredAfterDoubleDrop) {
735   // Run grace period so we have existing frames in both TL0 and Tl1.
736   EXPECT_TRUE(RunGracePeriod());
737 
738   // Move ahead until we have a sync frame in TL1.
739   EXPECT_EQ(kTl1SyncFlags, SkipUntilTlAndSync(1, true));
740   ASSERT_TRUE(tl_config_.layer_sync);
741 
742   // Simulate overshoot of this frame.
743   layers_->OnEncodeDone(0, timestamp_, 0, false, -1, nullptr);
744 
745   // Simulate re-encoded frame.
746   layers_->OnEncodeDone(0, timestamp_, 1, false, max_qp_,
747                         IgnoredCodecSpecificInfo());
748 
749   // Next frame, expect boosted quality.
750   // Slightly alter bitrate between each frame.
751   std::vector<uint32_t> kDefault2TlBitratesBpsAlt = kDefault2TlBitratesBps;
752   kDefault2TlBitratesBpsAlt[1] += 4000;
753   layers_->OnRatesUpdated(0, kDefault2TlBitratesBpsAlt, kFrameRate);
754   EXPECT_EQ(kTl1Flags, SkipUntilTlAndSync(1, false));
755   EXPECT_TRUE(config_updated_);
756   EXPECT_LT(cfg_.rc_max_quantizer, max_qp_);
757   ASSERT_TRUE(cfg_.rc_max_quantizer.has_value());
758   const uint32_t adjusted_qp = cfg_.rc_max_quantizer.value();
759 
760   // Simulate overshoot of this frame.
761   layers_->OnEncodeDone(0, timestamp_, 0, false, -1, nullptr);
762 
763   // Simulate re-encoded frame.
764   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, max_qp_,
765                         IgnoredCodecSpecificInfo());
766 
767   // A third frame, expect boosted quality.
768   layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, kFrameRate);
769   EXPECT_EQ(kTl1Flags, SkipUntilTlAndSync(1, false));
770   EXPECT_TRUE(config_updated_);
771   EXPECT_LT(cfg_.rc_max_quantizer, max_qp_);
772   EXPECT_EQ(adjusted_qp, cfg_.rc_max_quantizer);
773 
774   // Frame encoded.
775   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, max_qp_,
776                         IgnoredCodecSpecificInfo());
777 
778   // A fourth frame, max qp should be restored.
779   layers_->OnRatesUpdated(0, kDefault2TlBitratesBpsAlt, kFrameRate);
780   EXPECT_EQ(kTl1Flags, SkipUntilTlAndSync(1, false));
781   EXPECT_EQ(cfg_.rc_max_quantizer, max_qp_);
782 }
783 
784 }  // namespace webrtc
785