/*
 *  Copyright (c) 2021 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 "modules/audio_processing/agc2/clipping_predictor.h"

#include <cstdint>
#include <limits>
#include <optional>
#include <tuple>
#include <vector>

#include "api/audio/audio_processing.h"
#include "modules/audio_processing/include/audio_frame_view.h"
#include "rtc_base/checks.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::Eq;
using ::testing::Optional;
using ClippingPredictorConfig = AudioProcessing::Config::GainController1::
    AnalogGainController::ClippingPredictor;
using ClippingPredictorMode = AudioProcessing::Config::GainController1::
    AnalogGainController::ClippingPredictor::Mode;

constexpr int kSampleRateHz = 32000;
constexpr int kNumChannels = 1;
constexpr int kSamplesPerChannel = kSampleRateHz / 100;
constexpr int kMaxMicLevel = 255;
constexpr int kMinMicLevel = 12;
constexpr int kDefaultClippedLevelStep = 15;
constexpr float kMaxSampleS16 =
    static_cast<float>(std::numeric_limits<int16_t>::max());

// Threshold in dB corresponding to a signal with an amplitude equal to 99% of
// the dynamic range - i.e., computed as `20*log10(0.99)`.
constexpr float kClippingThresholdDb = -0.08729610804900176f;

void CallAnalyze(int num_calls,
                 const AudioFrameView<const float>& frame,
                 ClippingPredictor& predictor) {
  for (int i = 0; i < num_calls; ++i) {
    predictor.Analyze(frame);
  }
}

// Creates and analyzes an audio frame with a non-zero (approx. 4.15dB) crest
// factor.
void AnalyzeNonZeroCrestFactorAudio(int num_calls,
                                    int num_channels,
                                    float peak_ratio,
                                    ClippingPredictor& predictor) {
  RTC_DCHECK_GT(num_calls, 0);
  RTC_DCHECK_GT(num_channels, 0);
  RTC_DCHECK_LE(peak_ratio, 1.0f);
  std::vector<float*> audio(num_channels);
  std::vector<float> audio_data(num_channels * kSamplesPerChannel, 0.0f);
  for (int channel = 0; channel < num_channels; ++channel) {
    audio[channel] = &audio_data[channel * kSamplesPerChannel];
    for (int sample = 0; sample < kSamplesPerChannel; sample += 10) {
      audio[channel][sample] = 0.1f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 1] = 0.2f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 2] = 0.3f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 3] = 0.4f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 4] = 0.5f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 5] = 0.6f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 6] = 0.7f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 7] = 0.8f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 8] = 0.9f * peak_ratio * kMaxSampleS16;
      audio[channel][sample + 9] = 1.0f * peak_ratio * kMaxSampleS16;
    }
  }
  AudioFrameView<const float> frame(audio.data(), num_channels,
                                    kSamplesPerChannel);
  CallAnalyze(num_calls, frame, predictor);
}

void CheckChannelEstimatesWithValue(int num_channels,
                                    int level,
                                    int default_step,
                                    int min_mic_level,
                                    int max_mic_level,
                                    const ClippingPredictor& predictor,
                                    int expected) {
  for (int i = 0; i < num_channels; ++i) {
    SCOPED_TRACE(i);
    EXPECT_THAT(predictor.EstimateClippedLevelStep(
                    i, level, default_step, min_mic_level, max_mic_level),
                Optional(Eq(expected)));
  }
}

void CheckChannelEstimatesWithoutValue(int num_channels,
                                       int level,
                                       int default_step,
                                       int min_mic_level,
                                       int max_mic_level,
                                       const ClippingPredictor& predictor) {
  for (int i = 0; i < num_channels; ++i) {
    SCOPED_TRACE(i);
    EXPECT_EQ(predictor.EstimateClippedLevelStep(i, level, default_step,
                                                 min_mic_level, max_mic_level),
              std::nullopt);
  }
}

// Creates and analyzes an audio frame with a zero crest factor.
void AnalyzeZeroCrestFactorAudio(int num_calls,
                                 int num_channels,
                                 float peak_ratio,
                                 ClippingPredictor& predictor) {
  RTC_DCHECK_GT(num_calls, 0);
  RTC_DCHECK_GT(num_channels, 0);
  RTC_DCHECK_LE(peak_ratio, 1.f);
  std::vector<float*> audio(num_channels);
  std::vector<float> audio_data(num_channels * kSamplesPerChannel, 0.f);
  for (int channel = 0; channel < num_channels; ++channel) {
    audio[channel] = &audio_data[channel * kSamplesPerChannel];
    for (int sample = 0; sample < kSamplesPerChannel; ++sample) {
      audio[channel][sample] = peak_ratio * kMaxSampleS16;
    }
  }
  auto frame = AudioFrameView<const float>(audio.data(), num_channels,
                                           kSamplesPerChannel);
  CallAnalyze(num_calls, frame, predictor);
}

TEST(ClippingPeakPredictorTest, NoPredictorCreated) {
  auto predictor =
      CreateClippingPredictor(kNumChannels, /*config=*/{.enabled = false});
  EXPECT_FALSE(predictor);
}

