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