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