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