1 /*
2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
12 
13 #include <memory>
14 
15 #include "test/gtest.h"
16 
17 namespace webrtc {
18 
TEST(AudioDecoderFactoryTest,CreateUnknownDecoder)19 TEST(AudioDecoderFactoryTest, CreateUnknownDecoder) {
20   rtc::scoped_refptr<AudioDecoderFactory> adf =
21       CreateBuiltinAudioDecoderFactory();
22   ASSERT_TRUE(adf);
23   EXPECT_FALSE(
24       adf->MakeAudioDecoder(SdpAudioFormat("rey", 8000, 1), absl::nullopt));
25 }
26 
TEST(AudioDecoderFactoryTest,CreatePcmu)27 TEST(AudioDecoderFactoryTest, CreatePcmu) {
28   rtc::scoped_refptr<AudioDecoderFactory> adf =
29       CreateBuiltinAudioDecoderFactory();
30   ASSERT_TRUE(adf);
31   // PCMu supports 8 kHz, and any number of channels.
32   EXPECT_FALSE(
33       adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 0), absl::nullopt));
34   EXPECT_TRUE(
35       adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 1), absl::nullopt));
36   EXPECT_TRUE(
37       adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 2), absl::nullopt));
38   EXPECT_TRUE(
39       adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 8000, 3), absl::nullopt));
40   EXPECT_FALSE(
41       adf->MakeAudioDecoder(SdpAudioFormat("pcmu", 16000, 1), absl::nullopt));
42 }
43 
TEST(AudioDecoderFactoryTest,CreatePcma)44 TEST(AudioDecoderFactoryTest, CreatePcma) {
45   rtc::scoped_refptr<AudioDecoderFactory> adf =
46       CreateBuiltinAudioDecoderFactory();
47   ASSERT_TRUE(adf);
48   // PCMa supports 8 kHz, and any number of channels.
49   EXPECT_FALSE(
50       adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 0), absl::nullopt));
51   EXPECT_TRUE(
52       adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 1), absl::nullopt));
53   EXPECT_TRUE(
54       adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 2), absl::nullopt));
55   EXPECT_TRUE(
56       adf->MakeAudioDecoder(SdpAudioFormat("pcma", 8000, 3), absl::nullopt));
57   EXPECT_FALSE(
58       adf->MakeAudioDecoder(SdpAudioFormat("pcma", 16000, 1), absl::nullopt));
59 }
60 
TEST(AudioDecoderFactoryTest,CreateIlbc)61 TEST(AudioDecoderFactoryTest, CreateIlbc) {
62   rtc::scoped_refptr<AudioDecoderFactory> adf =
63       CreateBuiltinAudioDecoderFactory();
64   ASSERT_TRUE(adf);
65   // iLBC supports 8 kHz, 1 channel.
66   EXPECT_FALSE(
67       adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 0), absl::nullopt));
68 #ifdef WEBRTC_CODEC_ILBC
69   EXPECT_TRUE(
70       adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 1), absl::nullopt));
71 #endif
72   EXPECT_FALSE(
73       adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 8000, 2), absl::nullopt));
74   EXPECT_FALSE(
75       adf->MakeAudioDecoder(SdpAudioFormat("ilbc", 16000, 1), absl::nullopt));
76 }
77 
TEST(AudioDecoderFactoryTest,CreateL16)78 TEST(AudioDecoderFactoryTest, CreateL16) {
79   rtc::scoped_refptr<AudioDecoderFactory> adf =
80       CreateBuiltinAudioDecoderFactory();
81   ASSERT_TRUE(adf);
82   // L16 supports any clock rate and any number of channels up to 24.
83   const int clockrates[] = {8000, 16000, 32000, 48000};
84   const int num_channels[] = {1, 2, 3, 24};
85   for (int clockrate : clockrates) {
86     EXPECT_FALSE(adf->MakeAudioDecoder(SdpAudioFormat("l16", clockrate, 0),
87                                        absl::nullopt));
88     for (int channels : num_channels) {
89       EXPECT_TRUE(adf->MakeAudioDecoder(
90           SdpAudioFormat("l16", clockrate, channels), absl::nullopt));
91     }
92   }
93 }
94 
95 // Tests that using more channels than the maximum does not work
TEST(AudioDecoderFactoryTest,MaxNrOfChannels)96 TEST(AudioDecoderFactoryTest, MaxNrOfChannels) {
97   rtc::scoped_refptr<AudioDecoderFactory> adf =
98       CreateBuiltinAudioDecoderFactory();
99   std::vector<std::string> codecs = {
100 #ifdef WEBRTC_CODEC_OPUS
101     "opus",
102 #endif
103 #ifdef WEBRTC_CODEC_ILBC
104     "ilbc",
105 #endif
106     "pcmu",
107     "pcma",
108     "l16",
109     "G722",
110     "G711",
111   };
112 
113   for (auto codec : codecs) {
114     EXPECT_FALSE(adf->MakeAudioDecoder(
115         SdpAudioFormat(codec, 32000, AudioDecoder::kMaxNumberOfChannels + 1),
116         absl::nullopt));
117   }
118 }
119 
TEST(AudioDecoderFactoryTest,CreateG722)120 TEST(AudioDecoderFactoryTest, CreateG722) {
121   rtc::scoped_refptr<AudioDecoderFactory> adf =
122       CreateBuiltinAudioDecoderFactory();
123   ASSERT_TRUE(adf);
124   // g722 supports 8 kHz, 1-2 channels.
125   EXPECT_FALSE(
126       adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 0), absl::nullopt));
127   EXPECT_TRUE(
128       adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 1), absl::nullopt));
129   EXPECT_TRUE(
130       adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 2), absl::nullopt));
131   EXPECT_FALSE(
132       adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 3), absl::nullopt));
133   EXPECT_FALSE(
134       adf->MakeAudioDecoder(SdpAudioFormat("g722", 16000, 1), absl::nullopt));
135   EXPECT_FALSE(
136       adf->MakeAudioDecoder(SdpAudioFormat("g722", 32000, 1), absl::nullopt));
137 
138   // g722 actually uses a 16 kHz sample rate instead of the nominal 8 kHz.
139   std::unique_ptr<AudioDecoder> dec =
140       adf->MakeAudioDecoder(SdpAudioFormat("g722", 8000, 1), absl::nullopt);
141   EXPECT_EQ(16000, dec->SampleRateHz());
142 }
143 
TEST(AudioDecoderFactoryTest,CreateOpus)144 TEST(AudioDecoderFactoryTest, CreateOpus) {
145   rtc::scoped_refptr<AudioDecoderFactory> adf =
146       CreateBuiltinAudioDecoderFactory();
147   ASSERT_TRUE(adf);
148   // Opus supports 48 kHz, 2 channels, and wants a "stereo" parameter whose
149   // value is either "0" or "1".
150   for (int hz : {8000, 16000, 32000, 48000}) {
151     for (int channels : {0, 1, 2, 3}) {
152       for (std::string stereo : {"XX", "0", "1", "2"}) {
153         SdpAudioFormat::Parameters params;
154         if (stereo != "XX") {
155           params["stereo"] = stereo;
156         }
157         const bool good = (hz == 48000 && channels == 2 &&
158                            (stereo == "XX" || stereo == "0" || stereo == "1"));
159         EXPECT_EQ(good,
160                   static_cast<bool>(adf->MakeAudioDecoder(
161                       SdpAudioFormat("opus", hz, channels, std::move(params)),
162                       absl::nullopt)));
163       }
164     }
165   }
166 }
167 
168 }  // namespace webrtc
169