blob: cf8a54f713ce9404a90f948069ac6e35c8abb08b [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001// Copyright 2008 Google Inc.
2//
3// Author: Justin Uberti (juberti@google.com)
4
5#ifdef WIN32
6#include "talk/base/win32.h"
7#include <objbase.h>
8#endif
9
10#include "talk/base/byteorder.h"
11#include "talk/base/gunit.h"
12#include "talk/media/base/constants.h"
13#include "talk/media/base/fakemediaengine.h"
14#include "talk/media/base/fakemediaprocessor.h"
wu@webrtc.orgde305012013-10-31 15:40:38 +000015#include "talk/media/base/fakenetworkinterface.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016#include "talk/media/base/fakertp.h"
17#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
18#include "talk/media/webrtc/webrtcvoiceengine.h"
19#include "talk/p2p/base/fakesession.h"
20#include "talk/session/media/channel.h"
21
22// Tests for the WebRtcVoiceEngine/VoiceChannel code.
23
24static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
25static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
26static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
27static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
28static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
29static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
30static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
31static const cricket::AudioCodec
32 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
33static const cricket::AudioCodec* const kAudioCodecs[] = {
34 &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
35 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
36};
37const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
38static uint32 kSsrc1 = 0x99;
39static uint32 kSsrc2 = 0x98;
40
41class FakeVoEWrapper : public cricket::VoEWrapper {
42 public:
43 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
44 : cricket::VoEWrapper(engine, // processing
45 engine, // base
46 engine, // codec
47 engine, // dtmf
48 engine, // file
49 engine, // hw
50 engine, // media
51 engine, // neteq
52 engine, // network
53 engine, // rtp
54 engine, // sync
55 engine) { // volume
56 }
57};
58
wu@webrtc.org97077a32013-10-25 21:18:33 +000059class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060 public:
61 virtual int SetTraceFilter(const unsigned int filter) {
wu@webrtc.org97077a32013-10-25 21:18:33 +000062 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063 return 0;
64 }
65 virtual int SetTraceFile(const char* fileNameUTF8) {
66 return 0;
67 }
68 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
69 return 0;
70 }
wu@webrtc.org97077a32013-10-25 21:18:33 +000071 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072};
73
74class WebRtcVoiceEngineTestFake : public testing::Test {
75 public:
76 class ChannelErrorListener : public sigslot::has_slots<> {
77 public:
78 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
79 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
80 ASSERT(channel != NULL);
81 channel->SignalMediaError.connect(
82 this, &ChannelErrorListener::OnVoiceChannelError);
83 }
84 void OnVoiceChannelError(uint32 ssrc,
85 cricket::VoiceMediaChannel::Error error) {
86 ssrc_ = ssrc;
87 error_ = error;
88 }
89 void Reset() {
90 ssrc_ = 0;
91 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
92 }
93 uint32 ssrc() const {
94 return ssrc_;
95 }
96 cricket::VoiceMediaChannel::Error error() const {
97 return error_;
98 }
99
100 private:
101 uint32 ssrc_;
102 cricket::VoiceMediaChannel::Error error_;
103 };
104
105 WebRtcVoiceEngineTestFake()
106 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
107 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000108 trace_wrapper_(new FakeVoETraceWrapper()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000109 engine_(new FakeVoEWrapper(&voe_),
110 new FakeVoEWrapper(&voe_sc_),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000111 trace_wrapper_),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112 channel_(NULL), soundclip_(NULL) {
113 options_conference_.conference_mode.Set(true);
114 options_adjust_agc_.adjust_agc_delta.Set(-10);
115 }
116 bool SetupEngine() {
117 bool result = engine_.Init(talk_base::Thread::Current());
118 if (result) {
119 channel_ = engine_.CreateChannel();
120 result = (channel_ != NULL);
121 }
122 if (result) {
123 result = channel_->AddSendStream(
124 cricket::StreamParams::CreateLegacy(kSsrc1));
125 }
126 return result;
127 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000128 void SetupForMultiSendStream() {
129 EXPECT_TRUE(SetupEngine());
130 // Remove stream added in Setup, which is corresponding to default channel.
131 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000132 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000133 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
134 EXPECT_EQ(kSsrc1, default_send_ssrc);
135 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
136
137 // Verify the default channel still exists.
138 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
139 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 void DeliverPacket(const void* data, int len) {
141 talk_base::Buffer packet(data, len);
142 channel_->OnPacketReceived(&packet);
143 }
144 virtual void TearDown() {
145 delete soundclip_;
146 delete channel_;
147 engine_.Terminate();
148 }
149
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000150 void TestInsertDtmf(uint32 ssrc, bool caller) {
151 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
152 channel_ = engine_.CreateChannel();
153 EXPECT_TRUE(channel_ != NULL);
154 if (caller) {
155 // if this is a caller, local description will be applied and add the
156 // send stream.
157 EXPECT_TRUE(channel_->AddSendStream(
158 cricket::StreamParams::CreateLegacy(kSsrc1)));
159 }
160 int channel_id = voe_.GetLastChannel();
161
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162 // Test we can only InsertDtmf when the other side supports telephone-event.
163 std::vector<cricket::AudioCodec> codecs;
164 codecs.push_back(kPcmuCodec);
165 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
166 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
167 EXPECT_FALSE(channel_->CanInsertDtmf());
168 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
169 codecs.push_back(kTelephoneEventCodec);
170 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
171 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000172
173 if (!caller) {
174 // There's no active send channel yet.
175 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
176 EXPECT_TRUE(channel_->AddSendStream(
177 cricket::StreamParams::CreateLegacy(kSsrc1)));
178 }
179
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 // Check we fail if the ssrc is invalid.
181 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
182
183 // Test send
184 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
185 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
186 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
187
188 // Test play
189 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
190 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
191 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
192
193 // Test send and play
194 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
195 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
196 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
197 cricket::DF_PLAY | cricket::DF_SEND));
198 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
199 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
200 }
201
202 // Test that send bandwidth is set correctly.
203 // |codec| is the codec under test.
204 // |default_bitrate| is the default bitrate for the codec.
205 // |auto_bitrate| is a parameter to set to SetSendBandwidth().
206 // |desired_bitrate| is a parameter to set to SetSendBandwidth().
207 // |expected_result| is expected results from SetSendBandwidth().
208 void TestSendBandwidth(const cricket::AudioCodec& codec,
209 int default_bitrate,
210 bool auto_bitrate,
211 int desired_bitrate,
212 bool expected_result) {
213 int channel_num = voe_.GetLastChannel();
214 std::vector<cricket::AudioCodec> codecs;
215
216 codecs.push_back(codec);
217 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
218
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000219 bool result = channel_->SetSendBandwidth(auto_bitrate, desired_bitrate);
220 EXPECT_EQ(expected_result, result);
221
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000222 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
224
225 if (result) {
226 // If SetSendBandwidth() returns true then bitrate is set correctly.
227 if (auto_bitrate) {
228 EXPECT_EQ(default_bitrate, temp_codec.rate);
229 } else {
230 EXPECT_EQ(desired_bitrate, temp_codec.rate);
231 }
232 } else {
233 // If SetSendBandwidth() returns false then bitrate is set to the
234 // default value.
235 EXPECT_EQ(default_bitrate, temp_codec.rate);
236 }
237 }
238
239
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000240 void TestSetSendRtpHeaderExtensions(int channel_id) {
241 std::vector<cricket::RtpHeaderExtension> extensions;
242 bool enable = false;
243 unsigned char id = 0;
244
245 // Ensure audio levels are off by default.
246 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
247 channel_id, enable, id));
248 EXPECT_FALSE(enable);
249
250 // Ensure unknown extensions won't cause an error.
251 extensions.push_back(cricket::RtpHeaderExtension(
252 "urn:ietf:params:unknowextention", 1));
253 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
254 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
255 channel_id, enable, id));
256 EXPECT_FALSE(enable);
257
258 // Ensure audio levels stay off with an empty list of headers.
259 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
260 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
261 channel_id, enable, id));
262 EXPECT_FALSE(enable);
263
264 // Ensure audio levels are enabled if the audio-level header is specified.
265 extensions.push_back(cricket::RtpHeaderExtension(
266 "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
267 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
268 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
269 channel_id, enable, id));
270 EXPECT_TRUE(enable);
271 EXPECT_EQ(8, id);
272
273 // Ensure audio levels go back off with an empty list.
274 extensions.clear();
275 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
276 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
277 channel_id, enable, id));
278 EXPECT_FALSE(enable);
279 }
280
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 protected:
282 cricket::FakeWebRtcVoiceEngine voe_;
283 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000284 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 cricket::WebRtcVoiceEngine engine_;
286 cricket::VoiceMediaChannel* channel_;
287 cricket::SoundclipMedia* soundclip_;
288
289 cricket::AudioOptions options_conference_;
290 cricket::AudioOptions options_adjust_agc_;
291};
292
293// Tests that our stub library "works".
294TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
295 EXPECT_FALSE(voe_.IsInited());
296 EXPECT_FALSE(voe_sc_.IsInited());
297 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
298 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000299 // The soundclip engine is lazily initialized.
300 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301 engine_.Terminate();
302 EXPECT_FALSE(voe_.IsInited());
303 EXPECT_FALSE(voe_sc_.IsInited());
304}
305
306// Tests that we can create and destroy a channel.
307TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
308 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
309 channel_ = engine_.CreateChannel();
310 EXPECT_TRUE(channel_ != NULL);
311}
312
313// Tests that we properly handle failures in CreateChannel.
314TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
315 voe_.set_fail_create_channel(true);
316 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
317 channel_ = engine_.CreateChannel();
318 EXPECT_TRUE(channel_ == NULL);
319}
320
321// Tests that the list of supported codecs is created properly and ordered
322// correctly
323TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
324 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
325 ASSERT_FALSE(codecs.empty());
326 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
327 EXPECT_EQ(48000, codecs[0].clockrate);
328 EXPECT_EQ(2, codecs[0].channels);
329 EXPECT_EQ(64000, codecs[0].bitrate);
330 int pref = codecs[0].preference;
331 for (size_t i = 1; i < codecs.size(); ++i) {
332 EXPECT_GT(pref, codecs[i].preference);
333 pref = codecs[i].preference;
334 }
335}
336
337// Tests that we can find codecs by name or id, and that we interpret the
338// clockrate and bitrate fields properly.
339TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
340 cricket::AudioCodec codec;
341 webrtc::CodecInst codec_inst;
342 // Find PCMU with explicit clockrate and bitrate.
343 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
344 // Find ISAC with explicit clockrate and 0 bitrate.
345 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
346 // Find telephone-event with explicit clockrate and 0 bitrate.
347 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
348 // Find ISAC with a different payload id.
349 codec = kIsacCodec;
350 codec.id = 127;
351 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
352 EXPECT_EQ(codec.id, codec_inst.pltype);
353 // Find PCMU with a 0 clockrate.
354 codec = kPcmuCodec;
355 codec.clockrate = 0;
356 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
357 EXPECT_EQ(codec.id, codec_inst.pltype);
358 EXPECT_EQ(8000, codec_inst.plfreq);
359 // Find PCMU with a 0 bitrate.
360 codec = kPcmuCodec;
361 codec.bitrate = 0;
362 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
363 EXPECT_EQ(codec.id, codec_inst.pltype);
364 EXPECT_EQ(64000, codec_inst.rate);
365 // Find ISAC with an explicit bitrate.
366 codec = kIsacCodec;
367 codec.bitrate = 32000;
368 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
369 EXPECT_EQ(codec.id, codec_inst.pltype);
370 EXPECT_EQ(32000, codec_inst.rate);
371}
372
373// Test that we set our inbound codecs properly, including changing PT.
374TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
375 EXPECT_TRUE(SetupEngine());
376 int channel_num = voe_.GetLastChannel();
377 std::vector<cricket::AudioCodec> codecs;
378 codecs.push_back(kIsacCodec);
379 codecs.push_back(kPcmuCodec);
380 codecs.push_back(kTelephoneEventCodec);
381 codecs[0].id = 106; // collide with existing telephone-event
382 codecs[2].id = 126;
383 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
384 webrtc::CodecInst gcodec;
385 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
386 gcodec.plfreq = 16000;
387 gcodec.channels = 1;
388 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
389 EXPECT_EQ(106, gcodec.pltype);
390 EXPECT_STREQ("ISAC", gcodec.plname);
391 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
392 "telephone-event");
393 gcodec.plfreq = 8000;
394 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
395 EXPECT_EQ(126, gcodec.pltype);
396 EXPECT_STREQ("telephone-event", gcodec.plname);
397}
398
399// Test that we fail to set an unknown inbound codec.
400TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
401 EXPECT_TRUE(SetupEngine());
402 std::vector<cricket::AudioCodec> codecs;
403 codecs.push_back(kIsacCodec);
404 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
405 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
406}
407
408// Test that we fail if we have duplicate types in the inbound list.
409TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
410 EXPECT_TRUE(SetupEngine());
411 std::vector<cricket::AudioCodec> codecs;
412 codecs.push_back(kIsacCodec);
413 codecs.push_back(kCn16000Codec);
414 codecs[1].id = kIsacCodec.id;
415 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
416}
417
418// Test that we can decode OPUS without stereo parameters.
419TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
420 EXPECT_TRUE(SetupEngine());
421 EXPECT_TRUE(channel_->SetOptions(options_conference_));
422 std::vector<cricket::AudioCodec> codecs;
423 codecs.push_back(kIsacCodec);
424 codecs.push_back(kPcmuCodec);
425 codecs.push_back(kOpusCodec);
426 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
427 EXPECT_TRUE(channel_->AddRecvStream(
428 cricket::StreamParams::CreateLegacy(kSsrc1)));
429 int channel_num2 = voe_.GetLastChannel();
430 webrtc::CodecInst opus;
431 engine_.FindWebRtcCodec(kOpusCodec, &opus);
432 // Even without stereo parameters, recv codecs still specify channels = 2.
433 EXPECT_EQ(2, opus.channels);
434 EXPECT_EQ(111, opus.pltype);
435 EXPECT_STREQ("opus", opus.plname);
436 opus.pltype = 0;
437 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
438 EXPECT_EQ(111, opus.pltype);
439}
440
441// Test that we can decode OPUS with stereo = 0.
442TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
443 EXPECT_TRUE(SetupEngine());
444 EXPECT_TRUE(channel_->SetOptions(options_conference_));
445 std::vector<cricket::AudioCodec> codecs;
446 codecs.push_back(kIsacCodec);
447 codecs.push_back(kPcmuCodec);
448 codecs.push_back(kOpusCodec);
449 codecs[2].params["stereo"] = "0";
450 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
451 EXPECT_TRUE(channel_->AddRecvStream(
452 cricket::StreamParams::CreateLegacy(kSsrc1)));
453 int channel_num2 = voe_.GetLastChannel();
454 webrtc::CodecInst opus;
455 engine_.FindWebRtcCodec(kOpusCodec, &opus);
456 // Even when stereo is off, recv codecs still specify channels = 2.
457 EXPECT_EQ(2, opus.channels);
458 EXPECT_EQ(111, opus.pltype);
459 EXPECT_STREQ("opus", opus.plname);
460 opus.pltype = 0;
461 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
462 EXPECT_EQ(111, opus.pltype);
463}
464
465// Test that we can decode OPUS with stereo = 1.
466TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
467 EXPECT_TRUE(SetupEngine());
468 EXPECT_TRUE(channel_->SetOptions(options_conference_));
469 std::vector<cricket::AudioCodec> codecs;
470 codecs.push_back(kIsacCodec);
471 codecs.push_back(kPcmuCodec);
472 codecs.push_back(kOpusCodec);
473 codecs[2].params["stereo"] = "1";
474 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
475 EXPECT_TRUE(channel_->AddRecvStream(
476 cricket::StreamParams::CreateLegacy(kSsrc1)));
477 int channel_num2 = voe_.GetLastChannel();
478 webrtc::CodecInst opus;
479 engine_.FindWebRtcCodec(kOpusCodec, &opus);
480 EXPECT_EQ(2, opus.channels);
481 EXPECT_EQ(111, opus.pltype);
482 EXPECT_STREQ("opus", opus.plname);
483 opus.pltype = 0;
484 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
485 EXPECT_EQ(111, opus.pltype);
486}
487
488// Test that changes to recv codecs are applied to all streams.
489TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
490 EXPECT_TRUE(SetupEngine());
491 EXPECT_TRUE(channel_->SetOptions(options_conference_));
492 std::vector<cricket::AudioCodec> codecs;
493 codecs.push_back(kIsacCodec);
494 codecs.push_back(kPcmuCodec);
495 codecs.push_back(kTelephoneEventCodec);
496 codecs[0].id = 106; // collide with existing telephone-event
497 codecs[2].id = 126;
498 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
499 EXPECT_TRUE(channel_->AddRecvStream(
500 cricket::StreamParams::CreateLegacy(kSsrc1)));
501 int channel_num2 = voe_.GetLastChannel();
502 webrtc::CodecInst gcodec;
503 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
504 gcodec.plfreq = 16000;
505 gcodec.channels = 1;
506 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
507 EXPECT_EQ(106, gcodec.pltype);
508 EXPECT_STREQ("ISAC", gcodec.plname);
509 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
510 "telephone-event");
511 gcodec.plfreq = 8000;
512 gcodec.channels = 1;
513 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
514 EXPECT_EQ(126, gcodec.pltype);
515 EXPECT_STREQ("telephone-event", gcodec.plname);
516}
517
518TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
519 EXPECT_TRUE(SetupEngine());
520 EXPECT_TRUE(channel_->SetOptions(options_conference_));
521 std::vector<cricket::AudioCodec> codecs;
522 codecs.push_back(kIsacCodec);
523 codecs[0].id = 106; // collide with existing telephone-event
524
525 EXPECT_TRUE(channel_->AddRecvStream(
526 cricket::StreamParams::CreateLegacy(kSsrc1)));
527 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
528
529 int channel_num2 = voe_.GetLastChannel();
530 webrtc::CodecInst gcodec;
531 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
532 gcodec.plfreq = 16000;
533 gcodec.channels = 1;
534 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
535 EXPECT_EQ(106, gcodec.pltype);
536 EXPECT_STREQ("ISAC", gcodec.plname);
537}
538
539// Test that we can apply the same set of codecs again while playing.
540TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
541 EXPECT_TRUE(SetupEngine());
542 int channel_num = voe_.GetLastChannel();
543 std::vector<cricket::AudioCodec> codecs;
544 codecs.push_back(kIsacCodec);
545 codecs.push_back(kCn16000Codec);
546 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
547 EXPECT_TRUE(channel_->SetPlayout(true));
548 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
549
550 // Changing the payload type of a codec should fail.
551 codecs[0].id = 127;
552 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
553 EXPECT_TRUE(voe_.GetPlayout(channel_num));
554}
555
556// Test that we can add a codec while playing.
557TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
558 EXPECT_TRUE(SetupEngine());
559 int channel_num = voe_.GetLastChannel();
560 std::vector<cricket::AudioCodec> codecs;
561 codecs.push_back(kIsacCodec);
562 codecs.push_back(kCn16000Codec);
563 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
564 EXPECT_TRUE(channel_->SetPlayout(true));
565
566 codecs.push_back(kOpusCodec);
567 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
568 EXPECT_TRUE(voe_.GetPlayout(channel_num));
569 webrtc::CodecInst gcodec;
570 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
571 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
572}
573
574TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
575 EXPECT_TRUE(SetupEngine());
576 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
577
578 // Test that when autobw is true, bitrate is kept as the default
579 // value. autobw is true for the following tests.
580
581 // ISAC, default bitrate == 32000.
582 TestSendBandwidth(kIsacCodec, 32000, true, 96000, true);
583
584 // PCMU, default bitrate == 64000.
585 TestSendBandwidth(kPcmuCodec, 64000, true, 96000, true);
586
587 // CELT, default bitrate == 64000.
588 TestSendBandwidth(kCeltCodec, 64000, true, 96000, true);
589
590 // opus, default bitrate == 64000.
591 TestSendBandwidth(kOpusCodec, 64000, true, 96000, true);
592}
593
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000594TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthFixedMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595 EXPECT_TRUE(SetupEngine());
596 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
597
598 // Test that we can set bitrate if a multi-rate codec is used.
599 // autobw is false for the following tests.
600
601 // ISAC, default bitrate == 32000.
602 TestSendBandwidth(kIsacCodec, 32000, false, 128000, true);
603
604 // CELT, default bitrate == 64000.
605 TestSendBandwidth(kCeltCodec, 64000, false, 96000, true);
606
607 // opus, default bitrate == 64000.
608 TestSendBandwidth(kOpusCodec, 64000, false, 96000, true);
609}
610
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000611TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthFixedMultiRateAsCallee) {
612 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
613 channel_ = engine_.CreateChannel();
614 EXPECT_TRUE(channel_ != NULL);
615 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
616
617 int desired_bitrate = 128000;
618 EXPECT_TRUE(channel_->SetSendBandwidth(false, desired_bitrate));
619
620 EXPECT_TRUE(channel_->AddSendStream(
621 cricket::StreamParams::CreateLegacy(kSsrc1)));
622
623 int channel_num = voe_.GetLastChannel();
624 webrtc::CodecInst codec;
625 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
626 EXPECT_EQ(desired_bitrate, codec.rate);
627}
628
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629// Test that bitrate cannot be set for CBR codecs.
630// Bitrate is ignored if it is higher than the fixed bitrate.
631// Bitrate less then the fixed bitrate is an error.
632TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthFixedCbr) {
633 EXPECT_TRUE(SetupEngine());
634 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
635
636 webrtc::CodecInst codec;
637 int channel_num = voe_.GetLastChannel();
638 std::vector<cricket::AudioCodec> codecs;
639
640 // PCMU, default bitrate == 64000.
641 codecs.push_back(kPcmuCodec);
642 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
643 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
644 EXPECT_EQ(64000, codec.rate);
645 EXPECT_TRUE(channel_->SetSendBandwidth(false, 128000));
646 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
647 EXPECT_EQ(64000, codec.rate);
648 EXPECT_FALSE(channel_->SetSendBandwidth(false, 128));
649 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
650 EXPECT_EQ(64000, codec.rate);
651}
652
653// Test that we apply codecs properly.
654TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
655 EXPECT_TRUE(SetupEngine());
656 int channel_num = voe_.GetLastChannel();
657 std::vector<cricket::AudioCodec> codecs;
658 codecs.push_back(kIsacCodec);
659 codecs.push_back(kPcmuCodec);
660 codecs.push_back(kRedCodec);
661 codecs[0].id = 96;
662 codecs[0].bitrate = 48000;
663 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
664 webrtc::CodecInst gcodec;
665 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
666 EXPECT_EQ(96, gcodec.pltype);
667 EXPECT_EQ(48000, gcodec.rate);
668 EXPECT_STREQ("ISAC", gcodec.plname);
669 EXPECT_FALSE(voe_.GetVAD(channel_num));
670 EXPECT_FALSE(voe_.GetFEC(channel_num));
671 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
672 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
673 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
674}
675
676// TODO(pthatcher): Change failure behavior to returning false rather
677// than defaulting to PCMU.
678// Test that if clockrate is not 48000 for opus, we fail by fallback to PCMU.
679TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
680 EXPECT_TRUE(SetupEngine());
681 int channel_num = voe_.GetLastChannel();
682 std::vector<cricket::AudioCodec> codecs;
683 codecs.push_back(kOpusCodec);
684 codecs[0].bitrate = 0;
685 codecs[0].clockrate = 50000;
686 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
687 webrtc::CodecInst gcodec;
688 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
689 EXPECT_STREQ("PCMU", gcodec.plname);
690}
691
692// Test that if channels=0 for opus, we fail by falling back to PCMU.
693TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
694 EXPECT_TRUE(SetupEngine());
695 int channel_num = voe_.GetLastChannel();
696 std::vector<cricket::AudioCodec> codecs;
697 codecs.push_back(kOpusCodec);
698 codecs[0].bitrate = 0;
699 codecs[0].channels = 0;
700 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
701 webrtc::CodecInst gcodec;
702 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
703 EXPECT_STREQ("PCMU", gcodec.plname);
704}
705
706// Test that if channels=0 for opus, we fail by falling back to PCMU.
707TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
708 EXPECT_TRUE(SetupEngine());
709 int channel_num = voe_.GetLastChannel();
710 std::vector<cricket::AudioCodec> codecs;
711 codecs.push_back(kOpusCodec);
712 codecs[0].bitrate = 0;
713 codecs[0].channels = 0;
714 codecs[0].params["stereo"] = "1";
715 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
716 webrtc::CodecInst gcodec;
717 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
718 EXPECT_STREQ("PCMU", gcodec.plname);
719}
720
721// Test that if channel is 1 for opus and there's no stereo, we fail.
722TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
723 EXPECT_TRUE(SetupEngine());
724 int channel_num = voe_.GetLastChannel();
725 std::vector<cricket::AudioCodec> codecs;
726 codecs.push_back(kOpusCodec);
727 codecs[0].bitrate = 0;
728 codecs[0].channels = 1;
729 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
730 webrtc::CodecInst gcodec;
731 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
732 EXPECT_STREQ("PCMU", gcodec.plname);
733}
734
735// Test that if channel is 1 for opus and stereo=0, we fail.
736TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
737 EXPECT_TRUE(SetupEngine());
738 int channel_num = voe_.GetLastChannel();
739 std::vector<cricket::AudioCodec> codecs;
740 codecs.push_back(kOpusCodec);
741 codecs[0].bitrate = 0;
742 codecs[0].channels = 1;
743 codecs[0].params["stereo"] = "0";
744 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
745 webrtc::CodecInst gcodec;
746 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
747 EXPECT_STREQ("PCMU", gcodec.plname);
748}
749
750// Test that if channel is 1 for opus and stereo=1, we fail.
751TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
752 EXPECT_TRUE(SetupEngine());
753 int channel_num = voe_.GetLastChannel();
754 std::vector<cricket::AudioCodec> codecs;
755 codecs.push_back(kOpusCodec);
756 codecs[0].bitrate = 0;
757 codecs[0].channels = 1;
758 codecs[0].params["stereo"] = "1";
759 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
760 webrtc::CodecInst gcodec;
761 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
762 EXPECT_STREQ("PCMU", gcodec.plname);
763}
764
765// Test that with bitrate=0 and no stereo,
766// channels and bitrate are 1 and 32000.
767TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
768 EXPECT_TRUE(SetupEngine());
769 int channel_num = voe_.GetLastChannel();
770 std::vector<cricket::AudioCodec> codecs;
771 codecs.push_back(kOpusCodec);
772 codecs[0].bitrate = 0;
773 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
774 webrtc::CodecInst gcodec;
775 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
776 EXPECT_STREQ("opus", gcodec.plname);
777 EXPECT_EQ(1, gcodec.channels);
778 EXPECT_EQ(32000, gcodec.rate);
779}
780
781// Test that with bitrate=0 and stereo=0,
782// channels and bitrate are 1 and 32000.
783TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
784 EXPECT_TRUE(SetupEngine());
785 int channel_num = voe_.GetLastChannel();
786 std::vector<cricket::AudioCodec> codecs;
787 codecs.push_back(kOpusCodec);
788 codecs[0].bitrate = 0;
789 codecs[0].params["stereo"] = "0";
790 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
791 webrtc::CodecInst gcodec;
792 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
793 EXPECT_STREQ("opus", gcodec.plname);
794 EXPECT_EQ(1, gcodec.channels);
795 EXPECT_EQ(32000, gcodec.rate);
796}
797
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000798// Test that with bitrate=invalid and stereo=0,
799// channels and bitrate are 1 and 32000.
800TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
801 EXPECT_TRUE(SetupEngine());
802 int channel_num = voe_.GetLastChannel();
803 std::vector<cricket::AudioCodec> codecs;
804 codecs.push_back(kOpusCodec);
805 codecs[0].params["stereo"] = "0";
806 webrtc::CodecInst gcodec;
807
808 // bitrate that's out of the range between 6000 and 510000 will be considered
809 // as invalid and ignored.
810 codecs[0].bitrate = 5999;
811 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
812 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
813 EXPECT_STREQ("opus", gcodec.plname);
814 EXPECT_EQ(1, gcodec.channels);
815 EXPECT_EQ(32000, gcodec.rate);
816
817 codecs[0].bitrate = 510001;
818 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
819 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
820 EXPECT_STREQ("opus", gcodec.plname);
821 EXPECT_EQ(1, gcodec.channels);
822 EXPECT_EQ(32000, gcodec.rate);
823}
824
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825// Test that with bitrate=0 and stereo=1,
826// channels and bitrate are 2 and 64000.
827TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
828 EXPECT_TRUE(SetupEngine());
829 int channel_num = voe_.GetLastChannel();
830 std::vector<cricket::AudioCodec> codecs;
831 codecs.push_back(kOpusCodec);
832 codecs[0].bitrate = 0;
833 codecs[0].params["stereo"] = "1";
834 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
835 webrtc::CodecInst gcodec;
836 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
837 EXPECT_STREQ("opus", gcodec.plname);
838 EXPECT_EQ(2, gcodec.channels);
839 EXPECT_EQ(64000, gcodec.rate);
840}
841
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000842// Test that with bitrate=invalid and stereo=1,
843// channels and bitrate are 2 and 64000.
844TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
845 EXPECT_TRUE(SetupEngine());
846 int channel_num = voe_.GetLastChannel();
847 std::vector<cricket::AudioCodec> codecs;
848 codecs.push_back(kOpusCodec);
849 codecs[0].params["stereo"] = "1";
850 webrtc::CodecInst gcodec;
851
852 // bitrate that's out of the range between 6000 and 510000 will be considered
853 // as invalid and ignored.
854 codecs[0].bitrate = 5999;
855 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
856 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
857 EXPECT_STREQ("opus", gcodec.plname);
858 EXPECT_EQ(2, gcodec.channels);
859 EXPECT_EQ(64000, gcodec.rate);
860
861 codecs[0].bitrate = 510001;
862 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
863 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
864 EXPECT_STREQ("opus", gcodec.plname);
865 EXPECT_EQ(2, gcodec.channels);
866 EXPECT_EQ(64000, gcodec.rate);
867}
868
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000869// Test that with bitrate=N and stereo unset,
870// channels and bitrate are 1 and N.
871TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
872 EXPECT_TRUE(SetupEngine());
873 int channel_num = voe_.GetLastChannel();
874 std::vector<cricket::AudioCodec> codecs;
875 codecs.push_back(kOpusCodec);
876 codecs[0].bitrate = 96000;
877 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
878 webrtc::CodecInst gcodec;
879 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
880 EXPECT_EQ(111, gcodec.pltype);
881 EXPECT_EQ(96000, gcodec.rate);
882 EXPECT_STREQ("opus", gcodec.plname);
883 EXPECT_EQ(1, gcodec.channels);
884 EXPECT_EQ(48000, gcodec.plfreq);
885}
886
887// Test that with bitrate=N and stereo=0,
888// channels and bitrate are 1 and N.
889TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
890 EXPECT_TRUE(SetupEngine());
891 int channel_num = voe_.GetLastChannel();
892 std::vector<cricket::AudioCodec> codecs;
893 codecs.push_back(kOpusCodec);
894 codecs[0].bitrate = 30000;
895 codecs[0].params["stereo"] = "0";
896 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
897 webrtc::CodecInst gcodec;
898 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
899 EXPECT_EQ(1, gcodec.channels);
900 EXPECT_EQ(30000, gcodec.rate);
901 EXPECT_STREQ("opus", gcodec.plname);
902}
903
904// Test that with bitrate=N and without any parameters,
905// channels and bitrate are 1 and N.
906TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
907 EXPECT_TRUE(SetupEngine());
908 int channel_num = voe_.GetLastChannel();
909 std::vector<cricket::AudioCodec> codecs;
910 codecs.push_back(kOpusCodec);
911 codecs[0].bitrate = 30000;
912 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
913 webrtc::CodecInst gcodec;
914 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
915 EXPECT_EQ(1, gcodec.channels);
916 EXPECT_EQ(30000, gcodec.rate);
917 EXPECT_STREQ("opus", gcodec.plname);
918}
919
920// Test that with bitrate=N and stereo=1,
921// channels and bitrate are 2 and N.
922TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
923 EXPECT_TRUE(SetupEngine());
924 int channel_num = voe_.GetLastChannel();
925 std::vector<cricket::AudioCodec> codecs;
926 codecs.push_back(kOpusCodec);
927 codecs[0].bitrate = 30000;
928 codecs[0].params["stereo"] = "1";
929 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
930 webrtc::CodecInst gcodec;
931 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
932 EXPECT_EQ(2, gcodec.channels);
933 EXPECT_EQ(30000, gcodec.rate);
934 EXPECT_STREQ("opus", gcodec.plname);
935}
936
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000937// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
938// Also test that the "maxaveragebitrate" can't be set to values outside the
939// range of 6000 and 510000
940TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
941 EXPECT_TRUE(SetupEngine());
942 int channel_num = voe_.GetLastChannel();
943 std::vector<cricket::AudioCodec> codecs;
944 codecs.push_back(kOpusCodec);
945 codecs[0].bitrate = 30000;
946 webrtc::CodecInst gcodec;
947
948 // Ignore if less than 6000.
949 codecs[0].params["maxaveragebitrate"] = "5999";
950 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
951 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
952 EXPECT_EQ(30000, gcodec.rate);
953
954 // Ignore if larger than 510000.
955 codecs[0].params["maxaveragebitrate"] = "510001";
956 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
957 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
958 EXPECT_EQ(30000, gcodec.rate);
959
960 codecs[0].params["maxaveragebitrate"] = "200000";
961 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
962 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
963 EXPECT_EQ(200000, gcodec.rate);
964}
965
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000966// Test that we can enable NACK with opus as caller.
967TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000968 EXPECT_TRUE(SetupEngine());
969 int channel_num = voe_.GetLastChannel();
970 std::vector<cricket::AudioCodec> codecs;
971 codecs.push_back(kOpusCodec);
972 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
973 cricket::kParamValueEmpty));
974 EXPECT_FALSE(voe_.GetNACK(channel_num));
975 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
976 EXPECT_TRUE(voe_.GetNACK(channel_num));
977}
978
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000979// Test that we can enable NACK with opus as callee.
980TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
981 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
982 channel_ = engine_.CreateChannel();
983 EXPECT_TRUE(channel_ != NULL);
984
985 int channel_num = voe_.GetLastChannel();
986 std::vector<cricket::AudioCodec> codecs;
987 codecs.push_back(kOpusCodec);
988 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
989 cricket::kParamValueEmpty));
990 EXPECT_FALSE(voe_.GetNACK(channel_num));
991 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
992 EXPECT_FALSE(voe_.GetNACK(channel_num));
993
994 EXPECT_TRUE(channel_->AddSendStream(
995 cricket::StreamParams::CreateLegacy(kSsrc1)));
996 EXPECT_TRUE(voe_.GetNACK(channel_num));
997}
998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999// Test that we can enable NACK on receive streams.
1000TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1001 EXPECT_TRUE(SetupEngine());
1002 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1003 int channel_num1 = voe_.GetLastChannel();
1004 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1005 int channel_num2 = voe_.GetLastChannel();
1006 std::vector<cricket::AudioCodec> codecs;
1007 codecs.push_back(kOpusCodec);
1008 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1009 cricket::kParamValueEmpty));
1010 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1011 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1012 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1013 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1014 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1015}
1016
1017// Test that we can disable NACK.
1018TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1019 EXPECT_TRUE(SetupEngine());
1020 int channel_num = voe_.GetLastChannel();
1021 std::vector<cricket::AudioCodec> codecs;
1022 codecs.push_back(kOpusCodec);
1023 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1024 cricket::kParamValueEmpty));
1025 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1026 EXPECT_TRUE(voe_.GetNACK(channel_num));
1027
1028 codecs.clear();
1029 codecs.push_back(kOpusCodec);
1030 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1031 EXPECT_FALSE(voe_.GetNACK(channel_num));
1032}
1033
1034// Test that we can disable NACK on receive streams.
1035TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1036 EXPECT_TRUE(SetupEngine());
1037 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1038 int channel_num1 = voe_.GetLastChannel();
1039 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1040 int channel_num2 = voe_.GetLastChannel();
1041 std::vector<cricket::AudioCodec> codecs;
1042 codecs.push_back(kOpusCodec);
1043 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1044 cricket::kParamValueEmpty));
1045 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1046 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1047 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1048
1049 codecs.clear();
1050 codecs.push_back(kOpusCodec);
1051 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1052 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1053 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1054}
1055
1056// Test that NACK is enabled on a new receive stream.
1057TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1058 EXPECT_TRUE(SetupEngine());
1059 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1060 int channel_num = voe_.GetLastChannel();
1061 std::vector<cricket::AudioCodec> codecs;
1062 codecs.push_back(kIsacCodec);
1063 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1064 cricket::kParamValueEmpty));
1065 codecs.push_back(kCn16000Codec);
1066 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1067 EXPECT_TRUE(voe_.GetNACK(channel_num));
1068
1069 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1070 channel_num = voe_.GetLastChannel();
1071 EXPECT_TRUE(voe_.GetNACK(channel_num));
1072 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1073 channel_num = voe_.GetLastChannel();
1074 EXPECT_TRUE(voe_.GetNACK(channel_num));
1075}
1076
1077// Test that we can apply CELT with stereo mode but fail with mono mode.
1078TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1079 EXPECT_TRUE(SetupEngine());
1080 int channel_num = voe_.GetLastChannel();
1081 std::vector<cricket::AudioCodec> codecs;
1082 codecs.push_back(kCeltCodec);
1083 codecs.push_back(kPcmuCodec);
1084 codecs[0].id = 96;
1085 codecs[0].channels = 2;
1086 codecs[0].bitrate = 96000;
1087 codecs[1].bitrate = 96000;
1088 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1089 webrtc::CodecInst gcodec;
1090 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1091 EXPECT_EQ(96, gcodec.pltype);
1092 EXPECT_EQ(96000, gcodec.rate);
1093 EXPECT_EQ(2, gcodec.channels);
1094 EXPECT_STREQ("CELT", gcodec.plname);
1095 // Doesn't support mono, expect it to fall back to the next codec in the list.
1096 codecs[0].channels = 1;
1097 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1098 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1099 EXPECT_EQ(0, gcodec.pltype);
1100 EXPECT_EQ(1, gcodec.channels);
1101 EXPECT_EQ(64000, gcodec.rate);
1102 EXPECT_STREQ("PCMU", gcodec.plname);
1103}
1104
1105// Test that we can switch back and forth between CELT and ISAC with CN.
1106TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1107 EXPECT_TRUE(SetupEngine());
1108 int channel_num = voe_.GetLastChannel();
1109 std::vector<cricket::AudioCodec> celt_codecs;
1110 celt_codecs.push_back(kCeltCodec);
1111 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1112 webrtc::CodecInst gcodec;
1113 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1114 EXPECT_EQ(110, gcodec.pltype);
1115 EXPECT_STREQ("CELT", gcodec.plname);
1116
1117 std::vector<cricket::AudioCodec> isac_codecs;
1118 isac_codecs.push_back(kIsacCodec);
1119 isac_codecs.push_back(kCn16000Codec);
1120 isac_codecs.push_back(kCeltCodec);
1121 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1122 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1123 EXPECT_EQ(103, gcodec.pltype);
1124 EXPECT_STREQ("ISAC", gcodec.plname);
1125
1126 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1127 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1128 EXPECT_EQ(110, gcodec.pltype);
1129 EXPECT_STREQ("CELT", gcodec.plname);
1130}
1131
1132// Test that we handle various ways of specifying bitrate.
1133TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1134 EXPECT_TRUE(SetupEngine());
1135 int channel_num = voe_.GetLastChannel();
1136 std::vector<cricket::AudioCodec> codecs;
1137 codecs.push_back(kIsacCodec); // bitrate == 32000
1138 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1139 webrtc::CodecInst gcodec;
1140 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1141 EXPECT_EQ(103, gcodec.pltype);
1142 EXPECT_STREQ("ISAC", gcodec.plname);
1143 EXPECT_EQ(32000, gcodec.rate);
1144
1145 codecs[0].bitrate = 0; // bitrate == default
1146 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1147 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1148 EXPECT_EQ(103, gcodec.pltype);
1149 EXPECT_STREQ("ISAC", gcodec.plname);
1150 EXPECT_EQ(-1, gcodec.rate);
1151
1152 codecs[0].bitrate = 28000; // bitrate == 28000
1153 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1154 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1155 EXPECT_EQ(103, gcodec.pltype);
1156 EXPECT_STREQ("ISAC", gcodec.plname);
1157 EXPECT_EQ(28000, gcodec.rate);
1158
1159 codecs[0] = kPcmuCodec; // bitrate == 64000
1160 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1161 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1162 EXPECT_EQ(0, gcodec.pltype);
1163 EXPECT_STREQ("PCMU", gcodec.plname);
1164 EXPECT_EQ(64000, gcodec.rate);
1165
1166 codecs[0].bitrate = 0; // bitrate == default
1167 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1168 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1169 EXPECT_EQ(0, gcodec.pltype);
1170 EXPECT_STREQ("PCMU", gcodec.plname);
1171 EXPECT_EQ(64000, gcodec.rate);
1172
1173 codecs[0] = kOpusCodec;
1174 codecs[0].bitrate = 0; // bitrate == default
1175 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1176 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1177 EXPECT_EQ(111, gcodec.pltype);
1178 EXPECT_STREQ("opus", gcodec.plname);
1179 EXPECT_EQ(32000, gcodec.rate);
1180}
1181
1182// Test that we fall back to PCMU if no codecs are specified.
1183TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1184 EXPECT_TRUE(SetupEngine());
1185 int channel_num = voe_.GetLastChannel();
1186 std::vector<cricket::AudioCodec> codecs;
1187 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1188 webrtc::CodecInst gcodec;
1189 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1190 EXPECT_EQ(0, gcodec.pltype);
1191 EXPECT_STREQ("PCMU", gcodec.plname);
1192 EXPECT_FALSE(voe_.GetVAD(channel_num));
1193 EXPECT_FALSE(voe_.GetFEC(channel_num));
1194 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1195 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
1196 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
1197}
1198
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001199// Test that we set VAD and DTMF types correctly as caller.
1200TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001201 EXPECT_TRUE(SetupEngine());
1202 int channel_num = voe_.GetLastChannel();
1203 std::vector<cricket::AudioCodec> codecs;
1204 codecs.push_back(kIsacCodec);
1205 codecs.push_back(kPcmuCodec);
1206 // TODO(juberti): cn 32000
1207 codecs.push_back(kCn16000Codec);
1208 codecs.push_back(kCn8000Codec);
1209 codecs.push_back(kTelephoneEventCodec);
1210 codecs.push_back(kRedCodec);
1211 codecs[0].id = 96;
1212 codecs[2].id = 97; // wideband CN
1213 codecs[4].id = 98; // DTMF
1214 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1215 webrtc::CodecInst gcodec;
1216 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1217 EXPECT_EQ(96, gcodec.pltype);
1218 EXPECT_STREQ("ISAC", gcodec.plname);
1219 EXPECT_TRUE(voe_.GetVAD(channel_num));
1220 EXPECT_FALSE(voe_.GetFEC(channel_num));
1221 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1222 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1223 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1224}
1225
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001226// Test that we set VAD and DTMF types correctly as callee.
1227TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1228 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1229 channel_ = engine_.CreateChannel();
1230 EXPECT_TRUE(channel_ != NULL);
1231
1232 int channel_num = voe_.GetLastChannel();
1233 std::vector<cricket::AudioCodec> codecs;
1234 codecs.push_back(kIsacCodec);
1235 codecs.push_back(kPcmuCodec);
1236 // TODO(juberti): cn 32000
1237 codecs.push_back(kCn16000Codec);
1238 codecs.push_back(kCn8000Codec);
1239 codecs.push_back(kTelephoneEventCodec);
1240 codecs.push_back(kRedCodec);
1241 codecs[0].id = 96;
1242 codecs[2].id = 97; // wideband CN
1243 codecs[4].id = 98; // DTMF
1244 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1245 EXPECT_TRUE(channel_->AddSendStream(
1246 cricket::StreamParams::CreateLegacy(kSsrc1)));
1247
1248 webrtc::CodecInst gcodec;
1249 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1250 EXPECT_EQ(96, gcodec.pltype);
1251 EXPECT_STREQ("ISAC", gcodec.plname);
1252 EXPECT_TRUE(voe_.GetVAD(channel_num));
1253 EXPECT_FALSE(voe_.GetFEC(channel_num));
1254 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1255 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1256 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1257}
1258
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001259// Test that we only apply VAD if we have a CN codec that matches the
1260// send codec clockrate.
1261TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1262 EXPECT_TRUE(SetupEngine());
1263 int channel_num = voe_.GetLastChannel();
1264 std::vector<cricket::AudioCodec> codecs;
1265 // Set ISAC(16K) and CN(16K). VAD should be activated.
1266 codecs.push_back(kIsacCodec);
1267 codecs.push_back(kCn16000Codec);
1268 codecs[1].id = 97;
1269 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1270 webrtc::CodecInst gcodec;
1271 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1272 EXPECT_STREQ("ISAC", gcodec.plname);
1273 EXPECT_TRUE(voe_.GetVAD(channel_num));
1274 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1275 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1276 codecs[0] = kPcmuCodec;
1277 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1278 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1279 EXPECT_STREQ("PCMU", gcodec.plname);
1280 EXPECT_FALSE(voe_.GetVAD(channel_num));
1281 // Set PCMU(8K) and CN(8K). VAD should be activated.
1282 codecs[1] = kCn8000Codec;
1283 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1284 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1285 EXPECT_STREQ("PCMU", gcodec.plname);
1286 EXPECT_TRUE(voe_.GetVAD(channel_num));
1287 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1288 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1289 codecs[0] = kIsacCodec;
1290 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1291 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1292 EXPECT_STREQ("ISAC", gcodec.plname);
1293 EXPECT_FALSE(voe_.GetVAD(channel_num));
1294}
1295
1296// Test that we perform case-insensitive matching of codec names.
1297TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1298 EXPECT_TRUE(SetupEngine());
1299 int channel_num = voe_.GetLastChannel();
1300 std::vector<cricket::AudioCodec> codecs;
1301 codecs.push_back(kIsacCodec);
1302 codecs.push_back(kPcmuCodec);
1303 codecs.push_back(kCn16000Codec);
1304 codecs.push_back(kCn8000Codec);
1305 codecs.push_back(kTelephoneEventCodec);
1306 codecs.push_back(kRedCodec);
1307 codecs[0].name = "iSaC";
1308 codecs[0].id = 96;
1309 codecs[2].id = 97; // wideband CN
1310 codecs[4].id = 98; // DTMF
1311 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1312 webrtc::CodecInst gcodec;
1313 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1314 EXPECT_EQ(96, gcodec.pltype);
1315 EXPECT_STREQ("ISAC", gcodec.plname);
1316 EXPECT_TRUE(voe_.GetVAD(channel_num));
1317 EXPECT_FALSE(voe_.GetFEC(channel_num));
1318 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1319 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1320 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1321}
1322
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001323// Test that we set up FEC correctly as caller.
1324TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001325 EXPECT_TRUE(SetupEngine());
1326 int channel_num = voe_.GetLastChannel();
1327 std::vector<cricket::AudioCodec> codecs;
1328 codecs.push_back(kRedCodec);
1329 codecs.push_back(kIsacCodec);
1330 codecs.push_back(kPcmuCodec);
1331 codecs[0].id = 127;
1332 codecs[0].params[""] = "96/96";
1333 codecs[1].id = 96;
1334 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1335 webrtc::CodecInst gcodec;
1336 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1337 EXPECT_EQ(96, gcodec.pltype);
1338 EXPECT_STREQ("ISAC", gcodec.plname);
1339 EXPECT_TRUE(voe_.GetFEC(channel_num));
1340 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1341}
1342
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001343// Test that we set up FEC correctly as callee.
1344TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1345 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1346 channel_ = engine_.CreateChannel();
1347 EXPECT_TRUE(channel_ != NULL);
1348
1349 int channel_num = voe_.GetLastChannel();
1350 std::vector<cricket::AudioCodec> codecs;
1351 codecs.push_back(kRedCodec);
1352 codecs.push_back(kIsacCodec);
1353 codecs.push_back(kPcmuCodec);
1354 codecs[0].id = 127;
1355 codecs[0].params[""] = "96/96";
1356 codecs[1].id = 96;
1357 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1358 EXPECT_TRUE(channel_->AddSendStream(
1359 cricket::StreamParams::CreateLegacy(kSsrc1)));
1360 webrtc::CodecInst gcodec;
1361 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1362 EXPECT_EQ(96, gcodec.pltype);
1363 EXPECT_STREQ("ISAC", gcodec.plname);
1364 EXPECT_TRUE(voe_.GetFEC(channel_num));
1365 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1366}
1367
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001368// Test that we set up FEC correctly if params are omitted.
1369TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1370 EXPECT_TRUE(SetupEngine());
1371 int channel_num = voe_.GetLastChannel();
1372 std::vector<cricket::AudioCodec> codecs;
1373 codecs.push_back(kRedCodec);
1374 codecs.push_back(kIsacCodec);
1375 codecs.push_back(kPcmuCodec);
1376 codecs[0].id = 127;
1377 codecs[1].id = 96;
1378 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1379 webrtc::CodecInst gcodec;
1380 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1381 EXPECT_EQ(96, gcodec.pltype);
1382 EXPECT_STREQ("ISAC", gcodec.plname);
1383 EXPECT_TRUE(voe_.GetFEC(channel_num));
1384 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1385}
1386
1387// Test that we ignore RED if the parameters aren't named the way we expect.
1388TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1389 EXPECT_TRUE(SetupEngine());
1390 int channel_num = voe_.GetLastChannel();
1391 std::vector<cricket::AudioCodec> codecs;
1392 codecs.push_back(kRedCodec);
1393 codecs.push_back(kIsacCodec);
1394 codecs.push_back(kPcmuCodec);
1395 codecs[0].id = 127;
1396 codecs[0].params["ABC"] = "96/96";
1397 codecs[1].id = 96;
1398 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1399 webrtc::CodecInst gcodec;
1400 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1401 EXPECT_EQ(96, gcodec.pltype);
1402 EXPECT_STREQ("ISAC", gcodec.plname);
1403 EXPECT_FALSE(voe_.GetFEC(channel_num));
1404}
1405
1406// Test that we ignore RED if it uses different primary/secondary encoding.
1407TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1408 EXPECT_TRUE(SetupEngine());
1409 int channel_num = voe_.GetLastChannel();
1410 std::vector<cricket::AudioCodec> codecs;
1411 codecs.push_back(kRedCodec);
1412 codecs.push_back(kIsacCodec);
1413 codecs.push_back(kPcmuCodec);
1414 codecs[0].id = 127;
1415 codecs[0].params[""] = "96/0";
1416 codecs[1].id = 96;
1417 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1418 webrtc::CodecInst gcodec;
1419 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1420 EXPECT_EQ(96, gcodec.pltype);
1421 EXPECT_STREQ("ISAC", gcodec.plname);
1422 EXPECT_FALSE(voe_.GetFEC(channel_num));
1423}
1424
1425// Test that we ignore RED if it uses more than 2 encodings.
1426TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1427 EXPECT_TRUE(SetupEngine());
1428 int channel_num = voe_.GetLastChannel();
1429 std::vector<cricket::AudioCodec> codecs;
1430 codecs.push_back(kRedCodec);
1431 codecs.push_back(kIsacCodec);
1432 codecs.push_back(kPcmuCodec);
1433 codecs[0].id = 127;
1434 codecs[0].params[""] = "96/96/96";
1435 codecs[1].id = 96;
1436 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1437 webrtc::CodecInst gcodec;
1438 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1439 EXPECT_EQ(96, gcodec.pltype);
1440 EXPECT_STREQ("ISAC", gcodec.plname);
1441 EXPECT_FALSE(voe_.GetFEC(channel_num));
1442}
1443
1444// Test that we ignore RED if it has bogus codec ids.
1445TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1446 EXPECT_TRUE(SetupEngine());
1447 int channel_num = voe_.GetLastChannel();
1448 std::vector<cricket::AudioCodec> codecs;
1449 codecs.push_back(kRedCodec);
1450 codecs.push_back(kIsacCodec);
1451 codecs.push_back(kPcmuCodec);
1452 codecs[0].id = 127;
1453 codecs[0].params[""] = "ABC/ABC";
1454 codecs[1].id = 96;
1455 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1456 webrtc::CodecInst gcodec;
1457 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1458 EXPECT_EQ(96, gcodec.pltype);
1459 EXPECT_STREQ("ISAC", gcodec.plname);
1460 EXPECT_FALSE(voe_.GetFEC(channel_num));
1461}
1462
1463// Test that we ignore RED if it refers to a codec that is not present.
1464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1465 EXPECT_TRUE(SetupEngine());
1466 int channel_num = voe_.GetLastChannel();
1467 std::vector<cricket::AudioCodec> codecs;
1468 codecs.push_back(kRedCodec);
1469 codecs.push_back(kIsacCodec);
1470 codecs.push_back(kPcmuCodec);
1471 codecs[0].id = 127;
1472 codecs[0].params[""] = "97/97";
1473 codecs[1].id = 96;
1474 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1475 webrtc::CodecInst gcodec;
1476 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1477 EXPECT_EQ(96, gcodec.pltype);
1478 EXPECT_STREQ("ISAC", gcodec.plname);
1479 EXPECT_FALSE(voe_.GetFEC(channel_num));
1480}
1481
1482// Test that we support setting an empty list of recv header extensions.
1483TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
1484 EXPECT_TRUE(SetupEngine());
1485 std::vector<cricket::RtpHeaderExtension> extensions;
1486 int channel_num = voe_.GetLastChannel();
1487 bool enable = false;
1488 unsigned char id = 0;
1489
1490 // An empty list shouldn't cause audio-level headers to be enabled.
1491 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1492 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
1493 channel_num, enable, id));
1494 EXPECT_FALSE(enable);
1495
1496 // Nor should indicating we can receive the audio-level header.
1497 extensions.push_back(cricket::RtpHeaderExtension(
1498 "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
1499 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1500 EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
1501 channel_num, enable, id));
1502 EXPECT_FALSE(enable);
1503}
1504
1505// Test that we support setting certain send header extensions.
1506TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
1507 EXPECT_TRUE(SetupEngine());
1508 std::vector<cricket::RtpHeaderExtension> extensions;
1509 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001510 TestSetSendRtpHeaderExtensions(channel_num);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511}
1512
1513// Test that we can create a channel and start sending/playing out on it.
1514TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1515 EXPECT_TRUE(SetupEngine());
1516 int channel_num = voe_.GetLastChannel();
1517 std::vector<cricket::AudioCodec> codecs;
1518 codecs.push_back(kPcmuCodec);
1519 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1520 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1521 EXPECT_TRUE(voe_.GetSend(channel_num));
1522 EXPECT_TRUE(channel_->SetPlayout(true));
1523 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1524 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1525 EXPECT_FALSE(voe_.GetSend(channel_num));
1526 EXPECT_TRUE(channel_->SetPlayout(false));
1527 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1528}
1529
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001530// Test that we can add and remove send streams.
1531TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1532 SetupForMultiSendStream();
1533
1534 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1535
1536 // Set the global state for sending.
1537 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1538
1539 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1540 EXPECT_TRUE(channel_->AddSendStream(
1541 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1542
1543 // Verify that we are in a sending state for all the created streams.
1544 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1545 EXPECT_TRUE(voe_.GetSend(channel_num));
1546 }
1547
1548 // Remove the first send channel, which is the default channel. It will only
1549 // recycle the default channel but not delete it.
1550 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1551 // Stream should already be Removed from the send stream list.
1552 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1553 // But the default still exists.
1554 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1555
1556 // Delete the rest of send channel streams.
1557 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1558 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1559 // Stream should already be deleted.
1560 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1561 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1562 }
1563}
1564
1565// Test SetSendCodecs correctly configure the codecs in all send streams.
1566TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1567 SetupForMultiSendStream();
1568
1569 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1570 // Create send streams.
1571 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1572 EXPECT_TRUE(channel_->AddSendStream(
1573 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1574 }
1575
1576 std::vector<cricket::AudioCodec> codecs;
1577 // Set ISAC(16K) and CN(16K). VAD should be activated.
1578 codecs.push_back(kIsacCodec);
1579 codecs.push_back(kCn16000Codec);
1580 codecs[1].id = 97;
1581 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1582
1583 // Verify ISAC and VAD are corrected configured on all send channels.
1584 webrtc::CodecInst gcodec;
1585 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1586 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1587 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1588 EXPECT_STREQ("ISAC", gcodec.plname);
1589 EXPECT_TRUE(voe_.GetVAD(channel_num));
1590 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1591 }
1592
1593 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1594 codecs[0] = kPcmuCodec;
1595 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1596 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1597 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1598 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1599 EXPECT_STREQ("PCMU", gcodec.plname);
1600 EXPECT_FALSE(voe_.GetVAD(channel_num));
1601 }
1602}
1603
1604// Test we can SetSend on all send streams correctly.
1605TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1606 SetupForMultiSendStream();
1607
1608 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1609 // Create the send channels and they should be a SEND_NOTHING date.
1610 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1611 EXPECT_TRUE(channel_->AddSendStream(
1612 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1613 int channel_num = voe_.GetLastChannel();
1614 EXPECT_FALSE(voe_.GetSend(channel_num));
1615 }
1616
1617 // Set the global state for starting sending.
1618 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1619 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1620 // Verify that we are in a sending state for all the send streams.
1621 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1622 EXPECT_TRUE(voe_.GetSend(channel_num));
1623 }
1624
1625 // Set the global state for stopping sending.
1626 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1627 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1628 // Verify that we are in a stop state for all the send streams.
1629 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1630 EXPECT_FALSE(voe_.GetSend(channel_num));
1631 }
1632}
1633
1634// Test we can set the correct statistics on all send streams.
1635TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1636 SetupForMultiSendStream();
1637
1638 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1639 // Create send streams.
1640 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1641 EXPECT_TRUE(channel_->AddSendStream(
1642 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1643 }
1644
1645 // We need send codec to be set to get all stats.
1646 std::vector<cricket::AudioCodec> codecs;
1647 codecs.push_back(kPcmuCodec);
1648 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1649
1650 cricket::VoiceMediaInfo info;
1651 EXPECT_EQ(true, channel_->GetStats(&info));
1652 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1653
1654 // Verify the statistic information is correct.
1655 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001656 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001657 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1658 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1659 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1660 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1661 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1662 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1663 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1664 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1665 }
1666
1667 EXPECT_EQ(1u, info.receivers.size());
1668}
1669
1670// Test that we support setting certain send header extensions on multiple
1671// send streams.
1672TEST_F(WebRtcVoiceEngineTestFake,
1673 SetSendRtpHeaderExtensionsWithMultpleSendStreams) {
1674 SetupForMultiSendStream();
1675
1676 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1677 // Create send streams.
1678 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1679 EXPECT_TRUE(channel_->AddSendStream(
1680 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1681 }
1682
1683 // Test SendRtpHeaderExtensions on each send channel.
1684 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1685 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1686 TestSetSendRtpHeaderExtensions(channel_num);
1687 }
1688}
1689
1690// Test that we can add and remove receive streams, and do proper send/playout.
1691// We can receive on multiple streams while sending one stream.
1692TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001693 EXPECT_TRUE(SetupEngine());
1694 int channel_num1 = voe_.GetLastChannel();
1695
1696 // Start playout on the default channel.
1697 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1698 EXPECT_TRUE(channel_->SetPlayout(true));
1699 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1700
1701 // Adding another stream should disable playout on the default channel.
1702 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1703 int channel_num2 = voe_.GetLastChannel();
1704 std::vector<cricket::AudioCodec> codecs;
1705 codecs.push_back(kPcmuCodec);
1706 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1707 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1708 EXPECT_TRUE(voe_.GetSend(channel_num1));
1709 EXPECT_FALSE(voe_.GetSend(channel_num2));
1710
1711 // Make sure only the new channel is played out.
1712 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1713 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1714
1715 // Adding yet another stream should have stream 2 and 3 enabled for playout.
1716 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1717 int channel_num3 = voe_.GetLastChannel();
1718 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1719 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1720 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1721 EXPECT_FALSE(voe_.GetSend(channel_num3));
1722
1723 // Stop sending.
1724 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1725 EXPECT_FALSE(voe_.GetSend(channel_num1));
1726 EXPECT_FALSE(voe_.GetSend(channel_num2));
1727 EXPECT_FALSE(voe_.GetSend(channel_num3));
1728
1729 // Stop playout.
1730 EXPECT_TRUE(channel_->SetPlayout(false));
1731 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1732 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1733 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1734
1735 // Restart playout and make sure the default channel still is not played out.
1736 EXPECT_TRUE(channel_->SetPlayout(true));
1737 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1738 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1739 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1740
1741 // Now remove the new streams and verify that the default channel is
1742 // played out again.
1743 EXPECT_TRUE(channel_->RemoveRecvStream(3));
1744 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1745
1746 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1747}
1748
1749// Test that we can set the devices to use.
1750TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1751 EXPECT_TRUE(SetupEngine());
1752 int channel_num = voe_.GetLastChannel();
1753 std::vector<cricket::AudioCodec> codecs;
1754 codecs.push_back(kPcmuCodec);
1755 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1756
1757 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1758 cricket::kFakeDefaultDeviceId);
1759 cricket::Device dev(cricket::kFakeDeviceName,
1760 cricket::kFakeDeviceId);
1761
1762 // Test SetDevices() while not sending or playing.
1763 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1764
1765 // Test SetDevices() while sending and playing.
1766 EXPECT_TRUE(engine_.SetLocalMonitor(true));
1767 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1768 EXPECT_TRUE(channel_->SetPlayout(true));
1769 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1770 EXPECT_TRUE(voe_.GetSend(channel_num));
1771 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1772
1773 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1774
1775 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1776 EXPECT_TRUE(voe_.GetSend(channel_num));
1777 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1778
1779 // Test that failure to open newly selected devices does not prevent opening
1780 // ones after that.
1781 voe_.set_fail_start_recording_microphone(true);
1782 voe_.set_playout_fail_channel(channel_num);
1783 voe_.set_send_fail_channel(channel_num);
1784
1785 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1786
1787 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1788 EXPECT_FALSE(voe_.GetSend(channel_num));
1789 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1790
1791 voe_.set_fail_start_recording_microphone(false);
1792 voe_.set_playout_fail_channel(-1);
1793 voe_.set_send_fail_channel(-1);
1794
1795 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1796
1797 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1798 EXPECT_TRUE(voe_.GetSend(channel_num));
1799 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1800}
1801
1802// Test that we can set the devices to use even if we failed to
1803// open the initial ones.
1804TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1805 EXPECT_TRUE(SetupEngine());
1806 int channel_num = voe_.GetLastChannel();
1807 std::vector<cricket::AudioCodec> codecs;
1808 codecs.push_back(kPcmuCodec);
1809 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1810
1811 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1812 cricket::kFakeDefaultDeviceId);
1813 cricket::Device dev(cricket::kFakeDeviceName,
1814 cricket::kFakeDeviceId);
1815
1816 // Test that failure to open devices selected before starting
1817 // send/play does not prevent opening newly selected ones after that.
1818 voe_.set_fail_start_recording_microphone(true);
1819 voe_.set_playout_fail_channel(channel_num);
1820 voe_.set_send_fail_channel(channel_num);
1821
1822 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1823
1824 EXPECT_FALSE(engine_.SetLocalMonitor(true));
1825 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
1826 EXPECT_FALSE(channel_->SetPlayout(true));
1827 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1828 EXPECT_FALSE(voe_.GetSend(channel_num));
1829 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1830
1831 voe_.set_fail_start_recording_microphone(false);
1832 voe_.set_playout_fail_channel(-1);
1833 voe_.set_send_fail_channel(-1);
1834
1835 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1836
1837 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1838 EXPECT_TRUE(voe_.GetSend(channel_num));
1839 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1840}
1841
1842// Test that we can create a channel configured for multi-point conferences,
1843// and start sending/playing out on it.
1844TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
1845 EXPECT_TRUE(SetupEngine());
1846 int channel_num = voe_.GetLastChannel();
1847 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1848 std::vector<cricket::AudioCodec> codecs;
1849 codecs.push_back(kPcmuCodec);
1850 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1851 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1852 EXPECT_TRUE(voe_.GetSend(channel_num));
1853}
1854
1855// Test that we can create a channel configured for Codian bridges,
1856// and start sending/playing out on it.
1857TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
1858 EXPECT_TRUE(SetupEngine());
1859 int channel_num = voe_.GetLastChannel();
1860 webrtc::AgcConfig agc_config;
1861 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1862 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1863 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
1864 std::vector<cricket::AudioCodec> codecs;
1865 codecs.push_back(kPcmuCodec);
1866 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1867 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1868 EXPECT_TRUE(voe_.GetSend(channel_num));
1869 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1870 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
1871 EXPECT_TRUE(channel_->SetPlayout(true));
1872 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1873 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1874 EXPECT_FALSE(voe_.GetSend(channel_num));
1875 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1876 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
1877 EXPECT_TRUE(channel_->SetPlayout(false));
1878 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1879}
1880
wu@webrtc.org97077a32013-10-25 21:18:33 +00001881TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
1882 EXPECT_TRUE(SetupEngine());
1883 webrtc::AgcConfig agc_config;
1884 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1885 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1886
1887 cricket::AudioOptions options;
1888 options.tx_agc_target_dbov.Set(3);
1889 options.tx_agc_digital_compression_gain.Set(9);
1890 options.tx_agc_limiter.Set(true);
1891 options.auto_gain_control.Set(true);
1892 EXPECT_TRUE(engine_.SetOptions(options));
1893
1894 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1895 EXPECT_EQ(3, agc_config.targetLeveldBOv);
1896 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
1897 EXPECT_TRUE(agc_config.limiterEnable);
1898
1899 // Check interaction with adjust_agc_delta. Both should be respected, for
1900 // backwards compatibility.
1901 options.adjust_agc_delta.Set(-10);
1902 EXPECT_TRUE(engine_.SetOptions(options));
1903
1904 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1905 EXPECT_EQ(13, agc_config.targetLeveldBOv);
1906}
1907
1908TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
1909 EXPECT_TRUE(SetupEngine());
1910 int channel_num = voe_.GetLastChannel();
1911 cricket::AudioOptions options;
1912 options.rx_agc_target_dbov.Set(6);
1913 options.rx_agc_digital_compression_gain.Set(0);
1914 options.rx_agc_limiter.Set(true);
1915 options.rx_auto_gain_control.Set(true);
1916 EXPECT_TRUE(channel_->SetOptions(options));
1917
1918 webrtc::AgcConfig agc_config;
1919 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
1920 channel_num, agc_config));
1921 EXPECT_EQ(6, agc_config.targetLeveldBOv);
1922 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
1923 EXPECT_TRUE(agc_config.limiterEnable);
1924}
1925
1926TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
1927 EXPECT_TRUE(SetupEngine());
1928 cricket::AudioOptions options;
1929 options.recording_sample_rate.Set(48000u);
1930 options.playout_sample_rate.Set(44100u);
1931 EXPECT_TRUE(engine_.SetOptions(options));
1932
1933 unsigned int recording_sample_rate, playout_sample_rate;
1934 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
1935 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
1936 EXPECT_EQ(48000u, recording_sample_rate);
1937 EXPECT_EQ(44100u, playout_sample_rate);
1938}
1939
1940TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
1941 EXPECT_TRUE(SetupEngine());
1942 engine_.SetLogging(talk_base::LS_INFO, "");
1943 EXPECT_EQ(
1944 // Info:
1945 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
1946 // Warning:
1947 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
1948 // Error:
1949 webrtc::kTraceError | webrtc::kTraceCritical,
1950 static_cast<int>(trace_wrapper_->filter_));
1951 // Now set it explicitly
1952 std::string filter =
1953 "tracefilter " + talk_base::ToString(webrtc::kTraceDefault);
1954 engine_.SetLogging(talk_base::LS_VERBOSE, filter.c_str());
1955 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
1956 trace_wrapper_->filter_);
1957}
1958
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001959// Test that we can set the outgoing SSRC properly.
1960// SSRC is set in SetupEngine by calling AddSendStream.
1961TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
1962 EXPECT_TRUE(SetupEngine());
1963 int channel_num = voe_.GetLastChannel();
1964 unsigned int send_ssrc;
1965 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
1966 EXPECT_NE(0U, send_ssrc);
1967 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
1968 EXPECT_EQ(kSsrc1, send_ssrc);
1969}
1970
1971TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
1972 // Setup. We need send codec to be set to get all stats.
1973 EXPECT_TRUE(SetupEngine());
1974 std::vector<cricket::AudioCodec> codecs;
1975 codecs.push_back(kPcmuCodec);
1976 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1977
1978 cricket::VoiceMediaInfo info;
1979 EXPECT_EQ(true, channel_->GetStats(&info));
1980 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001981 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001982 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
1983 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
1984 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
1985 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
1986 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
1987 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
1988 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
1989 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
1990 // TODO(sriniv): Add testing for more fields. These are not populated
1991 // in FakeWebrtcVoiceEngine yet.
1992 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
1993 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
1994 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
1995 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
1996 // EXPECT_EQ(cricket::kIntStatValue,
1997 // info.senders[0].echo_return_loss_enhancement);
1998
1999 EXPECT_EQ(1u, info.receivers.size());
2000 // TODO(sriniv): Add testing for receiver fields.
2001}
2002
2003// Test that we can set the outgoing SSRC properly with multiple streams.
2004// SSRC is set in SetupEngine by calling AddSendStream.
2005TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2006 EXPECT_TRUE(SetupEngine());
2007 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2008 int channel_num1 = voe_.GetLastChannel();
2009 unsigned int send_ssrc;
2010 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2011 EXPECT_EQ(kSsrc1, send_ssrc);
2012
2013 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2014 int channel_num2 = voe_.GetLastChannel();
2015 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2016 EXPECT_EQ(kSsrc1, send_ssrc);
2017}
2018
2019// Test that the local SSRC is the same on sending and receiving channels if the
2020// receive channel is created before the send channel.
2021TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2022 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2023 channel_ = engine_.CreateChannel();
2024 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2025
2026 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2027 int receive_channel_num = voe_.GetLastChannel();
2028 EXPECT_TRUE(channel_->AddSendStream(
2029 cricket::StreamParams::CreateLegacy(1234)));
2030 int send_channel_num = voe_.GetLastChannel();
2031
2032 unsigned int ssrc = 0;
2033 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2034 EXPECT_EQ(1234U, ssrc);
2035 ssrc = 0;
2036 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2037 EXPECT_EQ(1234U, ssrc);
2038}
2039
2040// Test that we can properly receive packets.
2041TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2042 EXPECT_TRUE(SetupEngine());
2043 int channel_num = voe_.GetLastChannel();
2044 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2045 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2046 sizeof(kPcmuFrame)));
2047}
2048
2049// Test that we can properly receive packets on multiple streams.
2050TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2051 EXPECT_TRUE(SetupEngine());
2052 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2053 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2054 int channel_num1 = voe_.GetLastChannel();
2055 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2056 int channel_num2 = voe_.GetLastChannel();
2057 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2058 int channel_num3 = voe_.GetLastChannel();
2059 // Create packets with the right SSRCs.
2060 char packets[4][sizeof(kPcmuFrame)];
2061 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2062 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2063 talk_base::SetBE32(packets[i] + 8, i);
2064 }
2065 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2066 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2067 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2068 DeliverPacket(packets[0], sizeof(packets[0]));
2069 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2070 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2071 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2072 DeliverPacket(packets[1], sizeof(packets[1]));
2073 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2074 sizeof(packets[1])));
2075 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2076 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2077 DeliverPacket(packets[2], sizeof(packets[2]));
2078 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2079 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2080 sizeof(packets[2])));
2081 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2082 DeliverPacket(packets[3], sizeof(packets[3]));
2083 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2084 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2085 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2086 sizeof(packets[3])));
2087 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2088 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2089 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2090}
2091
2092// Test that we properly handle failures to add a stream.
2093TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2094 EXPECT_TRUE(SetupEngine());
2095 voe_.set_fail_create_channel(true);
2096 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2097 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2098
2099 // In 1:1 call, we should not try to create a new channel.
2100 cricket::AudioOptions options_no_conference_;
2101 options_no_conference_.conference_mode.Set(false);
2102 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2103 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2104}
2105
2106// Test that AddRecvStream doesn't create new channel for 1:1 call.
2107TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2108 EXPECT_TRUE(SetupEngine());
2109 int channel_num = voe_.GetLastChannel();
2110 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2111 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2112}
2113
2114// Test that after adding a recv stream, we do not decode more codecs than
2115// those previously passed into SetRecvCodecs.
2116TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2117 EXPECT_TRUE(SetupEngine());
2118 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2119 std::vector<cricket::AudioCodec> codecs;
2120 codecs.push_back(kIsacCodec);
2121 codecs.push_back(kPcmuCodec);
2122 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2123 EXPECT_TRUE(channel_->AddRecvStream(
2124 cricket::StreamParams::CreateLegacy(kSsrc1)));
2125 int channel_num2 = voe_.GetLastChannel();
2126 webrtc::CodecInst gcodec;
2127 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2128 gcodec.plfreq = 32000;
2129 gcodec.channels = 2;
2130 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2131}
2132
2133// Test that we properly clean up any streams that were added, even if
2134// not explicitly removed.
2135TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2136 EXPECT_TRUE(SetupEngine());
2137 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2138 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2139 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2140 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2141 delete channel_;
2142 channel_ = NULL;
2143 EXPECT_EQ(0, voe_.GetNumChannels());
2144}
2145
wu@webrtc.org78187522013-10-07 23:32:02 +00002146TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2147 EXPECT_TRUE(SetupEngine());
2148 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2149}
2150
2151TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2152 EXPECT_TRUE(SetupEngine());
2153 // Stream 1 reuses default channel.
2154 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2155 // Manually delete default channel to simulate a failure.
2156 int default_channel = voe_.GetLastChannel();
2157 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2158 // Add recv stream 2 should fail because default channel is gone.
2159 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2160 int new_channel = voe_.GetLastChannel();
2161 EXPECT_NE(default_channel, new_channel);
2162 // The last created channel should have already been deleted.
2163 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2164}
2165
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002166// Test the InsertDtmf on default send stream as caller.
2167TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2168 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169}
2170
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002171// Test the InsertDtmf on default send stream as callee
2172TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2173 TestInsertDtmf(0, false);
2174}
2175
2176// Test the InsertDtmf on specified send stream as caller.
2177TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2178 TestInsertDtmf(kSsrc1, true);
2179}
2180
2181// Test the InsertDtmf on specified send stream as callee.
2182TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2183 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002184}
2185
2186// Test that we can play a ringback tone properly in a single-stream call.
2187TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2188 EXPECT_TRUE(SetupEngine());
2189 int channel_num = voe_.GetLastChannel();
2190 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2191 // Check we fail if no ringback tone specified.
2192 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2193 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2194 // Check we can set and play a ringback tone.
2195 EXPECT_TRUE(channel_->SetRingbackTone(kRingbackTone, strlen(kRingbackTone)));
2196 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2197 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2198 // Check we can stop the tone manually.
2199 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2200 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2201 // Check we stop the tone if a packet arrives.
2202 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2203 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2204 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2205 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2206}
2207
2208// Test that we can play a ringback tone properly in a multi-stream call.
2209TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2210 EXPECT_TRUE(SetupEngine());
2211 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2212 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2213 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2214 int channel_num = voe_.GetLastChannel();
2215 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2216 // Check we fail if no ringback tone specified.
2217 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2218 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2219 // Check we can set and play a ringback tone on the correct ssrc.
2220 EXPECT_TRUE(channel_->SetRingbackTone(kRingbackTone, strlen(kRingbackTone)));
2221 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2222 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2223 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2224 // Check we can stop the tone manually.
2225 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2226 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2227 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2228 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2229 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2230 // Send a packet with SSRC 1; the tone should not stop.
2231 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2232 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2233 // Send a packet with SSRC 2; the tone should stop.
2234 char packet[sizeof(kPcmuFrame)];
2235 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2236 talk_base::SetBE32(packet + 8, 2);
2237 DeliverPacket(packet, sizeof(packet));
2238 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2239}
2240
2241// Tests creating soundclips, and make sure they come from the right engine.
2242TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2243 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002244 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002245 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002246 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002247 ASSERT_TRUE(soundclip_ != NULL);
2248 EXPECT_EQ(0, voe_.GetNumChannels());
2249 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2250 int channel_num = voe_sc_.GetLastChannel();
2251 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2252 delete soundclip_;
2253 soundclip_ = NULL;
2254 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002255 // Make sure the soundclip engine is uninitialized on shutdown, now that
2256 // we've initialized it by creating a soundclip.
2257 engine_.Terminate();
2258 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002259}
2260
2261// Tests playing out a fake sound.
2262TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2263 static const char kZeroes[16000] = {};
2264 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2265 soundclip_ = engine_.CreateSoundclip();
2266 ASSERT_TRUE(soundclip_ != NULL);
2267 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2268}
2269
2270TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2271 talk_base::scoped_ptr<ChannelErrorListener> listener;
2272 cricket::WebRtcVoiceMediaChannel* media_channel;
2273 unsigned int ssrc = 0;
2274
2275 EXPECT_TRUE(SetupEngine());
2276 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2277 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2278
2279 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2280 listener.reset(new ChannelErrorListener(channel_));
2281
2282 // Test on WebRtc VoE channel.
2283 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2284 VE_SATURATION_WARNING);
2285 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2286 listener->error());
2287 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2288 EXPECT_EQ(ssrc, listener->ssrc());
2289
2290 listener->Reset();
2291 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2292 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2293 listener->error());
2294 EXPECT_EQ(0U, listener->ssrc());
2295
2296 // Add another stream and test on that.
2297 ++ssrc;
2298 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2299 ssrc)));
2300 listener->Reset();
2301 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2302 VE_SATURATION_WARNING);
2303 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2304 listener->error());
2305 EXPECT_EQ(ssrc, listener->ssrc());
2306
2307 // Testing a non-existing channel.
2308 listener->Reset();
2309 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2310 VE_SATURATION_WARNING);
2311 EXPECT_EQ(0, listener->error());
2312}
2313
2314TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2315 EXPECT_TRUE(SetupEngine());
2316 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2317 std::vector<cricket::AudioCodec> codecs;
2318 codecs.push_back(kPcmuCodec);
2319 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2320 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2321 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2322 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2323 EXPECT_TRUE(channel_->SetPlayout(true));
2324 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2325 EXPECT_TRUE(channel_->SetPlayout(false));
2326 EXPECT_FALSE(channel_->SetPlayout(true));
2327}
2328
2329// Test that the Registering/Unregistering with the
2330// webrtcvoiceengine works as expected
2331TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2332 EXPECT_TRUE(SetupEngine());
2333 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2334 EXPECT_TRUE(channel_->AddRecvStream(
2335 cricket::StreamParams::CreateLegacy(kSsrc2)));
2336 cricket::FakeMediaProcessor vp_1;
2337 cricket::FakeMediaProcessor vp_2;
2338
2339 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2340 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2341 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2342 voe_.TriggerProcessPacket(cricket::MPD_RX);
2343 voe_.TriggerProcessPacket(cricket::MPD_TX);
2344
2345 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2346 EXPECT_EQ(1, vp_1.voice_frame_count());
2347 EXPECT_EQ(1, vp_2.voice_frame_count());
2348
2349 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2350 &vp_2,
2351 cricket::MPD_RX));
2352 voe_.TriggerProcessPacket(cricket::MPD_RX);
2353 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2354 EXPECT_EQ(1, vp_2.voice_frame_count());
2355 EXPECT_EQ(2, vp_1.voice_frame_count());
2356
2357 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2358 &vp_1,
2359 cricket::MPD_RX));
2360 voe_.TriggerProcessPacket(cricket::MPD_RX);
2361 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2362 EXPECT_EQ(2, vp_1.voice_frame_count());
2363
2364 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2365 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2366 voe_.TriggerProcessPacket(cricket::MPD_RX);
2367 voe_.TriggerProcessPacket(cricket::MPD_TX);
2368 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2369 EXPECT_EQ(3, vp_1.voice_frame_count());
2370
2371 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2372 &vp_1,
2373 cricket::MPD_RX_AND_TX));
2374 voe_.TriggerProcessPacket(cricket::MPD_TX);
2375 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2376 EXPECT_EQ(3, vp_1.voice_frame_count());
2377 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2378 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2379 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2380
2381 // Test that we can register a processor on the receive channel on SSRC 0.
2382 // This tests the 1:1 case when the receive SSRC is unknown.
2383 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2384 voe_.TriggerProcessPacket(cricket::MPD_RX);
2385 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2386 EXPECT_EQ(4, vp_1.voice_frame_count());
2387 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2388 &vp_1,
2389 cricket::MPD_RX));
2390
2391 // The following tests test that FindChannelNumFromSsrc is doing
2392 // what we expect.
2393 // pick an invalid ssrc and make sure we can't register
2394 EXPECT_FALSE(engine_.RegisterProcessor(99,
2395 &vp_1,
2396 cricket::MPD_RX));
2397 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2398 EXPECT_TRUE(engine_.RegisterProcessor(1,
2399 &vp_1,
2400 cricket::MPD_RX));
2401 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2402 &vp_1,
2403 cricket::MPD_RX));
2404 EXPECT_FALSE(engine_.RegisterProcessor(1,
2405 &vp_1,
2406 cricket::MPD_TX));
2407 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2408}
2409
2410TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2411 EXPECT_TRUE(SetupEngine());
2412
2413 bool ec_enabled;
2414 webrtc::EcModes ec_mode;
2415 bool ec_metrics_enabled;
2416 webrtc::AecmModes aecm_mode;
2417 bool cng_enabled;
2418 bool agc_enabled;
2419 webrtc::AgcModes agc_mode;
2420 webrtc::AgcConfig agc_config;
2421 bool ns_enabled;
2422 webrtc::NsModes ns_mode;
2423 bool highpass_filter_enabled;
2424 bool stereo_swapping_enabled;
2425 bool typing_detection_enabled;
2426 voe_.GetEcStatus(ec_enabled, ec_mode);
2427 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2428 voe_.GetAecmMode(aecm_mode, cng_enabled);
2429 voe_.GetAgcStatus(agc_enabled, agc_mode);
2430 voe_.GetAgcConfig(agc_config);
2431 voe_.GetNsStatus(ns_enabled, ns_mode);
2432 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2433 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2434 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2435 EXPECT_TRUE(ec_enabled);
2436 EXPECT_TRUE(ec_metrics_enabled);
2437 EXPECT_FALSE(cng_enabled);
2438 EXPECT_TRUE(agc_enabled);
2439 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2440 EXPECT_TRUE(ns_enabled);
2441 EXPECT_TRUE(highpass_filter_enabled);
2442 EXPECT_FALSE(stereo_swapping_enabled);
2443 EXPECT_TRUE(typing_detection_enabled);
2444 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2445 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2446
2447 // Nothing set, so all ignored.
2448 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002449 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002450 voe_.GetEcStatus(ec_enabled, ec_mode);
2451 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2452 voe_.GetAecmMode(aecm_mode, cng_enabled);
2453 voe_.GetAgcStatus(agc_enabled, agc_mode);
2454 voe_.GetAgcConfig(agc_config);
2455 voe_.GetNsStatus(ns_enabled, ns_mode);
2456 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2457 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2458 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2459 EXPECT_TRUE(ec_enabled);
2460 EXPECT_TRUE(ec_metrics_enabled);
2461 EXPECT_FALSE(cng_enabled);
2462 EXPECT_TRUE(agc_enabled);
2463 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2464 EXPECT_TRUE(ns_enabled);
2465 EXPECT_TRUE(highpass_filter_enabled);
2466 EXPECT_FALSE(stereo_swapping_enabled);
2467 EXPECT_TRUE(typing_detection_enabled);
2468 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2469 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2470
2471 // Turn echo cancellation off
2472 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002473 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002474 voe_.GetEcStatus(ec_enabled, ec_mode);
2475 EXPECT_FALSE(ec_enabled);
2476
2477 // Turn echo cancellation back on, with settings, and make sure
2478 // nothing else changed.
2479 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002480 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 voe_.GetEcStatus(ec_enabled, ec_mode);
2482 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2483 voe_.GetAecmMode(aecm_mode, cng_enabled);
2484 voe_.GetAgcStatus(agc_enabled, agc_mode);
2485 voe_.GetAgcConfig(agc_config);
2486 voe_.GetNsStatus(ns_enabled, ns_mode);
2487 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2488 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2489 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2490 EXPECT_TRUE(ec_enabled);
2491 EXPECT_TRUE(ec_metrics_enabled);
2492 EXPECT_TRUE(agc_enabled);
2493 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2494 EXPECT_TRUE(ns_enabled);
2495 EXPECT_TRUE(highpass_filter_enabled);
2496 EXPECT_FALSE(stereo_swapping_enabled);
2497 EXPECT_TRUE(typing_detection_enabled);
2498 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2499 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2500
2501 // Turn off AGC
2502 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002503 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002504 voe_.GetAgcStatus(agc_enabled, agc_mode);
2505 EXPECT_FALSE(agc_enabled);
2506
2507 // Turn AGC back on
2508 options.auto_gain_control.Set(true);
2509 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002510 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511 voe_.GetAgcStatus(agc_enabled, agc_mode);
2512 EXPECT_TRUE(agc_enabled);
2513 voe_.GetAgcConfig(agc_config);
2514 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2515
2516 // Turn off other options (and stereo swapping on).
2517 options.noise_suppression.Set(false);
2518 options.highpass_filter.Set(false);
2519 options.typing_detection.Set(false);
2520 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002521 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002522 voe_.GetNsStatus(ns_enabled, ns_mode);
2523 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2524 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2525 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2526 EXPECT_FALSE(ns_enabled);
2527 EXPECT_FALSE(highpass_filter_enabled);
2528 EXPECT_FALSE(typing_detection_enabled);
2529 EXPECT_TRUE(stereo_swapping_enabled);
2530
2531 // Turn on "conference mode" to ensure it has no impact.
2532 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002533 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002534 voe_.GetEcStatus(ec_enabled, ec_mode);
2535 voe_.GetNsStatus(ns_enabled, ns_mode);
2536 EXPECT_TRUE(ec_enabled);
2537 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2538 EXPECT_FALSE(ns_enabled);
2539 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2540}
2541
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002542TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002543 EXPECT_TRUE(SetupEngine());
2544
2545 bool ec_enabled;
2546 webrtc::EcModes ec_mode;
2547 bool ec_metrics_enabled;
2548 bool agc_enabled;
2549 webrtc::AgcModes agc_mode;
2550 bool ns_enabled;
2551 webrtc::NsModes ns_mode;
2552 bool highpass_filter_enabled;
2553 bool stereo_swapping_enabled;
2554 bool typing_detection_enabled;
2555
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556 voe_.GetEcStatus(ec_enabled, ec_mode);
2557 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2558 voe_.GetAgcStatus(agc_enabled, agc_mode);
2559 voe_.GetNsStatus(ns_enabled, ns_mode);
2560 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2561 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2562 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2563 EXPECT_TRUE(ec_enabled);
2564 EXPECT_TRUE(agc_enabled);
2565 EXPECT_TRUE(ns_enabled);
2566 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002567 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002568 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002569}
2570
2571TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2572 webrtc::AgcConfig set_config = {0};
2573 set_config.targetLeveldBOv = 3;
2574 set_config.digitalCompressionGaindB = 9;
2575 set_config.limiterEnable = true;
2576 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2577 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2578
2579 webrtc::AgcConfig config = {0};
2580 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2581 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2582 EXPECT_EQ(set_config.digitalCompressionGaindB,
2583 config.digitalCompressionGaindB);
2584 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2585}
2586
2587
2588TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2589 EXPECT_TRUE(SetupEngine());
2590 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2591 engine_.CreateChannel());
2592 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2593 engine_.CreateChannel());
2594
2595 // Have to add a stream to make SetSend work.
2596 cricket::StreamParams stream1;
2597 stream1.ssrcs.push_back(1);
2598 channel1->AddSendStream(stream1);
2599 cricket::StreamParams stream2;
2600 stream2.ssrcs.push_back(2);
2601 channel2->AddSendStream(stream2);
2602
2603 // AEC and AGC and NS
2604 cricket::AudioOptions options_all;
2605 options_all.echo_cancellation.Set(true);
2606 options_all.auto_gain_control.Set(true);
2607 options_all.noise_suppression.Set(true);
2608
2609 ASSERT_TRUE(channel1->SetOptions(options_all));
2610 cricket::AudioOptions expected_options = options_all;
2611 cricket::AudioOptions actual_options;
2612 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2613 EXPECT_EQ(expected_options, actual_options);
2614 ASSERT_TRUE(channel2->SetOptions(options_all));
2615 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2616 EXPECT_EQ(expected_options, actual_options);
2617
2618 // unset NS
2619 cricket::AudioOptions options_no_ns;
2620 options_no_ns.noise_suppression.Set(false);
2621 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2622
2623 expected_options.echo_cancellation.Set(true);
2624 expected_options.auto_gain_control.Set(true);
2625 expected_options.noise_suppression.Set(false);
2626 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2627 EXPECT_EQ(expected_options, actual_options);
2628
2629 // unset AGC
2630 cricket::AudioOptions options_no_agc;
2631 options_no_agc.auto_gain_control.Set(false);
2632 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2633
2634 expected_options.echo_cancellation.Set(true);
2635 expected_options.auto_gain_control.Set(false);
2636 expected_options.noise_suppression.Set(true);
2637 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2638 EXPECT_EQ(expected_options, actual_options);
2639
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002640 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002641 bool ec_enabled;
2642 webrtc::EcModes ec_mode;
2643 bool agc_enabled;
2644 webrtc::AgcModes agc_mode;
2645 bool ns_enabled;
2646 webrtc::NsModes ns_mode;
2647 voe_.GetEcStatus(ec_enabled, ec_mode);
2648 voe_.GetAgcStatus(agc_enabled, agc_mode);
2649 voe_.GetNsStatus(ns_enabled, ns_mode);
2650 EXPECT_TRUE(ec_enabled);
2651 EXPECT_TRUE(agc_enabled);
2652 EXPECT_TRUE(ns_enabled);
2653
2654 channel1->SetSend(cricket::SEND_MICROPHONE);
2655 voe_.GetEcStatus(ec_enabled, ec_mode);
2656 voe_.GetAgcStatus(agc_enabled, agc_mode);
2657 voe_.GetNsStatus(ns_enabled, ns_mode);
2658 EXPECT_TRUE(ec_enabled);
2659 EXPECT_TRUE(agc_enabled);
2660 EXPECT_FALSE(ns_enabled);
2661
2662 channel1->SetSend(cricket::SEND_NOTHING);
2663 voe_.GetEcStatus(ec_enabled, ec_mode);
2664 voe_.GetAgcStatus(agc_enabled, agc_mode);
2665 voe_.GetNsStatus(ns_enabled, ns_mode);
2666 EXPECT_TRUE(ec_enabled);
2667 EXPECT_TRUE(agc_enabled);
2668 EXPECT_TRUE(ns_enabled);
2669
2670 channel2->SetSend(cricket::SEND_MICROPHONE);
2671 voe_.GetEcStatus(ec_enabled, ec_mode);
2672 voe_.GetAgcStatus(agc_enabled, agc_mode);
2673 voe_.GetNsStatus(ns_enabled, ns_mode);
2674 EXPECT_TRUE(ec_enabled);
2675 EXPECT_FALSE(agc_enabled);
2676 EXPECT_TRUE(ns_enabled);
2677
2678 channel2->SetSend(cricket::SEND_NOTHING);
2679 voe_.GetEcStatus(ec_enabled, ec_mode);
2680 voe_.GetAgcStatus(agc_enabled, agc_mode);
2681 voe_.GetNsStatus(ns_enabled, ns_mode);
2682 EXPECT_TRUE(ec_enabled);
2683 EXPECT_TRUE(agc_enabled);
2684 EXPECT_TRUE(ns_enabled);
2685
2686 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002687 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002688 cricket::AudioOptions options_no_agc_nor_ns;
2689 options_no_agc_nor_ns.auto_gain_control.Set(false);
2690 options_no_agc_nor_ns.noise_suppression.Set(false);
2691 channel2->SetSend(cricket::SEND_MICROPHONE);
2692 channel2->SetOptions(options_no_agc_nor_ns);
2693
2694 expected_options.echo_cancellation.Set(true);
2695 expected_options.auto_gain_control.Set(false);
2696 expected_options.noise_suppression.Set(false);
2697 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2698 EXPECT_EQ(expected_options, actual_options);
2699 voe_.GetEcStatus(ec_enabled, ec_mode);
2700 voe_.GetAgcStatus(agc_enabled, agc_mode);
2701 voe_.GetNsStatus(ns_enabled, ns_mode);
2702 EXPECT_TRUE(ec_enabled);
2703 EXPECT_FALSE(agc_enabled);
2704 EXPECT_FALSE(ns_enabled);
2705}
2706
wu@webrtc.orgde305012013-10-31 15:40:38 +00002707// This test verifies DSCP settings are properly applied on voice media channel.
2708TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2709 EXPECT_TRUE(SetupEngine());
2710 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel(
2711 engine_.CreateChannel());
2712 talk_base::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2713 new cricket::FakeNetworkInterface);
2714 channel->SetInterface(network_interface.get());
2715 cricket::AudioOptions options;
2716 options.dscp.Set(true);
2717 EXPECT_TRUE(channel->SetOptions(options));
2718 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
2719 options.dscp.Set(false);
2720 EXPECT_TRUE(channel->SetOptions(options));
2721 EXPECT_EQ(talk_base::DSCP_DEFAULT, network_interface->dscp());
2722}
2723
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002724TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2725 cricket::WebRtcVoiceEngine engine;
2726 cricket::AudioOptions options = engine.GetOptions();
2727 // The default options should have at least a few things set. We purposefully
2728 // don't check the option values here, though.
2729 EXPECT_TRUE(options.echo_cancellation.IsSet());
2730 EXPECT_TRUE(options.auto_gain_control.IsSet());
2731 EXPECT_TRUE(options.noise_suppression.IsSet());
2732}
2733
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734// Test that GetReceiveChannelNum returns the default channel for the first
2735// recv stream in 1-1 calls.
2736TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2737 EXPECT_TRUE(SetupEngine());
2738 cricket::WebRtcVoiceMediaChannel* media_channel =
2739 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2740 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2741 EXPECT_EQ(media_channel->voe_channel(),
2742 media_channel->GetReceiveChannelNum(0));
2743 cricket::StreamParams stream;
2744 stream.ssrcs.push_back(kSsrc2);
2745 EXPECT_TRUE(channel_->AddRecvStream(stream));
2746 EXPECT_EQ(media_channel->voe_channel(),
2747 media_channel->GetReceiveChannelNum(kSsrc2));
2748}
2749
2750// Test that GetReceiveChannelNum doesn't return the default channel for the
2751// first recv stream in conference calls.
2752TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2753 EXPECT_TRUE(SetupEngine());
2754 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2755 cricket::StreamParams stream;
2756 stream.ssrcs.push_back(kSsrc2);
2757 EXPECT_TRUE(channel_->AddRecvStream(stream));
2758 cricket::WebRtcVoiceMediaChannel* media_channel =
2759 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2760 EXPECT_LT(media_channel->voe_channel(),
2761 media_channel->GetReceiveChannelNum(kSsrc2));
2762}
2763
2764TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2765 EXPECT_TRUE(SetupEngine());
2766 double left, right;
2767 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2768 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2769 EXPECT_DOUBLE_EQ(1, left);
2770 EXPECT_DOUBLE_EQ(2, right);
2771
2772 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2773 cricket::StreamParams stream;
2774 stream.ssrcs.push_back(kSsrc2);
2775 EXPECT_TRUE(channel_->AddRecvStream(stream));
2776
2777 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2778 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2779 EXPECT_DOUBLE_EQ(2, left);
2780 EXPECT_DOUBLE_EQ(1, right);
2781}
2782
2783
2784// Tests for the actual WebRtc VoE library.
2785
2786// Tests that the library initializes and shuts down properly.
2787TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2788 cricket::WebRtcVoiceEngine engine;
2789 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2790 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2791 EXPECT_TRUE(channel != NULL);
2792 delete channel;
2793 engine.Terminate();
2794
2795 // Reinit to catch regression where VoiceEngineObserver reference is lost
2796 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2797 engine.Terminate();
2798}
2799
2800// Tests that the logging from the library is cleartext.
2801TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
2802 cricket::WebRtcVoiceEngine engine;
2803 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2804 new talk_base::MemoryStream);
2805 size_t size = 0;
2806 bool cleartext = true;
2807 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2808 engine.SetLogging(talk_base::LS_VERBOSE, "");
2809 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2810 EXPECT_TRUE(stream->GetSize(&size));
2811 EXPECT_GT(size, 0U);
2812 engine.Terminate();
2813 talk_base::LogMessage::RemoveLogToStream(stream.get());
2814 const char* buf = stream->GetBuffer();
2815 for (size_t i = 0; i < size && cleartext; ++i) {
2816 int ch = static_cast<int>(buf[i]);
2817 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
2818 << std::hex << ch;
2819 cleartext = (isprint(ch) || isspace(ch));
2820 }
2821 EXPECT_TRUE(cleartext);
2822}
2823
2824// Tests we do not see any references to a monitor thread being spun up
2825// when initiating the engine.
2826TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
2827 cricket::WebRtcVoiceEngine engine;
2828 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2829 new talk_base::MemoryStream);
2830 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2831 engine.SetLogging(talk_base::LS_VERBOSE, "");
2832 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2833 engine.Terminate();
2834 talk_base::LogMessage::RemoveLogToStream(stream.get());
2835
2836 size_t size = 0;
2837 EXPECT_TRUE(stream->GetSize(&size));
2838 EXPECT_GT(size, 0U);
2839 const std::string logs(stream->GetBuffer());
2840 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
2841}
2842
2843// Tests that the library is configured with the codecs we want.
2844TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
2845 cricket::WebRtcVoiceEngine engine;
2846 // Check codecs by name.
2847 EXPECT_TRUE(engine.FindCodec(
2848 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
2849 EXPECT_TRUE(engine.FindCodec(
2850 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
2851 EXPECT_TRUE(engine.FindCodec(
2852 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
2853 // Check that name matching is case-insensitive.
2854 EXPECT_TRUE(engine.FindCodec(
2855 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
2856 EXPECT_TRUE(engine.FindCodec(
2857 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
2858 EXPECT_TRUE(engine.FindCodec(
2859 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
2860 EXPECT_TRUE(engine.FindCodec(
2861 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
2862 EXPECT_TRUE(engine.FindCodec(
2863 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
2864 EXPECT_TRUE(engine.FindCodec(
2865 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002866 EXPECT_TRUE(engine.FindCodec(
2867 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
2868 EXPECT_TRUE(engine.FindCodec(
2869 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
2870 EXPECT_TRUE(engine.FindCodec(
2871 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
2872 EXPECT_TRUE(engine.FindCodec(
2873 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
2874 // Check codecs with an id by id.
2875 EXPECT_TRUE(engine.FindCodec(
2876 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
2877 EXPECT_TRUE(engine.FindCodec(
2878 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
2879 EXPECT_TRUE(engine.FindCodec(
2880 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
2881 EXPECT_TRUE(engine.FindCodec(
2882 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
2883 // Check sample/bitrate matching.
2884 EXPECT_TRUE(engine.FindCodec(
2885 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
2886 // Check that bad codecs fail.
2887 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
2888 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
2889 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
2890 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
2891 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
2892 // Check that there aren't any extra codecs lying around.
2893 EXPECT_EQ(13U, engine.codecs().size());
2894 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
2895 for (std::vector<cricket::AudioCodec>::const_iterator it =
2896 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
2897 if (it->name == "CN" && it->clockrate == 16000) {
2898 EXPECT_EQ(105, it->id);
2899 } else if (it->name == "CN" && it->clockrate == 32000) {
2900 EXPECT_EQ(106, it->id);
2901 } else if (it->name == "ISAC" && it->clockrate == 16000) {
2902 EXPECT_EQ(103, it->id);
2903 } else if (it->name == "ISAC" && it->clockrate == 32000) {
2904 EXPECT_EQ(104, it->id);
2905 } else if (it->name == "G722" && it->clockrate == 16000) {
2906 EXPECT_EQ(9, it->id);
2907 } else if (it->name == "telephone-event") {
2908 EXPECT_EQ(126, it->id);
2909 } else if (it->name == "red") {
2910 EXPECT_EQ(127, it->id);
2911 } else if (it->name == "opus") {
2912 EXPECT_EQ(111, it->id);
2913 ASSERT_NE(it->params.find("minptime"), it->params.end());
2914 EXPECT_EQ("10", it->params.find("minptime")->second);
2915 ASSERT_NE(it->params.find("maxptime"), it->params.end());
2916 EXPECT_EQ("60", it->params.find("maxptime")->second);
2917 }
2918 }
2919
2920 engine.Terminate();
2921}
2922
2923// Tests that VoE supports at least 32 channels
2924TEST(WebRtcVoiceEngineTest, Has32Channels) {
2925 cricket::WebRtcVoiceEngine engine;
2926 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2927
2928 cricket::VoiceMediaChannel* channels[32];
2929 int num_channels = 0;
2930
2931 while (num_channels < ARRAY_SIZE(channels)) {
2932 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2933 if (!channel)
2934 break;
2935
2936 channels[num_channels++] = channel;
2937 }
2938
2939 int expected = ARRAY_SIZE(channels);
2940 EXPECT_EQ(expected, num_channels);
2941
2942 while (num_channels > 0) {
2943 delete channels[--num_channels];
2944 }
2945
2946 engine.Terminate();
2947}
2948
2949// Test that we set our preferred codecs properly.
2950TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
2951 cricket::WebRtcVoiceEngine engine;
2952 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2953 cricket::WebRtcVoiceMediaChannel channel(&engine);
2954 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
2955}
2956
2957#ifdef WIN32
2958// Test our workarounds to WebRtc VoE' munging of the coinit count
2959TEST(WebRtcVoiceEngineTest, CoInitialize) {
2960 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
2961
2962 // Initial refcount should be 0.
2963 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
2964
2965 // Engine should start even with COM already inited.
2966 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
2967 engine->Terminate();
2968 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
2969 engine->Terminate();
2970
2971 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
2972 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
2973 // Decrement refcount to (hopefully) 0.
2974 CoUninitialize();
2975 CoUninitialize();
2976 delete engine;
2977
2978 // Ensure refcount is 0.
2979 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
2980 CoUninitialize();
2981}
2982#endif
2983
2984
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002985TEST_F(WebRtcVoiceEngineTestFake, SetExperimentalAcm) {
2986 EXPECT_TRUE(SetupEngine());
2987
2988 // By default experimental ACM should not be used.
2989 int media_channel = engine_.CreateMediaVoiceChannel();
2990 ASSERT_GE(media_channel, 0);
2991 EXPECT_FALSE(voe_.IsUsingExperimentalAcm(media_channel));
2992
2993 int soundclip_channel = engine_.CreateSoundclipVoiceChannel();
2994 ASSERT_GE(soundclip_channel, 0);
2995 EXPECT_FALSE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
2996
2997#ifdef USE_WEBRTC_DEV_BRANCH
2998 // Set options to use experimental ACM.
2999 cricket::AudioOptions options;
3000 options.experimental_acm.Set(true);
3001 ASSERT_TRUE(engine_.SetOptions(options));
3002 media_channel = engine_.CreateMediaVoiceChannel();
3003 ASSERT_GE(media_channel, 0);
3004 EXPECT_TRUE(voe_.IsUsingExperimentalAcm(media_channel));
3005
3006 soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3007 ASSERT_GE(soundclip_channel, 0);
3008 EXPECT_TRUE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
3009
3010 // Set option to use legacy ACM.
3011 options.experimental_acm.Set(false);
3012 ASSERT_TRUE(engine_.SetOptions(options));
3013 media_channel = engine_.CreateMediaVoiceChannel();
3014 ASSERT_GE(media_channel, 0);
3015 EXPECT_FALSE(voe_.IsUsingExperimentalAcm(media_channel));
3016
3017 soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3018 ASSERT_GE(soundclip_channel, 0);
3019 EXPECT_FALSE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
3020#endif
3021}