/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <random>
#include <utility>

#include "modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

// The test uses the following settings:
//
// recoverable ^
// packet-loss |   |  |
//             |  A| C|   FEC
//             |    \  \   ON
//             | FEC \ D\_______
//             | OFF B\_________
//             |-----------------> bandwidth
//
// A : (kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw)
// B : (kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw)
// C : (kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw)
// D : (kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw)

constexpr int kDisablingBandwidthLow = 15000;
constexpr float kDisablingRecoverablePacketLossAtLowBw = 0.08f;
constexpr int kDisablingBandwidthHigh = 64000;
constexpr float kDisablingRecoverablePacketLossAtHighBw = 0.01f;
constexpr int kEnablingBandwidthLow = 17000;
constexpr float kEnablingRecoverablePacketLossAtLowBw = 0.1f;
constexpr int kEnablingBandwidthHigh = 64000;
constexpr float kEnablingRecoverablePacketLossAtHighBw = 0.05f;

constexpr float kEpsilon = 1e-5f;

rtc::Optional<float> GetRandomProbabilityOrUnknown() {
  std::random_device rd;
  std::mt19937 generator(rd());
  std::uniform_real_distribution<> distribution(0, 1);

  if (distribution(generator) < 0.2) {
    return rtc::Optional<float>();
  } else {
    return rtc::Optional<float>(distribution(generator));
  }
}

std::unique_ptr<FecControllerRplrBased> CreateFecControllerRplrBased(
    bool initial_fec_enabled) {
  return std::unique_ptr<FecControllerRplrBased>(
      new FecControllerRplrBased(FecControllerRplrBased::Config(
          initial_fec_enabled,
          ThresholdCurve(
              kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw,
              kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw),
          ThresholdCurve(kDisablingBandwidthLow,
                         kDisablingRecoverablePacketLossAtLowBw,
                         kDisablingBandwidthHigh,
                         kDisablingRecoverablePacketLossAtHighBw))));
}

void UpdateNetworkMetrics(
    FecControllerRplrBased* controller,
    const rtc::Optional<int>& uplink_bandwidth_bps,
    const rtc::Optional<float>& uplink_packet_loss,
    const rtc::Optional<float>& uplink_recoveralbe_packet_loss) {
  // UpdateNetworkMetrics can accept multiple network metric updates at once.
  // However, currently, the most used case is to update one metric at a time.
  // To reflect this fact, we separate the calls.
  if (uplink_bandwidth_bps) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
    controller->UpdateNetworkMetrics(network_metrics);
  }
  if (uplink_packet_loss) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.uplink_packet_loss_fraction = uplink_packet_loss;
    controller->UpdateNetworkMetrics(network_metrics);
  }
  if (uplink_recoveralbe_packet_loss) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.uplink_recoverable_packet_loss_fraction =
        uplink_recoveralbe_packet_loss;
    controller->UpdateNetworkMetrics(network_metrics);
  }
}

void UpdateNetworkMetrics(
    FecControllerRplrBased* controller,
    const rtc::Optional<int>& uplink_bandwidth_bps,
    const rtc::Optional<float>& uplink_recoveralbe_packet_loss) {
  // FecControllerRplrBased doesn't currently use the PLR (general packet-loss
  // rate) at all. (This might be changed in the future.) The unit-tests will
  // use a random value (including unknown), to show this does not interfere.
  UpdateNetworkMetrics(controller, uplink_bandwidth_bps,
                       GetRandomProbabilityOrUnknown(),
                       uplink_recoveralbe_packet_loss);
}

void UpdateNetworkMetrics(FecControllerRplrBased* controller,
                          int uplink_bandwidth_bps,
                          float uplink_recoveralbe_packet_loss) {
  UpdateNetworkMetrics(controller, rtc::Optional<int>(uplink_bandwidth_bps),
                       rtc::Optional<float>(uplink_recoveralbe_packet_loss));
}

