/*
 *  Copyright (c) 2015 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 <array>
#include <memory>
#include <utility>

#include "absl/memory/memory.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h"
#include "common_audio/mocks/mock_smoothing_filter.h"
#include "modules/audio_coding/audio_network_adaptor/mock/mock_audio_network_adaptor.h"
#include "modules/audio_coding/codecs/opus/audio_encoder_opus.h"
#include "modules/audio_coding/codecs/opus/opus_interface.h"
#include "modules/audio_coding/neteq/tools/audio_loop.h"
#include "rtc_base/checks.h"
#include "rtc_base/fake_clock.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {
using ::testing::NiceMock;
using ::testing::Return;

namespace {

constexpr int kDefaultOpusPayloadType = 105;
constexpr int kDefaultOpusRate = 32000;
constexpr int kDefaultOpusPacSize = 960;
constexpr int64_t kInitialTimeUs = 12345678;

AudioEncoderOpusConfig CreateConfigWithParameters(
    const SdpAudioFormat::Parameters& params) {
  const SdpAudioFormat format("opus", 48000, 2, params);
  return *AudioEncoderOpus::SdpToConfig(format);
}

struct AudioEncoderOpusStates {
  MockAudioNetworkAdaptor* mock_audio_network_adaptor;
  MockSmoothingFilter* mock_bitrate_smoother;
  std::unique_ptr<AudioEncoderOpusImpl> encoder;
  std::unique_ptr<rtc::ScopedFakeClock> fake_clock;
  AudioEncoderOpusConfig config;
};

std::unique_ptr<AudioEncoderOpusStates> CreateCodec(size_t num_channels) {
  std::unique_ptr<AudioEncoderOpusStates> states =
      absl::make_unique<AudioEncoderOpusStates>();
  states->mock_audio_network_adaptor = nullptr;
  states->fake_clock.reset(new rtc::ScopedFakeClock());
  states->fake_clock->SetTimeMicros(kInitialTimeUs);

  MockAudioNetworkAdaptor** mock_ptr = &states->mock_audio_network_adaptor;
  AudioEncoderOpusImpl::AudioNetworkAdaptorCreator creator =
      [mock_ptr](const std::string&, RtcEventLog* event_log) {
        std::unique_ptr<MockAudioNetworkAdaptor> adaptor(
            new NiceMock<MockAudioNetworkAdaptor>());
        EXPECT_CALL(*adaptor, Die());
        *mock_ptr = adaptor.get();
        return adaptor;
      };

  AudioEncoderOpusConfig config;
  config.frame_size_ms = rtc::CheckedDivExact(kDefaultOpusPacSize, 48);
  config.num_channels = num_channels;
  config.bitrate_bps = kDefaultOpusRate;
  config.application = num_channels == 1
                           ? AudioEncoderOpusConfig::ApplicationMode::kVoip
                           : AudioEncoderOpusConfig::ApplicationMode::kAudio;
  config.supported_frame_lengths_ms.push_back(config.frame_size_ms);
  states->config = config;

  std::unique_ptr<MockSmoothingFilter> bitrate_smoother(
      new MockSmoothingFilter());
  states->mock_bitrate_smoother = bitrate_smoother.get();

  states->encoder.reset(new AudioEncoderOpusImpl(
      states->config, kDefaultOpusPayloadType, std::move(creator),
      std::move(bitrate_smoother)));
  return states;
}

AudioEncoderRuntimeConfig CreateEncoderRuntimeConfig() {
  constexpr int kBitrate = 40000;
  constexpr int kFrameLength = 60;
  constexpr bool kEnableFec = true;
  constexpr bool kEnableDtx = false;
  constexpr size_t kNumChannels = 1;
  constexpr float kPacketLossFraction = 0.1f;
  AudioEncoderRuntimeConfig config;
  config.bitrate_bps = kBitrate;
  config.frame_length_ms = kFrameLength;
  config.enable_fec = kEnableFec;
  config.enable_dtx = kEnableDtx;
  config.num_channels = kNumChannels;
  config.uplink_packet_loss_fraction = kPacketLossFraction;
  return config;
}

void CheckEncoderRuntimeConfig(const AudioEncoderOpusImpl* encoder,
                               const AudioEncoderRuntimeConfig& config) {
  EXPECT_EQ(*config.bitrate_bps, encoder->GetTargetBitrate());
  EXPECT_EQ(*config.frame_length_ms, encoder->next_frame_length_ms());
  EXPECT_EQ(*config.enable_fec, encoder->fec_enabled());
  EXPECT_EQ(*config.enable_dtx, encoder->GetDtx());
  EXPECT_EQ(*config.num_channels, encoder->num_channels_to_encode());
}

// Create 10ms audio data blocks for a total packet size of "packet_size_ms".
std::unique_ptr<test::AudioLoop> Create10msAudioBlocks(
    const std::unique_ptr<AudioEncoderOpusImpl>& encoder,
    int packet_size_ms) {
  const std::string file_name =
      test::ResourcePath("audio_coding/testfile32kHz", "pcm");

  std::unique_ptr<test::AudioLoop> speech_data(new test::AudioLoop());
  int audio_samples_per_ms =
      rtc::CheckedDivExact(encoder->SampleRateHz(), 1000);
  if (!speech_data->Init(
          file_name,
          packet_size_ms * audio_samples_per_ms *
              encoder->num_channels_to_encode(),
          10 * audio_samples_per_ms * encoder->num_channels_to_encode()))
    return nullptr;
  return speech_data;
}

}  // namespace

TEST(AudioEncoderOpusTest, DefaultApplicationModeMono) {
  auto states = CreateCodec(1);
  EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
            states->encoder->application());
}

TEST(AudioEncoderOpusTest, DefaultApplicationModeStereo) {
  auto states = CreateCodec(2);
  EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kAudio,
            states->encoder->application());
}

TEST(AudioEncoderOpusTest, ChangeApplicationMode) {
  auto states = CreateCodec(2);
  EXPECT_TRUE(
      states->encoder->SetApplication(AudioEncoder::Application::kSpeech));
  EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
            states->encoder->application());
}

TEST(AudioEncoderOpusTest, ResetWontChangeApplicationMode) {
  auto states = CreateCodec(2);

  // Trigger a reset.
  states->encoder->Reset();
  // Verify that the mode is still kAudio.
  EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kAudio,
            states->encoder->application());

  // Now change to kVoip.
  EXPECT_TRUE(
      states->encoder->SetApplication(AudioEncoder::Application::kSpeech));
  EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
            states->encoder->application());

  // Trigger a reset again.
  states->encoder->Reset();
  // Verify that the mode is still kVoip.
  EXPECT_EQ(AudioEncoderOpusConfig::ApplicationMode::kVoip,
            states->encoder->application());
}

TEST(AudioEncoderOpusTest, ToggleDtx) {
  auto states = CreateCodec(2);
  // Enable DTX
  EXPECT_TRUE(states->encoder->SetDtx(true));
  EXPECT_TRUE(states->encoder->GetDtx());
  // Turn off DTX.
  EXPECT_TRUE(states->encoder->SetDtx(false));
  EXPECT_FALSE(states->encoder->GetDtx());
}

TEST(AudioEncoderOpusTest,
     OnReceivedUplinkBandwidthWithoutAudioNetworkAdaptor) {
  auto states = CreateCodec(1);
  // Constants are replicated from audio_states->encoderopus.cc.
  const int kMinBitrateBps = 6000;
  const int kMaxBitrateBps = 510000;
  // Set a too low bitrate.
  states->encoder->OnReceivedUplinkBandwidth(kMinBitrateBps - 1, absl::nullopt);
  EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
  // Set a too high bitrate.
  states->encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps + 1, absl::nullopt);
  EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
  // Set the minimum rate.
  states->encoder->OnReceivedUplinkBandwidth(kMinBitrateBps, absl::nullopt);
  EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());
  // Set the maximum rate.
  states->encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps, absl::nullopt);
  EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
  // Set rates from kMaxBitrateBps up to 32000 bps.
  for (int rate = kMinBitrateBps; rate <= 32000; rate += 1000) {
    states->encoder->OnReceivedUplinkBandwidth(rate, absl::nullopt);
    EXPECT_EQ(rate, states->encoder->GetTargetBitrate());
  }
}

namespace {

// Returns a vector with the n evenly-spaced numbers a, a + (b - a)/(n - 1),
// ..., b.
std::vector<float> IntervalSteps(float a, float b, size_t n) {
  RTC_DCHECK_GT(n, 1u);
  const float step = (b - a) / (n - 1);
  std::vector<float> points;
  points.push_back(a);
  for (size_t i = 1; i < n - 1; ++i)
    points.push_back(a + i * step);
  points.push_back(b);
  return points;
}

// Sets the packet loss rate to each number in the vector in turn, and verifies
// that the loss rate as reported by the encoder is |expected_return| for all
// of them.
void TestSetPacketLossRate(const AudioEncoderOpusStates* states,
                           const std::vector<float>& losses,
                           float expected_return) {
  // |kSampleIntervalMs| is chosen to ease the calculation since
  // 0.9999 ^ 184198 = 1e-8. Which minimizes the effect of
  // PacketLossFractionSmoother used in AudioEncoderOpus.
  constexpr int64_t kSampleIntervalMs = 184198;
  for (float loss : losses) {
    states->encoder->OnReceivedUplinkPacketLossFraction(loss);
    states->fake_clock->AdvanceTime(TimeDelta::ms(kSampleIntervalMs));
    EXPECT_FLOAT_EQ(expected_return, states->encoder->packet_loss_rate());
  }
}

}  // namespace

TEST(AudioEncoderOpusTest, PacketLossRateOptimized) {
  auto states = CreateCodec(1);
  auto I = [](float a, float b) { return IntervalSteps(a, b, 10); };
  constexpr float eps = 1e-8f;

  // Note that the order of the following calls is critical.

  // clang-format off
  TestSetPacketLossRate(states.get(), I(0.00f      , 0.01f - eps), 0.00f);
  TestSetPacketLossRate(states.get(), I(0.01f + eps, 0.06f - eps), 0.01f);
  TestSetPacketLossRate(states.get(), I(0.06f + eps, 0.11f - eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.11f + eps, 0.22f - eps), 0.10f);
  TestSetPacketLossRate(states.get(), I(0.22f + eps, 1.00f      ), 0.20f);

  TestSetPacketLossRate(states.get(), I(1.00f      , 0.18f + eps), 0.20f);
  TestSetPacketLossRate(states.get(), I(0.18f - eps, 0.09f + eps), 0.10f);
  TestSetPacketLossRate(states.get(), I(0.09f - eps, 0.04f + eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.04f - eps, 0.01f + eps), 0.01f);
  TestSetPacketLossRate(states.get(), I(0.01f - eps, 0.00f      ), 0.00f);
  // clang-format on
}

TEST(AudioEncoderOpusTest, PacketLossRateLowerBounded) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Audio-OpusMinPacketLossRate/Enabled-5/");
  auto states = CreateCodec(1);
  auto I = [](float a, float b) { return IntervalSteps(a, b, 10); };
  constexpr float eps = 1e-8f;

  // clang-format off
  TestSetPacketLossRate(states.get(), I(0.00f      , 0.01f - eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.01f + eps, 0.06f - eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.06f + eps, 0.11f - eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.11f + eps, 0.22f - eps), 0.10f);
  TestSetPacketLossRate(states.get(), I(0.22f + eps, 1.00f      ), 0.20f);

  TestSetPacketLossRate(states.get(), I(1.00f      , 0.18f + eps), 0.20f);
  TestSetPacketLossRate(states.get(), I(0.18f - eps, 0.09f + eps), 0.10f);
  TestSetPacketLossRate(states.get(), I(0.09f - eps, 0.04f + eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.04f - eps, 0.01f + eps), 0.05f);
  TestSetPacketLossRate(states.get(), I(0.01f - eps, 0.00f      ), 0.05f);
  // clang-format on
}

TEST(AudioEncoderOpusTest, NewPacketLossRateOptimization) {
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-NewOpusPacketLossRateOptimization/Enabled-5-15-0.5/");
    auto states = CreateCodec(1);

    TestSetPacketLossRate(states.get(), {0.00f}, 0.05f);
    TestSetPacketLossRate(states.get(), {0.12f}, 0.06f);
    TestSetPacketLossRate(states.get(), {0.22f}, 0.11f);
    TestSetPacketLossRate(states.get(), {0.50f}, 0.15f);
  }
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-NewOpusPacketLossRateOptimization/Enabled/");
    auto states = CreateCodec(1);

    TestSetPacketLossRate(states.get(), {0.00f}, 0.01f);
    TestSetPacketLossRate(states.get(), {0.12f}, 0.12f);
    TestSetPacketLossRate(states.get(), {0.22f}, 0.20f);
    TestSetPacketLossRate(states.get(), {0.50f}, 0.20f);
  }
}

TEST(AudioEncoderOpusTest, SetReceiverFrameLengthRange) {
  auto states = CreateCodec(2);
  // Before calling to |SetReceiverFrameLengthRange|,
  // |supported_frame_lengths_ms| should contain only the frame length being
  // used.
  using ::testing::ElementsAre;
  EXPECT_THAT(states->encoder->supported_frame_lengths_ms(),
              ElementsAre(states->encoder->next_frame_length_ms()));
  states->encoder->SetReceiverFrameLengthRange(0, 12345);
  states->encoder->SetReceiverFrameLengthRange(21, 60);
  EXPECT_THAT(states->encoder->supported_frame_lengths_ms(), ElementsAre(60));
  states->encoder->SetReceiverFrameLengthRange(20, 59);
  EXPECT_THAT(states->encoder->supported_frame_lengths_ms(), ElementsAre(20));
}

TEST(AudioEncoderOpusTest,
     InvokeAudioNetworkAdaptorOnReceivedUplinkPacketLossFraction) {
  auto states = CreateCodec(2);
  states->encoder->EnableAudioNetworkAdaptor("", nullptr);

  auto config = CreateEncoderRuntimeConfig();
  EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
      .WillOnce(Return(config));

  // Since using mock audio network adaptor, any packet loss fraction is fine.
  constexpr float kUplinkPacketLoss = 0.1f;
  EXPECT_CALL(*states->mock_audio_network_adaptor,
              SetUplinkPacketLossFraction(kUplinkPacketLoss));
  states->encoder->OnReceivedUplinkPacketLossFraction(kUplinkPacketLoss);

  CheckEncoderRuntimeConfig(states->encoder.get(), config);
}

TEST(AudioEncoderOpusTest, InvokeAudioNetworkAdaptorOnReceivedUplinkBandwidth) {
  auto states = CreateCodec(2);
  states->encoder->EnableAudioNetworkAdaptor("", nullptr);

  auto config = CreateEncoderRuntimeConfig();
  EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
      .WillOnce(Return(config));

  // Since using mock audio network adaptor, any target audio bitrate is fine.
  constexpr int kTargetAudioBitrate = 30000;
  constexpr int64_t kProbingIntervalMs = 3000;
  EXPECT_CALL(*states->mock_audio_network_adaptor,
              SetTargetAudioBitrate(kTargetAudioBitrate));
  EXPECT_CALL(*states->mock_bitrate_smoother,
              SetTimeConstantMs(kProbingIntervalMs * 4));
  EXPECT_CALL(*states->mock_bitrate_smoother, AddSample(kTargetAudioBitrate));
  states->encoder->OnReceivedUplinkBandwidth(kTargetAudioBitrate,
                                             kProbingIntervalMs);

  CheckEncoderRuntimeConfig(states->encoder.get(), config);
}

TEST(AudioEncoderOpusTest, InvokeAudioNetworkAdaptorOnReceivedRtt) {
  auto states = CreateCodec(2);
  states->encoder->EnableAudioNetworkAdaptor("", nullptr);

  auto config = CreateEncoderRuntimeConfig();
  EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
      .WillOnce(Return(config));

  // Since using mock audio network adaptor, any rtt is fine.
  constexpr int kRtt = 30;
  EXPECT_CALL(*states->mock_audio_network_adaptor, SetRtt(kRtt));
  states->encoder->OnReceivedRtt(kRtt);

  CheckEncoderRuntimeConfig(states->encoder.get(), config);
}

TEST(AudioEncoderOpusTest, InvokeAudioNetworkAdaptorOnReceivedOverhead) {
  auto states = CreateCodec(2);
  states->encoder->EnableAudioNetworkAdaptor("", nullptr);

  auto config = CreateEncoderRuntimeConfig();
  EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
      .WillOnce(Return(config));

  // Since using mock audio network adaptor, any overhead is fine.
  constexpr size_t kOverhead = 64;
  EXPECT_CALL(*states->mock_audio_network_adaptor, SetOverhead(kOverhead));
  states->encoder->OnReceivedOverhead(kOverhead);

  CheckEncoderRuntimeConfig(states->encoder.get(), config);
}

TEST(AudioEncoderOpusTest,
     PacketLossFractionSmoothedOnSetUplinkPacketLossFraction) {
  auto states = CreateCodec(2);

  // The values are carefully chosen so that if no smoothing is made, the test
  // will fail.
  constexpr float kPacketLossFraction_1 = 0.02f;
  constexpr float kPacketLossFraction_2 = 0.198f;
  // |kSecondSampleTimeMs| is chosen to ease the calculation since
  // 0.9999 ^ 6931 = 0.5.
  constexpr int64_t kSecondSampleTimeMs = 6931;

  // First time, no filtering.
  states->encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_1);
  EXPECT_FLOAT_EQ(0.01f, states->encoder->packet_loss_rate());

  states->fake_clock->AdvanceTime(TimeDelta::ms(kSecondSampleTimeMs));
  states->encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_2);

  // Now the output of packet loss fraction smoother should be
  // (0.02 + 0.198) / 2 = 0.109, which reach the threshold for the optimized
  // packet loss rate to increase to 0.05. If no smoothing has been made, the
  // optimized packet loss rate should have been increase to 0.1.
  EXPECT_FLOAT_EQ(0.05f, states->encoder->packet_loss_rate());
}

TEST(AudioEncoderOpusTest, DoNotInvokeSetTargetBitrateIfOverheadUnknown) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-SendSideBwe-WithOverhead/Enabled/");

  auto states = CreateCodec(2);

  states->encoder->OnReceivedUplinkBandwidth(kDefaultOpusRate * 2,
                                             absl::nullopt);

  // Since |OnReceivedOverhead| has not been called, the codec bitrate should
  // not change.
  EXPECT_EQ(kDefaultOpusRate, states->encoder->GetTargetBitrate());
}

TEST(AudioEncoderOpusTest, OverheadRemovedFromTargetAudioBitrate) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-SendSideBwe-WithOverhead/Enabled/");

  auto states = CreateCodec(2);

  constexpr size_t kOverheadBytesPerPacket = 64;
  states->encoder->OnReceivedOverhead(kOverheadBytesPerPacket);

  constexpr int kTargetBitrateBps = 40000;
  states->encoder->OnReceivedUplinkBandwidth(kTargetBitrateBps, absl::nullopt);

  int packet_rate = rtc::CheckedDivExact(48000, kDefaultOpusPacSize);
  EXPECT_EQ(kTargetBitrateBps -
                8 * static_cast<int>(kOverheadBytesPerPacket) * packet_rate,
            states->encoder->GetTargetBitrate());
}

TEST(AudioEncoderOpusTest, BitrateBounded) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-SendSideBwe-WithOverhead/Enabled/");

  constexpr int kMinBitrateBps = 6000;
  constexpr int kMaxBitrateBps = 510000;

  auto states = CreateCodec(2);

  constexpr size_t kOverheadBytesPerPacket = 64;
  states->encoder->OnReceivedOverhead(kOverheadBytesPerPacket);

  int packet_rate = rtc::CheckedDivExact(48000, kDefaultOpusPacSize);

  // Set a target rate that is smaller than |kMinBitrateBps| when overhead is
  // subtracted. The eventual codec rate should be bounded by |kMinBitrateBps|.
  int target_bitrate =
      kOverheadBytesPerPacket * 8 * packet_rate + kMinBitrateBps - 1;
  states->encoder->OnReceivedUplinkBandwidth(target_bitrate, absl::nullopt);
  EXPECT_EQ(kMinBitrateBps, states->encoder->GetTargetBitrate());

  // Set a target rate that is greater than |kMaxBitrateBps| when overhead is
  // subtracted. The eventual codec rate should be bounded by |kMaxBitrateBps|.
  target_bitrate =
      kOverheadBytesPerPacket * 8 * packet_rate + kMaxBitrateBps + 1;
  states->encoder->OnReceivedUplinkBandwidth(target_bitrate, absl::nullopt);
  EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
}

TEST(AudioEncoderOpusTest, MinPacketLossRate) {
  constexpr float kDefaultMinPacketLossRate = 0.01;
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-OpusMinPacketLossRate/Enabled/");
    auto states = CreateCodec(1);
    EXPECT_EQ(kDefaultMinPacketLossRate, states->encoder->packet_loss_rate());
  }
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-OpusMinPacketLossRate/Enabled-200/");
    auto states = CreateCodec(1);
    EXPECT_EQ(kDefaultMinPacketLossRate, states->encoder->packet_loss_rate());
  }
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-OpusMinPacketLossRate/Enabled-50/");
    constexpr float kMinPacketLossRate = 0.5;
    auto states = CreateCodec(1);
    EXPECT_EQ(kMinPacketLossRate, states->encoder->packet_loss_rate());
  }
}

TEST(AudioEncoderOpusTest, NewPacketLossRateOptimizer) {
  {
    auto states = CreateCodec(1);
    auto optimizer = states->encoder->new_packet_loss_optimizer();
    EXPECT_EQ(nullptr, optimizer);
  }
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-NewOpusPacketLossRateOptimization/Enabled/");
    auto states = CreateCodec(1);
    auto optimizer = states->encoder->new_packet_loss_optimizer();
    ASSERT_NE(nullptr, optimizer);
    EXPECT_FLOAT_EQ(0.01, optimizer->min_packet_loss_rate());
    EXPECT_FLOAT_EQ(0.20, optimizer->max_packet_loss_rate());
    EXPECT_FLOAT_EQ(1.00, optimizer->slope());
  }
  {
    test::ScopedFieldTrials override_field_trials(
        "WebRTC-Audio-NewOpusPacketLossRateOptimization/Enabled-2-50-0.7/");
    auto states = CreateCodec(1);
    auto optimizer = states->encoder->new_packet_loss_optimizer();
    ASSERT_NE(nullptr, optimizer);
    EXPECT_FLOAT_EQ(0.02, optimizer->min_packet_loss_rate());
    EXPECT_FLOAT_EQ(0.50, optimizer->max_packet_loss_rate());
    EXPECT_FLOAT_EQ(0.70, optimizer->slope());
  }
}

// Verifies that the complexity adaptation in the config works as intended.
TEST(AudioEncoderOpusTest, ConfigComplexityAdaptation) {
  AudioEncoderOpusConfig config;
  config.low_rate_complexity = 8;
  config.complexity = 6;

  // Bitrate within hysteresis window. Expect empty output.
  config.bitrate_bps = 12500;
  EXPECT_EQ(absl::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));

  // Bitrate below hysteresis window. Expect higher complexity.
  config.bitrate_bps = 10999;
  EXPECT_EQ(8, AudioEncoderOpusImpl::GetNewComplexity(config));

  // Bitrate within hysteresis window. Expect empty output.
  config.bitrate_bps = 12500;
  EXPECT_EQ(absl::nullopt, AudioEncoderOpusImpl::GetNewComplexity(config));

  // Bitrate above hysteresis window. Expect lower complexity.
  config.bitrate_bps = 14001;
  EXPECT_EQ(6, AudioEncoderOpusImpl::GetNewComplexity(config));
}

// Verifies that the bandwidth adaptation in the config works as intended.
TEST(AudioEncoderOpusTest, ConfigBandwidthAdaptation) {
  AudioEncoderOpusConfig config;
  // Sample rate of Opus.
  constexpr size_t kOpusRateKhz = 48;
  std::vector<int16_t> silence(
      kOpusRateKhz * config.frame_size_ms * config.num_channels, 0);
  constexpr size_t kMaxBytes = 1000;
  uint8_t bitstream[kMaxBytes];

  OpusEncInst* inst;
  EXPECT_EQ(0, WebRtcOpus_EncoderCreate(
                   &inst, config.num_channels,
                   config.application ==
                           AudioEncoderOpusConfig::ApplicationMode::kVoip
                       ? 0
                       : 1));

  // Bitrate below minmum wideband. Expect narrowband.
  config.bitrate_bps = absl::optional<int>(7999);
  auto bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
  EXPECT_EQ(absl::optional<int>(OPUS_BANDWIDTH_NARROWBAND), bandwidth);
  WebRtcOpus_SetBandwidth(inst, *bandwidth);
  // It is necessary to encode here because Opus has some logic in the encoder
  // that goes from the user-set bandwidth to the used and returned one.
  WebRtcOpus_Encode(inst, silence.data(),
                    rtc::CheckedDivExact(silence.size(), config.num_channels),
                    kMaxBytes, bitstream);

  // Bitrate not yet above maximum narrowband. Expect empty.
  config.bitrate_bps = absl::optional<int>(9000);
  bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
  EXPECT_EQ(absl::optional<int>(), bandwidth);

  // Bitrate above maximum narrowband. Expect wideband.
  config.bitrate_bps = absl::optional<int>(9001);
  bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
  EXPECT_EQ(absl::optional<int>(OPUS_BANDWIDTH_WIDEBAND), bandwidth);
  WebRtcOpus_SetBandwidth(inst, *bandwidth);
  // It is necessary to encode here because Opus has some logic in the encoder
  // that goes from the user-set bandwidth to the used and returned one.
  WebRtcOpus_Encode(inst, silence.data(),
                    rtc::CheckedDivExact(silence.size(), config.num_channels),
                    kMaxBytes, bitstream);

  // Bitrate not yet below minimum wideband. Expect empty.
  config.bitrate_bps = absl::optional<int>(8000);
  bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
  EXPECT_EQ(absl::optional<int>(), bandwidth);

  // Bitrate above automatic threshold. Expect automatic.
  config.bitrate_bps = absl::optional<int>(12001);
  bandwidth = AudioEncoderOpusImpl::GetNewBandwidth(config, inst);
  EXPECT_EQ(absl::optional<int>(OPUS_AUTO), bandwidth);

  EXPECT_EQ(0, WebRtcOpus_EncoderFree(inst));
}

TEST(AudioEncoderOpusTest, EmptyConfigDoesNotAffectEncoderSettings) {
  auto states = CreateCodec(2);
  states->encoder->EnableAudioNetworkAdaptor("", nullptr);

  auto config = CreateEncoderRuntimeConfig();
  AudioEncoderRuntimeConfig empty_config;

  EXPECT_CALL(*states->mock_audio_network_adaptor, GetEncoderRuntimeConfig())
      .WillOnce(Return(config))
      .WillOnce(Return(empty_config));

  constexpr size_t kOverhead = 64;
  EXPECT_CALL(*states->mock_audio_network_adaptor, SetOverhead(kOverhead))
      .Times(2);
  states->encoder->OnReceivedOverhead(kOverhead);
  states->encoder->OnReceivedOverhead(kOverhead);

  CheckEncoderRuntimeConfig(states->encoder.get(), config);
}

TEST(AudioEncoderOpusTest, UpdateUplinkBandwidthInAudioNetworkAdaptor) {
  auto states = CreateCodec(2);
  states->encoder->EnableAudioNetworkAdaptor("", nullptr);
  std::array<int16_t, 480 * 2> audio;
  audio.fill(0);
  rtc::Buffer encoded;
  EXPECT_CALL(*states->mock_bitrate_smoother, GetAverage())
      .WillOnce(Return(50000));
  EXPECT_CALL(*states->mock_audio_network_adaptor, SetUplinkBandwidth(50000));
  states->encoder->Encode(
      0, rtc::ArrayView<const int16_t>(audio.data(), audio.size()), &encoded);

  // Repeat update uplink bandwidth tests.
  for (int i = 0; i < 5; i++) {
    // Don't update till it is time to update again.
    states->fake_clock->AdvanceTime(
        TimeDelta::ms(states->config.uplink_bandwidth_update_interval_ms - 1));
    states->encoder->Encode(
        0, rtc::ArrayView<const int16_t>(audio.data(), audio.size()), &encoded);

    // Update when it is time to update.
    EXPECT_CALL(*states->mock_bitrate_smoother, GetAverage())
        .WillOnce(Return(40000));
    EXPECT_CALL(*states->mock_audio_network_adaptor, SetUplinkBandwidth(40000));
    states->fake_clock->AdvanceTime(TimeDelta::ms(1));
    states->encoder->Encode(
        0, rtc::ArrayView<const int16_t>(audio.data(), audio.size()), &encoded);
  }
}

TEST(AudioEncoderOpusTest, EncodeAtMinBitrate) {
  auto states = CreateCodec(1);
  constexpr int kNumPacketsToEncode = 2;
  auto audio_frames =
      Create10msAudioBlocks(states->encoder, kNumPacketsToEncode * 20);
  ASSERT_TRUE(audio_frames) << "Create10msAudioBlocks failed";
  rtc::Buffer encoded;
  uint32_t rtp_timestamp = 12345;  // Just a number not important to this test.

  states->encoder->OnReceivedUplinkBandwidth(0, absl::nullopt);
  for (int packet_index = 0; packet_index < kNumPacketsToEncode;
       packet_index++) {
    // Make sure we are not encoding before we have enough data for
    // a 20ms packet.
    for (int index = 0; index < 1; index++) {
      states->encoder->Encode(rtp_timestamp, audio_frames->GetNextBlock(),
                              &encoded);
      EXPECT_EQ(0u, encoded.size());
    }

    // Should encode now.
    states->encoder->Encode(rtp_timestamp, audio_frames->GetNextBlock(),
                            &encoded);
    EXPECT_GT(encoded.size(), 0u);
    encoded.Clear();
  }
}

TEST(AudioEncoderOpusTest, TestConfigDefaults) {
  const auto config_opt = AudioEncoderOpus::SdpToConfig({"opus", 48000, 2});
  ASSERT_TRUE(config_opt);
  EXPECT_EQ(48000, config_opt->max_playback_rate_hz);
  EXPECT_EQ(1u, config_opt->num_channels);
  EXPECT_FALSE(config_opt->fec_enabled);
  EXPECT_FALSE(config_opt->dtx_enabled);
  EXPECT_EQ(20, config_opt->frame_size_ms);
}

TEST(AudioEncoderOpusTest, TestConfigFromParams) {
  const auto config1 = CreateConfigWithParameters({{"stereo", "0"}});
  EXPECT_EQ(1U, config1.num_channels);

  const auto config2 = CreateConfigWithParameters({{"stereo", "1"}});
  EXPECT_EQ(2U, config2.num_channels);

  const auto config3 = CreateConfigWithParameters({{"useinbandfec", "0"}});
  EXPECT_FALSE(config3.fec_enabled);

  const auto config4 = CreateConfigWithParameters({{"useinbandfec", "1"}});
  EXPECT_TRUE(config4.fec_enabled);

  const auto config5 = CreateConfigWithParameters({{"usedtx", "0"}});
  EXPECT_FALSE(config5.dtx_enabled);

  const auto config6 = CreateConfigWithParameters({{"usedtx", "1"}});
  EXPECT_TRUE(config6.dtx_enabled);

  const auto config7 = CreateConfigWithParameters({{"cbr", "0"}});
  EXPECT_FALSE(config7.cbr_enabled);

  const auto config8 = CreateConfigWithParameters({{"cbr", "1"}});
  EXPECT_TRUE(config8.cbr_enabled);

  const auto config9 =
      CreateConfigWithParameters({{"maxplaybackrate", "12345"}});
  EXPECT_EQ(12345, config9.max_playback_rate_hz);

  const auto config10 =
      CreateConfigWithParameters({{"maxaveragebitrate", "96000"}});
  EXPECT_EQ(96000, config10.bitrate_bps);

  const auto config11 = CreateConfigWithParameters({{"maxptime", "40"}});
  for (int frame_length : config11.supported_frame_lengths_ms) {
    EXPECT_LE(frame_length, 40);
  }

  const auto config12 = CreateConfigWithParameters({{"minptime", "40"}});
  for (int frame_length : config12.supported_frame_lengths_ms) {
    EXPECT_GE(frame_length, 40);
  }

  const auto config13 = CreateConfigWithParameters({{"ptime", "40"}});
  EXPECT_EQ(40, config13.frame_size_ms);

  constexpr int kMinSupportedFrameLength = 10;
  constexpr int kMaxSupportedFrameLength =
      WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60;

  const auto config14 = CreateConfigWithParameters({{"ptime", "1"}});
  EXPECT_EQ(kMinSupportedFrameLength, config14.frame_size_ms);

  const auto config15 = CreateConfigWithParameters({{"ptime", "2000"}});
  EXPECT_EQ(kMaxSupportedFrameLength, config15.frame_size_ms);
}

TEST(AudioEncoderOpusTest, TestConfigFromInvalidParams) {
  const webrtc::SdpAudioFormat format("opus", 48000, 2);
  const auto default_config = *AudioEncoderOpus::SdpToConfig(format);
#if WEBRTC_OPUS_SUPPORT_120MS_PTIME
  const std::vector<int> default_supported_frame_lengths_ms({20, 60, 120});
#else
  const std::vector<int> default_supported_frame_lengths_ms({20, 60});
#endif

  AudioEncoderOpusConfig config;
  config = CreateConfigWithParameters({{"stereo", "invalid"}});
  EXPECT_EQ(default_config.num_channels, config.num_channels);

  config = CreateConfigWithParameters({{"useinbandfec", "invalid"}});
  EXPECT_EQ(default_config.fec_enabled, config.fec_enabled);

  config = CreateConfigWithParameters({{"usedtx", "invalid"}});
  EXPECT_EQ(default_config.dtx_enabled, config.dtx_enabled);

  config = CreateConfigWithParameters({{"cbr", "invalid"}});
  EXPECT_EQ(default_config.dtx_enabled, config.dtx_enabled);

  config = CreateConfigWithParameters({{"maxplaybackrate", "0"}});
  EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz);

  config = CreateConfigWithParameters({{"maxplaybackrate", "-23"}});
  EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz);

  config = CreateConfigWithParameters({{"maxplaybackrate", "not a number!"}});
  EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz);

  config = CreateConfigWithParameters({{"maxaveragebitrate", "0"}});
  EXPECT_EQ(6000, config.bitrate_bps);

  config = CreateConfigWithParameters({{"maxaveragebitrate", "-1000"}});
  EXPECT_EQ(6000, config.bitrate_bps);

  config = CreateConfigWithParameters({{"maxaveragebitrate", "1024000"}});
  EXPECT_EQ(510000, config.bitrate_bps);

  config = CreateConfigWithParameters({{"maxaveragebitrate", "not a number!"}});
  EXPECT_EQ(default_config.bitrate_bps, config.bitrate_bps);

  config = CreateConfigWithParameters({{"maxptime", "invalid"}});
  EXPECT_EQ(default_supported_frame_lengths_ms,
            config.supported_frame_lengths_ms);

  config = CreateConfigWithParameters({{"minptime", "invalid"}});
  EXPECT_EQ(default_supported_frame_lengths_ms,
            config.supported_frame_lengths_ms);

  config = CreateConfigWithParameters({{"ptime", "invalid"}});
  EXPECT_EQ(default_supported_frame_lengths_ms,
            config.supported_frame_lengths_ms);
}

// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
// Also test that the "maxaveragebitrate" can't be set to values outside the
// range of 6000 and 510000
TEST(AudioEncoderOpusTest, SetSendCodecOpusMaxAverageBitrate) {
  // Ignore if less than 6000.
  const auto config1 = AudioEncoderOpus::SdpToConfig(
      {"opus", 48000, 2, {{"maxaveragebitrate", "5999"}}});
  EXPECT_EQ(6000, config1->bitrate_bps);

  // Ignore if larger than 510000.
  const auto config2 = AudioEncoderOpus::SdpToConfig(
      {"opus", 48000, 2, {{"maxaveragebitrate", "510001"}}});
  EXPECT_EQ(510000, config2->bitrate_bps);

  const auto config3 = AudioEncoderOpus::SdpToConfig(
      {"opus", 48000, 2, {{"maxaveragebitrate", "200000"}}});
  EXPECT_EQ(200000, config3->bitrate_bps);
}

// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
TEST(AudioEncoderOpusTest, SetMaxPlaybackRateNb) {
  auto config = CreateConfigWithParameters({{"maxplaybackrate", "8000"}});
  EXPECT_EQ(8000, config.max_playback_rate_hz);
  EXPECT_EQ(12000, config.bitrate_bps);

  config = CreateConfigWithParameters(
      {{"maxplaybackrate", "8000"}, {"stereo", "1"}});
  EXPECT_EQ(8000, config.max_playback_rate_hz);
  EXPECT_EQ(24000, config.bitrate_bps);
}

// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
TEST(AudioEncoderOpusTest, SetMaxPlaybackRateMb) {
  auto config = CreateConfigWithParameters({{"maxplaybackrate", "8001"}});
  EXPECT_EQ(8001, config.max_playback_rate_hz);
  EXPECT_EQ(20000, config.bitrate_bps);

  config = CreateConfigWithParameters(
      {{"maxplaybackrate", "8001"}, {"stereo", "1"}});
  EXPECT_EQ(8001, config.max_playback_rate_hz);
  EXPECT_EQ(40000, config.bitrate_bps);
}

// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
TEST(AudioEncoderOpusTest, SetMaxPlaybackRateWb) {
  auto config = CreateConfigWithParameters({{"maxplaybackrate", "12001"}});
  EXPECT_EQ(12001, config.max_playback_rate_hz);
  EXPECT_EQ(20000, config.bitrate_bps);

  config = CreateConfigWithParameters(
      {{"maxplaybackrate", "12001"}, {"stereo", "1"}});
  EXPECT_EQ(12001, config.max_playback_rate_hz);
  EXPECT_EQ(40000, config.bitrate_bps);
}

// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
TEST(AudioEncoderOpusTest, SetMaxPlaybackRateSwb) {
  auto config = CreateConfigWithParameters({{"maxplaybackrate", "16001"}});
  EXPECT_EQ(16001, config.max_playback_rate_hz);
  EXPECT_EQ(32000, config.bitrate_bps);

  config = CreateConfigWithParameters(
      {{"maxplaybackrate", "16001"}, {"stereo", "1"}});
  EXPECT_EQ(16001, config.max_playback_rate_hz);
  EXPECT_EQ(64000, config.bitrate_bps);
}

// Test 24000 < maxplaybackrate triggers Opus full band mode.
TEST(AudioEncoderOpusTest, SetMaxPlaybackRateFb) {
  auto config = CreateConfigWithParameters({{"maxplaybackrate", "24001"}});
  EXPECT_EQ(24001, config.max_playback_rate_hz);
  EXPECT_EQ(32000, config.bitrate_bps);

  config = CreateConfigWithParameters(
      {{"maxplaybackrate", "24001"}, {"stereo", "1"}});
  EXPECT_EQ(24001, config.max_playback_rate_hz);
  EXPECT_EQ(64000, config.bitrate_bps);
}

TEST(AudioEncoderOpusTest, OpusFlagDtxAsNonSpeech) {
  // Create encoder with DTX enabled.
  AudioEncoderOpusConfig config;
  config.dtx_enabled = true;
  constexpr int payload_type = 17;
  const auto encoder = AudioEncoderOpus::MakeAudioEncoder(config, payload_type);

  // Open file containing speech and silence.
  const std::string kInputFileName =
      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
  test::AudioLoop audio_loop;
  // Use the file as if it were sampled at 48 kHz.
  constexpr int kSampleRateHz = 48000;
  EXPECT_EQ(kSampleRateHz, encoder->SampleRateHz());
  constexpr size_t kMaxLoopLengthSamples =
      kSampleRateHz * 10;  // Max 10 second loop.
  constexpr size_t kInputBlockSizeSamples =
      10 * kSampleRateHz / 1000;  // 10 ms.
  EXPECT_TRUE(audio_loop.Init(kInputFileName, kMaxLoopLengthSamples,
                              kInputBlockSizeSamples));

  // Encode.
  AudioEncoder::EncodedInfo info;
  rtc::Buffer encoded(500);
  int nonspeech_frames = 0;
  int max_nonspeech_frames = 0;
  int dtx_frames = 0;
  int max_dtx_frames = 0;
  uint32_t rtp_timestamp = 0u;
  for (size_t i = 0; i < 500; ++i) {
    encoded.Clear();

    // Every second call to the encoder will generate an Opus packet.
    for (int j = 0; j < 2; j++) {
      info =
          encoder->Encode(rtp_timestamp, audio_loop.GetNextBlock(), &encoded);
      rtp_timestamp += kInputBlockSizeSamples;
    }

    // Bookkeeping of number of DTX frames.
    if (info.encoded_bytes <= 2) {
      ++dtx_frames;
    } else {
      if (dtx_frames > max_dtx_frames)
        max_dtx_frames = dtx_frames;
      dtx_frames = 0;
    }

    // Bookkeeping of number of non-speech frames.
    if (info.speech == 0) {
      ++nonspeech_frames;
    } else {
      if (nonspeech_frames > max_nonspeech_frames)
        max_nonspeech_frames = nonspeech_frames;
      nonspeech_frames = 0;
    }
  }

  // Maximum number of consecutive non-speech packets should exceed 20.
  EXPECT_GT(max_nonspeech_frames, 20);
}

}  // namespace webrtc