TEST(ClippingPeakPredictorTest, ClippingEventPredictionCreated) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  auto predictor = CreateClippingPredictor(
      kNumChannels,
      /*config=*/{.enabled = true,
                  .mode = ClippingPredictorMode::kClippingEventPrediction});
  EXPECT_TRUE(predictor);
}

TEST(ClippingPeakPredictorTest, AdaptiveStepClippingPeakPredictionCreated) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  auto predictor = CreateClippingPredictor(
      kNumChannels, /*config=*/{
          .enabled = true,
          .mode = ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction});
  EXPECT_TRUE(predictor);
}

TEST(ClippingPeakPredictorTest, FixedStepClippingPeakPredictionCreated) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  auto predictor = CreateClippingPredictor(
      kNumChannels,
      /*config=*/{
          .enabled = true,
          .mode = ClippingPredictorMode::kFixedStepClippingPeakPrediction});
  EXPECT_TRUE(predictor);
}

class ClippingPredictorParameterization
    : public ::testing::TestWithParam<std::tuple<int, int, int, int>> {
 protected:
  int num_channels() const { return std::get<0>(GetParam()); }
  ClippingPredictorConfig GetConfig(ClippingPredictorMode mode) const {
    // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
    return {/*enabled=*/.enabled = true,
            /*mode=*/.mode = mode,
            /*window_length=*/.window_length = std::get<1>(GetParam()),
            /*reference_window_length=*/.reference_window_length =
                std::get<2>(GetParam()),
            /*reference_window_delay=*/.reference_window_delay =
                std::get<3>(GetParam()),
            /*clipping_threshold=*/.clipping_threshold = -1.0f,
            /*crest_factor_margin=*/.crest_factor_margin = 0.5f};
  }
};

