/*
 *  Copyright (c) 2016 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 "api/audio_codecs/builtin_audio_decoder_factory.h"

#include <memory>

#include "test/gtest.h"

namespace webrtc {

TEST(AudioDecoderFactoryTest, CreateUnknownDecoder) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("rey", 8000, 1), absl::nullopt));
}

TEST(AudioDecoderFactoryTest, CreatePcmu) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // PCMu supports 8 kHz, and any number of channels.
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 0), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 1), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 2), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 3), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 16000, 1), absl::nullopt));
}

TEST(AudioDecoderFactoryTest, CreatePcma) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // PCMa supports 8 kHz, and any number of channels.
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 0), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 1), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 2), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 3), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("pcma", 16000, 1), absl::nullopt));
}

TEST(AudioDecoderFactoryTest, CreateIlbc) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // iLBC supports 8 kHz, 1 channel.
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 0), absl::nullopt));
#ifdef WEBRTC_CODEC_ILBC
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 1), absl::nullopt));
#endif
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 2), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 16000, 1), absl::nullopt));
}

TEST(AudioDecoderFactoryTest, CreateIsac) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // iSAC supports 16 kHz, 1 channel. The float implementation additionally
  // supports 32 kHz, 1 channel.
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 16000, 0), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 16000, 1), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 16000, 2), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 8000, 1), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 48000, 1), absl::nullopt));
#ifdef WEBRTC_ARCH_ARM
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 32000, 1), absl::nullopt));
#else
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("isac", 32000, 1), absl::nullopt));
#endif
}

TEST(AudioDecoderFactoryTest, CreateL16) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // L16 supports any clock rate, any number of channels.
  const int clockrates[] = {8000, 16000, 32000, 48000};
  const int num_channels[] = {1, 2, 3, 4711};
  for (int clockrate : clockrates) {
    EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("l16", clockrate, 0),
                                       absl::nullopt));
    for (int channels : num_channels) {
      EXPECT_TRUE(adf->MakeAudioDecoder(
          SdpAudioFormat("l16", clockrate, channels), absl::nullopt));
    }
  }
}

TEST(AudioDecoderFactoryTest, CreateG722) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // g722 supports 8 kHz, 1-2 channels.
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 0), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 1), absl::nullopt));
  EXPECT_TRUE(
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 2), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 3), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 16000, 1), absl::nullopt));
  EXPECT_FALSE(
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 32000, 1), absl::nullopt));

  // g722 actually uses a 16 kHz sample rate instead of the nominal 8 kHz.
  std::unique_ptr<AudioDecoder> dec =
      adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 1), absl::nullopt);
  EXPECT_EQ(16000, dec->SampleRateHz());
}

TEST(AudioDecoderFactoryTest, CreateOpus) {
  rtc::scoped_refptr<AudioDecoderFactory> adf =
      CreateBuiltinAudioDecoderFactory();
  ASSERT_TRUE(adf);
  // Opus supports 48 kHz, 2 channels, and wants a "stereo" parameter whose
  // value is either "0" or "1".
  for (int hz : {8000, 16000, 32000, 48000}) {
    for (int channels : {0, 1, 2, 3}) {
      for (std::string stereo : {"XX", "0", "1", "2"}) {
        std::map<std::string, std::string> params;
        if (stereo != "XX") {
          params["stereo"] = stereo;
        }
        const bool good = (hz == 48000 && channels == 2 &&
                           (stereo == "XX" || stereo == "0" || stereo == "1"));
        EXPECT_EQ(good,
                  static_cast<bool>(adf->MakeAudioDecoder(
                      SdpAudioFormat("opus", hz, channels, std::move(params)),
                      absl::nullopt)));
      }
    }
  }
}

}  // namespace webrtc
