1 /*
2 * Copyright (c) 2017 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/audio_encoder_factory_template.h"
12
13 #include <memory>
14
15 #include "api/audio_codecs/L16/audio_encoder_L16.h"
16 #include "api/audio_codecs/g711/audio_encoder_g711.h"
17 #include "api/audio_codecs/g722/audio_encoder_g722.h"
18 #include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
19 #include "api/audio_codecs/opus/audio_encoder_opus.h"
20 #include "test/gmock.h"
21 #include "test/gtest.h"
22 #include "test/mock_audio_encoder.h"
23 #include "test/scoped_key_value_config.h"
24
25 namespace webrtc {
26
27 namespace {
28
29 struct BogusParams {
AudioFormatwebrtc::__anon59c6d61c0111::BogusParams30 static SdpAudioFormat AudioFormat() { return {"bogus", 8000, 1}; }
CodecInfowebrtc::__anon59c6d61c0111::BogusParams31 static AudioCodecInfo CodecInfo() { return {8000, 1, 12345}; }
32 };
33
34 struct ShamParams {
AudioFormatwebrtc::__anon59c6d61c0111::ShamParams35 static SdpAudioFormat AudioFormat() {
36 return {"sham", 16000, 2, {{"param", "value"}}};
37 }
CodecInfowebrtc::__anon59c6d61c0111::ShamParams38 static AudioCodecInfo CodecInfo() { return {16000, 2, 23456}; }
39 };
40
41 template <typename Params>
42 struct AudioEncoderFakeApi {
43 struct Config {
44 SdpAudioFormat audio_format;
45 };
46
SdpToConfigwebrtc::__anon59c6d61c0111::AudioEncoderFakeApi47 static absl::optional<Config> SdpToConfig(
48 const SdpAudioFormat& audio_format) {
49 if (Params::AudioFormat() == audio_format) {
50 Config config = {audio_format};
51 return config;
52 } else {
53 return absl::nullopt;
54 }
55 }
56
AppendSupportedEncoderswebrtc::__anon59c6d61c0111::AudioEncoderFakeApi57 static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
58 specs->push_back({Params::AudioFormat(), Params::CodecInfo()});
59 }
60
QueryAudioEncoderwebrtc::__anon59c6d61c0111::AudioEncoderFakeApi61 static AudioCodecInfo QueryAudioEncoder(const Config&) {
62 return Params::CodecInfo();
63 }
64
MakeAudioEncoderwebrtc::__anon59c6d61c0111::AudioEncoderFakeApi65 static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
66 const Config&,
67 int payload_type,
68 absl::optional<AudioCodecPairId> /*codec_pair_id*/ = absl::nullopt) {
69 auto enc = std::make_unique<testing::StrictMock<MockAudioEncoder>>();
70 EXPECT_CALL(*enc, SampleRateHz())
71 .WillOnce(::testing::Return(Params::CodecInfo().sample_rate_hz));
72 return std::move(enc);
73 }
74 };
75
76 } // namespace
77
TEST(AudioEncoderFactoryTemplateTest,NoEncoderTypes)78 TEST(AudioEncoderFactoryTemplateTest, NoEncoderTypes) {
79 test::ScopedKeyValueConfig field_trials;
80 rtc::scoped_refptr<AudioEncoderFactory> factory(
81 rtc::make_ref_counted<
82 audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>(
83 &field_trials));
84 EXPECT_THAT(factory->GetSupportedEncoders(), ::testing::IsEmpty());
85 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
86 EXPECT_EQ(nullptr,
87 factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
88 }
89
TEST(AudioEncoderFactoryTemplateTest,OneEncoderType)90 TEST(AudioEncoderFactoryTemplateTest, OneEncoderType) {
91 auto factory = CreateAudioEncoderFactory<AudioEncoderFakeApi<BogusParams>>();
92 EXPECT_THAT(factory->GetSupportedEncoders(),
93 ::testing::ElementsAre(
94 AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}}));
95 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
96 EXPECT_EQ(AudioCodecInfo(8000, 1, 12345),
97 factory->QueryAudioEncoder({"bogus", 8000, 1}));
98 EXPECT_EQ(nullptr,
99 factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
100 auto enc = factory->MakeAudioEncoder(17, {"bogus", 8000, 1}, absl::nullopt);
101 ASSERT_NE(nullptr, enc);
102 EXPECT_EQ(8000, enc->SampleRateHz());
103 }
104
TEST(AudioEncoderFactoryTemplateTest,TwoEncoderTypes)105 TEST(AudioEncoderFactoryTemplateTest, TwoEncoderTypes) {
106 auto factory = CreateAudioEncoderFactory<AudioEncoderFakeApi<BogusParams>,
107 AudioEncoderFakeApi<ShamParams>>();
108 EXPECT_THAT(factory->GetSupportedEncoders(),
109 ::testing::ElementsAre(
110 AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}},
111 AudioCodecSpec{{"sham", 16000, 2, {{"param", "value"}}},
112 {16000, 2, 23456}}));
113 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
114 EXPECT_EQ(AudioCodecInfo(8000, 1, 12345),
115 factory->QueryAudioEncoder({"bogus", 8000, 1}));
116 EXPECT_EQ(
117 AudioCodecInfo(16000, 2, 23456),
118 factory->QueryAudioEncoder({"sham", 16000, 2, {{"param", "value"}}}));
119 EXPECT_EQ(nullptr,
120 factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
121 auto enc1 = factory->MakeAudioEncoder(17, {"bogus", 8000, 1}, absl::nullopt);
122 ASSERT_NE(nullptr, enc1);
123 EXPECT_EQ(8000, enc1->SampleRateHz());
124 EXPECT_EQ(nullptr,
125 factory->MakeAudioEncoder(17, {"sham", 16000, 2}, absl::nullopt));
126 auto enc2 = factory->MakeAudioEncoder(
127 17, {"sham", 16000, 2, {{"param", "value"}}}, absl::nullopt);
128 ASSERT_NE(nullptr, enc2);
129 EXPECT_EQ(16000, enc2->SampleRateHz());
130 }
131
TEST(AudioEncoderFactoryTemplateTest,G711)132 TEST(AudioEncoderFactoryTemplateTest, G711) {
133 auto factory = CreateAudioEncoderFactory<AudioEncoderG711>();
134 EXPECT_THAT(factory->GetSupportedEncoders(),
135 ::testing::ElementsAre(
136 AudioCodecSpec{{"PCMU", 8000, 1}, {8000, 1, 64000}},
137 AudioCodecSpec{{"PCMA", 8000, 1}, {8000, 1, 64000}}));
138 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"PCMA", 16000, 1}));
139 EXPECT_EQ(AudioCodecInfo(8000, 1, 64000),
140 factory->QueryAudioEncoder({"PCMA", 8000, 1}));
141 EXPECT_EQ(nullptr,
142 factory->MakeAudioEncoder(17, {"PCMU", 16000, 1}, absl::nullopt));
143 auto enc1 = factory->MakeAudioEncoder(17, {"PCMU", 8000, 1}, absl::nullopt);
144 ASSERT_NE(nullptr, enc1);
145 EXPECT_EQ(8000, enc1->SampleRateHz());
146 auto enc2 = factory->MakeAudioEncoder(17, {"PCMA", 8000, 1}, absl::nullopt);
147 ASSERT_NE(nullptr, enc2);
148 EXPECT_EQ(8000, enc2->SampleRateHz());
149 }
150
TEST(AudioEncoderFactoryTemplateTest,G722)151 TEST(AudioEncoderFactoryTemplateTest, G722) {
152 auto factory = CreateAudioEncoderFactory<AudioEncoderG722>();
153 EXPECT_THAT(factory->GetSupportedEncoders(),
154 ::testing::ElementsAre(
155 AudioCodecSpec{{"G722", 8000, 1}, {16000, 1, 64000}}));
156 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
157 EXPECT_EQ(AudioCodecInfo(16000, 1, 64000),
158 factory->QueryAudioEncoder({"G722", 8000, 1}));
159 EXPECT_EQ(nullptr,
160 factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
161 auto enc = factory->MakeAudioEncoder(17, {"G722", 8000, 1}, absl::nullopt);
162 ASSERT_NE(nullptr, enc);
163 EXPECT_EQ(16000, enc->SampleRateHz());
164 }
165
TEST(AudioEncoderFactoryTemplateTest,Ilbc)166 TEST(AudioEncoderFactoryTemplateTest, Ilbc) {
167 auto factory = CreateAudioEncoderFactory<AudioEncoderIlbc>();
168 EXPECT_THAT(factory->GetSupportedEncoders(),
169 ::testing::ElementsAre(
170 AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13333}}));
171 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
172 EXPECT_EQ(AudioCodecInfo(8000, 1, 13333),
173 factory->QueryAudioEncoder({"ilbc", 8000, 1}));
174 EXPECT_EQ(nullptr,
175 factory->MakeAudioEncoder(17, {"bar", 8000, 1}, absl::nullopt));
176 auto enc = factory->MakeAudioEncoder(17, {"ilbc", 8000, 1}, absl::nullopt);
177 ASSERT_NE(nullptr, enc);
178 EXPECT_EQ(8000, enc->SampleRateHz());
179 }
180
TEST(AudioEncoderFactoryTemplateTest,L16)181 TEST(AudioEncoderFactoryTemplateTest, L16) {
182 auto factory = CreateAudioEncoderFactory<AudioEncoderL16>();
183 EXPECT_THAT(
184 factory->GetSupportedEncoders(),
185 ::testing::ElementsAre(
186 AudioCodecSpec{{"L16", 8000, 1}, {8000, 1, 8000 * 16}},
187 AudioCodecSpec{{"L16", 16000, 1}, {16000, 1, 16000 * 16}},
188 AudioCodecSpec{{"L16", 32000, 1}, {32000, 1, 32000 * 16}},
189 AudioCodecSpec{{"L16", 8000, 2}, {8000, 2, 8000 * 16 * 2}},
190 AudioCodecSpec{{"L16", 16000, 2}, {16000, 2, 16000 * 16 * 2}},
191 AudioCodecSpec{{"L16", 32000, 2}, {32000, 2, 32000 * 16 * 2}}));
192 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"L16", 8000, 0}));
193 EXPECT_EQ(AudioCodecInfo(48000, 1, 48000 * 16),
194 factory->QueryAudioEncoder({"L16", 48000, 1}));
195 EXPECT_EQ(nullptr,
196 factory->MakeAudioEncoder(17, {"L16", 8000, 0}, absl::nullopt));
197 auto enc = factory->MakeAudioEncoder(17, {"L16", 48000, 2}, absl::nullopt);
198 ASSERT_NE(nullptr, enc);
199 EXPECT_EQ(48000, enc->SampleRateHz());
200 }
201
TEST(AudioEncoderFactoryTemplateTest,Opus)202 TEST(AudioEncoderFactoryTemplateTest, Opus) {
203 auto factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
204 AudioCodecInfo info = {48000, 1, 32000, 6000, 510000};
205 info.allow_comfort_noise = false;
206 info.supports_network_adaption = true;
207 EXPECT_THAT(
208 factory->GetSupportedEncoders(),
209 ::testing::ElementsAre(AudioCodecSpec{
210 {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}},
211 info}));
212 EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
213 EXPECT_EQ(
214 info,
215 factory->QueryAudioEncoder(
216 {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}}));
217 EXPECT_EQ(nullptr,
218 factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
219 auto enc = factory->MakeAudioEncoder(17, {"opus", 48000, 2}, absl::nullopt);
220 ASSERT_NE(nullptr, enc);
221 EXPECT_EQ(48000, enc->SampleRateHz());
222 }
223
224 } // namespace webrtc
225