Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: talk/media/webrtc/webrtcvoiceengine_unittest.cc

Issue 1587193006: Move talk/media to webrtc/media (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rename back test to libjingle_media_unittest Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2008 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "webrtc/base/arraysize.h"
29 #include "webrtc/base/byteorder.h"
30 #include "webrtc/base/gunit.h"
31 #include "webrtc/call.h"
32 #include "talk/media/base/constants.h"
33 #include "talk/media/base/fakemediaengine.h"
34 #include "talk/media/base/fakenetworkinterface.h"
35 #include "talk/media/base/fakertp.h"
36 #include "talk/media/webrtc/fakewebrtccall.h"
37 #include "talk/media/webrtc/fakewebrtcvoiceengine.h"
38 #include "talk/media/webrtc/webrtcvoiceengine.h"
39 #include "webrtc/p2p/base/faketransportcontroller.h"
40 #include "talk/session/media/channel.h"
41
42 using cricket::kRtpAudioLevelHeaderExtension;
43 using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
44
45 namespace {
46
47 const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
48 const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
49 const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
50 const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
51 const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
52 const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
53 const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
54 const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
55 const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0,
56 1, 0);
57 const uint32_t kSsrc1 = 0x99;
58 const uint32_t kSsrc2 = 0x98;
59 const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
60
61 class FakeVoEWrapper : public cricket::VoEWrapper {
62 public:
63 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
64 : cricket::VoEWrapper(engine, // processing
65 engine, // base
66 engine, // codec
67 engine, // hw
68 engine, // network
69 engine, // rtp
70 engine) { // volume
71 }
72 };
73 } // namespace
74
75 class FakeAudioSink : public webrtc::AudioSinkInterface {
76 public:
77 void OnData(const Data& audio) override {}
78 };
79
80 class WebRtcVoiceEngineTestFake : public testing::Test {
81 public:
82 WebRtcVoiceEngineTestFake()
83 : call_(webrtc::Call::Config()),
84 engine_(new FakeVoEWrapper(&voe_)),
85 channel_(nullptr) {
86 send_parameters_.codecs.push_back(kPcmuCodec);
87 recv_parameters_.codecs.push_back(kPcmuCodec);
88 }
89 bool SetupEngine() {
90 if (!engine_.Init(rtc::Thread::Current())) {
91 return false;
92 }
93 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
94 return (channel_ != nullptr);
95 }
96 bool SetupEngineWithRecvStream() {
97 if (!SetupEngine()) {
98 return false;
99 }
100 return channel_->AddRecvStream(
101 cricket::StreamParams::CreateLegacy(kSsrc1));
102 }
103 bool SetupEngineWithSendStream() {
104 if (!SetupEngine()) {
105 return false;
106 }
107 return channel_->AddSendStream(
108 cricket::StreamParams::CreateLegacy(kSsrc1));
109 }
110 void SetupForMultiSendStream() {
111 EXPECT_TRUE(SetupEngineWithSendStream());
112 // Remove stream added in Setup.
113 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
114 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
115 // Verify the channel does not exist.
116 EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
117 }
118 void DeliverPacket(const void* data, int len) {
119 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
120 channel_->OnPacketReceived(&packet, rtc::PacketTime());
121 }
122 void TearDown() override {
123 delete channel_;
124 engine_.Terminate();
125 }
126
127 const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
128 const auto* send_stream = call_.GetAudioSendStream(ssrc);
129 EXPECT_TRUE(send_stream);
130 return *send_stream;
131 }
132
133 const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
134 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
135 EXPECT_TRUE(recv_stream);
136 return *recv_stream;
137 }
138
139 const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
140 const auto* send_stream = call_.GetAudioSendStream(ssrc);
141 EXPECT_TRUE(send_stream);
142 return send_stream->GetConfig();
143 }
144
145 const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
146 const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
147 EXPECT_TRUE(recv_stream);
148 return recv_stream->GetConfig();
149 }
150
151 void TestInsertDtmf(uint32_t ssrc, bool caller) {
152 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
153 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
154 EXPECT_TRUE(channel_ != nullptr);
155 if (caller) {
156 // If this is a caller, local description will be applied and add the
157 // send stream.
158 EXPECT_TRUE(channel_->AddSendStream(
159 cricket::StreamParams::CreateLegacy(kSsrc1)));
160 }
161
162 // Test we can only InsertDtmf when the other side supports telephone-event.
163 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
164 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
165 EXPECT_FALSE(channel_->CanInsertDtmf());
166 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
167 send_parameters_.codecs.push_back(kTelephoneEventCodec);
168 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
169 EXPECT_TRUE(channel_->CanInsertDtmf());
170
171 if (!caller) {
172 // If this is callee, there's no active send channel yet.
173 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
174 EXPECT_TRUE(channel_->AddSendStream(
175 cricket::StreamParams::CreateLegacy(kSsrc1)));
176 }
177
178 // Check we fail if the ssrc is invalid.
179 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
180
181 // Test send.
182 cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
183 GetSendStream(kSsrc1).GetLatestTelephoneEvent();
184 EXPECT_EQ(-1, telephone_event.payload_type);
185 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
186 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
187 EXPECT_EQ(kTelephoneEventCodec.id, telephone_event.payload_type);
188 EXPECT_EQ(2, telephone_event.event_code);
189 EXPECT_EQ(123, telephone_event.duration_ms);
190 }
191
192 // Test that send bandwidth is set correctly.
193 // |codec| is the codec under test.
194 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
195 // |expected_result| is the expected result from SetMaxSendBandwidth().
196 // |expected_bitrate| is the expected audio bitrate afterward.
197 void TestSendBandwidth(const cricket::AudioCodec& codec,
198 int max_bitrate,
199 bool expected_result,
200 int expected_bitrate) {
201 cricket::AudioSendParameters parameters;
202 parameters.codecs.push_back(codec);
203 parameters.max_bandwidth_bps = max_bitrate;
204 EXPECT_EQ(expected_result, channel_->SetSendParameters(parameters));
205
206 int channel_num = voe_.GetLastChannel();
207 webrtc::CodecInst temp_codec;
208 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
209 EXPECT_EQ(expected_bitrate, temp_codec.rate);
210 }
211
212 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
213 EXPECT_TRUE(SetupEngineWithSendStream());
214
215 // Ensure extensions are off by default.
216 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
217
218 // Ensure unknown extensions won't cause an error.
219 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
220 "urn:ietf:params:unknownextention", 1));
221 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
222 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
223
224 // Ensure extensions stay off with an empty list of headers.
225 send_parameters_.extensions.clear();
226 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
227 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
228
229 // Ensure extension is set properly.
230 const int id = 1;
231 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(ext, id));
232 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
233 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
234 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].name);
235 EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
236
237 // Ensure extension is set properly on new stream.
238 EXPECT_TRUE(channel_->AddSendStream(
239 cricket::StreamParams::CreateLegacy(kSsrc2)));
240 EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
241 call_.GetAudioSendStream(kSsrc2));
242 EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
243 EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].name);
244 EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
245
246 // Ensure all extensions go back off with an empty list.
247 send_parameters_.codecs.push_back(kPcmuCodec);
248 send_parameters_.extensions.clear();
249 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
250 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
251 EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
252 }
253
254 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
255 EXPECT_TRUE(SetupEngineWithRecvStream());
256
257 // Ensure extensions are off by default.
258 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
259
260 // Ensure unknown extensions won't cause an error.
261 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
262 "urn:ietf:params:unknownextention", 1));
263 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
264 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
265
266 // Ensure extensions stay off with an empty list of headers.
267 recv_parameters_.extensions.clear();
268 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
269 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
270
271 // Ensure extension is set properly.
272 const int id = 2;
273 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(ext, id));
274 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
275 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
276 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].name);
277 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
278
279 // Ensure extension is set properly on new stream.
280 EXPECT_TRUE(channel_->AddRecvStream(
281 cricket::StreamParams::CreateLegacy(kSsrc2)));
282 EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
283 call_.GetAudioReceiveStream(kSsrc2));
284 EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
285 EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].name);
286 EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
287
288 // Ensure all extensions go back off with an empty list.
289 recv_parameters_.extensions.clear();
290 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
291 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
292 EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
293 }
294
295 webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
296 webrtc::AudioSendStream::Stats stats;
297 stats.local_ssrc = 12;
298 stats.bytes_sent = 345;
299 stats.packets_sent = 678;
300 stats.packets_lost = 9012;
301 stats.fraction_lost = 34.56f;
302 stats.codec_name = "codec_name_send";
303 stats.ext_seqnum = 789;
304 stats.jitter_ms = 12;
305 stats.rtt_ms = 345;
306 stats.audio_level = 678;
307 stats.aec_quality_min = 9.01f;
308 stats.echo_delay_median_ms = 234;
309 stats.echo_delay_std_ms = 567;
310 stats.echo_return_loss = 890;
311 stats.echo_return_loss_enhancement = 1234;
312 stats.typing_noise_detected = true;
313 return stats;
314 }
315 void SetAudioSendStreamStats() {
316 for (auto* s : call_.GetAudioSendStreams()) {
317 s->SetStats(GetAudioSendStreamStats());
318 }
319 }
320 void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
321 bool is_sending) {
322 const auto stats = GetAudioSendStreamStats();
323 EXPECT_EQ(info.ssrc(), stats.local_ssrc);
324 EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
325 EXPECT_EQ(info.packets_sent, stats.packets_sent);
326 EXPECT_EQ(info.packets_lost, stats.packets_lost);
327 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
328 EXPECT_EQ(info.codec_name, stats.codec_name);
329 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
330 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
331 EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
332 EXPECT_EQ(info.audio_level, stats.audio_level);
333 EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
334 EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
335 EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
336 EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
337 EXPECT_EQ(info.echo_return_loss_enhancement,
338 stats.echo_return_loss_enhancement);
339 EXPECT_EQ(info.typing_noise_detected,
340 stats.typing_noise_detected && is_sending);
341 }
342
343 webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
344 webrtc::AudioReceiveStream::Stats stats;
345 stats.remote_ssrc = 123;
346 stats.bytes_rcvd = 456;
347 stats.packets_rcvd = 768;
348 stats.packets_lost = 101;
349 stats.fraction_lost = 23.45f;
350 stats.codec_name = "codec_name_recv";
351 stats.ext_seqnum = 678;
352 stats.jitter_ms = 901;
353 stats.jitter_buffer_ms = 234;
354 stats.jitter_buffer_preferred_ms = 567;
355 stats.delay_estimate_ms = 890;
356 stats.audio_level = 1234;
357 stats.expand_rate = 5.67f;
358 stats.speech_expand_rate = 8.90f;
359 stats.secondary_decoded_rate = 1.23f;
360 stats.accelerate_rate = 4.56f;
361 stats.preemptive_expand_rate = 7.89f;
362 stats.decoding_calls_to_silence_generator = 12;
363 stats.decoding_calls_to_neteq = 345;
364 stats.decoding_normal = 67890;
365 stats.decoding_plc = 1234;
366 stats.decoding_cng = 5678;
367 stats.decoding_plc_cng = 9012;
368 stats.capture_start_ntp_time_ms = 3456;
369 return stats;
370 }
371 void SetAudioReceiveStreamStats() {
372 for (auto* s : call_.GetAudioReceiveStreams()) {
373 s->SetStats(GetAudioReceiveStreamStats());
374 }
375 }
376 void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
377 const auto stats = GetAudioReceiveStreamStats();
378 EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
379 EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
380 EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
381 EXPECT_EQ(info.packets_lost, stats.packets_lost);
382 EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
383 EXPECT_EQ(info.codec_name, stats.codec_name);
384 EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
385 EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
386 EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
387 EXPECT_EQ(info.jitter_buffer_preferred_ms,
388 stats.jitter_buffer_preferred_ms);
389 EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
390 EXPECT_EQ(info.audio_level, stats.audio_level);
391 EXPECT_EQ(info.expand_rate, stats.expand_rate);
392 EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
393 EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
394 EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
395 EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
396 EXPECT_EQ(info.decoding_calls_to_silence_generator,
397 stats.decoding_calls_to_silence_generator);
398 EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
399 EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
400 EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
401 EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
402 EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
403 EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
404 }
405
406 protected:
407 cricket::FakeCall call_;
408 cricket::FakeWebRtcVoiceEngine voe_;
409 cricket::WebRtcVoiceEngine engine_;
410 cricket::VoiceMediaChannel* channel_;
411 cricket::AudioSendParameters send_parameters_;
412 cricket::AudioRecvParameters recv_parameters_;
413 };
414
415 // Tests that our stub library "works".
416 TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
417 EXPECT_FALSE(voe_.IsInited());
418 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
419 EXPECT_TRUE(voe_.IsInited());
420 engine_.Terminate();
421 EXPECT_FALSE(voe_.IsInited());
422 }
423
424 // Tests that we can create and destroy a channel.
425 TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
426 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
427 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
428 EXPECT_TRUE(channel_ != nullptr);
429 }
430
431 // Tests that the list of supported codecs is created properly and ordered
432 // correctly
433 TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
434 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
435 ASSERT_FALSE(codecs.empty());
436 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
437 EXPECT_EQ(48000, codecs[0].clockrate);
438 EXPECT_EQ(2, codecs[0].channels);
439 EXPECT_EQ(64000, codecs[0].bitrate);
440 int pref = codecs[0].preference;
441 for (size_t i = 1; i < codecs.size(); ++i) {
442 EXPECT_GT(pref, codecs[i].preference);
443 pref = codecs[i].preference;
444 }
445 }
446
447 // Tests that we can find codecs by name or id, and that we interpret the
448 // clockrate and bitrate fields properly.
449 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
450 cricket::AudioCodec codec;
451 webrtc::CodecInst codec_inst;
452 // Find PCMU with explicit clockrate and bitrate.
453 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
454 // Find ISAC with explicit clockrate and 0 bitrate.
455 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
456 // Find telephone-event with explicit clockrate and 0 bitrate.
457 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec,
458 &codec_inst));
459 // Find ISAC with a different payload id.
460 codec = kIsacCodec;
461 codec.id = 127;
462 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
463 EXPECT_EQ(codec.id, codec_inst.pltype);
464 // Find PCMU with a 0 clockrate.
465 codec = kPcmuCodec;
466 codec.clockrate = 0;
467 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
468 EXPECT_EQ(codec.id, codec_inst.pltype);
469 EXPECT_EQ(8000, codec_inst.plfreq);
470 // Find PCMU with a 0 bitrate.
471 codec = kPcmuCodec;
472 codec.bitrate = 0;
473 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
474 EXPECT_EQ(codec.id, codec_inst.pltype);
475 EXPECT_EQ(64000, codec_inst.rate);
476 // Find ISAC with an explicit bitrate.
477 codec = kIsacCodec;
478 codec.bitrate = 32000;
479 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
480 EXPECT_EQ(codec.id, codec_inst.pltype);
481 EXPECT_EQ(32000, codec_inst.rate);
482 }
483
484 // Test that we set our inbound codecs properly, including changing PT.
485 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
486 EXPECT_TRUE(SetupEngine());
487 cricket::AudioRecvParameters parameters;
488 parameters.codecs.push_back(kIsacCodec);
489 parameters.codecs.push_back(kPcmuCodec);
490 parameters.codecs.push_back(kTelephoneEventCodec);
491 parameters.codecs[0].id = 106; // collide with existing telephone-event
492 parameters.codecs[2].id = 126;
493 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
494 EXPECT_TRUE(channel_->AddRecvStream(
495 cricket::StreamParams::CreateLegacy(kSsrc1)));
496 int channel_num = voe_.GetLastChannel();
497 webrtc::CodecInst gcodec;
498 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
499 gcodec.plfreq = 16000;
500 gcodec.channels = 1;
501 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
502 EXPECT_EQ(106, gcodec.pltype);
503 EXPECT_STREQ("ISAC", gcodec.plname);
504 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
505 gcodec.plfreq = 8000;
506 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
507 EXPECT_EQ(126, gcodec.pltype);
508 EXPECT_STREQ("telephone-event", gcodec.plname);
509 }
510
511 // Test that we fail to set an unknown inbound codec.
512 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
513 EXPECT_TRUE(SetupEngine());
514 cricket::AudioRecvParameters parameters;
515 parameters.codecs.push_back(kIsacCodec);
516 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
517 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
518 }
519
520 // Test that we fail if we have duplicate types in the inbound list.
521 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
522 EXPECT_TRUE(SetupEngine());
523 cricket::AudioRecvParameters parameters;
524 parameters.codecs.push_back(kIsacCodec);
525 parameters.codecs.push_back(kCn16000Codec);
526 parameters.codecs[1].id = kIsacCodec.id;
527 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
528 }
529
530 // Test that we can decode OPUS without stereo parameters.
531 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
532 EXPECT_TRUE(SetupEngine());
533 cricket::AudioRecvParameters parameters;
534 parameters.codecs.push_back(kIsacCodec);
535 parameters.codecs.push_back(kPcmuCodec);
536 parameters.codecs.push_back(kOpusCodec);
537 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
538 EXPECT_TRUE(channel_->AddRecvStream(
539 cricket::StreamParams::CreateLegacy(kSsrc1)));
540 int channel_num = voe_.GetLastChannel();
541 webrtc::CodecInst opus;
542 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
543 // Even without stereo parameters, recv codecs still specify channels = 2.
544 EXPECT_EQ(2, opus.channels);
545 EXPECT_EQ(111, opus.pltype);
546 EXPECT_STREQ("opus", opus.plname);
547 opus.pltype = 0;
548 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
549 EXPECT_EQ(111, opus.pltype);
550 }
551
552 // Test that we can decode OPUS with stereo = 0.
553 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
554 EXPECT_TRUE(SetupEngine());
555 cricket::AudioRecvParameters parameters;
556 parameters.codecs.push_back(kIsacCodec);
557 parameters.codecs.push_back(kPcmuCodec);
558 parameters.codecs.push_back(kOpusCodec);
559 parameters.codecs[2].params["stereo"] = "0";
560 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
561 EXPECT_TRUE(channel_->AddRecvStream(
562 cricket::StreamParams::CreateLegacy(kSsrc1)));
563 int channel_num2 = voe_.GetLastChannel();
564 webrtc::CodecInst opus;
565 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
566 // Even when stereo is off, recv codecs still specify channels = 2.
567 EXPECT_EQ(2, opus.channels);
568 EXPECT_EQ(111, opus.pltype);
569 EXPECT_STREQ("opus", opus.plname);
570 opus.pltype = 0;
571 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
572 EXPECT_EQ(111, opus.pltype);
573 }
574
575 // Test that we can decode OPUS with stereo = 1.
576 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
577 EXPECT_TRUE(SetupEngine());
578 cricket::AudioRecvParameters parameters;
579 parameters.codecs.push_back(kIsacCodec);
580 parameters.codecs.push_back(kPcmuCodec);
581 parameters.codecs.push_back(kOpusCodec);
582 parameters.codecs[2].params["stereo"] = "1";
583 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
584 EXPECT_TRUE(channel_->AddRecvStream(
585 cricket::StreamParams::CreateLegacy(kSsrc1)));
586 int channel_num2 = voe_.GetLastChannel();
587 webrtc::CodecInst opus;
588 cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
589 EXPECT_EQ(2, opus.channels);
590 EXPECT_EQ(111, opus.pltype);
591 EXPECT_STREQ("opus", opus.plname);
592 opus.pltype = 0;
593 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
594 EXPECT_EQ(111, opus.pltype);
595 }
596
597 // Test that changes to recv codecs are applied to all streams.
598 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
599 EXPECT_TRUE(SetupEngine());
600 cricket::AudioRecvParameters parameters;
601 parameters.codecs.push_back(kIsacCodec);
602 parameters.codecs.push_back(kPcmuCodec);
603 parameters.codecs.push_back(kTelephoneEventCodec);
604 parameters.codecs[0].id = 106; // collide with existing telephone-event
605 parameters.codecs[2].id = 126;
606 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
607 EXPECT_TRUE(channel_->AddRecvStream(
608 cricket::StreamParams::CreateLegacy(kSsrc1)));
609 int channel_num2 = voe_.GetLastChannel();
610 webrtc::CodecInst gcodec;
611 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
612 gcodec.plfreq = 16000;
613 gcodec.channels = 1;
614 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
615 EXPECT_EQ(106, gcodec.pltype);
616 EXPECT_STREQ("ISAC", gcodec.plname);
617 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
618 gcodec.plfreq = 8000;
619 gcodec.channels = 1;
620 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
621 EXPECT_EQ(126, gcodec.pltype);
622 EXPECT_STREQ("telephone-event", gcodec.plname);
623 }
624
625 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
626 EXPECT_TRUE(SetupEngineWithRecvStream());
627 cricket::AudioRecvParameters parameters;
628 parameters.codecs.push_back(kIsacCodec);
629 parameters.codecs[0].id = 106; // collide with existing telephone-event
630 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
631
632 int channel_num2 = voe_.GetLastChannel();
633 webrtc::CodecInst gcodec;
634 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
635 gcodec.plfreq = 16000;
636 gcodec.channels = 1;
637 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
638 EXPECT_EQ(106, gcodec.pltype);
639 EXPECT_STREQ("ISAC", gcodec.plname);
640 }
641
642 // Test that we can apply the same set of codecs again while playing.
643 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
644 EXPECT_TRUE(SetupEngineWithRecvStream());
645 cricket::AudioRecvParameters parameters;
646 parameters.codecs.push_back(kIsacCodec);
647 parameters.codecs.push_back(kCn16000Codec);
648 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
649 EXPECT_TRUE(channel_->SetPlayout(true));
650 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
651
652 // Changing the payload type of a codec should fail.
653 parameters.codecs[0].id = 127;
654 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
655 int channel_num = voe_.GetLastChannel();
656 EXPECT_TRUE(voe_.GetPlayout(channel_num));
657 }
658
659 // Test that we can add a codec while playing.
660 TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
661 EXPECT_TRUE(SetupEngineWithRecvStream());
662 cricket::AudioRecvParameters parameters;
663 parameters.codecs.push_back(kIsacCodec);
664 parameters.codecs.push_back(kCn16000Codec);
665 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
666 EXPECT_TRUE(channel_->SetPlayout(true));
667
668 parameters.codecs.push_back(kOpusCodec);
669 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
670 int channel_num = voe_.GetLastChannel();
671 EXPECT_TRUE(voe_.GetPlayout(channel_num));
672 webrtc::CodecInst gcodec;
673 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
674 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
675 }
676
677 TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
678 EXPECT_TRUE(SetupEngineWithSendStream());
679
680 // Test that when autobw is enabled, bitrate is kept as the default
681 // value. autobw is enabled for the following tests because the target
682 // bitrate is <= 0.
683
684 // ISAC, default bitrate == 32000.
685 TestSendBandwidth(kIsacCodec, 0, true, 32000);
686
687 // PCMU, default bitrate == 64000.
688 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
689
690 // opus, default bitrate == 64000.
691 TestSendBandwidth(kOpusCodec, -1, true, 64000);
692 }
693
694 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
695 EXPECT_TRUE(SetupEngineWithSendStream());
696
697 // Test that the bitrate of a multi-rate codec is always the maximum.
698
699 // ISAC, default bitrate == 32000.
700 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
701 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
702
703 // opus, default bitrate == 64000.
704 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
705 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
706 }
707
708 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
709 EXPECT_TRUE(SetupEngineWithSendStream());
710
711 // Test that we can only set a maximum bitrate for a fixed-rate codec
712 // if it's bigger than the fixed rate.
713
714 // PCMU, fixed bitrate == 64000.
715 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
716 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
717 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
718 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
719 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
720 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
721 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
722 }
723
724 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
725 EXPECT_TRUE(SetupEngine());
726 const int kDesiredBitrate = 128000;
727 cricket::AudioSendParameters parameters;
728 parameters.codecs = engine_.codecs();
729 parameters.max_bandwidth_bps = kDesiredBitrate;
730 EXPECT_TRUE(channel_->SetSendParameters(parameters));
731
732 EXPECT_TRUE(channel_->AddSendStream(
733 cricket::StreamParams::CreateLegacy(kSsrc1)));
734
735 int channel_num = voe_.GetLastChannel();
736 webrtc::CodecInst codec;
737 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
738 EXPECT_EQ(kDesiredBitrate, codec.rate);
739 }
740
741 // Test that bitrate cannot be set for CBR codecs.
742 // Bitrate is ignored if it is higher than the fixed bitrate.
743 // Bitrate less then the fixed bitrate is an error.
744 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
745 EXPECT_TRUE(SetupEngineWithSendStream());
746
747 // PCMU, default bitrate == 64000.
748 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
749 int channel_num = voe_.GetLastChannel();
750 webrtc::CodecInst codec;
751 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
752 EXPECT_EQ(64000, codec.rate);
753
754 send_parameters_.max_bandwidth_bps = 128000;
755 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
756 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
757 EXPECT_EQ(64000, codec.rate);
758
759 send_parameters_.max_bandwidth_bps = 128;
760 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
761 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
762 EXPECT_EQ(64000, codec.rate);
763 }
764
765 // Test that we apply codecs properly.
766 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
767 EXPECT_TRUE(SetupEngineWithSendStream());
768 cricket::AudioSendParameters parameters;
769 parameters.codecs.push_back(kIsacCodec);
770 parameters.codecs.push_back(kPcmuCodec);
771 parameters.codecs.push_back(kRedCodec);
772 parameters.codecs[0].id = 96;
773 parameters.codecs[0].bitrate = 48000;
774 EXPECT_TRUE(channel_->SetSendParameters(parameters));
775 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
776 int channel_num = voe_.GetLastChannel();
777 webrtc::CodecInst gcodec;
778 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
779 EXPECT_EQ(96, gcodec.pltype);
780 EXPECT_EQ(48000, gcodec.rate);
781 EXPECT_STREQ("ISAC", gcodec.plname);
782 EXPECT_FALSE(voe_.GetVAD(channel_num));
783 EXPECT_FALSE(voe_.GetRED(channel_num));
784 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
785 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
786 EXPECT_FALSE(channel_->CanInsertDtmf());
787 }
788
789 // Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
790 // to apply.
791 TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
792 EXPECT_TRUE(SetupEngineWithSendStream());
793 cricket::AudioSendParameters parameters;
794 parameters.codecs.push_back(kIsacCodec);
795 parameters.codecs.push_back(kPcmuCodec);
796 parameters.codecs.push_back(kRedCodec);
797 parameters.codecs[0].id = 96;
798 parameters.codecs[0].bitrate = 48000;
799 EXPECT_TRUE(channel_->SetSendParameters(parameters));
800 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
801 // Calling SetSendCodec again with same codec which is already set.
802 // In this case media channel shouldn't send codec to VoE.
803 EXPECT_TRUE(channel_->SetSendParameters(parameters));
804 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
805 }
806
807 // Verify that G722 is set with 16000 samples per second to WebRTC.
808 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
809 EXPECT_TRUE(SetupEngineWithSendStream());
810 int channel_num = voe_.GetLastChannel();
811 cricket::AudioSendParameters parameters;
812 parameters.codecs.push_back(kG722CodecSdp);
813 EXPECT_TRUE(channel_->SetSendParameters(parameters));
814 webrtc::CodecInst gcodec;
815 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
816 EXPECT_STREQ("G722", gcodec.plname);
817 EXPECT_EQ(1, gcodec.channels);
818 EXPECT_EQ(16000, gcodec.plfreq);
819 }
820
821 // Test that if clockrate is not 48000 for opus, we fail.
822 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
823 EXPECT_TRUE(SetupEngineWithSendStream());
824 cricket::AudioSendParameters parameters;
825 parameters.codecs.push_back(kOpusCodec);
826 parameters.codecs[0].bitrate = 0;
827 parameters.codecs[0].clockrate = 50000;
828 EXPECT_FALSE(channel_->SetSendParameters(parameters));
829 }
830
831 // Test that if channels=0 for opus, we fail.
832 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
833 EXPECT_TRUE(SetupEngineWithSendStream());
834 cricket::AudioSendParameters parameters;
835 parameters.codecs.push_back(kOpusCodec);
836 parameters.codecs[0].bitrate = 0;
837 parameters.codecs[0].channels = 0;
838 EXPECT_FALSE(channel_->SetSendParameters(parameters));
839 }
840
841 // Test that if channels=0 for opus, we fail.
842 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
843 EXPECT_TRUE(SetupEngineWithSendStream());
844 cricket::AudioSendParameters parameters;
845 parameters.codecs.push_back(kOpusCodec);
846 parameters.codecs[0].bitrate = 0;
847 parameters.codecs[0].channels = 0;
848 parameters.codecs[0].params["stereo"] = "1";
849 EXPECT_FALSE(channel_->SetSendParameters(parameters));
850 }
851
852 // Test that if channel is 1 for opus and there's no stereo, we fail.
853 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
854 EXPECT_TRUE(SetupEngineWithSendStream());
855 cricket::AudioSendParameters parameters;
856 parameters.codecs.push_back(kOpusCodec);
857 parameters.codecs[0].bitrate = 0;
858 parameters.codecs[0].channels = 1;
859 EXPECT_FALSE(channel_->SetSendParameters(parameters));
860 }
861
862 // Test that if channel is 1 for opus and stereo=0, we fail.
863 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
864 EXPECT_TRUE(SetupEngineWithSendStream());
865 cricket::AudioSendParameters parameters;
866 parameters.codecs.push_back(kOpusCodec);
867 parameters.codecs[0].bitrate = 0;
868 parameters.codecs[0].channels = 1;
869 parameters.codecs[0].params["stereo"] = "0";
870 EXPECT_FALSE(channel_->SetSendParameters(parameters));
871 }
872
873 // Test that if channel is 1 for opus and stereo=1, we fail.
874 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
875 EXPECT_TRUE(SetupEngineWithSendStream());
876 cricket::AudioSendParameters parameters;
877 parameters.codecs.push_back(kOpusCodec);
878 parameters.codecs[0].bitrate = 0;
879 parameters.codecs[0].channels = 1;
880 parameters.codecs[0].params["stereo"] = "1";
881 EXPECT_FALSE(channel_->SetSendParameters(parameters));
882 }
883
884 // Test that with bitrate=0 and no stereo,
885 // channels and bitrate are 1 and 32000.
886 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
887 EXPECT_TRUE(SetupEngineWithSendStream());
888 int channel_num = voe_.GetLastChannel();
889 cricket::AudioSendParameters parameters;
890 parameters.codecs.push_back(kOpusCodec);
891 parameters.codecs[0].bitrate = 0;
892 EXPECT_TRUE(channel_->SetSendParameters(parameters));
893 webrtc::CodecInst gcodec;
894 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
895 EXPECT_STREQ("opus", gcodec.plname);
896 EXPECT_EQ(1, gcodec.channels);
897 EXPECT_EQ(32000, gcodec.rate);
898 }
899
900 // Test that with bitrate=0 and stereo=0,
901 // channels and bitrate are 1 and 32000.
902 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
903 EXPECT_TRUE(SetupEngineWithSendStream());
904 int channel_num = voe_.GetLastChannel();
905 cricket::AudioSendParameters parameters;
906 parameters.codecs.push_back(kOpusCodec);
907 parameters.codecs[0].bitrate = 0;
908 parameters.codecs[0].params["stereo"] = "0";
909 EXPECT_TRUE(channel_->SetSendParameters(parameters));
910 webrtc::CodecInst gcodec;
911 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
912 EXPECT_STREQ("opus", gcodec.plname);
913 EXPECT_EQ(1, gcodec.channels);
914 EXPECT_EQ(32000, gcodec.rate);
915 }
916
917 // Test that with bitrate=invalid and stereo=0,
918 // channels and bitrate are 1 and 32000.
919 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
920 EXPECT_TRUE(SetupEngineWithSendStream());
921 int channel_num = voe_.GetLastChannel();
922 cricket::AudioSendParameters parameters;
923 parameters.codecs.push_back(kOpusCodec);
924 parameters.codecs[0].params["stereo"] = "0";
925 webrtc::CodecInst gcodec;
926
927 // bitrate that's out of the range between 6000 and 510000 will be clamped.
928 parameters.codecs[0].bitrate = 5999;
929 EXPECT_TRUE(channel_->SetSendParameters(parameters));
930 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
931 EXPECT_STREQ("opus", gcodec.plname);
932 EXPECT_EQ(1, gcodec.channels);
933 EXPECT_EQ(6000, gcodec.rate);
934
935 parameters.codecs[0].bitrate = 510001;
936 EXPECT_TRUE(channel_->SetSendParameters(parameters));
937 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
938 EXPECT_STREQ("opus", gcodec.plname);
939 EXPECT_EQ(1, gcodec.channels);
940 EXPECT_EQ(510000, gcodec.rate);
941 }
942
943 // Test that with bitrate=0 and stereo=1,
944 // channels and bitrate are 2 and 64000.
945 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
946 EXPECT_TRUE(SetupEngineWithSendStream());
947 int channel_num = voe_.GetLastChannel();
948 cricket::AudioSendParameters parameters;
949 parameters.codecs.push_back(kOpusCodec);
950 parameters.codecs[0].bitrate = 0;
951 parameters.codecs[0].params["stereo"] = "1";
952 EXPECT_TRUE(channel_->SetSendParameters(parameters));
953 webrtc::CodecInst gcodec;
954 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
955 EXPECT_STREQ("opus", gcodec.plname);
956 EXPECT_EQ(2, gcodec.channels);
957 EXPECT_EQ(64000, gcodec.rate);
958 }
959
960 // Test that with bitrate=invalid and stereo=1,
961 // channels and bitrate are 2 and 64000.
962 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
963 EXPECT_TRUE(SetupEngineWithSendStream());
964 int channel_num = voe_.GetLastChannel();
965 cricket::AudioSendParameters parameters;
966 parameters.codecs.push_back(kOpusCodec);
967 parameters.codecs[0].params["stereo"] = "1";
968 webrtc::CodecInst gcodec;
969
970 // bitrate that's out of the range between 6000 and 510000 will be clamped.
971 parameters.codecs[0].bitrate = 5999;
972 EXPECT_TRUE(channel_->SetSendParameters(parameters));
973 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
974 EXPECT_STREQ("opus", gcodec.plname);
975 EXPECT_EQ(2, gcodec.channels);
976 EXPECT_EQ(6000, gcodec.rate);
977
978 parameters.codecs[0].bitrate = 510001;
979 EXPECT_TRUE(channel_->SetSendParameters(parameters));
980 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
981 EXPECT_STREQ("opus", gcodec.plname);
982 EXPECT_EQ(2, gcodec.channels);
983 EXPECT_EQ(510000, gcodec.rate);
984 }
985
986 // Test that with bitrate=N and stereo unset,
987 // channels and bitrate are 1 and N.
988 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
989 EXPECT_TRUE(SetupEngineWithSendStream());
990 int channel_num = voe_.GetLastChannel();
991 cricket::AudioSendParameters parameters;
992 parameters.codecs.push_back(kOpusCodec);
993 parameters.codecs[0].bitrate = 96000;
994 EXPECT_TRUE(channel_->SetSendParameters(parameters));
995 webrtc::CodecInst gcodec;
996 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
997 EXPECT_EQ(111, gcodec.pltype);
998 EXPECT_EQ(96000, gcodec.rate);
999 EXPECT_STREQ("opus", gcodec.plname);
1000 EXPECT_EQ(1, gcodec.channels);
1001 EXPECT_EQ(48000, gcodec.plfreq);
1002 }
1003
1004 // Test that with bitrate=N and stereo=0,
1005 // channels and bitrate are 1 and N.
1006 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
1007 EXPECT_TRUE(SetupEngineWithSendStream());
1008 int channel_num = voe_.GetLastChannel();
1009 cricket::AudioSendParameters parameters;
1010 parameters.codecs.push_back(kOpusCodec);
1011 parameters.codecs[0].bitrate = 30000;
1012 parameters.codecs[0].params["stereo"] = "0";
1013 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1014 webrtc::CodecInst gcodec;
1015 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1016 EXPECT_EQ(1, gcodec.channels);
1017 EXPECT_EQ(30000, gcodec.rate);
1018 EXPECT_STREQ("opus", gcodec.plname);
1019 }
1020
1021 // Test that with bitrate=N and without any parameters,
1022 // channels and bitrate are 1 and N.
1023 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
1024 EXPECT_TRUE(SetupEngineWithSendStream());
1025 int channel_num = voe_.GetLastChannel();
1026 cricket::AudioSendParameters parameters;
1027 parameters.codecs.push_back(kOpusCodec);
1028 parameters.codecs[0].bitrate = 30000;
1029 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1030 webrtc::CodecInst gcodec;
1031 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1032 EXPECT_EQ(1, gcodec.channels);
1033 EXPECT_EQ(30000, gcodec.rate);
1034 EXPECT_STREQ("opus", gcodec.plname);
1035 }
1036
1037 // Test that with bitrate=N and stereo=1,
1038 // channels and bitrate are 2 and N.
1039 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
1040 EXPECT_TRUE(SetupEngineWithSendStream());
1041 int channel_num = voe_.GetLastChannel();
1042 cricket::AudioSendParameters parameters;
1043 parameters.codecs.push_back(kOpusCodec);
1044 parameters.codecs[0].bitrate = 30000;
1045 parameters.codecs[0].params["stereo"] = "1";
1046 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1047 webrtc::CodecInst gcodec;
1048 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1049 EXPECT_EQ(2, gcodec.channels);
1050 EXPECT_EQ(30000, gcodec.rate);
1051 EXPECT_STREQ("opus", gcodec.plname);
1052 }
1053
1054 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1055 // Also test that the "maxaveragebitrate" can't be set to values outside the
1056 // range of 6000 and 510000
1057 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1058 EXPECT_TRUE(SetupEngineWithSendStream());
1059 int channel_num = voe_.GetLastChannel();
1060 cricket::AudioSendParameters parameters;
1061 parameters.codecs.push_back(kOpusCodec);
1062 parameters.codecs[0].bitrate = 30000;
1063 webrtc::CodecInst gcodec;
1064
1065 // Ignore if less than 6000.
1066 parameters.codecs[0].params["maxaveragebitrate"] = "5999";
1067 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1068 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1069 EXPECT_EQ(6000, gcodec.rate);
1070
1071 // Ignore if larger than 510000.
1072 parameters.codecs[0].params["maxaveragebitrate"] = "510001";
1073 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1074 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1075 EXPECT_EQ(510000, gcodec.rate);
1076
1077 parameters.codecs[0].params["maxaveragebitrate"] = "200000";
1078 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1079 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1080 EXPECT_EQ(200000, gcodec.rate);
1081 }
1082
1083 // Test that we can enable NACK with opus as caller.
1084 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
1085 EXPECT_TRUE(SetupEngineWithSendStream());
1086 int channel_num = voe_.GetLastChannel();
1087 cricket::AudioSendParameters parameters;
1088 parameters.codecs.push_back(kOpusCodec);
1089 parameters.codecs[0].AddFeedbackParam(
1090 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1091 cricket::kParamValueEmpty));
1092 EXPECT_FALSE(voe_.GetNACK(channel_num));
1093 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1094 EXPECT_TRUE(voe_.GetNACK(channel_num));
1095 }
1096
1097 // Test that we can enable NACK with opus as callee.
1098 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1099 EXPECT_TRUE(SetupEngineWithRecvStream());
1100 int channel_num = voe_.GetLastChannel();
1101 cricket::AudioSendParameters parameters;
1102 parameters.codecs.push_back(kOpusCodec);
1103 parameters.codecs[0].AddFeedbackParam(
1104 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1105 cricket::kParamValueEmpty));
1106 EXPECT_FALSE(voe_.GetNACK(channel_num));
1107 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1108 EXPECT_FALSE(voe_.GetNACK(channel_num));
1109
1110 EXPECT_TRUE(channel_->AddSendStream(
1111 cricket::StreamParams::CreateLegacy(kSsrc1)));
1112 EXPECT_TRUE(voe_.GetNACK(voe_.GetLastChannel()));
1113 }
1114
1115 // Test that we can enable NACK on receive streams.
1116 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1117 EXPECT_TRUE(SetupEngineWithSendStream());
1118 int channel_num1 = voe_.GetLastChannel();
1119 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1120 int channel_num2 = voe_.GetLastChannel();
1121 cricket::AudioSendParameters parameters;
1122 parameters.codecs.push_back(kOpusCodec);
1123 parameters.codecs[0].AddFeedbackParam(
1124 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1125 cricket::kParamValueEmpty));
1126 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1127 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1128 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1129 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1130 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1131 }
1132
1133 // Test that we can disable NACK.
1134 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1135 EXPECT_TRUE(SetupEngineWithSendStream());
1136 int channel_num = voe_.GetLastChannel();
1137 cricket::AudioSendParameters parameters;
1138 parameters.codecs.push_back(kOpusCodec);
1139 parameters.codecs[0].AddFeedbackParam(
1140 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1141 cricket::kParamValueEmpty));
1142 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1143 EXPECT_TRUE(voe_.GetNACK(channel_num));
1144
1145 parameters.codecs.clear();
1146 parameters.codecs.push_back(kOpusCodec);
1147 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1148 EXPECT_FALSE(voe_.GetNACK(channel_num));
1149 }
1150
1151 // Test that we can disable NACK on receive streams.
1152 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1153 EXPECT_TRUE(SetupEngineWithSendStream());
1154 int channel_num1 = voe_.GetLastChannel();
1155 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1156 int channel_num2 = voe_.GetLastChannel();
1157 cricket::AudioSendParameters parameters;
1158 parameters.codecs.push_back(kOpusCodec);
1159 parameters.codecs[0].AddFeedbackParam(
1160 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1161 cricket::kParamValueEmpty));
1162 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1163 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1164 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1165
1166 parameters.codecs.clear();
1167 parameters.codecs.push_back(kOpusCodec);
1168 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1169 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1170 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1171 }
1172
1173 // Test that NACK is enabled on a new receive stream.
1174 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1175 EXPECT_TRUE(SetupEngineWithSendStream());
1176 int channel_num = voe_.GetLastChannel();
1177 cricket::AudioSendParameters parameters;
1178 parameters.codecs.push_back(kIsacCodec);
1179 parameters.codecs.push_back(kCn16000Codec);
1180 parameters.codecs[0].AddFeedbackParam(
1181 cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1182 cricket::kParamValueEmpty));
1183 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1184 EXPECT_TRUE(voe_.GetNACK(channel_num));
1185
1186 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1187 channel_num = voe_.GetLastChannel();
1188 EXPECT_TRUE(voe_.GetNACK(channel_num));
1189 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1190 channel_num = voe_.GetLastChannel();
1191 EXPECT_TRUE(voe_.GetNACK(channel_num));
1192 }
1193
1194 // Test that without useinbandfec, Opus FEC is off.
1195 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
1196 EXPECT_TRUE(SetupEngineWithSendStream());
1197 int channel_num = voe_.GetLastChannel();
1198 cricket::AudioSendParameters parameters;
1199 parameters.codecs.push_back(kOpusCodec);
1200 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1201 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1202 }
1203
1204 // Test that with useinbandfec=0, Opus FEC is off.
1205 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
1206 EXPECT_TRUE(SetupEngineWithSendStream());
1207 int channel_num = voe_.GetLastChannel();
1208 cricket::AudioSendParameters parameters;
1209 parameters.codecs.push_back(kOpusCodec);
1210 parameters.codecs[0].bitrate = 0;
1211 parameters.codecs[0].params["useinbandfec"] = "0";
1212 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1213 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1214 webrtc::CodecInst gcodec;
1215 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1216 EXPECT_STREQ("opus", gcodec.plname);
1217 EXPECT_EQ(1, gcodec.channels);
1218 EXPECT_EQ(32000, gcodec.rate);
1219 }
1220
1221 // Test that with useinbandfec=1, Opus FEC is on.
1222 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
1223 EXPECT_TRUE(SetupEngineWithSendStream());
1224 int channel_num = voe_.GetLastChannel();
1225 cricket::AudioSendParameters parameters;
1226 parameters.codecs.push_back(kOpusCodec);
1227 parameters.codecs[0].bitrate = 0;
1228 parameters.codecs[0].params["useinbandfec"] = "1";
1229 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1230 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1231 webrtc::CodecInst gcodec;
1232 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1233 EXPECT_STREQ("opus", gcodec.plname);
1234 EXPECT_EQ(1, gcodec.channels);
1235 EXPECT_EQ(32000, gcodec.rate);
1236 }
1237
1238 // Test that with useinbandfec=1, stereo=1, Opus FEC is on.
1239 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
1240 EXPECT_TRUE(SetupEngineWithSendStream());
1241 int channel_num = voe_.GetLastChannel();
1242 cricket::AudioSendParameters parameters;
1243 parameters.codecs.push_back(kOpusCodec);
1244 parameters.codecs[0].bitrate = 0;
1245 parameters.codecs[0].params["stereo"] = "1";
1246 parameters.codecs[0].params["useinbandfec"] = "1";
1247 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1248 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1249 webrtc::CodecInst gcodec;
1250 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1251 EXPECT_STREQ("opus", gcodec.plname);
1252 EXPECT_EQ(2, gcodec.channels);
1253 EXPECT_EQ(64000, gcodec.rate);
1254 }
1255
1256 // Test that with non-Opus, codec FEC is off.
1257 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
1258 EXPECT_TRUE(SetupEngineWithSendStream());
1259 int channel_num = voe_.GetLastChannel();
1260 cricket::AudioSendParameters parameters;
1261 parameters.codecs.push_back(kIsacCodec);
1262 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1263 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1264 }
1265
1266 // Test the with non-Opus, even if useinbandfec=1, FEC is off.
1267 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1268 EXPECT_TRUE(SetupEngineWithSendStream());
1269 int channel_num = voe_.GetLastChannel();
1270 cricket::AudioSendParameters parameters;
1271 parameters.codecs.push_back(kIsacCodec);
1272 parameters.codecs[0].params["useinbandfec"] = "1";
1273 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1274 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1275 }
1276
1277 // Test that Opus FEC status can be changed.
1278 TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1279 EXPECT_TRUE(SetupEngineWithSendStream());
1280 int channel_num = voe_.GetLastChannel();
1281 cricket::AudioSendParameters parameters;
1282 parameters.codecs.push_back(kOpusCodec);
1283 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1284 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1285 parameters.codecs[0].params["useinbandfec"] = "1";
1286 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1287 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1288 }
1289
1290 // Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1291 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1292 EXPECT_TRUE(SetupEngineWithSendStream());
1293 int channel_num = voe_.GetLastChannel();
1294 cricket::AudioSendParameters parameters;
1295 parameters.codecs.push_back(kOpusCodec);
1296 parameters.codecs[0].bitrate = 0;
1297 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1298 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1299 EXPECT_EQ(cricket::kOpusBandwidthNb,
1300 voe_.GetMaxEncodingBandwidth(channel_num));
1301 webrtc::CodecInst gcodec;
1302 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1303 EXPECT_STREQ("opus", gcodec.plname);
1304
1305 EXPECT_EQ(12000, gcodec.rate);
1306 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1307 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1308 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1309 EXPECT_EQ(24000, gcodec.rate);
1310 }
1311
1312 // Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1313 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1314 EXPECT_TRUE(SetupEngineWithSendStream());
1315 int channel_num = voe_.GetLastChannel();
1316 cricket::AudioSendParameters parameters;
1317 parameters.codecs.push_back(kOpusCodec);
1318 parameters.codecs[0].bitrate = 0;
1319 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1320 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1321 EXPECT_EQ(cricket::kOpusBandwidthMb,
1322 voe_.GetMaxEncodingBandwidth(channel_num));
1323 webrtc::CodecInst gcodec;
1324 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1325 EXPECT_STREQ("opus", gcodec.plname);
1326
1327 EXPECT_EQ(20000, gcodec.rate);
1328 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1329 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1330 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1331 EXPECT_EQ(40000, gcodec.rate);
1332 }
1333
1334 // Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1335 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1336 EXPECT_TRUE(SetupEngineWithSendStream());
1337 int channel_num = voe_.GetLastChannel();
1338 cricket::AudioSendParameters parameters;
1339 parameters.codecs.push_back(kOpusCodec);
1340 parameters.codecs[0].bitrate = 0;
1341 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1342 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1343 EXPECT_EQ(cricket::kOpusBandwidthWb,
1344 voe_.GetMaxEncodingBandwidth(channel_num));
1345 webrtc::CodecInst gcodec;
1346 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1347 EXPECT_STREQ("opus", gcodec.plname);
1348
1349 EXPECT_EQ(20000, gcodec.rate);
1350 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1351 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1352 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1353 EXPECT_EQ(40000, gcodec.rate);
1354 }
1355
1356 // Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1357 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1358 EXPECT_TRUE(SetupEngineWithSendStream());
1359 int channel_num = voe_.GetLastChannel();
1360 cricket::AudioSendParameters parameters;
1361 parameters.codecs.push_back(kOpusCodec);
1362 parameters.codecs[0].bitrate = 0;
1363 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1364 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1365 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1366 voe_.GetMaxEncodingBandwidth(channel_num));
1367 webrtc::CodecInst gcodec;
1368 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1369 EXPECT_STREQ("opus", gcodec.plname);
1370
1371 EXPECT_EQ(32000, gcodec.rate);
1372 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1373 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1374 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1375 EXPECT_EQ(64000, gcodec.rate);
1376 }
1377
1378 // Test 24000 < maxplaybackrate triggers Opus full band mode.
1379 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1380 EXPECT_TRUE(SetupEngineWithSendStream());
1381 int channel_num = voe_.GetLastChannel();
1382 cricket::AudioSendParameters parameters;
1383 parameters.codecs.push_back(kOpusCodec);
1384 parameters.codecs[0].bitrate = 0;
1385 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1386 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1387 EXPECT_EQ(cricket::kOpusBandwidthFb,
1388 voe_.GetMaxEncodingBandwidth(channel_num));
1389 webrtc::CodecInst gcodec;
1390 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1391 EXPECT_STREQ("opus", gcodec.plname);
1392
1393 EXPECT_EQ(32000, gcodec.rate);
1394 parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1395 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1396 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1397 EXPECT_EQ(64000, gcodec.rate);
1398 }
1399
1400 // Test Opus that without maxplaybackrate, default playback rate is used.
1401 TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1402 EXPECT_TRUE(SetupEngineWithSendStream());
1403 int channel_num = voe_.GetLastChannel();
1404 cricket::AudioSendParameters parameters;
1405 parameters.codecs.push_back(kOpusCodec);
1406 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1407 EXPECT_EQ(cricket::kOpusBandwidthFb,
1408 voe_.GetMaxEncodingBandwidth(channel_num));
1409 }
1410
1411 // Test the with non-Opus, maxplaybackrate has no effect.
1412 TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1413 EXPECT_TRUE(SetupEngineWithSendStream());
1414 int channel_num = voe_.GetLastChannel();
1415 cricket::AudioSendParameters parameters;
1416 parameters.codecs.push_back(kIsacCodec);
1417 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1418 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1419 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1420 }
1421
1422 // Test maxplaybackrate can be set on two streams.
1423 TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1424 EXPECT_TRUE(SetupEngineWithSendStream());
1425 int channel_num = voe_.GetLastChannel();
1426 cricket::AudioSendParameters parameters;
1427 parameters.codecs.push_back(kOpusCodec);
1428 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1429 // Default bandwidth is 24000.
1430 EXPECT_EQ(cricket::kOpusBandwidthFb,
1431 voe_.GetMaxEncodingBandwidth(channel_num));
1432
1433 parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1434
1435 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1436 EXPECT_EQ(cricket::kOpusBandwidthNb,
1437 voe_.GetMaxEncodingBandwidth(channel_num));
1438
1439 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1440 channel_num = voe_.GetLastChannel();
1441 EXPECT_EQ(cricket::kOpusBandwidthNb,
1442 voe_.GetMaxEncodingBandwidth(channel_num));
1443 }
1444
1445 // Test that with usedtx=0, Opus DTX is off.
1446 TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1447 EXPECT_TRUE(SetupEngineWithSendStream());
1448 int channel_num = voe_.GetLastChannel();
1449 cricket::AudioSendParameters parameters;
1450 parameters.codecs.push_back(kOpusCodec);
1451 parameters.codecs[0].params["usedtx"] = "0";
1452 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1453 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1454 }
1455
1456 // Test that with usedtx=1, Opus DTX is on.
1457 TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1458 EXPECT_TRUE(SetupEngineWithSendStream());
1459 int channel_num = voe_.GetLastChannel();
1460 cricket::AudioSendParameters parameters;
1461 parameters.codecs.push_back(kOpusCodec);
1462 parameters.codecs[0].params["usedtx"] = "1";
1463 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1464 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1465 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1466 }
1467
1468 // Test that usedtx=1 works with stereo Opus.
1469 TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1470 EXPECT_TRUE(SetupEngineWithSendStream());
1471 int channel_num = voe_.GetLastChannel();
1472 cricket::AudioSendParameters parameters;
1473 parameters.codecs.push_back(kOpusCodec);
1474 parameters.codecs[0].params["usedtx"] = "1";
1475 parameters.codecs[0].params["stereo"] = "1";
1476 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1477 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1478 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1479 }
1480
1481 // Test that usedtx=1 does not work with non Opus.
1482 TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1483 EXPECT_TRUE(SetupEngineWithSendStream());
1484 int channel_num = voe_.GetLastChannel();
1485 cricket::AudioSendParameters parameters;
1486 parameters.codecs.push_back(kIsacCodec);
1487 parameters.codecs[0].params["usedtx"] = "1";
1488 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1489 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1490 }
1491
1492 // Test that we can switch back and forth between Opus and ISAC with CN.
1493 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
1494 EXPECT_TRUE(SetupEngineWithSendStream());
1495 int channel_num = voe_.GetLastChannel();
1496 cricket::AudioSendParameters opus_parameters;
1497 opus_parameters.codecs.push_back(kOpusCodec);
1498 EXPECT_TRUE(channel_->SetSendParameters(opus_parameters));
1499 webrtc::CodecInst gcodec;
1500 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1501 EXPECT_EQ(111, gcodec.pltype);
1502 EXPECT_STREQ("opus", gcodec.plname);
1503
1504 cricket::AudioSendParameters isac_parameters;
1505 isac_parameters.codecs.push_back(kIsacCodec);
1506 isac_parameters.codecs.push_back(kCn16000Codec);
1507 isac_parameters.codecs.push_back(kOpusCodec);
1508 EXPECT_TRUE(channel_->SetSendParameters(isac_parameters));
1509 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1510 EXPECT_EQ(103, gcodec.pltype);
1511 EXPECT_STREQ("ISAC", gcodec.plname);
1512
1513 EXPECT_TRUE(channel_->SetSendParameters(opus_parameters));
1514 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1515 EXPECT_EQ(111, gcodec.pltype);
1516 EXPECT_STREQ("opus", gcodec.plname);
1517 }
1518
1519 // Test that we handle various ways of specifying bitrate.
1520 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1521 EXPECT_TRUE(SetupEngineWithSendStream());
1522 int channel_num = voe_.GetLastChannel();
1523 cricket::AudioSendParameters parameters;
1524 parameters.codecs.push_back(kIsacCodec); // bitrate == 32000
1525 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1526 webrtc::CodecInst gcodec;
1527 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1528 EXPECT_EQ(103, gcodec.pltype);
1529 EXPECT_STREQ("ISAC", gcodec.plname);
1530 EXPECT_EQ(32000, gcodec.rate);
1531
1532 parameters.codecs[0].bitrate = 0; // bitrate == default
1533 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1534 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1535 EXPECT_EQ(103, gcodec.pltype);
1536 EXPECT_STREQ("ISAC", gcodec.plname);
1537 EXPECT_EQ(-1, gcodec.rate);
1538
1539 parameters.codecs[0].bitrate = 28000; // bitrate == 28000
1540 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1541 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1542 EXPECT_EQ(103, gcodec.pltype);
1543 EXPECT_STREQ("ISAC", gcodec.plname);
1544 EXPECT_EQ(28000, gcodec.rate);
1545
1546 parameters.codecs[0] = kPcmuCodec; // bitrate == 64000
1547 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1548 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1549 EXPECT_EQ(0, gcodec.pltype);
1550 EXPECT_STREQ("PCMU", gcodec.plname);
1551 EXPECT_EQ(64000, gcodec.rate);
1552
1553 parameters.codecs[0].bitrate = 0; // bitrate == default
1554 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1555 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1556 EXPECT_EQ(0, gcodec.pltype);
1557 EXPECT_STREQ("PCMU", gcodec.plname);
1558 EXPECT_EQ(64000, gcodec.rate);
1559
1560 parameters.codecs[0] = kOpusCodec;
1561 parameters.codecs[0].bitrate = 0; // bitrate == default
1562 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1563 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1564 EXPECT_EQ(111, gcodec.pltype);
1565 EXPECT_STREQ("opus", gcodec.plname);
1566 EXPECT_EQ(32000, gcodec.rate);
1567 }
1568
1569 // Test that we could set packet size specified in kCodecParamPTime.
1570 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1571 EXPECT_TRUE(SetupEngineWithSendStream());
1572 int channel_num = voe_.GetLastChannel();
1573 cricket::AudioSendParameters parameters;
1574 parameters.codecs.push_back(kOpusCodec);
1575 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
1576 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1577 webrtc::CodecInst gcodec;
1578 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1579 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1580
1581 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
1582 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1583 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1584 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1585
1586 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
1587 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1588 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1589 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1590
1591 parameters.codecs[0] = kIsacCodec; // Also try Isac, with unsupported size.
1592 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
1593 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1594 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1595 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1596
1597 parameters.codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1598 parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1599 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1600 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1601 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1602 }
1603
1604 // Test that we fail if no codecs are specified.
1605 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1606 EXPECT_TRUE(SetupEngineWithSendStream());
1607 cricket::AudioSendParameters parameters;
1608 EXPECT_FALSE(channel_->SetSendParameters(parameters));
1609 }
1610
1611 // Test that we can set send codecs even with telephone-event codec as the first
1612 // one on the list.
1613 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1614 EXPECT_TRUE(SetupEngineWithSendStream());
1615 int channel_num = voe_.GetLastChannel();
1616 cricket::AudioSendParameters parameters;
1617 parameters.codecs.push_back(kTelephoneEventCodec);
1618 parameters.codecs.push_back(kIsacCodec);
1619 parameters.codecs.push_back(kPcmuCodec);
1620 parameters.codecs[0].id = 98; // DTMF
1621 parameters.codecs[1].id = 96;
1622 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1623 webrtc::CodecInst gcodec;
1624 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1625 EXPECT_EQ(96, gcodec.pltype);
1626 EXPECT_STREQ("ISAC", gcodec.plname);
1627 EXPECT_TRUE(channel_->CanInsertDtmf());
1628 }
1629
1630 // Test that we can set send codecs even with CN codec as the first
1631 // one on the list.
1632 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1633 EXPECT_TRUE(SetupEngineWithSendStream());
1634 int channel_num = voe_.GetLastChannel();
1635 cricket::AudioSendParameters parameters;
1636 parameters.codecs.push_back(kCn16000Codec);
1637 parameters.codecs.push_back(kIsacCodec);
1638 parameters.codecs.push_back(kPcmuCodec);
1639 parameters.codecs[0].id = 98; // wideband CN
1640 parameters.codecs[1].id = 96;
1641 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1642 webrtc::CodecInst gcodec;
1643 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1644 EXPECT_EQ(96, gcodec.pltype);
1645 EXPECT_STREQ("ISAC", gcodec.plname);
1646 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
1647 }
1648
1649 // Test that we set VAD and DTMF types correctly as caller.
1650 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
1651 EXPECT_TRUE(SetupEngineWithSendStream());
1652 int channel_num = voe_.GetLastChannel();
1653 cricket::AudioSendParameters parameters;
1654 parameters.codecs.push_back(kIsacCodec);
1655 parameters.codecs.push_back(kPcmuCodec);
1656 // TODO(juberti): cn 32000
1657 parameters.codecs.push_back(kCn16000Codec);
1658 parameters.codecs.push_back(kCn8000Codec);
1659 parameters.codecs.push_back(kTelephoneEventCodec);
1660 parameters.codecs.push_back(kRedCodec);
1661 parameters.codecs[0].id = 96;
1662 parameters.codecs[2].id = 97; // wideband CN
1663 parameters.codecs[4].id = 98; // DTMF
1664 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1665 webrtc::CodecInst gcodec;
1666 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1667 EXPECT_EQ(96, gcodec.pltype);
1668 EXPECT_STREQ("ISAC", gcodec.plname);
1669 EXPECT_TRUE(voe_.GetVAD(channel_num));
1670 EXPECT_FALSE(voe_.GetRED(channel_num));
1671 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1672 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1673 EXPECT_TRUE(channel_->CanInsertDtmf());
1674 }
1675
1676 // Test that we set VAD and DTMF types correctly as callee.
1677 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1678 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1679 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
1680 EXPECT_TRUE(channel_ != nullptr);
1681
1682 cricket::AudioSendParameters parameters;
1683 parameters.codecs.push_back(kIsacCodec);
1684 parameters.codecs.push_back(kPcmuCodec);
1685 // TODO(juberti): cn 32000
1686 parameters.codecs.push_back(kCn16000Codec);
1687 parameters.codecs.push_back(kCn8000Codec);
1688 parameters.codecs.push_back(kTelephoneEventCodec);
1689 parameters.codecs.push_back(kRedCodec);
1690 parameters.codecs[0].id = 96;
1691 parameters.codecs[2].id = 97; // wideband CN
1692 parameters.codecs[4].id = 98; // DTMF
1693 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1694 EXPECT_TRUE(channel_->AddSendStream(
1695 cricket::StreamParams::CreateLegacy(kSsrc1)));
1696 int channel_num = voe_.GetLastChannel();
1697
1698 webrtc::CodecInst gcodec;
1699 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1700 EXPECT_EQ(96, gcodec.pltype);
1701 EXPECT_STREQ("ISAC", gcodec.plname);
1702 EXPECT_TRUE(voe_.GetVAD(channel_num));
1703 EXPECT_FALSE(voe_.GetRED(channel_num));
1704 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1705 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1706 EXPECT_TRUE(channel_->CanInsertDtmf());
1707 }
1708
1709 // Test that we only apply VAD if we have a CN codec that matches the
1710 // send codec clockrate.
1711 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1712 EXPECT_TRUE(SetupEngineWithSendStream());
1713 int channel_num = voe_.GetLastChannel();
1714 cricket::AudioSendParameters parameters;
1715 // Set ISAC(16K) and CN(16K). VAD should be activated.
1716 parameters.codecs.push_back(kIsacCodec);
1717 parameters.codecs.push_back(kCn16000Codec);
1718 parameters.codecs[1].id = 97;
1719 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1720 webrtc::CodecInst gcodec;
1721 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1722 EXPECT_STREQ("ISAC", gcodec.plname);
1723 EXPECT_TRUE(voe_.GetVAD(channel_num));
1724 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1725 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1726 parameters.codecs[0] = kPcmuCodec;
1727 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1728 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1729 EXPECT_STREQ("PCMU", gcodec.plname);
1730 EXPECT_FALSE(voe_.GetVAD(channel_num));
1731 // Set PCMU(8K) and CN(8K). VAD should be activated.
1732 parameters.codecs[1] = kCn8000Codec;
1733 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1734 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1735 EXPECT_STREQ("PCMU", gcodec.plname);
1736 EXPECT_TRUE(voe_.GetVAD(channel_num));
1737 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1738 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1739 parameters.codecs[0] = kIsacCodec;
1740 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1741 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1742 EXPECT_STREQ("ISAC", gcodec.plname);
1743 EXPECT_FALSE(voe_.GetVAD(channel_num));
1744 }
1745
1746 // Test that we perform case-insensitive matching of codec names.
1747 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1748 EXPECT_TRUE(SetupEngineWithSendStream());
1749 int channel_num = voe_.GetLastChannel();
1750 cricket::AudioSendParameters parameters;
1751 parameters.codecs.push_back(kIsacCodec);
1752 parameters.codecs.push_back(kPcmuCodec);
1753 parameters.codecs.push_back(kCn16000Codec);
1754 parameters.codecs.push_back(kCn8000Codec);
1755 parameters.codecs.push_back(kTelephoneEventCodec);
1756 parameters.codecs.push_back(kRedCodec);
1757 parameters.codecs[0].name = "iSaC";
1758 parameters.codecs[0].id = 96;
1759 parameters.codecs[2].id = 97; // wideband CN
1760 parameters.codecs[4].id = 98; // DTMF
1761 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1762 webrtc::CodecInst gcodec;
1763 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1764 EXPECT_EQ(96, gcodec.pltype);
1765 EXPECT_STREQ("ISAC", gcodec.plname);
1766 EXPECT_TRUE(voe_.GetVAD(channel_num));
1767 EXPECT_FALSE(voe_.GetRED(channel_num));
1768 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1769 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1770 EXPECT_TRUE(channel_->CanInsertDtmf());
1771 }
1772
1773 // Test that we set up RED correctly as caller.
1774 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
1775 EXPECT_TRUE(SetupEngineWithSendStream());
1776 int channel_num = voe_.GetLastChannel();
1777 cricket::AudioSendParameters parameters;
1778 parameters.codecs.push_back(kRedCodec);
1779 parameters.codecs.push_back(kIsacCodec);
1780 parameters.codecs.push_back(kPcmuCodec);
1781 parameters.codecs[0].id = 127;
1782 parameters.codecs[0].params[""] = "96/96";
1783 parameters.codecs[1].id = 96;
1784 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1785 webrtc::CodecInst gcodec;
1786 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1787 EXPECT_EQ(96, gcodec.pltype);
1788 EXPECT_STREQ("ISAC", gcodec.plname);
1789 EXPECT_TRUE(voe_.GetRED(channel_num));
1790 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1791 }
1792
1793 // Test that we set up RED correctly as callee.
1794 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1795 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1796 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
1797 EXPECT_TRUE(channel_ != nullptr);
1798
1799 cricket::AudioSendParameters parameters;
1800 parameters.codecs.push_back(kRedCodec);
1801 parameters.codecs.push_back(kIsacCodec);
1802 parameters.codecs.push_back(kPcmuCodec);
1803 parameters.codecs[0].id = 127;
1804 parameters.codecs[0].params[""] = "96/96";
1805 parameters.codecs[1].id = 96;
1806 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1807 EXPECT_TRUE(channel_->AddSendStream(
1808 cricket::StreamParams::CreateLegacy(kSsrc1)));
1809 int channel_num = voe_.GetLastChannel();
1810 webrtc::CodecInst gcodec;
1811 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1812 EXPECT_EQ(96, gcodec.pltype);
1813 EXPECT_STREQ("ISAC", gcodec.plname);
1814 EXPECT_TRUE(voe_.GetRED(channel_num));
1815 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1816 }
1817
1818 // Test that we set up RED correctly if params are omitted.
1819 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1820 EXPECT_TRUE(SetupEngineWithSendStream());
1821 int channel_num = voe_.GetLastChannel();
1822 cricket::AudioSendParameters parameters;
1823 parameters.codecs.push_back(kRedCodec);
1824 parameters.codecs.push_back(kIsacCodec);
1825 parameters.codecs.push_back(kPcmuCodec);
1826 parameters.codecs[0].id = 127;
1827 parameters.codecs[1].id = 96;
1828 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1829 webrtc::CodecInst gcodec;
1830 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1831 EXPECT_EQ(96, gcodec.pltype);
1832 EXPECT_STREQ("ISAC", gcodec.plname);
1833 EXPECT_TRUE(voe_.GetRED(channel_num));
1834 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1835 }
1836
1837 // Test that we ignore RED if the parameters aren't named the way we expect.
1838 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1839 EXPECT_TRUE(SetupEngineWithSendStream());
1840 int channel_num = voe_.GetLastChannel();
1841 cricket::AudioSendParameters parameters;
1842 parameters.codecs.push_back(kRedCodec);
1843 parameters.codecs.push_back(kIsacCodec);
1844 parameters.codecs.push_back(kPcmuCodec);
1845 parameters.codecs[0].id = 127;
1846 parameters.codecs[0].params["ABC"] = "96/96";
1847 parameters.codecs[1].id = 96;
1848 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1849 webrtc::CodecInst gcodec;
1850 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1851 EXPECT_EQ(96, gcodec.pltype);
1852 EXPECT_STREQ("ISAC", gcodec.plname);
1853 EXPECT_FALSE(voe_.GetRED(channel_num));
1854 }
1855
1856 // Test that we ignore RED if it uses different primary/secondary encoding.
1857 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1858 EXPECT_TRUE(SetupEngineWithSendStream());
1859 int channel_num = voe_.GetLastChannel();
1860 cricket::AudioSendParameters parameters;
1861 parameters.codecs.push_back(kRedCodec);
1862 parameters.codecs.push_back(kIsacCodec);
1863 parameters.codecs.push_back(kPcmuCodec);
1864 parameters.codecs[0].id = 127;
1865 parameters.codecs[0].params[""] = "96/0";
1866 parameters.codecs[1].id = 96;
1867 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1868 webrtc::CodecInst gcodec;
1869 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1870 EXPECT_EQ(96, gcodec.pltype);
1871 EXPECT_STREQ("ISAC", gcodec.plname);
1872 EXPECT_FALSE(voe_.GetRED(channel_num));
1873 }
1874
1875 // Test that we ignore RED if it uses more than 2 encodings.
1876 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1877 EXPECT_TRUE(SetupEngineWithSendStream());
1878 int channel_num = voe_.GetLastChannel();
1879 cricket::AudioSendParameters parameters;
1880 parameters.codecs.push_back(kRedCodec);
1881 parameters.codecs.push_back(kIsacCodec);
1882 parameters.codecs.push_back(kPcmuCodec);
1883 parameters.codecs[0].id = 127;
1884 parameters.codecs[0].params[""] = "96/96/96";
1885 parameters.codecs[1].id = 96;
1886 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1887 webrtc::CodecInst gcodec;
1888 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1889 EXPECT_EQ(96, gcodec.pltype);
1890 EXPECT_STREQ("ISAC", gcodec.plname);
1891 EXPECT_FALSE(voe_.GetRED(channel_num));
1892 }
1893
1894 // Test that we ignore RED if it has bogus codec ids.
1895 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1896 EXPECT_TRUE(SetupEngineWithSendStream());
1897 int channel_num = voe_.GetLastChannel();
1898 cricket::AudioSendParameters parameters;
1899 parameters.codecs.push_back(kRedCodec);
1900 parameters.codecs.push_back(kIsacCodec);
1901 parameters.codecs.push_back(kPcmuCodec);
1902 parameters.codecs[0].id = 127;
1903 parameters.codecs[0].params[""] = "ABC/ABC";
1904 parameters.codecs[1].id = 96;
1905 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1906 webrtc::CodecInst gcodec;
1907 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1908 EXPECT_EQ(96, gcodec.pltype);
1909 EXPECT_STREQ("ISAC", gcodec.plname);
1910 EXPECT_FALSE(voe_.GetRED(channel_num));
1911 }
1912
1913 // Test that we ignore RED if it refers to a codec that is not present.
1914 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1915 EXPECT_TRUE(SetupEngineWithSendStream());
1916 int channel_num = voe_.GetLastChannel();
1917 cricket::AudioSendParameters parameters;
1918 parameters.codecs.push_back(kRedCodec);
1919 parameters.codecs.push_back(kIsacCodec);
1920 parameters.codecs.push_back(kPcmuCodec);
1921 parameters.codecs[0].id = 127;
1922 parameters.codecs[0].params[""] = "97/97";
1923 parameters.codecs[1].id = 96;
1924 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1925 webrtc::CodecInst gcodec;
1926 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1927 EXPECT_EQ(96, gcodec.pltype);
1928 EXPECT_STREQ("ISAC", gcodec.plname);
1929 EXPECT_FALSE(voe_.GetRED(channel_num));
1930 }
1931
1932 // Test support for audio level header extension.
1933 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1934 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1935 }
1936 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1937 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1938 }
1939
1940 // Test support for absolute send time header extension.
1941 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1942 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1943 }
1944 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1945 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1946 }
1947
1948 // Test that we can create a channel and start sending on it.
1949 TEST_F(WebRtcVoiceEngineTestFake, Send) {
1950 EXPECT_TRUE(SetupEngineWithSendStream());
1951 int channel_num = voe_.GetLastChannel();
1952 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1953 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1954 EXPECT_TRUE(voe_.GetSend(channel_num));
1955 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1956 EXPECT_FALSE(voe_.GetSend(channel_num));
1957 }
1958
1959 // Test that we can create a channel and start playing out on it.
1960 TEST_F(WebRtcVoiceEngineTestFake, Playout) {
1961 EXPECT_TRUE(SetupEngineWithRecvStream());
1962 int channel_num = voe_.GetLastChannel();
1963 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1964 EXPECT_TRUE(channel_->SetPlayout(true));
1965 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1966 EXPECT_TRUE(channel_->SetPlayout(false));
1967 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1968 }
1969
1970 // Test that we can add and remove send streams.
1971 TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1972 SetupForMultiSendStream();
1973
1974 // Set the global state for sending.
1975 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1976
1977 for (uint32_t ssrc : kSsrcs4) {
1978 EXPECT_TRUE(channel_->AddSendStream(
1979 cricket::StreamParams::CreateLegacy(ssrc)));
1980 // Verify that we are in a sending state for all the created streams.
1981 EXPECT_TRUE(voe_.GetSend(GetSendStreamConfig(ssrc).voe_channel_id));
1982 }
1983 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
1984
1985 // Delete the send streams.
1986 for (uint32_t ssrc : kSsrcs4) {
1987 EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
1988 EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
1989 EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
1990 }
1991 EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
1992 }
1993
1994 // Test SetSendCodecs correctly configure the codecs in all send streams.
1995 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1996 SetupForMultiSendStream();
1997
1998 // Create send streams.
1999 for (uint32_t ssrc : kSsrcs4) {
2000 EXPECT_TRUE(channel_->AddSendStream(
2001 cricket::StreamParams::CreateLegacy(ssrc)));
2002 }
2003
2004 cricket::AudioSendParameters parameters;
2005 // Set ISAC(16K) and CN(16K). VAD should be activated.
2006 parameters.codecs.push_back(kIsacCodec);
2007 parameters.codecs.push_back(kCn16000Codec);
2008 parameters.codecs[1].id = 97;
2009 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2010
2011 // Verify ISAC and VAD are corrected configured on all send channels.
2012 webrtc::CodecInst gcodec;
2013 for (uint32_t ssrc : kSsrcs4) {
2014 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2015 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
2016 EXPECT_STREQ("ISAC", gcodec.plname);
2017 EXPECT_TRUE(voe_.GetVAD(channel_num));
2018 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
2019 }
2020
2021 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
2022 parameters.codecs[0] = kPcmuCodec;
2023 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2024 for (uint32_t ssrc : kSsrcs4) {
2025 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2026 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
2027 EXPECT_STREQ("PCMU", gcodec.plname);
2028 EXPECT_FALSE(voe_.GetVAD(channel_num));
2029 }
2030 }
2031
2032 // Test we can SetSend on all send streams correctly.
2033 TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2034 SetupForMultiSendStream();
2035
2036 // Create the send channels and they should be a SEND_NOTHING date.
2037 for (uint32_t ssrc : kSsrcs4) {
2038 EXPECT_TRUE(channel_->AddSendStream(
2039 cricket::StreamParams::CreateLegacy(ssrc)));
2040 int channel_num = voe_.GetLastChannel();
2041 EXPECT_FALSE(voe_.GetSend(channel_num));
2042 }
2043
2044 // Set the global state for starting sending.
2045 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2046 for (uint32_t ssrc : kSsrcs4) {
2047 // Verify that we are in a sending state for all the send streams.
2048 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2049 EXPECT_TRUE(voe_.GetSend(channel_num));
2050 }
2051
2052 // Set the global state for stopping sending.
2053 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2054 for (uint32_t ssrc : kSsrcs4) {
2055 // Verify that we are in a stop state for all the send streams.
2056 int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2057 EXPECT_FALSE(voe_.GetSend(channel_num));
2058 }
2059 }
2060
2061 // Test we can set the correct statistics on all send streams.
2062 TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2063 SetupForMultiSendStream();
2064
2065 // Create send streams.
2066 for (uint32_t ssrc : kSsrcs4) {
2067 EXPECT_TRUE(channel_->AddSendStream(
2068 cricket::StreamParams::CreateLegacy(ssrc)));
2069 }
2070 SetAudioSendStreamStats();
2071
2072 // Create a receive stream to check that none of the send streams end up in
2073 // the receive stream stats.
2074 EXPECT_TRUE(channel_->AddRecvStream(
2075 cricket::StreamParams::CreateLegacy(kSsrc2)));
2076 // We need send codec to be set to get all stats.
2077 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2078 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2079
2080 // Check stats for the added streams.
2081 {
2082 cricket::VoiceMediaInfo info;
2083 EXPECT_EQ(true, channel_->GetStats(&info));
2084
2085 // We have added 4 send streams. We should see empty stats for all.
2086 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2087 for (const auto& sender : info.senders) {
2088 VerifyVoiceSenderInfo(sender, false);
2089 }
2090
2091 // We have added one receive stream. We should see empty stats.
2092 EXPECT_EQ(info.receivers.size(), 1u);
2093 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2094 }
2095
2096 // Remove the kSsrc2 stream. No receiver stats.
2097 {
2098 cricket::VoiceMediaInfo info;
2099 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2100 EXPECT_EQ(true, channel_->GetStats(&info));
2101 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2102 EXPECT_EQ(0u, info.receivers.size());
2103 }
2104
2105 // Deliver a new packet - a default receive stream should be created and we
2106 // should see stats again.
2107 {
2108 cricket::VoiceMediaInfo info;
2109 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2110 SetAudioReceiveStreamStats();
2111 EXPECT_EQ(true, channel_->GetStats(&info));
2112 EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2113 EXPECT_EQ(1u, info.receivers.size());
2114 VerifyVoiceReceiverInfo(info.receivers[0]);
2115 }
2116 }
2117
2118 // Test that we can add and remove receive streams, and do proper send/playout.
2119 // We can receive on multiple streams while sending one stream.
2120 TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
2121 EXPECT_TRUE(SetupEngineWithSendStream());
2122 int channel_num1 = voe_.GetLastChannel();
2123
2124 // Start playout without a receive stream.
2125 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2126 EXPECT_TRUE(channel_->SetPlayout(true));
2127 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2128
2129 // Adding another stream should enable playout on the new stream only.
2130 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2131 int channel_num2 = voe_.GetLastChannel();
2132 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2133 EXPECT_TRUE(voe_.GetSend(channel_num1));
2134 EXPECT_FALSE(voe_.GetSend(channel_num2));
2135
2136 // Make sure only the new stream is played out.
2137 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2138 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2139
2140 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2141 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2142 int channel_num3 = voe_.GetLastChannel();
2143 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2144 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2145 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2146 EXPECT_FALSE(voe_.GetSend(channel_num3));
2147
2148 // Stop sending.
2149 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2150 EXPECT_FALSE(voe_.GetSend(channel_num1));
2151 EXPECT_FALSE(voe_.GetSend(channel_num2));
2152 EXPECT_FALSE(voe_.GetSend(channel_num3));
2153
2154 // Stop playout.
2155 EXPECT_TRUE(channel_->SetPlayout(false));
2156 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2157 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2158 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2159
2160 // Restart playout and make sure only recv streams are played out.
2161 EXPECT_TRUE(channel_->SetPlayout(true));
2162 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2163 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2164 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2165
2166 // Now remove the recv streams and verify that the send stream doesn't play.
2167 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2168 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2169 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2170 }
2171
2172 // Test that we can create a channel configured for Codian bridges,
2173 // and start sending on it.
2174 TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
2175 EXPECT_TRUE(SetupEngineWithSendStream());
2176 cricket::AudioOptions options_adjust_agc;
2177 options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
2178 int channel_num = voe_.GetLastChannel();
2179 webrtc::AgcConfig agc_config;
2180 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2181 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2182 send_parameters_.options = options_adjust_agc;
2183 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2184 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2185 EXPECT_TRUE(voe_.GetSend(channel_num));
2186 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2187 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2188 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2189 EXPECT_FALSE(voe_.GetSend(channel_num));
2190 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2191 }
2192
2193 TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2194 EXPECT_TRUE(SetupEngineWithSendStream());
2195 webrtc::AgcConfig agc_config;
2196 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2197 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2198 send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2199 send_parameters_.options.tx_agc_digital_compression_gain =
2200 rtc::Optional<uint16_t>(9);
2201 send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2202 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2203 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2204 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2205 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2206 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2207 EXPECT_TRUE(agc_config.limiterEnable);
2208
2209 // Check interaction with adjust_agc_delta. Both should be respected, for
2210 // backwards compatibility.
2211 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2212 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2213 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2214 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2215 }
2216
2217 TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2218 EXPECT_TRUE(SetupEngineWithSendStream());
2219 send_parameters_.options.recording_sample_rate =
2220 rtc::Optional<uint32_t>(48000);
2221 send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
2222 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2223
2224 unsigned int recording_sample_rate, playout_sample_rate;
2225 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2226 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2227 EXPECT_EQ(48000u, recording_sample_rate);
2228 EXPECT_EQ(44100u, playout_sample_rate);
2229 }
2230
2231 // Test that we can set the outgoing SSRC properly.
2232 // SSRC is set in SetupEngine by calling AddSendStream.
2233 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2234 EXPECT_TRUE(SetupEngineWithSendStream());
2235 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2236 }
2237
2238 TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2239 // Setup. We need send codec to be set to get all stats.
2240 EXPECT_TRUE(SetupEngineWithSendStream());
2241 SetAudioSendStreamStats();
2242 // SetupEngineWithSendStream adds a send stream with kSsrc1, so the receive
2243 // stream has to use a different SSRC.
2244 EXPECT_TRUE(channel_->AddRecvStream(
2245 cricket::StreamParams::CreateLegacy(kSsrc2)));
2246 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2247 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2248
2249 // Check stats for the added streams.
2250 {
2251 cricket::VoiceMediaInfo info;
2252 EXPECT_EQ(true, channel_->GetStats(&info));
2253
2254 // We have added one send stream. We should see the stats we've set.
2255 EXPECT_EQ(1u, info.senders.size());
2256 VerifyVoiceSenderInfo(info.senders[0], false);
2257 // We have added one receive stream. We should see empty stats.
2258 EXPECT_EQ(info.receivers.size(), 1u);
2259 EXPECT_EQ(info.receivers[0].ssrc(), 0);
2260 }
2261
2262 // Start sending - this affects some reported stats.
2263 {
2264 cricket::VoiceMediaInfo info;
2265 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2266 EXPECT_EQ(true, channel_->GetStats(&info));
2267 VerifyVoiceSenderInfo(info.senders[0], true);
2268 }
2269
2270 // Remove the kSsrc2 stream. No receiver stats.
2271 {
2272 cricket::VoiceMediaInfo info;
2273 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2274 EXPECT_EQ(true, channel_->GetStats(&info));
2275 EXPECT_EQ(1u, info.senders.size());
2276 EXPECT_EQ(0u, info.receivers.size());
2277 }
2278
2279 // Deliver a new packet - a default receive stream should be created and we
2280 // should see stats again.
2281 {
2282 cricket::VoiceMediaInfo info;
2283 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2284 SetAudioReceiveStreamStats();
2285 EXPECT_EQ(true, channel_->GetStats(&info));
2286 EXPECT_EQ(1u, info.senders.size());
2287 EXPECT_EQ(1u, info.receivers.size());
2288 VerifyVoiceReceiverInfo(info.receivers[0]);
2289 }
2290 }
2291
2292 // Test that we can set the outgoing SSRC properly with multiple streams.
2293 // SSRC is set in SetupEngine by calling AddSendStream.
2294 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2295 EXPECT_TRUE(SetupEngineWithSendStream());
2296 EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2297 EXPECT_TRUE(channel_->AddRecvStream(
2298 cricket::StreamParams::CreateLegacy(kSsrc2)));
2299 EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
2300 }
2301
2302 // Test that the local SSRC is the same on sending and receiving channels if the
2303 // receive channel is created before the send channel.
2304 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2305 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2306 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
2307
2308 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2309 int receive_channel_num = voe_.GetLastChannel();
2310 EXPECT_TRUE(channel_->AddSendStream(
2311 cricket::StreamParams::CreateLegacy(1234)));
2312
2313 EXPECT_TRUE(call_.GetAudioSendStream(1234));
2314 EXPECT_EQ(1234U, voe_.GetLocalSSRC(receive_channel_num));
2315 }
2316
2317 // Test that we can properly receive packets.
2318 TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2319 EXPECT_TRUE(SetupEngine());
2320 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2321 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2322 int channel_num = voe_.GetLastChannel();
2323 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
2324 }
2325
2326 // Test that we can properly receive packets on multiple streams.
2327 TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2328 EXPECT_TRUE(SetupEngine());
2329 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2330 int channel_num1 = voe_.GetLastChannel();
2331 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2332 int channel_num2 = voe_.GetLastChannel();
2333 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2334 int channel_num3 = voe_.GetLastChannel();
2335 // Create packets with the right SSRCs.
2336 char packets[4][sizeof(kPcmuFrame)];
2337 for (size_t i = 0; i < arraysize(packets); ++i) {
2338 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2339 rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
2340 }
2341 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2342 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2343 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2344
2345 DeliverPacket(packets[0], sizeof(packets[0]));
2346 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2347 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2348 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2349
2350 DeliverPacket(packets[1], sizeof(packets[1]));
2351 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1], sizeof(packets[1])));
2352 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2353 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2354
2355 DeliverPacket(packets[2], sizeof(packets[2]));
2356 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2357 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2], sizeof(packets[2])));
2358 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2359
2360 DeliverPacket(packets[3], sizeof(packets[3]));
2361 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2362 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2363 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3], sizeof(packets[3])));
2364
2365 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2366 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2367 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2368 }
2369
2370 // Test that receiving on an unsignalled stream works (default channel will be
2371 // created).
2372 TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
2373 EXPECT_TRUE(SetupEngine());
2374 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2375 int channel_num = voe_.GetLastChannel();
2376 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
2377 }
2378
2379 // Test that receiving on an unsignalled stream works (default channel will be
2380 // created), and that packets will be forwarded to the default channel
2381 // regardless of their SSRCs.
2382 TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
2383 EXPECT_TRUE(SetupEngine());
2384 char packet[sizeof(kPcmuFrame)];
2385 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2386
2387 // Note that the first unknown SSRC cannot be 0, because we only support
2388 // creating receive streams for SSRC!=0.
2389 DeliverPacket(packet, sizeof(packet));
2390 int channel_num = voe_.GetLastChannel();
2391 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2392 // Once we have the default channel, SSRC==0 will be ok.
2393 for (uint32_t ssrc = 0; ssrc < 10; ++ssrc) {
2394 rtc::SetBE32(&packet[8], ssrc);
2395 DeliverPacket(packet, sizeof(packet));
2396 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2397 }
2398 }
2399
2400 // Test that a default channel is created even after a signalled stream has been
2401 // added, and that this stream will get any packets for unknown SSRCs.
2402 TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
2403 EXPECT_TRUE(SetupEngine());
2404 char packet[sizeof(kPcmuFrame)];
2405 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2406
2407 // Add a known stream, send packet and verify we got it.
2408 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2409 int signalled_channel_num = voe_.GetLastChannel();
2410 DeliverPacket(packet, sizeof(packet));
2411 EXPECT_TRUE(voe_.CheckPacket(signalled_channel_num, packet, sizeof(packet)));
2412
2413 // Note that the first unknown SSRC cannot be 0, because we only support
2414 // creating receive streams for SSRC!=0.
2415 rtc::SetBE32(&packet[8], 7011);
2416 DeliverPacket(packet, sizeof(packet));
2417 int channel_num = voe_.GetLastChannel();
2418 EXPECT_NE(channel_num, signalled_channel_num);
2419 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2420 // Once we have the default channel, SSRC==0 will be ok.
2421 for (uint32_t ssrc = 0; ssrc < 20; ssrc += 2) {
2422 rtc::SetBE32(&packet[8], ssrc);
2423 DeliverPacket(packet, sizeof(packet));
2424 EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2425 }
2426 }
2427
2428 // Test that we properly handle failures to add a receive stream.
2429 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
2430 EXPECT_TRUE(SetupEngine());
2431 voe_.set_fail_create_channel(true);
2432 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2433 }
2434
2435 // Test that we properly handle failures to add a send stream.
2436 TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
2437 EXPECT_TRUE(SetupEngine());
2438 voe_.set_fail_create_channel(true);
2439 EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2440 }
2441
2442 // Test that AddRecvStream creates new stream.
2443 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
2444 EXPECT_TRUE(SetupEngineWithRecvStream());
2445 int channel_num = voe_.GetLastChannel();
2446 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2447 EXPECT_NE(channel_num, voe_.GetLastChannel());
2448 }
2449
2450 // Test that after adding a recv stream, we do not decode more codecs than
2451 // those previously passed into SetRecvCodecs.
2452 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2453 EXPECT_TRUE(SetupEngineWithSendStream());
2454 cricket::AudioRecvParameters parameters;
2455 parameters.codecs.push_back(kIsacCodec);
2456 parameters.codecs.push_back(kPcmuCodec);
2457 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2458 EXPECT_TRUE(channel_->AddRecvStream(
2459 cricket::StreamParams::CreateLegacy(kSsrc1)));
2460 int channel_num2 = voe_.GetLastChannel();
2461 webrtc::CodecInst gcodec;
2462 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
2463 gcodec.plfreq = 48000;
2464 gcodec.channels = 2;
2465 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2466 }
2467
2468 // Test that we properly clean up any streams that were added, even if
2469 // not explicitly removed.
2470 TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2471 EXPECT_TRUE(SetupEngineWithSendStream());
2472 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2473 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2474 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2475 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2476 delete channel_;
2477 channel_ = NULL;
2478 EXPECT_EQ(0, voe_.GetNumChannels());
2479 }
2480
2481 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2482 EXPECT_TRUE(SetupEngineWithSendStream());
2483 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2484 }
2485
2486 TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2487 EXPECT_TRUE(SetupEngine());
2488 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2489 // Manually delete channel to simulate a failure.
2490 int channel = voe_.GetLastChannel();
2491 EXPECT_EQ(0, voe_.DeleteChannel(channel));
2492 // Add recv stream 2 should work.
2493 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2494 int new_channel = voe_.GetLastChannel();
2495 EXPECT_NE(channel, new_channel);
2496 // The last created channel is deleted too.
2497 EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
2498 }
2499
2500 // Test the InsertDtmf on default send stream as caller.
2501 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2502 TestInsertDtmf(0, true);
2503 }
2504
2505 // Test the InsertDtmf on default send stream as callee
2506 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2507 TestInsertDtmf(0, false);
2508 }
2509
2510 // Test the InsertDtmf on specified send stream as caller.
2511 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2512 TestInsertDtmf(kSsrc1, true);
2513 }
2514
2515 // Test the InsertDtmf on specified send stream as callee.
2516 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2517 TestInsertDtmf(kSsrc1, false);
2518 }
2519
2520 TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2521 EXPECT_TRUE(SetupEngineWithSendStream());
2522 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2523 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2524 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2525 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2526 EXPECT_TRUE(channel_->SetPlayout(true));
2527 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2528 EXPECT_TRUE(channel_->SetPlayout(false));
2529 EXPECT_FALSE(channel_->SetPlayout(true));
2530 }
2531
2532 TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2533 EXPECT_TRUE(SetupEngineWithSendStream());
2534
2535 bool ec_enabled;
2536 webrtc::EcModes ec_mode;
2537 webrtc::AecmModes aecm_mode;
2538 bool cng_enabled;
2539 bool agc_enabled;
2540 webrtc::AgcModes agc_mode;
2541 webrtc::AgcConfig agc_config;
2542 bool ns_enabled;
2543 webrtc::NsModes ns_mode;
2544 bool highpass_filter_enabled;
2545 bool stereo_swapping_enabled;
2546 bool typing_detection_enabled;
2547 voe_.GetEcStatus(ec_enabled, ec_mode);
2548 voe_.GetAecmMode(aecm_mode, cng_enabled);
2549 voe_.GetAgcStatus(agc_enabled, agc_mode);
2550 voe_.GetAgcConfig(agc_config);
2551 voe_.GetNsStatus(ns_enabled, ns_mode);
2552 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2553 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2554 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2555 EXPECT_TRUE(ec_enabled);
2556 EXPECT_TRUE(voe_.ec_metrics_enabled());
2557 EXPECT_FALSE(cng_enabled);
2558 EXPECT_TRUE(agc_enabled);
2559 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2560 EXPECT_TRUE(ns_enabled);
2561 EXPECT_TRUE(highpass_filter_enabled);
2562 EXPECT_FALSE(stereo_swapping_enabled);
2563 EXPECT_TRUE(typing_detection_enabled);
2564 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2565 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2566 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2567 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
2568
2569 // Nothing set in AudioOptions, so everything should be as default.
2570 send_parameters_.options = cricket::AudioOptions();
2571 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2572 voe_.GetEcStatus(ec_enabled, ec_mode);
2573 voe_.GetAecmMode(aecm_mode, cng_enabled);
2574 voe_.GetAgcStatus(agc_enabled, agc_mode);
2575 voe_.GetAgcConfig(agc_config);
2576 voe_.GetNsStatus(ns_enabled, ns_mode);
2577 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2578 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2579 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2580 EXPECT_TRUE(ec_enabled);
2581 EXPECT_TRUE(voe_.ec_metrics_enabled());
2582 EXPECT_FALSE(cng_enabled);
2583 EXPECT_TRUE(agc_enabled);
2584 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2585 EXPECT_TRUE(ns_enabled);
2586 EXPECT_TRUE(highpass_filter_enabled);
2587 EXPECT_FALSE(stereo_swapping_enabled);
2588 EXPECT_TRUE(typing_detection_enabled);
2589 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2590 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2591 EXPECT_EQ(50, voe_.GetNetEqCapacity());
2592 EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
2593
2594 // Turn echo cancellation off
2595 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
2596 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2597 voe_.GetEcStatus(ec_enabled, ec_mode);
2598 EXPECT_FALSE(ec_enabled);
2599
2600 // Turn echo cancellation back on, with settings, and make sure
2601 // nothing else changed.
2602 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
2603 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2604 voe_.GetEcStatus(ec_enabled, ec_mode);
2605 voe_.GetAecmMode(aecm_mode, cng_enabled);
2606 voe_.GetAgcStatus(agc_enabled, agc_mode);
2607 voe_.GetAgcConfig(agc_config);
2608 voe_.GetNsStatus(ns_enabled, ns_mode);
2609 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2610 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2611 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2612 EXPECT_TRUE(ec_enabled);
2613 EXPECT_TRUE(voe_.ec_metrics_enabled());
2614 EXPECT_TRUE(agc_enabled);
2615 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2616 EXPECT_TRUE(ns_enabled);
2617 EXPECT_TRUE(highpass_filter_enabled);
2618 EXPECT_FALSE(stereo_swapping_enabled);
2619 EXPECT_TRUE(typing_detection_enabled);
2620 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2621 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2622
2623 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2624 // control.
2625 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
2626 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2627 voe_.GetEcStatus(ec_enabled, ec_mode);
2628 voe_.GetAecmMode(aecm_mode, cng_enabled);
2629 EXPECT_TRUE(ec_enabled);
2630 EXPECT_TRUE(voe_.ec_metrics_enabled());
2631 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2632
2633 // Turn off echo cancellation and delay agnostic aec.
2634 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2635 send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2636 send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
2637 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2638 voe_.GetEcStatus(ec_enabled, ec_mode);
2639 EXPECT_FALSE(ec_enabled);
2640 // Turning delay agnostic aec back on should also turn on echo cancellation.
2641 send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
2642 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2643 voe_.GetEcStatus(ec_enabled, ec_mode);
2644 EXPECT_TRUE(ec_enabled);
2645 EXPECT_TRUE(voe_.ec_metrics_enabled());
2646 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2647
2648 // Turn off AGC
2649 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
2650 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2651 voe_.GetAgcStatus(agc_enabled, agc_mode);
2652 EXPECT_FALSE(agc_enabled);
2653
2654 // Turn AGC back on
2655 send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2656 send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
2657 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2658 voe_.GetAgcStatus(agc_enabled, agc_mode);
2659 EXPECT_TRUE(agc_enabled);
2660 voe_.GetAgcConfig(agc_config);
2661 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2662
2663 // Turn off other options (and stereo swapping on).
2664 send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2665 send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2666 send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2667 send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
2668 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2669 voe_.GetNsStatus(ns_enabled, ns_mode);
2670 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2671 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2672 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2673 EXPECT_FALSE(ns_enabled);
2674 EXPECT_FALSE(highpass_filter_enabled);
2675 EXPECT_FALSE(typing_detection_enabled);
2676 EXPECT_TRUE(stereo_swapping_enabled);
2677
2678 // Set options again to ensure it has no impact.
2679 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2680 voe_.GetEcStatus(ec_enabled, ec_mode);
2681 voe_.GetNsStatus(ns_enabled, ns_mode);
2682 EXPECT_TRUE(ec_enabled);
2683 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2684 EXPECT_FALSE(ns_enabled);
2685 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2686 }
2687
2688 TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
2689 EXPECT_TRUE(SetupEngineWithSendStream());
2690
2691 bool ec_enabled;
2692 webrtc::EcModes ec_mode;
2693 bool agc_enabled;
2694 webrtc::AgcModes agc_mode;
2695 bool ns_enabled;
2696 webrtc::NsModes ns_mode;
2697 bool highpass_filter_enabled;
2698 bool stereo_swapping_enabled;
2699 bool typing_detection_enabled;
2700
2701 voe_.GetEcStatus(ec_enabled, ec_mode);
2702 voe_.GetAgcStatus(agc_enabled, agc_mode);
2703 voe_.GetNsStatus(ns_enabled, ns_mode);
2704 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2705 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2706 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2707 EXPECT_TRUE(ec_enabled);
2708 EXPECT_TRUE(agc_enabled);
2709 EXPECT_TRUE(ns_enabled);
2710 EXPECT_TRUE(highpass_filter_enabled);
2711 EXPECT_TRUE(typing_detection_enabled);
2712 EXPECT_FALSE(stereo_swapping_enabled);
2713 }
2714
2715 TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2716 webrtc::AgcConfig set_config = {0};
2717 set_config.targetLeveldBOv = 3;
2718 set_config.digitalCompressionGaindB = 9;
2719 set_config.limiterEnable = true;
2720 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2721 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2722
2723 webrtc::AgcConfig config = {0};
2724 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2725 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2726 EXPECT_EQ(set_config.digitalCompressionGaindB,
2727 config.digitalCompressionGaindB);
2728 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2729 }
2730
2731 TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2732 EXPECT_TRUE(SetupEngineWithSendStream());
2733 rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
2734 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2735 engine_.CreateChannel(&call_, cricket::AudioOptions())));
2736 rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
2737 static_cast<cricket::WebRtcVoiceMediaChannel*>(
2738 engine_.CreateChannel(&call_, cricket::AudioOptions())));
2739
2740 // Have to add a stream to make SetSend work.
2741 cricket::StreamParams stream1;
2742 stream1.ssrcs.push_back(1);
2743 channel1->AddSendStream(stream1);
2744 cricket::StreamParams stream2;
2745 stream2.ssrcs.push_back(2);
2746 channel2->AddSendStream(stream2);
2747
2748 // AEC and AGC and NS
2749 cricket::AudioSendParameters parameters_options_all = send_parameters_;
2750 parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2751 parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2752 parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
2753 ASSERT_TRUE(channel1->SetSendParameters(parameters_options_all));
2754 EXPECT_EQ(parameters_options_all.options, channel1->options());
2755 ASSERT_TRUE(channel2->SetSendParameters(parameters_options_all));
2756 EXPECT_EQ(parameters_options_all.options, channel2->options());
2757
2758 // unset NS
2759 cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
2760 parameters_options_no_ns.options.noise_suppression =
2761 rtc::Optional<bool>(false);
2762 ASSERT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
2763 cricket::AudioOptions expected_options = parameters_options_all.options;
2764 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2765 expected_options.auto_gain_control = rtc::Optional<bool>(true);
2766 expected_options.noise_suppression = rtc::Optional<bool>(false);
2767 EXPECT_EQ(expected_options, channel1->options());
2768
2769 // unset AGC
2770 cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
2771 parameters_options_no_agc.options.auto_gain_control =
2772 rtc::Optional<bool>(false);
2773 ASSERT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
2774 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2775 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2776 expected_options.noise_suppression = rtc::Optional<bool>(true);
2777 EXPECT_EQ(expected_options, channel2->options());
2778
2779 ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
2780 bool ec_enabled;
2781 webrtc::EcModes ec_mode;
2782 bool agc_enabled;
2783 webrtc::AgcModes agc_mode;
2784 bool ns_enabled;
2785 webrtc::NsModes ns_mode;
2786 voe_.GetEcStatus(ec_enabled, ec_mode);
2787 voe_.GetAgcStatus(agc_enabled, agc_mode);
2788 voe_.GetNsStatus(ns_enabled, ns_mode);
2789 EXPECT_TRUE(ec_enabled);
2790 EXPECT_TRUE(agc_enabled);
2791 EXPECT_TRUE(ns_enabled);
2792
2793 channel1->SetSend(cricket::SEND_MICROPHONE);
2794 voe_.GetEcStatus(ec_enabled, ec_mode);
2795 voe_.GetAgcStatus(agc_enabled, agc_mode);
2796 voe_.GetNsStatus(ns_enabled, ns_mode);
2797 EXPECT_TRUE(ec_enabled);
2798 EXPECT_TRUE(agc_enabled);
2799 EXPECT_FALSE(ns_enabled);
2800
2801 channel2->SetSend(cricket::SEND_MICROPHONE);
2802 voe_.GetEcStatus(ec_enabled, ec_mode);
2803 voe_.GetAgcStatus(agc_enabled, agc_mode);
2804 voe_.GetNsStatus(ns_enabled, ns_mode);
2805 EXPECT_TRUE(ec_enabled);
2806 EXPECT_FALSE(agc_enabled);
2807 EXPECT_TRUE(ns_enabled);
2808
2809 // Make sure settings take effect while we are sending.
2810 ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
2811 cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2812 send_parameters_;
2813 parameters_options_no_agc_nor_ns.options.auto_gain_control =
2814 rtc::Optional<bool>(false);
2815 parameters_options_no_agc_nor_ns.options.noise_suppression =
2816 rtc::Optional<bool>(false);
2817 channel2->SetSend(cricket::SEND_MICROPHONE);
2818 channel2->SetSendParameters(parameters_options_no_agc_nor_ns);
2819 expected_options.echo_cancellation = rtc::Optional<bool>(true);
2820 expected_options.auto_gain_control = rtc::Optional<bool>(false);
2821 expected_options.noise_suppression = rtc::Optional<bool>(false);
2822 EXPECT_EQ(expected_options, channel2->options());
2823 voe_.GetEcStatus(ec_enabled, ec_mode);
2824 voe_.GetAgcStatus(agc_enabled, agc_mode);
2825 voe_.GetNsStatus(ns_enabled, ns_mode);
2826 EXPECT_TRUE(ec_enabled);
2827 EXPECT_FALSE(agc_enabled);
2828 EXPECT_FALSE(ns_enabled);
2829 }
2830
2831 // This test verifies DSCP settings are properly applied on voice media channel.
2832 TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2833 EXPECT_TRUE(SetupEngineWithSendStream());
2834 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
2835 engine_.CreateChannel(&call_, cricket::AudioOptions()));
2836 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2837 new cricket::FakeNetworkInterface);
2838 channel->SetInterface(network_interface.get());
2839 cricket::AudioSendParameters parameters = send_parameters_;
2840 parameters.options.dscp = rtc::Optional<bool>(true);
2841 EXPECT_TRUE(channel->SetSendParameters(parameters));
2842 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2843 // Verify previous value is not modified if dscp option is not set.
2844 EXPECT_TRUE(channel->SetSendParameters(send_parameters_));
2845 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2846 parameters.options.dscp = rtc::Optional<bool>(false);
2847 EXPECT_TRUE(channel->SetSendParameters(parameters));
2848 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2849 }
2850
2851 TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
2852 EXPECT_TRUE(SetupEngine());
2853 cricket::WebRtcVoiceMediaChannel* media_channel =
2854 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2855 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
2856 EXPECT_TRUE(channel_->AddRecvStream(
2857 cricket::StreamParams::CreateLegacy(kSsrc1)));
2858 int channel_id = voe_.GetLastChannel();
2859 EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
2860 EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
2861 EXPECT_TRUE(channel_->AddRecvStream(
2862 cricket::StreamParams::CreateLegacy(kSsrc2)));
2863 int channel_id2 = voe_.GetLastChannel();
2864 EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
2865 }
2866
2867 TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
2868 EXPECT_TRUE(SetupEngine());
2869 cricket::WebRtcVoiceMediaChannel* media_channel =
2870 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2871 EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2872 EXPECT_TRUE(channel_->AddSendStream(
2873 cricket::StreamParams::CreateLegacy(kSsrc1)));
2874 int channel_id = voe_.GetLastChannel();
2875 EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
2876 EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
2877 EXPECT_TRUE(channel_->AddSendStream(
2878 cricket::StreamParams::CreateLegacy(kSsrc2)));
2879 int channel_id2 = voe_.GetLastChannel();
2880 EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
2881 }
2882
2883 TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
2884 EXPECT_TRUE(SetupEngine());
2885 EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
2886 cricket::StreamParams stream;
2887 stream.ssrcs.push_back(kSsrc2);
2888 EXPECT_TRUE(channel_->AddRecvStream(stream));
2889 int channel_id = voe_.GetLastChannel();
2890 EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
2891 float scale = 0;
2892 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2893 EXPECT_DOUBLE_EQ(3, scale);
2894 }
2895
2896 TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
2897 EXPECT_TRUE(SetupEngine());
2898 EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
2899 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2900 int channel_id = voe_.GetLastChannel();
2901 float scale = 0;
2902 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2903 EXPECT_DOUBLE_EQ(2, scale);
2904 EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
2905 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2906 EXPECT_DOUBLE_EQ(3, scale);
2907 }
2908
2909 TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
2910 const uint32_t kAudioSsrc = 123;
2911 const std::string kSyncLabel = "AvSyncLabel";
2912
2913 EXPECT_TRUE(SetupEngineWithSendStream());
2914 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
2915 sp.sync_label = kSyncLabel;
2916 // Creating two channels to make sure that sync label is set properly for both
2917 // the default voice channel and following ones.
2918 EXPECT_TRUE(channel_->AddRecvStream(sp));
2919 sp.ssrcs[0] += 1;
2920 EXPECT_TRUE(channel_->AddRecvStream(sp));
2921
2922 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
2923 EXPECT_EQ(kSyncLabel,
2924 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
2925 << "SyncGroup should be set based on sync_label";
2926 EXPECT_EQ(kSyncLabel,
2927 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
2928 << "SyncGroup should be set based on sync_label";
2929 }
2930
2931 TEST_F(WebRtcVoiceEngineTestFake, CanChangeCombinedBweOption) {
2932 // Test that changing the combined_audio_video_bwe option results in the
2933 // expected state changes on an associated Call.
2934 std::vector<uint32_t> ssrcs;
2935 ssrcs.push_back(223);
2936 ssrcs.push_back(224);
2937
2938 EXPECT_TRUE(SetupEngineWithSendStream());
2939 cricket::WebRtcVoiceMediaChannel* media_channel =
2940 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2941 for (uint32_t ssrc : ssrcs) {
2942 EXPECT_TRUE(media_channel->AddRecvStream(
2943 cricket::StreamParams::CreateLegacy(ssrc)));
2944 }
2945 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2946
2947 // Combined BWE should be disabled.
2948 for (uint32_t ssrc : ssrcs) {
2949 const auto* s = call_.GetAudioReceiveStream(ssrc);
2950 EXPECT_NE(nullptr, s);
2951 EXPECT_FALSE(s->GetConfig().combined_audio_video_bwe);
2952 }
2953
2954 // Enable combined BWE option - now it should be set up.
2955 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2956 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2957 for (uint32_t ssrc : ssrcs) {
2958 const auto* s = call_.GetAudioReceiveStream(ssrc);
2959 EXPECT_NE(nullptr, s);
2960 EXPECT_EQ(true, s->GetConfig().combined_audio_video_bwe);
2961 }
2962
2963 // Disable combined BWE option - should be disabled again.
2964 send_parameters_.options.combined_audio_video_bwe =
2965 rtc::Optional<bool>(false);
2966 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2967 for (uint32_t ssrc : ssrcs) {
2968 const auto* s = call_.GetAudioReceiveStream(ssrc);
2969 EXPECT_NE(nullptr, s);
2970 EXPECT_FALSE(s->GetConfig().combined_audio_video_bwe);
2971 }
2972
2973 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2974 }
2975
2976 TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
2977 // Test that adding receive streams after enabling combined bandwidth
2978 // estimation will correctly configure each channel.
2979 EXPECT_TRUE(SetupEngineWithSendStream());
2980 cricket::WebRtcVoiceMediaChannel* media_channel =
2981 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2982 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2983 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2984
2985 for (uint32_t ssrc : kSsrcs4) {
2986 EXPECT_TRUE(media_channel->AddRecvStream(
2987 cricket::StreamParams::CreateLegacy(ssrc)));
2988 EXPECT_NE(nullptr, call_.GetAudioReceiveStream(ssrc));
2989 }
2990 EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioReceiveStreams().size());
2991 }
2992
2993 // TODO(solenberg): Remove, once recv streams are configured through Call.
2994 // (This is then covered by TestSetRecvRtpHeaderExtensions.)
2995 TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
2996 // Test that setting the header extensions results in the expected state
2997 // changes on an associated Call.
2998 std::vector<uint32_t> ssrcs;
2999 ssrcs.push_back(223);
3000 ssrcs.push_back(224);
3001
3002 EXPECT_TRUE(SetupEngineWithSendStream());
3003 cricket::WebRtcVoiceMediaChannel* media_channel =
3004 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3005 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
3006 EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
3007 for (uint32_t ssrc : ssrcs) {
3008 EXPECT_TRUE(media_channel->AddRecvStream(
3009 cricket::StreamParams::CreateLegacy(ssrc)));
3010 }
3011
3012 // Combined BWE should be set up, but with no configured extensions.
3013 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
3014 for (uint32_t ssrc : ssrcs) {
3015 const auto* s = call_.GetAudioReceiveStream(ssrc);
3016 EXPECT_NE(nullptr, s);
3017 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3018 }
3019
3020 // Set up receive extensions.
3021 cricket::RtpCapabilities capabilities = engine_.GetCapabilities();
3022 cricket::AudioRecvParameters recv_parameters;
3023 recv_parameters.extensions = capabilities.header_extensions;
3024 channel_->SetRecvParameters(recv_parameters);
3025 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
3026 for (uint32_t ssrc : ssrcs) {
3027 const auto* s = call_.GetAudioReceiveStream(ssrc);
3028 EXPECT_NE(nullptr, s);
3029 const auto& s_exts = s->GetConfig().rtp.extensions;
3030 EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3031 for (const auto& e_ext : capabilities.header_extensions) {
3032 for (const auto& s_ext : s_exts) {
3033 if (e_ext.id == s_ext.id) {
3034 EXPECT_EQ(e_ext.uri, s_ext.name);
3035 }
3036 }
3037 }
3038 }
3039
3040 // Disable receive extensions.
3041 channel_->SetRecvParameters(cricket::AudioRecvParameters());
3042 for (uint32_t ssrc : ssrcs) {
3043 const auto* s = call_.GetAudioReceiveStream(ssrc);
3044 EXPECT_NE(nullptr, s);
3045 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3046 }
3047 }
3048
3049 TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3050 // Test that packets are forwarded to the Call when configured accordingly.
3051 const uint32_t kAudioSsrc = 1;
3052 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3053 static const unsigned char kRtcp[] = {
3054 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3055 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3056 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3057 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3058 };
3059 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3060
3061 EXPECT_TRUE(SetupEngineWithSendStream());
3062 cricket::WebRtcVoiceMediaChannel* media_channel =
3063 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3064 send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
3065 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3066 EXPECT_TRUE(media_channel->AddRecvStream(
3067 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3068
3069 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
3070 const cricket::FakeAudioReceiveStream* s =
3071 call_.GetAudioReceiveStream(kAudioSsrc);
3072 EXPECT_EQ(0, s->received_packets());
3073 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3074 EXPECT_EQ(1, s->received_packets());
3075 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3076 EXPECT_EQ(2, s->received_packets());
3077 }
3078
3079 // All receive channels should be associated with the first send channel,
3080 // since they do not send RTCP SR.
3081 TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel) {
3082 EXPECT_TRUE(SetupEngineWithSendStream());
3083 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3084 int default_channel = voe_.GetLastChannel();
3085 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3086 int recv_ch = voe_.GetLastChannel();
3087 EXPECT_NE(recv_ch, default_channel);
3088 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3089 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3090 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3091 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
3092 recv_ch = voe_.GetLastChannel();
3093 EXPECT_NE(recv_ch, default_channel);
3094 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3095 }
3096
3097 TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
3098 EXPECT_TRUE(SetupEngineWithSendStream());
3099 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3100
3101 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3102 int recv_ch = voe_.GetLastChannel();
3103
3104 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3105 int send_ch = voe_.GetLastChannel();
3106
3107 // Manually associate |recv_ch| to |send_ch|. This test is to verify a
3108 // deleting logic, i.e., deleting |send_ch| will reset the associate send
3109 // channel of |recv_ch|.This is not a common case, since, normally, only the
3110 // default channel can be associated. However, the default is not deletable.
3111 // So we force the |recv_ch| to associate with a non-default channel.
3112 EXPECT_EQ(0, voe_.AssociateSendChannel(recv_ch, send_ch));
3113 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), send_ch);
3114
3115 EXPECT_TRUE(channel_->RemoveSendStream(2));
3116 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3117 }
3118
3119 TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
3120 EXPECT_TRUE(SetupEngine());
3121 rtc::scoped_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3122 rtc::scoped_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
3123
3124 // Setting the sink before a recv stream exists should do nothing.
3125 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
3126 EXPECT_TRUE(
3127 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc1)));
3128 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3129
3130 // Now try actually setting the sink.
3131 channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
3132 EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
3133
3134 // Now try resetting it.
3135 channel_->SetRawAudioSink(kSsrc1, nullptr);
3136 EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
3137 }
3138
3139 TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
3140 EXPECT_TRUE(SetupEngine());
3141 rtc::scoped_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
3142 rtc::scoped_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
3143
3144 // Should be able to set a default sink even when no stream exists.
3145 channel_->SetRawAudioSink(0, std::move(fake_sink_1));
3146
3147 // Create default channel and ensure it's assigned the default sink.
3148 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3149 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3150
3151 // Try resetting the default sink.
3152 channel_->SetRawAudioSink(0, nullptr);
3153 EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
3154
3155 // Try setting the default sink while the default stream exists.
3156 channel_->SetRawAudioSink(0, std::move(fake_sink_2));
3157 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3158
3159 // If we remove and add a default stream, it should get the same sink.
3160 EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
3161 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
3162 EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
3163 }
3164
3165 // Tests that the library initializes and shuts down properly.
3166 TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3167 cricket::WebRtcVoiceEngine engine;
3168 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3169 rtc::scoped_ptr<webrtc::Call> call(
3170 webrtc::Call::Create(webrtc::Call::Config()));
3171 cricket::VoiceMediaChannel* channel =
3172 engine.CreateChannel(call.get(), cricket::AudioOptions());
3173 EXPECT_TRUE(channel != nullptr);
3174 delete channel;
3175 engine.Terminate();
3176
3177 // Reinit to catch regression where VoiceEngineObserver reference is lost
3178 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3179 engine.Terminate();
3180 }
3181
3182 // Tests that the library is configured with the codecs we want.
3183 TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3184 // Check codecs by name.
3185 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3186 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0), nullptr));
3187 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3188 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0), nullptr));
3189 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3190 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0), nullptr));
3191 // Check that name matching is case-insensitive.
3192 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3193 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0), nullptr));
3194 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3195 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0), nullptr));
3196 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3197 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0), nullptr));
3198 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3199 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0), nullptr));
3200 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3201 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0), nullptr));
3202 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3203 cricket::AudioCodec(96, "red", 8000, 0, 1, 0), nullptr));
3204 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3205 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0), nullptr));
3206 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3207 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0), nullptr));
3208 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3209 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0), nullptr));
3210 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3211 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0), nullptr));
3212 // Check codecs with an id by id.
3213 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3214 cricket::AudioCodec(0, "", 8000, 0, 1, 0), nullptr)); // PCMU
3215 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3216 cricket::AudioCodec(8, "", 8000, 0, 1, 0), nullptr)); // PCMA
3217 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3218 cricket::AudioCodec(9, "", 8000, 0, 1, 0), nullptr)); // G722
3219 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3220 cricket::AudioCodec(13, "", 8000, 0, 1, 0), nullptr)); // CN
3221 // Check sample/bitrate matching.
3222 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3223 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0), nullptr));
3224 // Check that bad codecs fail.
3225 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3226 cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0), nullptr));
3227 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3228 cricket::AudioCodec(88, "", 0, 0, 1, 0), nullptr));
3229 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3230 cricket::AudioCodec(0, "", 0, 0, 2, 0), nullptr));
3231 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3232 cricket::AudioCodec(0, "", 5000, 0, 1, 0), nullptr));
3233 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3234 cricket::AudioCodec(0, "", 0, 5000, 1, 0), nullptr));
3235
3236 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3237 cricket::WebRtcVoiceEngine engine;
3238 for (std::vector<cricket::AudioCodec>::const_iterator it =
3239 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3240 if (it->name == "CN" && it->clockrate == 16000) {
3241 EXPECT_EQ(105, it->id);
3242 } else if (it->name == "CN" && it->clockrate == 32000) {
3243 EXPECT_EQ(106, it->id);
3244 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3245 EXPECT_EQ(103, it->id);
3246 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3247 EXPECT_EQ(104, it->id);
3248 } else if (it->name == "G722" && it->clockrate == 8000) {
3249 EXPECT_EQ(9, it->id);
3250 } else if (it->name == "telephone-event") {
3251 EXPECT_EQ(126, it->id);
3252 } else if (it->name == "red") {
3253 EXPECT_EQ(127, it->id);
3254 } else if (it->name == "opus") {
3255 EXPECT_EQ(111, it->id);
3256 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3257 EXPECT_EQ("10", it->params.find("minptime")->second);
3258 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3259 EXPECT_EQ("60", it->params.find("maxptime")->second);
3260 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3261 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
3262 }
3263 }
3264 engine.Terminate();
3265 }
3266
3267 // Tests that VoE supports at least 32 channels
3268 TEST(WebRtcVoiceEngineTest, Has32Channels) {
3269 cricket::WebRtcVoiceEngine engine;
3270 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3271 rtc::scoped_ptr<webrtc::Call> call(
3272 webrtc::Call::Create(webrtc::Call::Config()));
3273
3274 cricket::VoiceMediaChannel* channels[32];
3275 int num_channels = 0;
3276 while (num_channels < arraysize(channels)) {
3277 cricket::VoiceMediaChannel* channel =
3278 engine.CreateChannel(call.get(), cricket::AudioOptions());
3279 if (!channel)
3280 break;
3281 channels[num_channels++] = channel;
3282 }
3283
3284 int expected = arraysize(channels);
3285 EXPECT_EQ(expected, num_channels);
3286
3287 while (num_channels > 0) {
3288 delete channels[--num_channels];
3289 }
3290 engine.Terminate();
3291 }
3292
3293 // Test that we set our preferred codecs properly.
3294 TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3295 cricket::WebRtcVoiceEngine engine;
3296 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3297 rtc::scoped_ptr<webrtc::Call> call(
3298 webrtc::Call::Create(webrtc::Call::Config()));
3299 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::AudioOptions(),
3300 call.get());
3301 cricket::AudioRecvParameters parameters;
3302 parameters.codecs = engine.codecs();
3303 EXPECT_TRUE(channel.SetRecvParameters(parameters));
3304 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698