// Checks that the FEC decision and |uplink_packet_loss_fraction| given by
// |states->controller->MakeDecision| matches |expected_enable_fec| and
// |expected_uplink_packet_loss_fraction|, respectively.
void CheckDecision(FecControllerRplrBased* controller,
                   bool expected_enable_fec,
                   float expected_uplink_packet_loss_fraction) {
  AudioEncoderRuntimeConfig config;
  controller->MakeDecision(&config);

  // Less compact than comparing optionals, but yields more readable errors.
  EXPECT_TRUE(config.enable_fec);
  if (config.enable_fec) {
    EXPECT_EQ(expected_enable_fec, *config.enable_fec);
  }
  EXPECT_TRUE(config.uplink_packet_loss_fraction);
  if (config.uplink_packet_loss_fraction) {
    EXPECT_EQ(expected_uplink_packet_loss_fraction,
              *config.uplink_packet_loss_fraction);
  }
}

}  // namespace

TEST(FecControllerRplrBasedTest, OutputInitValueBeforeAnyInputsAreReceived) {
  for (bool initial_fec_enabled : {false, true}) {
    auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
    CheckDecision(controller.get(), initial_fec_enabled, 0);
  }
}

TEST(FecControllerRplrBasedTest, OutputInitValueWhenUplinkBandwidthUnknown) {
  // Regardless of the initial FEC state and the recoverable-packet-loss
  // rate, the initial FEC state is maintained as long as the BWE is unknown.
  for (bool initial_fec_enabled : {false, true}) {
    for (float recoverable_packet_loss :
         {kDisablingRecoverablePacketLossAtHighBw - kEpsilon,
          kDisablingRecoverablePacketLossAtHighBw,
          kDisablingRecoverablePacketLossAtHighBw + kEpsilon,
          kEnablingRecoverablePacketLossAtHighBw - kEpsilon,
          kEnablingRecoverablePacketLossAtHighBw,
          kEnablingRecoverablePacketLossAtHighBw + kEpsilon}) {
      auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
      UpdateNetworkMetrics(controller.get(), rtc::Optional<int>(),
                           rtc::Optional<float>(recoverable_packet_loss));
      CheckDecision(controller.get(), initial_fec_enabled,
                    recoverable_packet_loss);
    }
  }
}

TEST(FecControllerRplrBasedTest,
     OutputInitValueWhenUplinkRecoverablePacketLossFractionUnknown) {
  // Regardless of the initial FEC state and the BWE, the initial FEC state
  // is maintained as long as the recoverable-packet-loss rate is unknown.
  for (bool initial_fec_enabled : {false, true}) {
    for (int bandwidth : {kDisablingBandwidthLow - 1, kDisablingBandwidthLow,
                          kDisablingBandwidthLow + 1, kEnablingBandwidthLow - 1,
                          kEnablingBandwidthLow, kEnablingBandwidthLow + 1}) {
      auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
      UpdateNetworkMetrics(controller.get(), rtc::Optional<int>(bandwidth),
                           rtc::Optional<float>());
      CheckDecision(controller.get(), initial_fec_enabled, 0.0);
    }
  }
}

TEST(FecControllerRplrBasedTest, EnableFecForHighBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthHigh,
                       kEnablingRecoverablePacketLossAtHighBw);
  CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw);
}

TEST(FecControllerRplrBasedTest, UpdateMultipleNetworkMetricsAtOnce) {
  // This test is similar to EnableFecForHighBandwidth. But instead of
  // using ::UpdateNetworkMetrics(...), which calls
  // FecControllerRplrBasedTest::UpdateNetworkMetrics(...) multiple times, we
  // we call it only once. This is to verify that
  // FecControllerRplrBasedTest::UpdateNetworkMetrics(...) can handle multiple
  // network updates at once. This is, however, not a common use case in current
  // audio_network_adaptor_impl.cc.
  auto controller = CreateFecControllerRplrBased(false);
  Controller::NetworkMetrics network_metrics;
  network_metrics.uplink_bandwidth_bps =
      rtc::Optional<int>(kEnablingBandwidthHigh);
  network_metrics.uplink_packet_loss_fraction =
      rtc::Optional<float>(GetRandomProbabilityOrUnknown());
  network_metrics.uplink_recoverable_packet_loss_fraction =
      rtc::Optional<float>(kEnablingRecoverablePacketLossAtHighBw);
  controller->UpdateNetworkMetrics(network_metrics);
  CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw);
}