TEST_P(ClippingPredictorParameterization,
       CheckClippingEventPredictorEstimateAfterCrestFactorDrop) {
  const ClippingPredictorConfig config =
      GetConfig(ClippingPredictorMode::kClippingEventPrediction);
  if (config.reference_window_length + config.reference_window_delay <=
      config.window_length) {
    return;
  }
  auto predictor = CreateClippingPredictor(num_channels(), config);
  AnalyzeNonZeroCrestFactorAudio(
      /*num_calls=*/config.reference_window_length +
          config.reference_window_delay - config.window_length,
      num_channels(), /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeZeroCrestFactorAudio(config.window_length, num_channels(),
                              /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithValue(
      num_channels(), /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel,
      kMaxMicLevel, *predictor, kDefaultClippedLevelStep);
}

TEST_P(ClippingPredictorParameterization,
       CheckClippingEventPredictorNoEstimateAfterConstantCrestFactor) {
  const ClippingPredictorConfig config =
      GetConfig(ClippingPredictorMode::kClippingEventPrediction);
  if (config.reference_window_length + config.reference_window_delay <=
      config.window_length) {
    return;
  }
  auto predictor = CreateClippingPredictor(num_channels(), config);
  AnalyzeNonZeroCrestFactorAudio(
      /*num_calls=*/config.reference_window_length +
          config.reference_window_delay - config.window_length,
      num_channels(), /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.window_length,
                                 num_channels(),
                                 /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
}

TEST_P(ClippingPredictorParameterization,
       CheckClippingPeakPredictorEstimateAfterHighCrestFactor) {
  const ClippingPredictorConfig config =
      GetConfig(ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction);
  if (config.reference_window_length + config.reference_window_delay <=
      config.window_length) {
    return;
  }
  auto predictor = CreateClippingPredictor(num_channels(), config);
  AnalyzeNonZeroCrestFactorAudio(
      /*num_calls=*/config.reference_window_length +
          config.reference_window_delay - config.window_length,
      num_channels(), /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.window_length,
                                 num_channels(),
                                 /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithValue(
      num_channels(), /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel,
      kMaxMicLevel, *predictor, kDefaultClippedLevelStep);
}

TEST_P(ClippingPredictorParameterization,
       CheckClippingPeakPredictorNoEstimateAfterLowCrestFactor) {
  const ClippingPredictorConfig config =
      GetConfig(ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction);
  if (config.reference_window_length + config.reference_window_delay <=
      config.window_length) {
    return;
  }
  auto predictor = CreateClippingPredictor(num_channels(), config);
  AnalyzeZeroCrestFactorAudio(
      /*num_calls=*/config.reference_window_length +
          config.reference_window_delay - config.window_length,
      num_channels(), /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.window_length,
                                 num_channels(),
                                 /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(num_channels(), /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
}

INSTANTIATE_TEST_SUITE_P(GainController1ClippingPredictor,
                         ClippingPredictorParameterization,
                         ::testing::Combine(::testing::Values(1, 5),
                                            ::testing::Values(1, 5, 10),
                                            ::testing::Values(1, 5),
                                            ::testing::Values(0, 1, 5)));

class ClippingEventPredictorParameterization
    : public ::testing::TestWithParam<std::tuple<float, float>> {
 protected:
  ClippingPredictorConfig GetConfig() const {
    // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
    return {
        /*enabled=*/.enabled = true,
        /*mode=*/.mode = ClippingPredictorMode::kClippingEventPrediction,
        /*window_length=*/.window_length = 5,
        /*reference_window_length=*/.reference_window_length = 5,
        /*reference_window_delay=*/.reference_window_delay = 5,
        /*clipping_threshold=*/.clipping_threshold = std::get<0>(GetParam()),
        /*crest_factor_margin=*/.crest_factor_margin = std::get<1>(GetParam())};
  }
};

TEST_P(ClippingEventPredictorParameterization,
       CheckEstimateAfterCrestFactorDrop) {
  const ClippingPredictorConfig config = GetConfig();
  auto predictor = CreateClippingPredictor(kNumChannels, config);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.reference_window_length,
                                 kNumChannels, /*peak_ratio=*/0.99f,
                                 *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeZeroCrestFactorAudio(config.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  // TODO(bugs.webrtc.org/12774): Add clarifying comment.
  // TODO(bugs.webrtc.org/12774): Remove 4.15f threshold and split tests.
  if (config.clipping_threshold < kClippingThresholdDb &&
      config.crest_factor_margin < 4.15f) {
    CheckChannelEstimatesWithValue(
        kNumChannels, /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel,
        kMaxMicLevel, *predictor, kDefaultClippedLevelStep);
  } else {
    CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                      kDefaultClippedLevelStep, kMinMicLevel,
                                      kMaxMicLevel, *predictor);
  }
}

INSTANTIATE_TEST_SUITE_P(GainController1ClippingPredictor,
                         ClippingEventPredictorParameterization,
                         ::testing::Combine(::testing::Values(-1.0f, 0.0f),
                                            ::testing::Values(3.0f, 4.16f)));

class ClippingPredictorModeParameterization
    : public ::testing::TestWithParam<ClippingPredictorMode> {
 protected:
  ClippingPredictorConfig GetConfig(float clipping_threshold_dbfs) const {
    // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
    return {
        /*enabled=*/.enabled = true,
        /*mode=*/.mode = GetParam(),
        /*window_length=*/.window_length = 5,
        /*reference_window_length=*/.reference_window_length = 5,
        /*reference_window_delay=*/.reference_window_delay = 5,
        /*clipping_threshold=*/.clipping_threshold = clipping_threshold_dbfs,
        /*crest_factor_margin=*/.crest_factor_margin = 3.0f};
  }
};

TEST_P(ClippingPredictorModeParameterization,
       CheckEstimateAfterHighCrestFactorWithNoClippingMargin) {
  const ClippingPredictorConfig config = GetConfig(
      /*clipping_threshold_dbfs=*/0.0f);
  auto predictor = CreateClippingPredictor(kNumChannels, config);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.reference_window_length,
                                 kNumChannels, /*peak_ratio=*/0.99f,
                                 *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeZeroCrestFactorAudio(config.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  // Since the clipping threshold is set to 0 dBFS, `EstimateClippedLevelStep()`
  // is expected to return an unavailable value.
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
}

TEST_P(ClippingPredictorModeParameterization,
       CheckEstimateAfterHighCrestFactorWithClippingMargin) {
  const ClippingPredictorConfig config =
      GetConfig(/*clipping_threshold_dbfs=*/-1.0f);
  auto predictor = CreateClippingPredictor(kNumChannels, config);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/config.reference_window_length,
                                 kNumChannels,
                                 /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeZeroCrestFactorAudio(config.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  // TODO(bugs.webrtc.org/12774): Add clarifying comment.
  const float expected_step =
      config.mode == ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction
          ? 17
          : kDefaultClippedLevelStep;
  CheckChannelEstimatesWithValue(kNumChannels, /*level=*/255,
                                 kDefaultClippedLevelStep, kMinMicLevel,
                                 kMaxMicLevel, *predictor, expected_step);
}

INSTANTIATE_TEST_SUITE_P(
    GainController1ClippingPredictor,
    ClippingPredictorModeParameterization,
    ::testing::Values(
        ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction,
        ClippingPredictorMode::kFixedStepClippingPeakPrediction));

TEST(ClippingEventPredictorTest, CheckEstimateAfterReset) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  constexpr ClippingPredictorConfig kConfig{
      /*enabled=*/.enabled = true,
      /*mode=*/.mode = ClippingPredictorMode::kClippingEventPrediction,
      /*window_length=*/.window_length = 5,
      /*reference_window_length=*/.reference_window_length = 5,
      /*reference_window_delay=*/.reference_window_delay = 5,
      /*clipping_threshold=*/.clipping_threshold = -1.0f,
      /*crest_factor_margin=*/.crest_factor_margin = 3.0f};
  auto predictor = CreateClippingPredictor(kNumChannels, kConfig);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length,
                                 kNumChannels,
                                 /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  predictor->Reset();
  AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
}

TEST(ClippingPeakPredictorTest, CheckNoEstimateAfterReset) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  constexpr ClippingPredictorConfig kConfig{
      /*enabled=*/.enabled = true,
      /*mode=*/.mode =
          ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction,
      /*window_length=*/.window_length = 5,
      /*reference_window_length=*/.reference_window_length = 5,
      /*reference_window_delay=*/.reference_window_delay = 5,
      /*clipping_threshold=*/.clipping_threshold = -1.0f};
  auto predictor = CreateClippingPredictor(kNumChannels, kConfig);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length,
                                 kNumChannels,
                                 /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  predictor->Reset();
  AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
}

TEST(ClippingPeakPredictorTest, CheckAdaptiveStepEstimate) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  constexpr ClippingPredictorConfig kConfig{
      /*enabled=*/.enabled = true,
      /*mode=*/.mode =
          ClippingPredictorMode::kAdaptiveStepClippingPeakPrediction,
      /*window_length=*/.window_length = 5,
      /*reference_window_length=*/.reference_window_length = 5,
      /*reference_window_delay=*/.reference_window_delay = 5,
      /*clipping_threshold=*/.clipping_threshold = -1.0f};
  auto predictor = CreateClippingPredictor(kNumChannels, kConfig);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length,
                                 kNumChannels, /*peak_ratio=*/0.99f,
                                 *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithValue(kNumChannels, /*level=*/255,
                                 kDefaultClippedLevelStep, kMinMicLevel,
                                 kMaxMicLevel, *predictor, /*expected=*/17);
}

TEST(ClippingPeakPredictorTest, CheckFixedStepEstimate) {
  // TODO(bugs.webrtc.org/12874): Use designated initializers one fixed.
  constexpr ClippingPredictorConfig kConfig{
      /*enabled=*/.enabled = true,
      /*mode=*/.mode = ClippingPredictorMode::kFixedStepClippingPeakPrediction,
      /*window_length=*/.window_length = 5,
      /*reference_window_length=*/.reference_window_length = 5,
      /*reference_window_delay=*/.reference_window_delay = 5,
      /*clipping_threshold=*/.clipping_threshold = -1.0f};
  auto predictor = CreateClippingPredictor(kNumChannels, kConfig);
  AnalyzeNonZeroCrestFactorAudio(/*num_calls=*/kConfig.reference_window_length,
                                 kNumChannels, /*peak_ratio=*/0.99f,
                                 *predictor);
  CheckChannelEstimatesWithoutValue(kNumChannels, /*level=*/255,
                                    kDefaultClippedLevelStep, kMinMicLevel,
                                    kMaxMicLevel, *predictor);
  AnalyzeZeroCrestFactorAudio(kConfig.window_length, kNumChannels,
                              /*peak_ratio=*/0.99f, *predictor);
  CheckChannelEstimatesWithValue(
      kNumChannels, /*level=*/255, kDefaultClippedLevelStep, kMinMicLevel,
      kMaxMicLevel, *predictor, kDefaultClippedLevelStep);
}

}  // namespace
}  // namespace webrtc
