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