TEST(FecControllerRplrBasedTest, MaintainFecOffForHighBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  constexpr float kRecoverablePacketLoss =
      kEnablingRecoverablePacketLossAtHighBw * 0.99f;
  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthHigh,
                       kRecoverablePacketLoss);
  CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, EnableFecForMediumBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  constexpr float kRecoverablePacketLoss =
      (kEnablingRecoverablePacketLossAtLowBw +
       kEnablingRecoverablePacketLossAtHighBw) / 2.0;
  UpdateNetworkMetrics(
      controller.get(),
      (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2,
      kRecoverablePacketLoss);
  CheckDecision(controller.get(), true, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, MaintainFecOffForMediumBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  constexpr float kRecoverablePacketLoss =
      kEnablingRecoverablePacketLossAtLowBw * 0.49f +
      kEnablingRecoverablePacketLossAtHighBw * 0.51f;
  UpdateNetworkMetrics(controller.get(),
                       (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2,
                       kRecoverablePacketLoss);
  CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, EnableFecForLowBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow,
                       kEnablingRecoverablePacketLossAtLowBw);
  CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtLowBw);
}

TEST(FecControllerRplrBasedTest, MaintainFecOffForLowBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  constexpr float kRecoverablePacketLoss =
      kEnablingRecoverablePacketLossAtLowBw * 0.99f;
  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow,
                       kRecoverablePacketLoss);
  CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, MaintainFecOffForVeryLowBandwidth) {
  auto controller = CreateFecControllerRplrBased(false);
  // Below |kEnablingBandwidthLow|, no recoverable packet loss fraction can
  // cause FEC to turn on.
  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow - 1, 1.0);
  CheckDecision(controller.get(), false, 1.0);
}

TEST(FecControllerRplrBasedTest, DisableFecForHighBandwidth) {
  auto controller = CreateFecControllerRplrBased(true);
  constexpr float kRecoverablePacketLoss =
      kDisablingRecoverablePacketLossAtHighBw - kEpsilon;
  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh,
                       kRecoverablePacketLoss);
  CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, MaintainFecOnForHighBandwidth) {
  // Note: Disabling happens when the value is strictly below the threshold.
  auto controller = CreateFecControllerRplrBased(true);
  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh,
                       kDisablingRecoverablePacketLossAtHighBw);
  CheckDecision(controller.get(), true,
                kDisablingRecoverablePacketLossAtHighBw);
}

TEST(FecControllerRplrBasedTest, DisableFecOnMediumBandwidth) {
  auto controller = CreateFecControllerRplrBased(true);
  constexpr float kRecoverablePacketLoss =
      ((kDisablingRecoverablePacketLossAtLowBw +
        kDisablingRecoverablePacketLossAtHighBw) / 2.0f) - kEpsilon;
  UpdateNetworkMetrics(
      controller.get(),
      (kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2,
      kRecoverablePacketLoss);
  CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, MaintainFecOnForMediumBandwidth) {
  auto controller = CreateFecControllerRplrBased(true);
  constexpr float kRecoverablePacketLoss =
      kDisablingRecoverablePacketLossAtLowBw * 0.51f +
      kDisablingRecoverablePacketLossAtHighBw * 0.49f - kEpsilon;
  UpdateNetworkMetrics(controller.get(),
                       (kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2,
                       kRecoverablePacketLoss);
  CheckDecision(controller.get(), true, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, DisableFecForLowBandwidth) {
  auto controller = CreateFecControllerRplrBased(true);
  constexpr float kRecoverablePacketLoss =
      kDisablingRecoverablePacketLossAtLowBw - kEpsilon;
  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthLow,
                       kRecoverablePacketLoss);
  CheckDecision(controller.get(), false, kRecoverablePacketLoss);
}

TEST(FecControllerRplrBasedTest, DisableFecForVeryLowBandwidth) {
  auto controller = CreateFecControllerRplrBased(true);
  // Below |kEnablingBandwidthLow|, any recoverable packet loss fraction can
  // cause FEC to turn off.
  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthLow - 1, 1.0);
  CheckDecision(controller.get(), false, 1.0);
}

TEST(FecControllerRplrBasedTest, CheckBehaviorOnChangingNetworkMetrics) {
  // In this test, we let the network metrics to traverse from 1 to 5.
  //
  // recoverable ^
  // packet-loss | 1 |  |
  //             |   | 2|
  //             |    \  \ 3
  //             |     \4 \_______
  //             |      \_________
  //             |---------5-------> bandwidth

  auto controller = CreateFecControllerRplrBased(true);
  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthLow - 1, 1.0);
  CheckDecision(controller.get(), false, 1.0);

  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthLow,
                       kEnablingRecoverablePacketLossAtLowBw * 0.99f);
  CheckDecision(controller.get(), false,
                kEnablingRecoverablePacketLossAtLowBw * 0.99f);

  UpdateNetworkMetrics(controller.get(), kEnablingBandwidthHigh,
                       kEnablingRecoverablePacketLossAtHighBw);
  CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw);

  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh,
                       kDisablingRecoverablePacketLossAtHighBw);
  CheckDecision(controller.get(), true,
                kDisablingRecoverablePacketLossAtHighBw);

  UpdateNetworkMetrics(controller.get(), kDisablingBandwidthHigh + 1, 0.0);
  CheckDecision(controller.get(), false, 0.0);
}

