xref: /aosp_15_r20/external/webrtc/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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(/*base_sync=*/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   EXPECT_EQ(info->generic_frame_info->temporal_id, 0);
227 
228   info = std::make_unique<CodecSpecificInfo>();
229   flags = EncodeFrame(/*base_sync=*/false, info.get());
230   EXPECT_EQ(kSingleLayerFlags, flags);
231   EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx),
232             info->codecSpecific.VP8.temporalIdx);
233   EXPECT_FALSE(info->codecSpecific.VP8.layerSync);
234   EXPECT_EQ(info->generic_frame_info->temporal_id, 0);
235 }
236 
237 TEST_F(ScreenshareLayerTest, 2LayersPeriodicSync) {
238   std::vector<int> sync_times;
239   const int kNumFrames = kSyncPeriodSeconds * kFrameRate * 2 - 1;
240   for (int i = 0; i < kNumFrames; ++i) {
241     CodecSpecificInfo info;
242     EncodeFrame(false, &info);
243     timestamp_ += kTimestampDelta5Fps;
244     if (info.codecSpecific.VP8.temporalIdx == 1 &&
245         info.codecSpecific.VP8.layerSync) {
246       sync_times.push_back(timestamp_);
247     }
248   }
249 
250   ASSERT_EQ(2u, sync_times.size());
251   EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kSyncPeriodSeconds);
252 }
253 
254 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) {
255   std::vector<int> sync_times;
256   const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1;
257   for (int i = 0; i < kNumFrames; ++i) {
258     CodecSpecificInfo info;
259 
260     tl_config_ = NextFrameConfig(0, timestamp_);
261     cfg_ = layers_->UpdateConfiguration(0);
262 
263     // Simulate TL1 being at least 8 qp steps better.
264     if (tl_config_.packetizer_temporal_idx == 0) {
265       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
266                             &info);
267     } else {
268       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp - 8,
269                             &info);
270     }
271 
272     if (info.codecSpecific.VP8.temporalIdx == 1 &&
273         info.codecSpecific.VP8.layerSync)
274       sync_times.push_back(timestamp_);
275 
276     timestamp_ += kTimestampDelta5Fps;
277   }
278 
279   ASSERT_EQ(2u, sync_times.size());
280   EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds);
281 }
282 
283 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) {
284   std::vector<int> sync_times;
285 
286   const int kNumFrames = (kSyncPeriodSeconds +
287                           ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) *
288                          kFrameRate;
289   for (int i = 0; i < kNumFrames; ++i) {
290     CodecSpecificInfo info;
291 
292     ConfigureFrame(false);
293 
294     // Simulate TL1 being at least 8 qp steps better.
295     if (tl_config_.packetizer_temporal_idx == 0) {
296       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
297                             &info);
298     } else {
299       layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp - 8,
300                             &info);
301     }
302 
303     if (info.codecSpecific.VP8.temporalIdx == 1 &&
304         info.codecSpecific.VP8.layerSync)
305       sync_times.push_back(timestamp_);
306 
307     timestamp_ += kTimestampDelta5Fps;
308   }
309 
310   ASSERT_EQ(1u, sync_times.size());
311 
312   bool bumped_tl0_quality = false;
313   for (int i = 0; i < 3; ++i) {
314     CodecSpecificInfo info;
315 
316     int flags = ConfigureFrame(false);
317     layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp - 8,
318                           &info);
319     if (info.codecSpecific.VP8.temporalIdx == 0) {
320       // Bump TL0 to same quality as TL1.
321       bumped_tl0_quality = true;
322     } else {
323       if (bumped_tl0_quality) {
324         EXPECT_TRUE(info.codecSpecific.VP8.layerSync);
325         EXPECT_EQ(kTl1SyncFlags, flags);
326         return;
327       }
328     }
329     timestamp_ += kTimestampDelta5Fps;
330   }
331   ADD_FAILURE() << "No TL1 frame arrived within time limit.";
332 }
333 
334 TEST_F(ScreenshareLayerTest, 2LayersToggling) {
335   EXPECT_TRUE(RunGracePeriod());
336 
337   // Insert 50 frames. 2/5 should be TL0.
338   int tl0_frames = 0;
339   int tl1_frames = 0;
340   for (int i = 0; i < 50; ++i) {
341     CodecSpecificInfo info;
342     EncodeFrame(/*base_sync=*/false, &info);
343     EXPECT_EQ(info.codecSpecific.VP8.temporalIdx,
344               info.generic_frame_info->temporal_id);
345     timestamp_ += kTimestampDelta5Fps;
346     switch (info.codecSpecific.VP8.temporalIdx) {
347       case 0:
348         ++tl0_frames;
349         break;
350       case 1:
351         ++tl1_frames;
352         break;
353       default:
354         abort();
355     }
356   }
357   EXPECT_EQ(20, tl0_frames);
358   EXPECT_EQ(30, tl1_frames);
359 }
360 
TEST_F(ScreenshareLayerTest,AllFitsLayer0)361 TEST_F(ScreenshareLayerTest, AllFitsLayer0) {
362   frame_size_ = FrameSizeForBitrate(kDefaultTl0BitrateKbps);
363 
364   // Insert 50 frames, small enough that all fits in TL0.
365   for (int i = 0; i < 50; ++i) {
366     CodecSpecificInfo info;
367     int flags = EncodeFrame(false, &info);
368     timestamp_ += kTimestampDelta5Fps;
369     EXPECT_EQ(kTl0Flags, flags);
370     EXPECT_EQ(0, info.codecSpecific.VP8.temporalIdx);
371   }
372 }
373 
TEST_F(ScreenshareLayerTest,TooHighBitrate)374 TEST_F(ScreenshareLayerTest, TooHighBitrate) {
375   frame_size_ = 2 * FrameSizeForBitrate(kDefaultTl1BitrateKbps);
376 
377   // Insert 100 frames. Half should be dropped.
378   int tl0_frames = 0;
379   int tl1_frames = 0;
380   int dropped_frames = 0;
381   for (int i = 0; i < 100; ++i) {
382     CodecSpecificInfo info;
383     int flags = EncodeFrame(false, &info);
384     timestamp_ += kTimestampDelta5Fps;
385     if (flags == -1) {
386       ++dropped_frames;
387     } else {
388       switch (info.codecSpecific.VP8.temporalIdx) {
389         case 0:
390           ++tl0_frames;
391           break;
392         case 1:
393           ++tl1_frames;
394           break;
395         default:
396           ADD_FAILURE() << "Unexpected temporal id";
397       }
398     }
399   }
400 
401   EXPECT_NEAR(50, tl0_frames + tl1_frames, 1);
402   EXPECT_NEAR(50, dropped_frames, 1);
403 }
404 
TEST_F(ScreenshareLayerTest,TargetBitrateCappedByTL0)405 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL0) {
406   const int kTl0_kbps = 100;
407   const int kTl1_kbps = 1000;
408   const std::vector<uint32_t> layer_rates = {kTl0_kbps * 1000,
409                                              (kTl1_kbps - kTl0_kbps) * 1000};
410   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
411   cfg_ = layers_->UpdateConfiguration(0);
412 
413   EXPECT_EQ(static_cast<unsigned int>(
414                 ScreenshareLayers::kMaxTL0FpsReduction * kTl0_kbps + 0.5),
415             cfg_.rc_target_bitrate);
416 }
417 
TEST_F(ScreenshareLayerTest,TargetBitrateCappedByTL1)418 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL1) {
419   const int kTl0_kbps = 100;
420   const int kTl1_kbps = 450;
421   const std::vector<uint32_t> layer_rates = {kTl0_kbps * 1000,
422                                              (kTl1_kbps - kTl0_kbps) * 1000};
423   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
424   cfg_ = layers_->UpdateConfiguration(0);
425 
426   EXPECT_EQ(static_cast<unsigned int>(
427                 kTl1_kbps / ScreenshareLayers::kAcceptableTargetOvershoot),
428             cfg_.rc_target_bitrate);
429 }
430 
TEST_F(ScreenshareLayerTest,TargetBitrateBelowTL0)431 TEST_F(ScreenshareLayerTest, TargetBitrateBelowTL0) {
432   const int kTl0_kbps = 100;
433   const std::vector<uint32_t> layer_rates = {kTl0_kbps * 1000};
434   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
435   cfg_ = layers_->UpdateConfiguration(0);
436 
437   EXPECT_EQ(static_cast<uint32_t>(kTl0_kbps), cfg_.rc_target_bitrate);
438 }
439 
TEST_F(ScreenshareLayerTest,EncoderDrop)440 TEST_F(ScreenshareLayerTest, EncoderDrop) {
441   EXPECT_TRUE(RunGracePeriod());
442   SkipUntilTl(0);
443 
444   // Size 0 indicates dropped frame.
445   layers_->OnEncodeDone(0, timestamp_, 0, false, 0, IgnoredCodecSpecificInfo());
446 
447   // Re-encode frame (so don't advance timestamp).
448   int flags = EncodeFrame(false);
449   timestamp_ += kTimestampDelta5Fps;
450   EXPECT_FALSE(config_updated_);
451   EXPECT_EQ(kTl0Flags, flags);
452 
453   // Next frame should have boosted quality...
454   SkipUntilTl(0);
455   EXPECT_TRUE(config_updated_);
456   EXPECT_LT(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
457   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
458                         IgnoredCodecSpecificInfo());
459   timestamp_ += kTimestampDelta5Fps;
460 
461   // ...then back to standard setup.
462   SkipUntilTl(0);
463   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
464                         IgnoredCodecSpecificInfo());
465   timestamp_ += kTimestampDelta5Fps;
466   EXPECT_EQ(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
467 
468   // Next drop in TL1.
469   SkipUntilTl(1);
470   layers_->OnEncodeDone(0, timestamp_, 0, false, 0, IgnoredCodecSpecificInfo());
471 
472   // Re-encode frame (so don't advance timestamp).
473   flags = EncodeFrame(false);
474   timestamp_ += kTimestampDelta5Fps;
475   EXPECT_FALSE(config_updated_);
476   EXPECT_EQ(kTl1Flags, flags);
477 
478   // Next frame should have boosted QP.
479   SkipUntilTl(1);
480   EXPECT_TRUE(config_updated_);
481   EXPECT_LT(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
482   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
483                         IgnoredCodecSpecificInfo());
484   timestamp_ += kTimestampDelta5Fps;
485 
486   // ...and back to normal.
487   SkipUntilTl(1);
488   EXPECT_EQ(cfg_.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
489   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
490                         IgnoredCodecSpecificInfo());
491   timestamp_ += kTimestampDelta5Fps;
492 }
493 
TEST_F(ScreenshareLayerTest,RespectsMaxIntervalBetweenFrames)494 TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) {
495   const int kLowBitrateKbps = 50;
496   const int kLargeFrameSizeBytes = 100000;
497   const uint32_t kStartTimestamp = 1234;
498 
499   const std::vector<uint32_t> layer_rates = {kLowBitrateKbps * 1000};
500   layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
501   cfg_ = layers_->UpdateConfiguration(0);
502 
503   EXPECT_EQ(kTl0Flags,
504             LibvpxVp8Encoder::EncodeFlags(NextFrameConfig(0, kStartTimestamp)));
505   layers_->OnEncodeDone(0, kStartTimestamp, kLargeFrameSizeBytes, false,
506                         kDefaultQp, IgnoredCodecSpecificInfo());
507 
508   const uint32_t kTwoSecondsLater =
509       kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90);
510 
511   // Sanity check, repayment time should exceed kMaxFrameIntervalMs.
512   ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps,
513             kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90));
514 
515   // Expect drop one frame interval before the two second timeout. If we try
516   // any later, the frame will be dropped anyway by the frame rate throttling
517   // logic.
518   EXPECT_TRUE(
519       NextFrameConfig(0, kTwoSecondsLater - kTimestampDelta5Fps).drop_frame);
520 
521   // More than two seconds has passed since last frame, one should be emitted
522   // even if bitrate target is then exceeded.
523   EXPECT_EQ(kTl0Flags, LibvpxVp8Encoder::EncodeFlags(
524                            NextFrameConfig(0, kTwoSecondsLater + 90)));
525 }
526 
TEST_F(ScreenshareLayerTest,UpdatesHistograms)527 TEST_F(ScreenshareLayerTest, UpdatesHistograms) {
528   metrics::Reset();
529   bool trigger_drop = false;
530   bool dropped_frame = false;
531   bool overshoot = false;
532   const int kTl0Qp = 35;
533   const int kTl1Qp = 30;
534   for (int64_t timestamp = 0;
535        timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds;
536        timestamp += kTimestampDelta5Fps) {
537     tl_config_ = NextFrameConfig(0, timestamp);
538     if (tl_config_.drop_frame) {
539       dropped_frame = true;
540       continue;
541     }
542     int flags = LibvpxVp8Encoder::EncodeFlags(tl_config_);
543     if (flags != -1)
544       cfg_ = layers_->UpdateConfiguration(0);
545 
546     if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) {
547       // Simulate one overshoot.
548       layers_->OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
549       overshoot = true;
550     }
551 
552     if (flags == kTl0Flags) {
553       if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) {
554         // Simulate a too large frame, to cause frame drop.
555         layers_->OnEncodeDone(0, timestamp, frame_size_ * 10, false, kTl0Qp,
556                               IgnoredCodecSpecificInfo());
557         trigger_drop = true;
558       } else {
559         layers_->OnEncodeDone(0, timestamp, frame_size_, false, kTl0Qp,
560                               IgnoredCodecSpecificInfo());
561       }
562     } else if (flags == kTl1Flags || flags == kTl1SyncFlags) {
563       layers_->OnEncodeDone(0, timestamp, frame_size_, false, kTl1Qp,
564                             IgnoredCodecSpecificInfo());
565     } else if (flags == -1) {
566       dropped_frame = true;
567     } else {
568       RTC_DCHECK_NOTREACHED() << "Unexpected flags";
569     }
570     clock_.AdvanceTime(TimeDelta::Millis(1000 / 5));
571   }
572 
573   EXPECT_TRUE(overshoot);
574   EXPECT_TRUE(dropped_frame);
575 
576   layers_.reset();  // Histograms are reported on destruction.
577 
578   EXPECT_METRIC_EQ(
579       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer0.FrameRate"));
580   EXPECT_METRIC_EQ(
581       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer1.FrameRate"));
582   EXPECT_METRIC_EQ(
583       1, metrics::NumSamples("WebRTC.Video.Screenshare.FramesPerDrop"));
584   EXPECT_METRIC_EQ(
585       1, metrics::NumSamples("WebRTC.Video.Screenshare.FramesPerOvershoot"));
586   EXPECT_METRIC_EQ(1,
587                    metrics::NumSamples("WebRTC.Video.Screenshare.Layer0.Qp"));
588   EXPECT_METRIC_EQ(1,
589                    metrics::NumSamples("WebRTC.Video.Screenshare.Layer1.Qp"));
590   EXPECT_METRIC_EQ(
591       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer0.TargetBitrate"));
592   EXPECT_METRIC_EQ(
593       1, metrics::NumSamples("WebRTC.Video.Screenshare.Layer1.TargetBitrate"));
594 
595   EXPECT_METRIC_GT(
596       metrics::MinSample("WebRTC.Video.Screenshare.Layer0.FrameRate"), 1);
597   EXPECT_METRIC_GT(
598       metrics::MinSample("WebRTC.Video.Screenshare.Layer1.FrameRate"), 1);
599   EXPECT_METRIC_GT(metrics::MinSample("WebRTC.Video.Screenshare.FramesPerDrop"),
600                    1);
601   EXPECT_METRIC_GT(
602       metrics::MinSample("WebRTC.Video.Screenshare.FramesPerOvershoot"), 1);
603   EXPECT_METRIC_EQ(
604       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer0.Qp", kTl0Qp));
605   EXPECT_METRIC_EQ(
606       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer1.Qp", kTl1Qp));
607   EXPECT_METRIC_EQ(
608       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer0.TargetBitrate",
609                             kDefaultTl0BitrateKbps));
610   EXPECT_METRIC_EQ(
611       1, metrics::NumEvents("WebRTC.Video.Screenshare.Layer1.TargetBitrate",
612                             kDefaultTl1BitrateKbps));
613 }
614 
TEST_F(ScreenshareLayerTest,RespectsConfiguredFramerate)615 TEST_F(ScreenshareLayerTest, RespectsConfiguredFramerate) {
616   int64_t kTestSpanMs = 2000;
617   int64_t kFrameIntervalsMs = 1000 / kFrameRate;
618 
619   uint32_t timestamp = 1234;
620   int num_input_frames = 0;
621   int num_discarded_frames = 0;
622 
623   // Send at regular rate - no drops expected.
624   for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) {
625     if (NextFrameConfig(0, timestamp).drop_frame) {
626       ++num_discarded_frames;
627     } else {
628       size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
629       layers_->OnEncodeDone(0, timestamp, frame_size_bytes, false, kDefaultQp,
630                             IgnoredCodecSpecificInfo());
631     }
632     timestamp += kFrameIntervalsMs * 90;
633     clock_.AdvanceTime(TimeDelta::Millis(kFrameIntervalsMs));
634 
635     ++num_input_frames;
636   }
637   EXPECT_EQ(0, num_discarded_frames);
638 
639   // Send at twice the configured rate - drop every other frame.
640   num_input_frames = 0;
641   num_discarded_frames = 0;
642   for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) {
643     if (NextFrameConfig(0, timestamp).drop_frame) {
644       ++num_discarded_frames;
645     } else {
646       size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
647       layers_->OnEncodeDone(0, timestamp, frame_size_bytes, false, kDefaultQp,
648                             IgnoredCodecSpecificInfo());
649     }
650     timestamp += kFrameIntervalsMs * 90 / 2;
651     clock_.AdvanceTime(TimeDelta::Millis(kFrameIntervalsMs));
652     ++num_input_frames;
653   }
654 
655   // Allow for some rounding errors in the measurements.
656   EXPECT_NEAR(num_discarded_frames, num_input_frames / 2, 2);
657 }
658 
659 TEST_F(ScreenshareLayerTest, 2LayersSyncAtOvershootDrop) {
660   // Run grace period so we have existing frames in both TL0 and Tl1.
661   EXPECT_TRUE(RunGracePeriod());
662 
663   // Move ahead until we have a sync frame in TL1.
664   EXPECT_EQ(kTl1SyncFlags, SkipUntilTlAndSync(1, true));
665   ASSERT_TRUE(tl_config_.layer_sync);
666 
667   // Simulate overshoot of this frame.
668   layers_->OnEncodeDone(0, timestamp_, 0, false, 0, nullptr);
669 
670   cfg_ = layers_->UpdateConfiguration(0);
671   EXPECT_EQ(kTl1SyncFlags, LibvpxVp8Encoder::EncodeFlags(tl_config_));
672 
673   CodecSpecificInfo new_info;
674   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
675                         &new_info);
676   EXPECT_TRUE(new_info.codecSpecific.VP8.layerSync);
677 }
678 
TEST_F(ScreenshareLayerTest,DropOnTooShortFrameInterval)679 TEST_F(ScreenshareLayerTest, DropOnTooShortFrameInterval) {
680   // Run grace period so we have existing frames in both TL0 and Tl1.
681   EXPECT_TRUE(RunGracePeriod());
682 
683   // Add a large gap, so there's plenty of room in the rate tracker.
684   timestamp_ += kTimestampDelta5Fps * 3;
685   EXPECT_FALSE(NextFrameConfig(0, timestamp_).drop_frame);
686   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
687                         IgnoredCodecSpecificInfo());
688 
689   // Frame interval below 90% if desired time is not allowed, try inserting
690   // frame just before this limit.
691   const int64_t kMinFrameInterval = (kTimestampDelta5Fps * 85) / 100;
692   timestamp_ += kMinFrameInterval - 90;
693   EXPECT_TRUE(NextFrameConfig(0, timestamp_).drop_frame);
694 
695   // Try again at the limit, now it should pass.
696   timestamp_ += 90;
697   EXPECT_FALSE(NextFrameConfig(0, timestamp_).drop_frame);
698 }
699 
TEST_F(ScreenshareLayerTest,AdjustsBitrateWhenDroppingFrames)700 TEST_F(ScreenshareLayerTest, AdjustsBitrateWhenDroppingFrames) {
701   const uint32_t kTimestampDelta10Fps = kTimestampDelta5Fps / 2;
702   const int kNumFrames = 30;
703   ASSERT_TRUE(cfg_.rc_target_bitrate.has_value());
704   const uint32_t default_bitrate = cfg_.rc_target_bitrate.value();
705   layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, 10);
706 
707   int num_dropped_frames = 0;
708   for (int i = 0; i < kNumFrames; ++i) {
709     if (EncodeFrame(false) == -1)
710       ++num_dropped_frames;
711     timestamp_ += kTimestampDelta10Fps;
712   }
713   cfg_ = layers_->UpdateConfiguration(0);
714 
715   EXPECT_EQ(num_dropped_frames, kNumFrames / 2);
716   EXPECT_EQ(cfg_.rc_target_bitrate, default_bitrate * 2);
717 }
718 
TEST_F(ScreenshareLayerTest,UpdatesConfigurationAfterRateChange)719 TEST_F(ScreenshareLayerTest, UpdatesConfigurationAfterRateChange) {
720   // Set inital rate again, no need to update configuration.
721   layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, kFrameRate);
722   cfg_ = layers_->UpdateConfiguration(0);
723 
724   // Rate changed, now update config.
725   std::vector<uint32_t> bitrates = kDefault2TlBitratesBps;
726   bitrates[1] -= 100000;
727   layers_->OnRatesUpdated(0, bitrates, 5);
728   cfg_ = layers_->UpdateConfiguration(0);
729 
730   // Changed rate, but then set changed rate again before trying to update
731   // configuration, update should still apply.
732   bitrates[1] -= 100000;
733   layers_->OnRatesUpdated(0, bitrates, 5);
734   layers_->OnRatesUpdated(0, bitrates, 5);
735   cfg_ = layers_->UpdateConfiguration(0);
736 }
737 
TEST_F(ScreenshareLayerTest,MaxQpRestoredAfterDoubleDrop)738 TEST_F(ScreenshareLayerTest, MaxQpRestoredAfterDoubleDrop) {
739   // Run grace period so we have existing frames in both TL0 and Tl1.
740   EXPECT_TRUE(RunGracePeriod());
741 
742   // Move ahead until we have a sync frame in TL1.
743   EXPECT_EQ(kTl1SyncFlags, SkipUntilTlAndSync(1, true));
744   ASSERT_TRUE(tl_config_.layer_sync);
745 
746   // Simulate overshoot of this frame.
747   layers_->OnEncodeDone(0, timestamp_, 0, false, -1, nullptr);
748 
749   // Simulate re-encoded frame.
750   layers_->OnEncodeDone(0, timestamp_, 1, false, max_qp_,
751                         IgnoredCodecSpecificInfo());
752 
753   // Next frame, expect boosted quality.
754   // Slightly alter bitrate between each frame.
755   std::vector<uint32_t> kDefault2TlBitratesBpsAlt = kDefault2TlBitratesBps;
756   kDefault2TlBitratesBpsAlt[1] += 4000;
757   layers_->OnRatesUpdated(0, kDefault2TlBitratesBpsAlt, kFrameRate);
758   EXPECT_EQ(kTl1Flags, SkipUntilTlAndSync(1, false));
759   EXPECT_TRUE(config_updated_);
760   EXPECT_LT(cfg_.rc_max_quantizer, max_qp_);
761   ASSERT_TRUE(cfg_.rc_max_quantizer.has_value());
762   const uint32_t adjusted_qp = cfg_.rc_max_quantizer.value();
763 
764   // Simulate overshoot of this frame.
765   layers_->OnEncodeDone(0, timestamp_, 0, false, -1, nullptr);
766 
767   // Simulate re-encoded frame.
768   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, max_qp_,
769                         IgnoredCodecSpecificInfo());
770 
771   // A third frame, expect boosted quality.
772   layers_->OnRatesUpdated(0, kDefault2TlBitratesBps, kFrameRate);
773   EXPECT_EQ(kTl1Flags, SkipUntilTlAndSync(1, false));
774   EXPECT_TRUE(config_updated_);
775   EXPECT_LT(cfg_.rc_max_quantizer, max_qp_);
776   EXPECT_EQ(adjusted_qp, cfg_.rc_max_quantizer);
777 
778   // Frame encoded.
779   layers_->OnEncodeDone(0, timestamp_, frame_size_, false, max_qp_,
780                         IgnoredCodecSpecificInfo());
781 
782   // A fourth frame, max qp should be restored.
783   layers_->OnRatesUpdated(0, kDefault2TlBitratesBpsAlt, kFrameRate);
784   EXPECT_EQ(kTl1Flags, SkipUntilTlAndSync(1, false));
785   EXPECT_EQ(cfg_.rc_max_quantizer, max_qp_);
786 }
787 
788 }  // namespace webrtc
789