tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

screenshare_layers_unittest.cc (28227B)


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