TEST(FecControllerRplrBasedTest, CheckBehaviorOnSpecialCurves) {
  // We test a special configuration, where the points to define the FEC
  // enabling/disabling curves are placed like the following, otherwise the test
  // is the same as CheckBehaviorOnChangingNetworkMetrics.
  //
  // recoverable ^
  // packet-loss |   |  |
  //             |   | C|
  //             |   |  |
  //             |   | D|_______
  //             |  A|___B______
  //             |-----------------> bandwidth

  constexpr int kEnablingBandwidthHigh = kEnablingBandwidthLow;
  constexpr float kDisablingRecoverablePacketLossAtLowBw =
      kDisablingRecoverablePacketLossAtHighBw;
  FecControllerRplrBased controller(FecControllerRplrBased::Config(
      true,
      ThresholdCurve(
          kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw,
          kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw),
      ThresholdCurve(
          kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw,
          kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw)));

  UpdateNetworkMetrics(&controller, kDisablingBandwidthLow - 1, 1.0);
  CheckDecision(&controller, false, 1.0);

  UpdateNetworkMetrics(&controller, kEnablingBandwidthLow,
                       kEnablingRecoverablePacketLossAtHighBw * 0.99f);
  CheckDecision(&controller, false,
                kEnablingRecoverablePacketLossAtHighBw * 0.99f);

  UpdateNetworkMetrics(&controller, kEnablingBandwidthHigh,
                       kEnablingRecoverablePacketLossAtHighBw);
  CheckDecision(&controller, true, kEnablingRecoverablePacketLossAtHighBw);

  UpdateNetworkMetrics(&controller, kDisablingBandwidthHigh,
                       kDisablingRecoverablePacketLossAtHighBw);
  CheckDecision(&controller, true, kDisablingRecoverablePacketLossAtHighBw);

  UpdateNetworkMetrics(&controller, kDisablingBandwidthHigh + 1, 0.0);
  CheckDecision(&controller, false, 0.0);
}

