/*
 *  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);

  return (distribution(generator) < 0.2)
             ? rtc::nullopt
             : 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);
}

// 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::nullopt,
                           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(), bandwidth, rtc::nullopt);
      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 = kEnablingBandwidthHigh;
  network_metrics.uplink_packet_loss_fraction = GetRandomProbabilityOrUnknown();
  network_metrics.uplink_recoverable_packet_loss_fraction =
      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
