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