TEST(FecControllerRplrBasedTest, SingleThresholdCurveForEnablingAndDisabling) {
  // Note: To avoid numerical errors, keep kRecoverablePacketLossAtLowBw and
  // kRecoverablePacketLossAthighBw as (negative) integer powers of 2.
  // This is mostly relevant for the O3 case.
  constexpr int kBandwidthLow = 10000;
  constexpr float kRecoverablePacketLossAtLowBw = 0.25f;
  constexpr int kBandwidthHigh = 20000;
  constexpr float kRecoverablePacketLossAtHighBw = 0.125f;
  auto curve = ThresholdCurve(kBandwidthLow, kRecoverablePacketLossAtLowBw,
                              kBandwidthHigh, kRecoverablePacketLossAtHighBw);

  // B* stands for "below-curve", O* for "on-curve", and A* for "above-curve".
  //
  //                                            //
  // recoverable ^                              //
  // packet-loss |    |                         //
  //             | B1 O1                        //
  //             |    |                         //
  //             |    O2                        //
  //             |     \ A1                     //
  //             |      \                       //
  //             |       O3   A2                //
  //             |     B2 \                     //
  //             |         \                    //
  //             |          O4--O5----          //
  //             |                              //
  //             |            B3                //
  //             |-----------------> bandwidth  //

  struct NetworkState {
    int bandwidth;
    float recoverable_packet_loss;
  };

  std::vector<NetworkState> below{
      {kBandwidthLow - 1, kRecoverablePacketLossAtLowBw + 0.1f},  // B1
      {(kBandwidthLow + kBandwidthHigh) / 2,
       (kRecoverablePacketLossAtLowBw + kRecoverablePacketLossAtHighBw) / 2 -
           kEpsilon},                                                  // B2
      {kBandwidthHigh + 1, kRecoverablePacketLossAtHighBw - kEpsilon}  // B3
  };

  std::vector<NetworkState> on{
      {kBandwidthLow, kRecoverablePacketLossAtLowBw + 0.1f},  // O1
      {kBandwidthLow, kRecoverablePacketLossAtLowBw},         // O2
      {(kBandwidthLow + kBandwidthHigh) / 2,
       (kRecoverablePacketLossAtLowBw + kRecoverablePacketLossAtHighBw) /
           2},                                               // O3
      {kBandwidthHigh, kRecoverablePacketLossAtHighBw},      // O4
      {kBandwidthHigh + 1, kRecoverablePacketLossAtHighBw},  // O5
  };

  std::vector<NetworkState> above{
      {(kBandwidthLow + kBandwidthHigh) / 2,
       (kRecoverablePacketLossAtLowBw + kRecoverablePacketLossAtHighBw) / 2 +
           kEpsilon},                                                   // A1
      {kBandwidthHigh + 1, kRecoverablePacketLossAtHighBw + kEpsilon},  // A2
  };

  // Test that FEC is turned off whenever we're below the curve, independent
  // of the starting FEC state.
  for (NetworkState net_state : below) {
    for (bool initial_fec_enabled : {false, true}) {
      FecControllerRplrBased controller(
          FecControllerRplrBased::Config(initial_fec_enabled, curve, curve));
      UpdateNetworkMetrics(&controller, net_state.bandwidth,
                           net_state.recoverable_packet_loss);
      CheckDecision(&controller, false, net_state.recoverable_packet_loss);
    }
  }

  // Test that FEC is turned on whenever we're on the curve or above it,
  // independent of the starting FEC state.
  for (std::vector<NetworkState> states_list : {on, above}) {
    for (NetworkState net_state : states_list) {
      for (bool initial_fec_enabled : {false, true}) {
        FecControllerRplrBased controller(
            FecControllerRplrBased::Config(initial_fec_enabled, curve, curve));
        UpdateNetworkMetrics(&controller, net_state.bandwidth,
                             net_state.recoverable_packet_loss);
        CheckDecision(&controller, true, net_state.recoverable_packet_loss);
      }
    }
  }
}

TEST(FecControllerRplrBasedTest, FecAlwaysOff) {
  ThresholdCurve always_off_curve(0, 1.0f + kEpsilon, 0, 1.0f + kEpsilon);
  for (bool initial_fec_enabled : {false, true}) {
    for (int bandwidth : {0, 10000}) {
      for (float recoverable_packet_loss : {0.0f, 0.5f, 1.0f}) {
        FecControllerRplrBased controller(FecControllerRplrBased::Config(
            initial_fec_enabled, always_off_curve, always_off_curve));
        UpdateNetworkMetrics(&controller, bandwidth, recoverable_packet_loss);
        CheckDecision(&controller, false, recoverable_packet_loss);
      }
    }
  }
}

TEST(FecControllerRplrBasedTest, FecAlwaysOn) {
  ThresholdCurve always_on_curve(0, 0.0f, 0, 0.0f);
  for (bool initial_fec_enabled : {false, true}) {
    for (int bandwidth : {0, 10000}) {
      for (float recoverable_packet_loss : {0.0f, 0.5f, 1.0f}) {
        FecControllerRplrBased controller(FecControllerRplrBased::Config(
            initial_fec_enabled, always_on_curve, always_on_curve));
        UpdateNetworkMetrics(&controller, bandwidth, recoverable_packet_loss);
        CheckDecision(&controller, true, recoverable_packet_loss);
      }
    }
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(FecControllerRplrBasedDeathTest, InvalidConfig) {
  EXPECT_DEATH(
      FecControllerRplrBased controller(FecControllerRplrBased::Config(
          true,
          ThresholdCurve(
              kDisablingBandwidthLow - 1, kEnablingRecoverablePacketLossAtLowBw,
              kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw),
          ThresholdCurve(kDisablingBandwidthLow,
                         kDisablingRecoverablePacketLossAtLowBw,
                         kDisablingBandwidthHigh,
                         kDisablingRecoverablePacketLossAtHighBw))),
      "Check failed");
}
#endif
}  // namespace webrtc
