blob: 4dbeebaaa9693e855d557db3075986e4b766d823 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
2 * libjingle
3 * Copyright 2008 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
28#ifdef WIN32
29#include "talk/base/win32.h"
30#include <objbase.h>
31#endif
32
33#include "talk/base/byteorder.h"
34#include "talk/base/gunit.h"
35#include "talk/media/base/constants.h"
36#include "talk/media/base/fakemediaengine.h"
37#include "talk/media/base/fakemediaprocessor.h"
wu@webrtc.orgde305012013-10-31 15:40:38 +000038#include "talk/media/base/fakenetworkinterface.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/media/base/fakertp.h"
40#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
41#include "talk/media/webrtc/webrtcvoiceengine.h"
42#include "talk/p2p/base/fakesession.h"
43#include "talk/session/media/channel.h"
44
45// Tests for the WebRtcVoiceEngine/VoiceChannel code.
46
47static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
48static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
49static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
50static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
51static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
52static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
53static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
54static const cricket::AudioCodec
55 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
56static const cricket::AudioCodec* const kAudioCodecs[] = {
57 &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
58 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
59};
60const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
61static uint32 kSsrc1 = 0x99;
62static uint32 kSsrc2 = 0x98;
63
64class FakeVoEWrapper : public cricket::VoEWrapper {
65 public:
66 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
67 : cricket::VoEWrapper(engine, // processing
68 engine, // base
69 engine, // codec
70 engine, // dtmf
71 engine, // file
72 engine, // hw
73 engine, // media
74 engine, // neteq
75 engine, // network
76 engine, // rtp
77 engine, // sync
78 engine) { // volume
79 }
80};
81
wu@webrtc.org97077a32013-10-25 21:18:33 +000082class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083 public:
84 virtual int SetTraceFilter(const unsigned int filter) {
wu@webrtc.org97077a32013-10-25 21:18:33 +000085 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 return 0;
87 }
88 virtual int SetTraceFile(const char* fileNameUTF8) {
89 return 0;
90 }
91 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
92 return 0;
93 }
wu@webrtc.org97077a32013-10-25 21:18:33 +000094 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095};
96
97class WebRtcVoiceEngineTestFake : public testing::Test {
98 public:
99 class ChannelErrorListener : public sigslot::has_slots<> {
100 public:
101 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
102 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
103 ASSERT(channel != NULL);
104 channel->SignalMediaError.connect(
105 this, &ChannelErrorListener::OnVoiceChannelError);
106 }
107 void OnVoiceChannelError(uint32 ssrc,
108 cricket::VoiceMediaChannel::Error error) {
109 ssrc_ = ssrc;
110 error_ = error;
111 }
112 void Reset() {
113 ssrc_ = 0;
114 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
115 }
116 uint32 ssrc() const {
117 return ssrc_;
118 }
119 cricket::VoiceMediaChannel::Error error() const {
120 return error_;
121 }
122
123 private:
124 uint32 ssrc_;
125 cricket::VoiceMediaChannel::Error error_;
126 };
127
128 WebRtcVoiceEngineTestFake()
129 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
130 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000131 trace_wrapper_(new FakeVoETraceWrapper()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132 engine_(new FakeVoEWrapper(&voe_),
133 new FakeVoEWrapper(&voe_sc_),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000134 trace_wrapper_),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135 channel_(NULL), soundclip_(NULL) {
136 options_conference_.conference_mode.Set(true);
137 options_adjust_agc_.adjust_agc_delta.Set(-10);
138 }
139 bool SetupEngine() {
140 bool result = engine_.Init(talk_base::Thread::Current());
141 if (result) {
142 channel_ = engine_.CreateChannel();
143 result = (channel_ != NULL);
144 }
145 if (result) {
146 result = channel_->AddSendStream(
147 cricket::StreamParams::CreateLegacy(kSsrc1));
148 }
149 return result;
150 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000151 void SetupForMultiSendStream() {
152 EXPECT_TRUE(SetupEngine());
153 // Remove stream added in Setup, which is corresponding to default channel.
154 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000155 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000156 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
157 EXPECT_EQ(kSsrc1, default_send_ssrc);
158 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
159
160 // Verify the default channel still exists.
161 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
162 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163 void DeliverPacket(const void* data, int len) {
164 talk_base::Buffer packet(data, len);
wu@webrtc.orga9890802013-12-13 00:21:03 +0000165 channel_->OnPacketReceived(&packet, talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 }
167 virtual void TearDown() {
168 delete soundclip_;
169 delete channel_;
170 engine_.Terminate();
171 }
172
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000173 void TestInsertDtmf(uint32 ssrc, bool caller) {
174 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
175 channel_ = engine_.CreateChannel();
176 EXPECT_TRUE(channel_ != NULL);
177 if (caller) {
178 // if this is a caller, local description will be applied and add the
179 // send stream.
180 EXPECT_TRUE(channel_->AddSendStream(
181 cricket::StreamParams::CreateLegacy(kSsrc1)));
182 }
183 int channel_id = voe_.GetLastChannel();
184
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185 // Test we can only InsertDtmf when the other side supports telephone-event.
186 std::vector<cricket::AudioCodec> codecs;
187 codecs.push_back(kPcmuCodec);
188 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
189 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
190 EXPECT_FALSE(channel_->CanInsertDtmf());
191 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
192 codecs.push_back(kTelephoneEventCodec);
193 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
194 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000195
196 if (!caller) {
197 // There's no active send channel yet.
198 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
199 EXPECT_TRUE(channel_->AddSendStream(
200 cricket::StreamParams::CreateLegacy(kSsrc1)));
201 }
202
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 // Check we fail if the ssrc is invalid.
204 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
205
206 // Test send
207 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
208 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
209 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
210
211 // Test play
212 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
213 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
214 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
215
216 // Test send and play
217 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
218 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
219 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
220 cricket::DF_PLAY | cricket::DF_SEND));
221 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
222 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
223 }
224
225 // Test that send bandwidth is set correctly.
226 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000227 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
228 // |expected_result| is the expected result from SetMaxSendBandwidth().
229 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000231 int max_bitrate,
232 bool expected_result,
233 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 int channel_num = voe_.GetLastChannel();
235 std::vector<cricket::AudioCodec> codecs;
236
237 codecs.push_back(codec);
238 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
239
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000240 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 EXPECT_EQ(expected_result, result);
242
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000243 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
245
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000246 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 }
248
249
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000250 void TestSetSendRtpHeaderExtensions(int channel_id) {
251 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000252
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000253 // Ensure extensions are off by default.
254 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
255#ifdef USE_WEBRTC_DEV_BRANCH
256 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
257#endif
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258
259 // Ensure unknown extensions won't cause an error.
260 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000261 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000262 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000263 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
264#ifdef USE_WEBRTC_DEV_BRANCH
265 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
266#endif
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000267
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000268 // Ensure extensions stay off with an empty list of headers.
269 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000270 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000271 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
272#ifdef USE_WEBRTC_DEV_BRANCH
273 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
274#endif
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000275
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000276 // Ensure audio levels are enabled if the audio-level header is specified
277 // (but AST is still off).
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000278 extensions.push_back(cricket::RtpHeaderExtension(
279 "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
280 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000281 EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id));
282#ifdef USE_WEBRTC_DEV_BRANCH
283 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
284#endif
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000285
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000286#ifdef USE_WEBRTC_DEV_BRANCH
287 // Ensure audio level and AST are enabled if the extensions are specified.
288 extensions.push_back(cricket::RtpHeaderExtension(
289 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", 12));
290 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
291 EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id));
292 EXPECT_EQ(12, voe_.GetSendAbsoluteSenderTimeId(channel_id));
293#endif
294
295 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000296 extensions.clear();
297 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000298 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
299#ifdef USE_WEBRTC_DEV_BRANCH
300 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
301#endif
302 }
303
304 void TestSetRecvRtpHeaderExtensions(int channel_id) {
305 std::vector<cricket::RtpHeaderExtension> extensions;
306
307#ifdef USE_WEBRTC_DEV_BRANCH
308 // Ensure extensions are off by default.
309 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
310#endif
311
312 // Ensure unknown extensions won't cause an error.
313 extensions.push_back(cricket::RtpHeaderExtension(
314 "urn:ietf:params:unknownextention", 1));
315 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
316#ifdef USE_WEBRTC_DEV_BRANCH
317 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
318#endif
319
320 // An empty list shouldn't cause any headers to be enabled.
321 extensions.clear();
322 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
323#ifdef USE_WEBRTC_DEV_BRANCH
324 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
325#endif
326
327#ifdef USE_WEBRTC_DEV_BRANCH
328 // Nor should indicating we can receive the absolute sender time header.
329 extensions.push_back(cricket::RtpHeaderExtension(
330 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", 11));
331 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
332 EXPECT_EQ(11, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
333#endif
334
335 // Resetting to an empty list shouldn't cause any headers to be enabled.
336 extensions.clear();
337 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
338#ifdef USE_WEBRTC_DEV_BRANCH
339 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
340#endif
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000341 }
342
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 protected:
344 cricket::FakeWebRtcVoiceEngine voe_;
345 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000346 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 cricket::WebRtcVoiceEngine engine_;
348 cricket::VoiceMediaChannel* channel_;
349 cricket::SoundclipMedia* soundclip_;
350
351 cricket::AudioOptions options_conference_;
352 cricket::AudioOptions options_adjust_agc_;
353};
354
355// Tests that our stub library "works".
356TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
357 EXPECT_FALSE(voe_.IsInited());
358 EXPECT_FALSE(voe_sc_.IsInited());
359 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
360 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000361 // The soundclip engine is lazily initialized.
362 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363 engine_.Terminate();
364 EXPECT_FALSE(voe_.IsInited());
365 EXPECT_FALSE(voe_sc_.IsInited());
366}
367
368// Tests that we can create and destroy a channel.
369TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
370 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
371 channel_ = engine_.CreateChannel();
372 EXPECT_TRUE(channel_ != NULL);
373}
374
375// Tests that we properly handle failures in CreateChannel.
376TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
377 voe_.set_fail_create_channel(true);
378 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
379 channel_ = engine_.CreateChannel();
380 EXPECT_TRUE(channel_ == NULL);
381}
382
383// Tests that the list of supported codecs is created properly and ordered
384// correctly
385TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
386 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
387 ASSERT_FALSE(codecs.empty());
388 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
389 EXPECT_EQ(48000, codecs[0].clockrate);
390 EXPECT_EQ(2, codecs[0].channels);
391 EXPECT_EQ(64000, codecs[0].bitrate);
392 int pref = codecs[0].preference;
393 for (size_t i = 1; i < codecs.size(); ++i) {
394 EXPECT_GT(pref, codecs[i].preference);
395 pref = codecs[i].preference;
396 }
397}
398
399// Tests that we can find codecs by name or id, and that we interpret the
400// clockrate and bitrate fields properly.
401TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
402 cricket::AudioCodec codec;
403 webrtc::CodecInst codec_inst;
404 // Find PCMU with explicit clockrate and bitrate.
405 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
406 // Find ISAC with explicit clockrate and 0 bitrate.
407 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
408 // Find telephone-event with explicit clockrate and 0 bitrate.
409 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
410 // Find ISAC with a different payload id.
411 codec = kIsacCodec;
412 codec.id = 127;
413 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
414 EXPECT_EQ(codec.id, codec_inst.pltype);
415 // Find PCMU with a 0 clockrate.
416 codec = kPcmuCodec;
417 codec.clockrate = 0;
418 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
419 EXPECT_EQ(codec.id, codec_inst.pltype);
420 EXPECT_EQ(8000, codec_inst.plfreq);
421 // Find PCMU with a 0 bitrate.
422 codec = kPcmuCodec;
423 codec.bitrate = 0;
424 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
425 EXPECT_EQ(codec.id, codec_inst.pltype);
426 EXPECT_EQ(64000, codec_inst.rate);
427 // Find ISAC with an explicit bitrate.
428 codec = kIsacCodec;
429 codec.bitrate = 32000;
430 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
431 EXPECT_EQ(codec.id, codec_inst.pltype);
432 EXPECT_EQ(32000, codec_inst.rate);
433}
434
435// Test that we set our inbound codecs properly, including changing PT.
436TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
437 EXPECT_TRUE(SetupEngine());
438 int channel_num = voe_.GetLastChannel();
439 std::vector<cricket::AudioCodec> codecs;
440 codecs.push_back(kIsacCodec);
441 codecs.push_back(kPcmuCodec);
442 codecs.push_back(kTelephoneEventCodec);
443 codecs[0].id = 106; // collide with existing telephone-event
444 codecs[2].id = 126;
445 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
446 webrtc::CodecInst gcodec;
447 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
448 gcodec.plfreq = 16000;
449 gcodec.channels = 1;
450 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
451 EXPECT_EQ(106, gcodec.pltype);
452 EXPECT_STREQ("ISAC", gcodec.plname);
453 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
454 "telephone-event");
455 gcodec.plfreq = 8000;
456 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
457 EXPECT_EQ(126, gcodec.pltype);
458 EXPECT_STREQ("telephone-event", gcodec.plname);
459}
460
461// Test that we fail to set an unknown inbound codec.
462TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
463 EXPECT_TRUE(SetupEngine());
464 std::vector<cricket::AudioCodec> codecs;
465 codecs.push_back(kIsacCodec);
466 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
467 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
468}
469
470// Test that we fail if we have duplicate types in the inbound list.
471TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
472 EXPECT_TRUE(SetupEngine());
473 std::vector<cricket::AudioCodec> codecs;
474 codecs.push_back(kIsacCodec);
475 codecs.push_back(kCn16000Codec);
476 codecs[1].id = kIsacCodec.id;
477 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
478}
479
480// Test that we can decode OPUS without stereo parameters.
481TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
482 EXPECT_TRUE(SetupEngine());
483 EXPECT_TRUE(channel_->SetOptions(options_conference_));
484 std::vector<cricket::AudioCodec> codecs;
485 codecs.push_back(kIsacCodec);
486 codecs.push_back(kPcmuCodec);
487 codecs.push_back(kOpusCodec);
488 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
489 EXPECT_TRUE(channel_->AddRecvStream(
490 cricket::StreamParams::CreateLegacy(kSsrc1)));
491 int channel_num2 = voe_.GetLastChannel();
492 webrtc::CodecInst opus;
493 engine_.FindWebRtcCodec(kOpusCodec, &opus);
494 // Even without stereo parameters, recv codecs still specify channels = 2.
495 EXPECT_EQ(2, opus.channels);
496 EXPECT_EQ(111, opus.pltype);
497 EXPECT_STREQ("opus", opus.plname);
498 opus.pltype = 0;
499 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
500 EXPECT_EQ(111, opus.pltype);
501}
502
503// Test that we can decode OPUS with stereo = 0.
504TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
505 EXPECT_TRUE(SetupEngine());
506 EXPECT_TRUE(channel_->SetOptions(options_conference_));
507 std::vector<cricket::AudioCodec> codecs;
508 codecs.push_back(kIsacCodec);
509 codecs.push_back(kPcmuCodec);
510 codecs.push_back(kOpusCodec);
511 codecs[2].params["stereo"] = "0";
512 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
513 EXPECT_TRUE(channel_->AddRecvStream(
514 cricket::StreamParams::CreateLegacy(kSsrc1)));
515 int channel_num2 = voe_.GetLastChannel();
516 webrtc::CodecInst opus;
517 engine_.FindWebRtcCodec(kOpusCodec, &opus);
518 // Even when stereo is off, recv codecs still specify channels = 2.
519 EXPECT_EQ(2, opus.channels);
520 EXPECT_EQ(111, opus.pltype);
521 EXPECT_STREQ("opus", opus.plname);
522 opus.pltype = 0;
523 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
524 EXPECT_EQ(111, opus.pltype);
525}
526
527// Test that we can decode OPUS with stereo = 1.
528TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
529 EXPECT_TRUE(SetupEngine());
530 EXPECT_TRUE(channel_->SetOptions(options_conference_));
531 std::vector<cricket::AudioCodec> codecs;
532 codecs.push_back(kIsacCodec);
533 codecs.push_back(kPcmuCodec);
534 codecs.push_back(kOpusCodec);
535 codecs[2].params["stereo"] = "1";
536 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
537 EXPECT_TRUE(channel_->AddRecvStream(
538 cricket::StreamParams::CreateLegacy(kSsrc1)));
539 int channel_num2 = voe_.GetLastChannel();
540 webrtc::CodecInst opus;
541 engine_.FindWebRtcCodec(kOpusCodec, &opus);
542 EXPECT_EQ(2, opus.channels);
543 EXPECT_EQ(111, opus.pltype);
544 EXPECT_STREQ("opus", opus.plname);
545 opus.pltype = 0;
546 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
547 EXPECT_EQ(111, opus.pltype);
548}
549
550// Test that changes to recv codecs are applied to all streams.
551TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
552 EXPECT_TRUE(SetupEngine());
553 EXPECT_TRUE(channel_->SetOptions(options_conference_));
554 std::vector<cricket::AudioCodec> codecs;
555 codecs.push_back(kIsacCodec);
556 codecs.push_back(kPcmuCodec);
557 codecs.push_back(kTelephoneEventCodec);
558 codecs[0].id = 106; // collide with existing telephone-event
559 codecs[2].id = 126;
560 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
561 EXPECT_TRUE(channel_->AddRecvStream(
562 cricket::StreamParams::CreateLegacy(kSsrc1)));
563 int channel_num2 = voe_.GetLastChannel();
564 webrtc::CodecInst gcodec;
565 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
566 gcodec.plfreq = 16000;
567 gcodec.channels = 1;
568 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
569 EXPECT_EQ(106, gcodec.pltype);
570 EXPECT_STREQ("ISAC", gcodec.plname);
571 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
572 "telephone-event");
573 gcodec.plfreq = 8000;
574 gcodec.channels = 1;
575 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
576 EXPECT_EQ(126, gcodec.pltype);
577 EXPECT_STREQ("telephone-event", gcodec.plname);
578}
579
580TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
581 EXPECT_TRUE(SetupEngine());
582 EXPECT_TRUE(channel_->SetOptions(options_conference_));
583 std::vector<cricket::AudioCodec> codecs;
584 codecs.push_back(kIsacCodec);
585 codecs[0].id = 106; // collide with existing telephone-event
586
587 EXPECT_TRUE(channel_->AddRecvStream(
588 cricket::StreamParams::CreateLegacy(kSsrc1)));
589 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
590
591 int channel_num2 = voe_.GetLastChannel();
592 webrtc::CodecInst gcodec;
593 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
594 gcodec.plfreq = 16000;
595 gcodec.channels = 1;
596 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
597 EXPECT_EQ(106, gcodec.pltype);
598 EXPECT_STREQ("ISAC", gcodec.plname);
599}
600
601// Test that we can apply the same set of codecs again while playing.
602TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
603 EXPECT_TRUE(SetupEngine());
604 int channel_num = voe_.GetLastChannel();
605 std::vector<cricket::AudioCodec> codecs;
606 codecs.push_back(kIsacCodec);
607 codecs.push_back(kCn16000Codec);
608 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
609 EXPECT_TRUE(channel_->SetPlayout(true));
610 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
611
612 // Changing the payload type of a codec should fail.
613 codecs[0].id = 127;
614 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
615 EXPECT_TRUE(voe_.GetPlayout(channel_num));
616}
617
618// Test that we can add a codec while playing.
619TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
620 EXPECT_TRUE(SetupEngine());
621 int channel_num = voe_.GetLastChannel();
622 std::vector<cricket::AudioCodec> codecs;
623 codecs.push_back(kIsacCodec);
624 codecs.push_back(kCn16000Codec);
625 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
626 EXPECT_TRUE(channel_->SetPlayout(true));
627
628 codecs.push_back(kOpusCodec);
629 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
630 EXPECT_TRUE(voe_.GetPlayout(channel_num));
631 webrtc::CodecInst gcodec;
632 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
633 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
634}
635
636TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
637 EXPECT_TRUE(SetupEngine());
638 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
639
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000640 // Test that when autobw is enabled, bitrate is kept as the default
641 // value. autobw is enabled for the following tests because the target
642 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000643
644 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000645 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646
647 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000648 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649
650 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000651 TestSendBandwidth(kCeltCodec, 0, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000652
653 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000654 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655}
656
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000657TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658 EXPECT_TRUE(SetupEngine());
659 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
660
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000661 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662
663 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000664 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
665 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000666
667 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000668 TestSendBandwidth(kCeltCodec, 96000, true, 96000);
669 TestSendBandwidth(kCeltCodec, 32000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670
671 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000672 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
673 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000674}
675
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000676TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
677 EXPECT_TRUE(SetupEngine());
678 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
679
680 // Test that we can only set a maximum bitrate for a fixed-rate codec
681 // if it's bigger than the fixed rate.
682
683 // PCMU, fixed bitrate == 64000.
684 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
685 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
686 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
687 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
688 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
689 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
690 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
691}
692
693TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000694 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
695 channel_ = engine_.CreateChannel();
696 EXPECT_TRUE(channel_ != NULL);
697 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
698
699 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000700 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000701
702 EXPECT_TRUE(channel_->AddSendStream(
703 cricket::StreamParams::CreateLegacy(kSsrc1)));
704
705 int channel_num = voe_.GetLastChannel();
706 webrtc::CodecInst codec;
707 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
708 EXPECT_EQ(desired_bitrate, codec.rate);
709}
710
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711// Test that bitrate cannot be set for CBR codecs.
712// Bitrate is ignored if it is higher than the fixed bitrate.
713// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000714TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 EXPECT_TRUE(SetupEngine());
716 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
717
718 webrtc::CodecInst codec;
719 int channel_num = voe_.GetLastChannel();
720 std::vector<cricket::AudioCodec> codecs;
721
722 // PCMU, default bitrate == 64000.
723 codecs.push_back(kPcmuCodec);
724 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
725 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
726 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000727 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
729 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000730 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
732 EXPECT_EQ(64000, codec.rate);
733}
734
735// Test that we apply codecs properly.
736TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
737 EXPECT_TRUE(SetupEngine());
738 int channel_num = voe_.GetLastChannel();
739 std::vector<cricket::AudioCodec> codecs;
740 codecs.push_back(kIsacCodec);
741 codecs.push_back(kPcmuCodec);
742 codecs.push_back(kRedCodec);
743 codecs[0].id = 96;
744 codecs[0].bitrate = 48000;
745 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000746 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000747 webrtc::CodecInst gcodec;
748 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
749 EXPECT_EQ(96, gcodec.pltype);
750 EXPECT_EQ(48000, gcodec.rate);
751 EXPECT_STREQ("ISAC", gcodec.plname);
752 EXPECT_FALSE(voe_.GetVAD(channel_num));
753 EXPECT_FALSE(voe_.GetFEC(channel_num));
754 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
755 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
756 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
757}
758
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000759// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
760// to apply.
761TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
762 EXPECT_TRUE(SetupEngine());
763 std::vector<cricket::AudioCodec> codecs;
764 codecs.push_back(kIsacCodec);
765 codecs.push_back(kPcmuCodec);
766 codecs.push_back(kRedCodec);
767 codecs[0].id = 96;
768 codecs[0].bitrate = 48000;
769 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
770 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
771 // Calling SetSendCodec again with same codec which is already set.
772 // In this case media channel shouldn't send codec to VoE.
773 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
774 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
775}
776
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000777// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000778TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
779 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780 std::vector<cricket::AudioCodec> codecs;
781 codecs.push_back(kOpusCodec);
782 codecs[0].bitrate = 0;
783 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000784 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785}
786
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000787// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
789 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 std::vector<cricket::AudioCodec> codecs;
791 codecs.push_back(kOpusCodec);
792 codecs[0].bitrate = 0;
793 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000794 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795}
796
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000797// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
799 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800 std::vector<cricket::AudioCodec> codecs;
801 codecs.push_back(kOpusCodec);
802 codecs[0].bitrate = 0;
803 codecs[0].channels = 0;
804 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000805 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806}
807
808// Test that if channel is 1 for opus and there's no stereo, we fail.
809TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
810 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811 std::vector<cricket::AudioCodec> codecs;
812 codecs.push_back(kOpusCodec);
813 codecs[0].bitrate = 0;
814 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000815 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816}
817
818// Test that if channel is 1 for opus and stereo=0, we fail.
819TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
820 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821 std::vector<cricket::AudioCodec> codecs;
822 codecs.push_back(kOpusCodec);
823 codecs[0].bitrate = 0;
824 codecs[0].channels = 1;
825 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000826 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827}
828
829// Test that if channel is 1 for opus and stereo=1, we fail.
830TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
831 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832 std::vector<cricket::AudioCodec> codecs;
833 codecs.push_back(kOpusCodec);
834 codecs[0].bitrate = 0;
835 codecs[0].channels = 1;
836 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000837 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838}
839
840// Test that with bitrate=0 and no stereo,
841// channels and bitrate are 1 and 32000.
842TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
843 EXPECT_TRUE(SetupEngine());
844 int channel_num = voe_.GetLastChannel();
845 std::vector<cricket::AudioCodec> codecs;
846 codecs.push_back(kOpusCodec);
847 codecs[0].bitrate = 0;
848 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
849 webrtc::CodecInst gcodec;
850 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
851 EXPECT_STREQ("opus", gcodec.plname);
852 EXPECT_EQ(1, gcodec.channels);
853 EXPECT_EQ(32000, gcodec.rate);
854}
855
856// Test that with bitrate=0 and stereo=0,
857// channels and bitrate are 1 and 32000.
858TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
859 EXPECT_TRUE(SetupEngine());
860 int channel_num = voe_.GetLastChannel();
861 std::vector<cricket::AudioCodec> codecs;
862 codecs.push_back(kOpusCodec);
863 codecs[0].bitrate = 0;
864 codecs[0].params["stereo"] = "0";
865 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
866 webrtc::CodecInst gcodec;
867 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
868 EXPECT_STREQ("opus", gcodec.plname);
869 EXPECT_EQ(1, gcodec.channels);
870 EXPECT_EQ(32000, gcodec.rate);
871}
872
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000873// Test that with bitrate=invalid and stereo=0,
874// channels and bitrate are 1 and 32000.
875TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
876 EXPECT_TRUE(SetupEngine());
877 int channel_num = voe_.GetLastChannel();
878 std::vector<cricket::AudioCodec> codecs;
879 codecs.push_back(kOpusCodec);
880 codecs[0].params["stereo"] = "0";
881 webrtc::CodecInst gcodec;
882
883 // bitrate that's out of the range between 6000 and 510000 will be considered
884 // as invalid and ignored.
885 codecs[0].bitrate = 5999;
886 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
887 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
888 EXPECT_STREQ("opus", gcodec.plname);
889 EXPECT_EQ(1, gcodec.channels);
890 EXPECT_EQ(32000, gcodec.rate);
891
892 codecs[0].bitrate = 510001;
893 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
894 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
895 EXPECT_STREQ("opus", gcodec.plname);
896 EXPECT_EQ(1, gcodec.channels);
897 EXPECT_EQ(32000, gcodec.rate);
898}
899
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900// Test that with bitrate=0 and stereo=1,
901// channels and bitrate are 2 and 64000.
902TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
903 EXPECT_TRUE(SetupEngine());
904 int channel_num = voe_.GetLastChannel();
905 std::vector<cricket::AudioCodec> codecs;
906 codecs.push_back(kOpusCodec);
907 codecs[0].bitrate = 0;
908 codecs[0].params["stereo"] = "1";
909 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
910 webrtc::CodecInst gcodec;
911 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
912 EXPECT_STREQ("opus", gcodec.plname);
913 EXPECT_EQ(2, gcodec.channels);
914 EXPECT_EQ(64000, gcodec.rate);
915}
916
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000917// Test that with bitrate=invalid and stereo=1,
918// channels and bitrate are 2 and 64000.
919TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
920 EXPECT_TRUE(SetupEngine());
921 int channel_num = voe_.GetLastChannel();
922 std::vector<cricket::AudioCodec> codecs;
923 codecs.push_back(kOpusCodec);
924 codecs[0].params["stereo"] = "1";
925 webrtc::CodecInst gcodec;
926
927 // bitrate that's out of the range between 6000 and 510000 will be considered
928 // as invalid and ignored.
929 codecs[0].bitrate = 5999;
930 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
931 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
932 EXPECT_STREQ("opus", gcodec.plname);
933 EXPECT_EQ(2, gcodec.channels);
934 EXPECT_EQ(64000, gcodec.rate);
935
936 codecs[0].bitrate = 510001;
937 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
938 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
939 EXPECT_STREQ("opus", gcodec.plname);
940 EXPECT_EQ(2, gcodec.channels);
941 EXPECT_EQ(64000, gcodec.rate);
942}
943
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000944// Test that with bitrate=N and stereo unset,
945// channels and bitrate are 1 and N.
946TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
947 EXPECT_TRUE(SetupEngine());
948 int channel_num = voe_.GetLastChannel();
949 std::vector<cricket::AudioCodec> codecs;
950 codecs.push_back(kOpusCodec);
951 codecs[0].bitrate = 96000;
952 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
953 webrtc::CodecInst gcodec;
954 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
955 EXPECT_EQ(111, gcodec.pltype);
956 EXPECT_EQ(96000, gcodec.rate);
957 EXPECT_STREQ("opus", gcodec.plname);
958 EXPECT_EQ(1, gcodec.channels);
959 EXPECT_EQ(48000, gcodec.plfreq);
960}
961
962// Test that with bitrate=N and stereo=0,
963// channels and bitrate are 1 and N.
964TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
965 EXPECT_TRUE(SetupEngine());
966 int channel_num = voe_.GetLastChannel();
967 std::vector<cricket::AudioCodec> codecs;
968 codecs.push_back(kOpusCodec);
969 codecs[0].bitrate = 30000;
970 codecs[0].params["stereo"] = "0";
971 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
972 webrtc::CodecInst gcodec;
973 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
974 EXPECT_EQ(1, gcodec.channels);
975 EXPECT_EQ(30000, gcodec.rate);
976 EXPECT_STREQ("opus", gcodec.plname);
977}
978
979// Test that with bitrate=N and without any parameters,
980// channels and bitrate are 1 and N.
981TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
982 EXPECT_TRUE(SetupEngine());
983 int channel_num = voe_.GetLastChannel();
984 std::vector<cricket::AudioCodec> codecs;
985 codecs.push_back(kOpusCodec);
986 codecs[0].bitrate = 30000;
987 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
988 webrtc::CodecInst gcodec;
989 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
990 EXPECT_EQ(1, gcodec.channels);
991 EXPECT_EQ(30000, gcodec.rate);
992 EXPECT_STREQ("opus", gcodec.plname);
993}
994
995// Test that with bitrate=N and stereo=1,
996// channels and bitrate are 2 and N.
997TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
998 EXPECT_TRUE(SetupEngine());
999 int channel_num = voe_.GetLastChannel();
1000 std::vector<cricket::AudioCodec> codecs;
1001 codecs.push_back(kOpusCodec);
1002 codecs[0].bitrate = 30000;
1003 codecs[0].params["stereo"] = "1";
1004 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1005 webrtc::CodecInst gcodec;
1006 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1007 EXPECT_EQ(2, gcodec.channels);
1008 EXPECT_EQ(30000, gcodec.rate);
1009 EXPECT_STREQ("opus", gcodec.plname);
1010}
1011
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001012// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1013// Also test that the "maxaveragebitrate" can't be set to values outside the
1014// range of 6000 and 510000
1015TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1016 EXPECT_TRUE(SetupEngine());
1017 int channel_num = voe_.GetLastChannel();
1018 std::vector<cricket::AudioCodec> codecs;
1019 codecs.push_back(kOpusCodec);
1020 codecs[0].bitrate = 30000;
1021 webrtc::CodecInst gcodec;
1022
1023 // Ignore if less than 6000.
1024 codecs[0].params["maxaveragebitrate"] = "5999";
1025 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1026 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1027 EXPECT_EQ(30000, gcodec.rate);
1028
1029 // Ignore if larger than 510000.
1030 codecs[0].params["maxaveragebitrate"] = "510001";
1031 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1032 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1033 EXPECT_EQ(30000, gcodec.rate);
1034
1035 codecs[0].params["maxaveragebitrate"] = "200000";
1036 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1037 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1038 EXPECT_EQ(200000, gcodec.rate);
1039}
1040
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001041// Test that we can enable NACK with opus as caller.
1042TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043 EXPECT_TRUE(SetupEngine());
1044 int channel_num = voe_.GetLastChannel();
1045 std::vector<cricket::AudioCodec> codecs;
1046 codecs.push_back(kOpusCodec);
1047 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1048 cricket::kParamValueEmpty));
1049 EXPECT_FALSE(voe_.GetNACK(channel_num));
1050 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1051 EXPECT_TRUE(voe_.GetNACK(channel_num));
1052}
1053
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001054// Test that we can enable NACK with opus as callee.
1055TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1056 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1057 channel_ = engine_.CreateChannel();
1058 EXPECT_TRUE(channel_ != NULL);
1059
1060 int channel_num = voe_.GetLastChannel();
1061 std::vector<cricket::AudioCodec> codecs;
1062 codecs.push_back(kOpusCodec);
1063 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1064 cricket::kParamValueEmpty));
1065 EXPECT_FALSE(voe_.GetNACK(channel_num));
1066 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1067 EXPECT_FALSE(voe_.GetNACK(channel_num));
1068
1069 EXPECT_TRUE(channel_->AddSendStream(
1070 cricket::StreamParams::CreateLegacy(kSsrc1)));
1071 EXPECT_TRUE(voe_.GetNACK(channel_num));
1072}
1073
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001074// Test that we can enable NACK on receive streams.
1075TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1076 EXPECT_TRUE(SetupEngine());
1077 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1078 int channel_num1 = voe_.GetLastChannel();
1079 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1080 int channel_num2 = voe_.GetLastChannel();
1081 std::vector<cricket::AudioCodec> codecs;
1082 codecs.push_back(kOpusCodec);
1083 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1084 cricket::kParamValueEmpty));
1085 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1086 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1087 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1088 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1089 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1090}
1091
1092// Test that we can disable NACK.
1093TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1094 EXPECT_TRUE(SetupEngine());
1095 int channel_num = voe_.GetLastChannel();
1096 std::vector<cricket::AudioCodec> codecs;
1097 codecs.push_back(kOpusCodec);
1098 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1099 cricket::kParamValueEmpty));
1100 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1101 EXPECT_TRUE(voe_.GetNACK(channel_num));
1102
1103 codecs.clear();
1104 codecs.push_back(kOpusCodec);
1105 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1106 EXPECT_FALSE(voe_.GetNACK(channel_num));
1107}
1108
1109// Test that we can disable NACK on receive streams.
1110TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1111 EXPECT_TRUE(SetupEngine());
1112 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1113 int channel_num1 = voe_.GetLastChannel();
1114 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1115 int channel_num2 = voe_.GetLastChannel();
1116 std::vector<cricket::AudioCodec> codecs;
1117 codecs.push_back(kOpusCodec);
1118 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1119 cricket::kParamValueEmpty));
1120 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1121 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1122 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1123
1124 codecs.clear();
1125 codecs.push_back(kOpusCodec);
1126 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1127 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1128 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1129}
1130
1131// Test that NACK is enabled on a new receive stream.
1132TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1133 EXPECT_TRUE(SetupEngine());
1134 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1135 int channel_num = voe_.GetLastChannel();
1136 std::vector<cricket::AudioCodec> codecs;
1137 codecs.push_back(kIsacCodec);
1138 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1139 cricket::kParamValueEmpty));
1140 codecs.push_back(kCn16000Codec);
1141 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1142 EXPECT_TRUE(voe_.GetNACK(channel_num));
1143
1144 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1145 channel_num = voe_.GetLastChannel();
1146 EXPECT_TRUE(voe_.GetNACK(channel_num));
1147 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1148 channel_num = voe_.GetLastChannel();
1149 EXPECT_TRUE(voe_.GetNACK(channel_num));
1150}
1151
1152// Test that we can apply CELT with stereo mode but fail with mono mode.
1153TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1154 EXPECT_TRUE(SetupEngine());
1155 int channel_num = voe_.GetLastChannel();
1156 std::vector<cricket::AudioCodec> codecs;
1157 codecs.push_back(kCeltCodec);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001158 codecs.push_back(kIsacCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001159 codecs[0].id = 96;
1160 codecs[0].channels = 2;
1161 codecs[0].bitrate = 96000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001162 codecs[1].bitrate = 64000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001163 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1164 webrtc::CodecInst gcodec;
1165 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1166 EXPECT_EQ(96, gcodec.pltype);
1167 EXPECT_EQ(96000, gcodec.rate);
1168 EXPECT_EQ(2, gcodec.channels);
1169 EXPECT_STREQ("CELT", gcodec.plname);
1170 // Doesn't support mono, expect it to fall back to the next codec in the list.
1171 codecs[0].channels = 1;
1172 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1173 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001174 EXPECT_EQ(103, gcodec.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001175 EXPECT_EQ(1, gcodec.channels);
1176 EXPECT_EQ(64000, gcodec.rate);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001177 EXPECT_STREQ("ISAC", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001178}
1179
1180// Test that we can switch back and forth between CELT and ISAC with CN.
1181TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1182 EXPECT_TRUE(SetupEngine());
1183 int channel_num = voe_.GetLastChannel();
1184 std::vector<cricket::AudioCodec> celt_codecs;
1185 celt_codecs.push_back(kCeltCodec);
1186 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1187 webrtc::CodecInst gcodec;
1188 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1189 EXPECT_EQ(110, gcodec.pltype);
1190 EXPECT_STREQ("CELT", gcodec.plname);
1191
1192 std::vector<cricket::AudioCodec> isac_codecs;
1193 isac_codecs.push_back(kIsacCodec);
1194 isac_codecs.push_back(kCn16000Codec);
1195 isac_codecs.push_back(kCeltCodec);
1196 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1197 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1198 EXPECT_EQ(103, gcodec.pltype);
1199 EXPECT_STREQ("ISAC", gcodec.plname);
1200
1201 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1202 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1203 EXPECT_EQ(110, gcodec.pltype);
1204 EXPECT_STREQ("CELT", gcodec.plname);
1205}
1206
1207// Test that we handle various ways of specifying bitrate.
1208TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1209 EXPECT_TRUE(SetupEngine());
1210 int channel_num = voe_.GetLastChannel();
1211 std::vector<cricket::AudioCodec> codecs;
1212 codecs.push_back(kIsacCodec); // bitrate == 32000
1213 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1214 webrtc::CodecInst gcodec;
1215 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1216 EXPECT_EQ(103, gcodec.pltype);
1217 EXPECT_STREQ("ISAC", gcodec.plname);
1218 EXPECT_EQ(32000, gcodec.rate);
1219
1220 codecs[0].bitrate = 0; // bitrate == default
1221 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1222 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1223 EXPECT_EQ(103, gcodec.pltype);
1224 EXPECT_STREQ("ISAC", gcodec.plname);
1225 EXPECT_EQ(-1, gcodec.rate);
1226
1227 codecs[0].bitrate = 28000; // bitrate == 28000
1228 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1229 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1230 EXPECT_EQ(103, gcodec.pltype);
1231 EXPECT_STREQ("ISAC", gcodec.plname);
1232 EXPECT_EQ(28000, gcodec.rate);
1233
1234 codecs[0] = kPcmuCodec; // bitrate == 64000
1235 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1236 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1237 EXPECT_EQ(0, gcodec.pltype);
1238 EXPECT_STREQ("PCMU", gcodec.plname);
1239 EXPECT_EQ(64000, gcodec.rate);
1240
1241 codecs[0].bitrate = 0; // bitrate == default
1242 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1243 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1244 EXPECT_EQ(0, gcodec.pltype);
1245 EXPECT_STREQ("PCMU", gcodec.plname);
1246 EXPECT_EQ(64000, gcodec.rate);
1247
1248 codecs[0] = kOpusCodec;
1249 codecs[0].bitrate = 0; // bitrate == default
1250 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1251 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1252 EXPECT_EQ(111, gcodec.pltype);
1253 EXPECT_STREQ("opus", gcodec.plname);
1254 EXPECT_EQ(32000, gcodec.rate);
1255}
1256
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001257// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001258TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1259 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001260 std::vector<cricket::AudioCodec> codecs;
1261 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1262}
1263
1264// Test that we can set send codecs even with telephone-event codec as the first
1265// one on the list.
1266TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1267 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001268 int channel_num = voe_.GetLastChannel();
1269 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001270 codecs.push_back(kTelephoneEventCodec);
1271 codecs.push_back(kIsacCodec);
1272 codecs.push_back(kPcmuCodec);
1273 codecs[0].id = 98; // DTMF
1274 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001275 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1276 webrtc::CodecInst gcodec;
1277 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001278 EXPECT_EQ(96, gcodec.pltype);
1279 EXPECT_STREQ("ISAC", gcodec.plname);
1280 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1281}
1282
1283// Test that we can set send codecs even with CN codec as the first
1284// one on the list.
1285TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1286 EXPECT_TRUE(SetupEngine());
1287 int channel_num = voe_.GetLastChannel();
1288 std::vector<cricket::AudioCodec> codecs;
1289 codecs.push_back(kCn16000Codec);
1290 codecs.push_back(kIsacCodec);
1291 codecs.push_back(kPcmuCodec);
1292 codecs[0].id = 98; // wideband CN
1293 codecs[1].id = 96;
1294 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1295 webrtc::CodecInst gcodec;
1296 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1297 EXPECT_EQ(96, gcodec.pltype);
1298 EXPECT_STREQ("ISAC", gcodec.plname);
1299 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001300}
1301
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001302// Test that we set VAD and DTMF types correctly as caller.
1303TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001304 EXPECT_TRUE(SetupEngine());
1305 int channel_num = voe_.GetLastChannel();
1306 std::vector<cricket::AudioCodec> codecs;
1307 codecs.push_back(kIsacCodec);
1308 codecs.push_back(kPcmuCodec);
1309 // TODO(juberti): cn 32000
1310 codecs.push_back(kCn16000Codec);
1311 codecs.push_back(kCn8000Codec);
1312 codecs.push_back(kTelephoneEventCodec);
1313 codecs.push_back(kRedCodec);
1314 codecs[0].id = 96;
1315 codecs[2].id = 97; // wideband CN
1316 codecs[4].id = 98; // DTMF
1317 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1318 webrtc::CodecInst gcodec;
1319 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1320 EXPECT_EQ(96, gcodec.pltype);
1321 EXPECT_STREQ("ISAC", gcodec.plname);
1322 EXPECT_TRUE(voe_.GetVAD(channel_num));
1323 EXPECT_FALSE(voe_.GetFEC(channel_num));
1324 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1325 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1326 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1327}
1328
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001329// Test that we set VAD and DTMF types correctly as callee.
1330TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1331 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1332 channel_ = engine_.CreateChannel();
1333 EXPECT_TRUE(channel_ != NULL);
1334
1335 int channel_num = voe_.GetLastChannel();
1336 std::vector<cricket::AudioCodec> codecs;
1337 codecs.push_back(kIsacCodec);
1338 codecs.push_back(kPcmuCodec);
1339 // TODO(juberti): cn 32000
1340 codecs.push_back(kCn16000Codec);
1341 codecs.push_back(kCn8000Codec);
1342 codecs.push_back(kTelephoneEventCodec);
1343 codecs.push_back(kRedCodec);
1344 codecs[0].id = 96;
1345 codecs[2].id = 97; // wideband CN
1346 codecs[4].id = 98; // DTMF
1347 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1348 EXPECT_TRUE(channel_->AddSendStream(
1349 cricket::StreamParams::CreateLegacy(kSsrc1)));
1350
1351 webrtc::CodecInst gcodec;
1352 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1353 EXPECT_EQ(96, gcodec.pltype);
1354 EXPECT_STREQ("ISAC", gcodec.plname);
1355 EXPECT_TRUE(voe_.GetVAD(channel_num));
1356 EXPECT_FALSE(voe_.GetFEC(channel_num));
1357 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1358 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1359 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1360}
1361
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362// Test that we only apply VAD if we have a CN codec that matches the
1363// send codec clockrate.
1364TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1365 EXPECT_TRUE(SetupEngine());
1366 int channel_num = voe_.GetLastChannel();
1367 std::vector<cricket::AudioCodec> codecs;
1368 // Set ISAC(16K) and CN(16K). VAD should be activated.
1369 codecs.push_back(kIsacCodec);
1370 codecs.push_back(kCn16000Codec);
1371 codecs[1].id = 97;
1372 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1373 webrtc::CodecInst gcodec;
1374 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1375 EXPECT_STREQ("ISAC", gcodec.plname);
1376 EXPECT_TRUE(voe_.GetVAD(channel_num));
1377 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1378 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1379 codecs[0] = kPcmuCodec;
1380 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1381 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1382 EXPECT_STREQ("PCMU", gcodec.plname);
1383 EXPECT_FALSE(voe_.GetVAD(channel_num));
1384 // Set PCMU(8K) and CN(8K). VAD should be activated.
1385 codecs[1] = kCn8000Codec;
1386 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1387 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1388 EXPECT_STREQ("PCMU", gcodec.plname);
1389 EXPECT_TRUE(voe_.GetVAD(channel_num));
1390 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1391 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1392 codecs[0] = kIsacCodec;
1393 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1394 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1395 EXPECT_STREQ("ISAC", gcodec.plname);
1396 EXPECT_FALSE(voe_.GetVAD(channel_num));
1397}
1398
1399// Test that we perform case-insensitive matching of codec names.
1400TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1401 EXPECT_TRUE(SetupEngine());
1402 int channel_num = voe_.GetLastChannel();
1403 std::vector<cricket::AudioCodec> codecs;
1404 codecs.push_back(kIsacCodec);
1405 codecs.push_back(kPcmuCodec);
1406 codecs.push_back(kCn16000Codec);
1407 codecs.push_back(kCn8000Codec);
1408 codecs.push_back(kTelephoneEventCodec);
1409 codecs.push_back(kRedCodec);
1410 codecs[0].name = "iSaC";
1411 codecs[0].id = 96;
1412 codecs[2].id = 97; // wideband CN
1413 codecs[4].id = 98; // DTMF
1414 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1415 webrtc::CodecInst gcodec;
1416 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1417 EXPECT_EQ(96, gcodec.pltype);
1418 EXPECT_STREQ("ISAC", gcodec.plname);
1419 EXPECT_TRUE(voe_.GetVAD(channel_num));
1420 EXPECT_FALSE(voe_.GetFEC(channel_num));
1421 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1422 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1423 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1424}
1425
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001426// Test that we set up FEC correctly as caller.
1427TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001428 EXPECT_TRUE(SetupEngine());
1429 int channel_num = voe_.GetLastChannel();
1430 std::vector<cricket::AudioCodec> codecs;
1431 codecs.push_back(kRedCodec);
1432 codecs.push_back(kIsacCodec);
1433 codecs.push_back(kPcmuCodec);
1434 codecs[0].id = 127;
1435 codecs[0].params[""] = "96/96";
1436 codecs[1].id = 96;
1437 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1438 webrtc::CodecInst gcodec;
1439 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1440 EXPECT_EQ(96, gcodec.pltype);
1441 EXPECT_STREQ("ISAC", gcodec.plname);
1442 EXPECT_TRUE(voe_.GetFEC(channel_num));
1443 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1444}
1445
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001446// Test that we set up FEC correctly as callee.
1447TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1448 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1449 channel_ = engine_.CreateChannel();
1450 EXPECT_TRUE(channel_ != NULL);
1451
1452 int channel_num = voe_.GetLastChannel();
1453 std::vector<cricket::AudioCodec> codecs;
1454 codecs.push_back(kRedCodec);
1455 codecs.push_back(kIsacCodec);
1456 codecs.push_back(kPcmuCodec);
1457 codecs[0].id = 127;
1458 codecs[0].params[""] = "96/96";
1459 codecs[1].id = 96;
1460 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1461 EXPECT_TRUE(channel_->AddSendStream(
1462 cricket::StreamParams::CreateLegacy(kSsrc1)));
1463 webrtc::CodecInst gcodec;
1464 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1465 EXPECT_EQ(96, gcodec.pltype);
1466 EXPECT_STREQ("ISAC", gcodec.plname);
1467 EXPECT_TRUE(voe_.GetFEC(channel_num));
1468 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1469}
1470
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471// Test that we set up FEC correctly if params are omitted.
1472TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1473 EXPECT_TRUE(SetupEngine());
1474 int channel_num = voe_.GetLastChannel();
1475 std::vector<cricket::AudioCodec> codecs;
1476 codecs.push_back(kRedCodec);
1477 codecs.push_back(kIsacCodec);
1478 codecs.push_back(kPcmuCodec);
1479 codecs[0].id = 127;
1480 codecs[1].id = 96;
1481 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1482 webrtc::CodecInst gcodec;
1483 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1484 EXPECT_EQ(96, gcodec.pltype);
1485 EXPECT_STREQ("ISAC", gcodec.plname);
1486 EXPECT_TRUE(voe_.GetFEC(channel_num));
1487 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1488}
1489
1490// Test that we ignore RED if the parameters aren't named the way we expect.
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1492 EXPECT_TRUE(SetupEngine());
1493 int channel_num = voe_.GetLastChannel();
1494 std::vector<cricket::AudioCodec> codecs;
1495 codecs.push_back(kRedCodec);
1496 codecs.push_back(kIsacCodec);
1497 codecs.push_back(kPcmuCodec);
1498 codecs[0].id = 127;
1499 codecs[0].params["ABC"] = "96/96";
1500 codecs[1].id = 96;
1501 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1502 webrtc::CodecInst gcodec;
1503 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1504 EXPECT_EQ(96, gcodec.pltype);
1505 EXPECT_STREQ("ISAC", gcodec.plname);
1506 EXPECT_FALSE(voe_.GetFEC(channel_num));
1507}
1508
1509// Test that we ignore RED if it uses different primary/secondary encoding.
1510TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1511 EXPECT_TRUE(SetupEngine());
1512 int channel_num = voe_.GetLastChannel();
1513 std::vector<cricket::AudioCodec> codecs;
1514 codecs.push_back(kRedCodec);
1515 codecs.push_back(kIsacCodec);
1516 codecs.push_back(kPcmuCodec);
1517 codecs[0].id = 127;
1518 codecs[0].params[""] = "96/0";
1519 codecs[1].id = 96;
1520 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1521 webrtc::CodecInst gcodec;
1522 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1523 EXPECT_EQ(96, gcodec.pltype);
1524 EXPECT_STREQ("ISAC", gcodec.plname);
1525 EXPECT_FALSE(voe_.GetFEC(channel_num));
1526}
1527
1528// Test that we ignore RED if it uses more than 2 encodings.
1529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1530 EXPECT_TRUE(SetupEngine());
1531 int channel_num = voe_.GetLastChannel();
1532 std::vector<cricket::AudioCodec> codecs;
1533 codecs.push_back(kRedCodec);
1534 codecs.push_back(kIsacCodec);
1535 codecs.push_back(kPcmuCodec);
1536 codecs[0].id = 127;
1537 codecs[0].params[""] = "96/96/96";
1538 codecs[1].id = 96;
1539 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1540 webrtc::CodecInst gcodec;
1541 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1542 EXPECT_EQ(96, gcodec.pltype);
1543 EXPECT_STREQ("ISAC", gcodec.plname);
1544 EXPECT_FALSE(voe_.GetFEC(channel_num));
1545}
1546
1547// Test that we ignore RED if it has bogus codec ids.
1548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1549 EXPECT_TRUE(SetupEngine());
1550 int channel_num = voe_.GetLastChannel();
1551 std::vector<cricket::AudioCodec> codecs;
1552 codecs.push_back(kRedCodec);
1553 codecs.push_back(kIsacCodec);
1554 codecs.push_back(kPcmuCodec);
1555 codecs[0].id = 127;
1556 codecs[0].params[""] = "ABC/ABC";
1557 codecs[1].id = 96;
1558 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1559 webrtc::CodecInst gcodec;
1560 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1561 EXPECT_EQ(96, gcodec.pltype);
1562 EXPECT_STREQ("ISAC", gcodec.plname);
1563 EXPECT_FALSE(voe_.GetFEC(channel_num));
1564}
1565
1566// Test that we ignore RED if it refers to a codec that is not present.
1567TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1568 EXPECT_TRUE(SetupEngine());
1569 int channel_num = voe_.GetLastChannel();
1570 std::vector<cricket::AudioCodec> codecs;
1571 codecs.push_back(kRedCodec);
1572 codecs.push_back(kIsacCodec);
1573 codecs.push_back(kPcmuCodec);
1574 codecs[0].id = 127;
1575 codecs[0].params[""] = "97/97";
1576 codecs[1].id = 96;
1577 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1578 webrtc::CodecInst gcodec;
1579 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1580 EXPECT_EQ(96, gcodec.pltype);
1581 EXPECT_STREQ("ISAC", gcodec.plname);
1582 EXPECT_FALSE(voe_.GetFEC(channel_num));
1583}
1584
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585// Test that we support setting certain send header extensions.
1586TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
1587 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001588 TestSetSendRtpHeaderExtensions(voe_.GetLastChannel());
1589}
1590
1591// Test that we support setting recv header extensions.
1592TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
1593 EXPECT_TRUE(SetupEngine());
1594 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1595 TestSetRecvRtpHeaderExtensions(voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596}
1597
1598// Test that we can create a channel and start sending/playing out on it.
1599TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1600 EXPECT_TRUE(SetupEngine());
1601 int channel_num = voe_.GetLastChannel();
1602 std::vector<cricket::AudioCodec> codecs;
1603 codecs.push_back(kPcmuCodec);
1604 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1605 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1606 EXPECT_TRUE(voe_.GetSend(channel_num));
1607 EXPECT_TRUE(channel_->SetPlayout(true));
1608 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1609 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1610 EXPECT_FALSE(voe_.GetSend(channel_num));
1611 EXPECT_TRUE(channel_->SetPlayout(false));
1612 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1613}
1614
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001615// Test that we can add and remove send streams.
1616TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1617 SetupForMultiSendStream();
1618
1619 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1620
1621 // Set the global state for sending.
1622 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1623
1624 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1625 EXPECT_TRUE(channel_->AddSendStream(
1626 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1627
1628 // Verify that we are in a sending state for all the created streams.
1629 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1630 EXPECT_TRUE(voe_.GetSend(channel_num));
1631 }
1632
1633 // Remove the first send channel, which is the default channel. It will only
1634 // recycle the default channel but not delete it.
1635 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1636 // Stream should already be Removed from the send stream list.
1637 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1638 // But the default still exists.
1639 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1640
1641 // Delete the rest of send channel streams.
1642 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1643 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1644 // Stream should already be deleted.
1645 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1646 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1647 }
1648}
1649
1650// Test SetSendCodecs correctly configure the codecs in all send streams.
1651TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1652 SetupForMultiSendStream();
1653
1654 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1655 // Create send streams.
1656 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1657 EXPECT_TRUE(channel_->AddSendStream(
1658 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1659 }
1660
1661 std::vector<cricket::AudioCodec> codecs;
1662 // Set ISAC(16K) and CN(16K). VAD should be activated.
1663 codecs.push_back(kIsacCodec);
1664 codecs.push_back(kCn16000Codec);
1665 codecs[1].id = 97;
1666 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1667
1668 // Verify ISAC and VAD are corrected configured on all send channels.
1669 webrtc::CodecInst gcodec;
1670 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1671 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1672 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1673 EXPECT_STREQ("ISAC", gcodec.plname);
1674 EXPECT_TRUE(voe_.GetVAD(channel_num));
1675 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1676 }
1677
1678 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1679 codecs[0] = kPcmuCodec;
1680 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1681 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1682 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1683 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1684 EXPECT_STREQ("PCMU", gcodec.plname);
1685 EXPECT_FALSE(voe_.GetVAD(channel_num));
1686 }
1687}
1688
1689// Test we can SetSend on all send streams correctly.
1690TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1691 SetupForMultiSendStream();
1692
1693 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1694 // Create the send channels and they should be a SEND_NOTHING date.
1695 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1696 EXPECT_TRUE(channel_->AddSendStream(
1697 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1698 int channel_num = voe_.GetLastChannel();
1699 EXPECT_FALSE(voe_.GetSend(channel_num));
1700 }
1701
1702 // Set the global state for starting sending.
1703 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1704 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1705 // Verify that we are in a sending state for all the send streams.
1706 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1707 EXPECT_TRUE(voe_.GetSend(channel_num));
1708 }
1709
1710 // Set the global state for stopping sending.
1711 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1712 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1713 // Verify that we are in a stop state for all the send streams.
1714 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1715 EXPECT_FALSE(voe_.GetSend(channel_num));
1716 }
1717}
1718
1719// Test we can set the correct statistics on all send streams.
1720TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1721 SetupForMultiSendStream();
1722
1723 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1724 // Create send streams.
1725 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1726 EXPECT_TRUE(channel_->AddSendStream(
1727 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1728 }
1729
1730 // We need send codec to be set to get all stats.
1731 std::vector<cricket::AudioCodec> codecs;
1732 codecs.push_back(kPcmuCodec);
1733 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1734
1735 cricket::VoiceMediaInfo info;
1736 EXPECT_EQ(true, channel_->GetStats(&info));
1737 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1738
1739 // Verify the statistic information is correct.
1740 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001741 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001742 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1743 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1744 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1745 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1746 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1747 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1748 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1749 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1750 }
1751
1752 EXPECT_EQ(1u, info.receivers.size());
1753}
1754
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001755// Test that we support setting header extensions on multiple send streams.
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001756TEST_F(WebRtcVoiceEngineTestFake,
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001757 SetSendRtpHeaderExtensionsWithMultipleSendStreams) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001758 SetupForMultiSendStream();
1759
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001760 static const uint32 kSsrcs[] = {1, 2, 3, 4};
1761 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001762 EXPECT_TRUE(channel_->AddSendStream(
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001763 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001764 }
1765
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001766 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1767 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs[i]);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001768 TestSetSendRtpHeaderExtensions(channel_num);
1769 }
1770}
1771
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001772// Test that we support setting header extensions on multiple receive streams.
1773TEST_F(WebRtcVoiceEngineTestFake,
1774 SetRecvRtpHeaderExtensionsWithMultipleRecvStreams) {
1775 EXPECT_TRUE(SetupEngine());
1776
1777 static const uint32 kSsrcs[] = {1, 2, 3, 4};
1778 int channel_ids[ARRAY_SIZE(kSsrcs)] = {0};
1779 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1780 EXPECT_TRUE(channel_->AddRecvStream(
1781 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
1782 channel_ids[i] = voe_.GetLastChannel();
1783 }
1784
1785 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1786 TestSetRecvRtpHeaderExtensions(channel_ids[i]);
1787 }
1788}
1789
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001790// Test that we can add and remove receive streams, and do proper send/playout.
1791// We can receive on multiple streams while sending one stream.
1792TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793 EXPECT_TRUE(SetupEngine());
1794 int channel_num1 = voe_.GetLastChannel();
1795
1796 // Start playout on the default channel.
1797 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1798 EXPECT_TRUE(channel_->SetPlayout(true));
1799 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1800
1801 // Adding another stream should disable playout on the default channel.
1802 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1803 int channel_num2 = voe_.GetLastChannel();
1804 std::vector<cricket::AudioCodec> codecs;
1805 codecs.push_back(kPcmuCodec);
1806 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1807 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1808 EXPECT_TRUE(voe_.GetSend(channel_num1));
1809 EXPECT_FALSE(voe_.GetSend(channel_num2));
1810
1811 // Make sure only the new channel is played out.
1812 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1813 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1814
1815 // Adding yet another stream should have stream 2 and 3 enabled for playout.
1816 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1817 int channel_num3 = voe_.GetLastChannel();
1818 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1819 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1820 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1821 EXPECT_FALSE(voe_.GetSend(channel_num3));
1822
1823 // Stop sending.
1824 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1825 EXPECT_FALSE(voe_.GetSend(channel_num1));
1826 EXPECT_FALSE(voe_.GetSend(channel_num2));
1827 EXPECT_FALSE(voe_.GetSend(channel_num3));
1828
1829 // Stop playout.
1830 EXPECT_TRUE(channel_->SetPlayout(false));
1831 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1832 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1833 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1834
1835 // Restart playout and make sure the default channel still is not played out.
1836 EXPECT_TRUE(channel_->SetPlayout(true));
1837 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1838 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1839 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1840
1841 // Now remove the new streams and verify that the default channel is
1842 // played out again.
1843 EXPECT_TRUE(channel_->RemoveRecvStream(3));
1844 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1845
1846 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1847}
1848
1849// Test that we can set the devices to use.
1850TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1851 EXPECT_TRUE(SetupEngine());
1852 int channel_num = voe_.GetLastChannel();
1853 std::vector<cricket::AudioCodec> codecs;
1854 codecs.push_back(kPcmuCodec);
1855 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1856
1857 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1858 cricket::kFakeDefaultDeviceId);
1859 cricket::Device dev(cricket::kFakeDeviceName,
1860 cricket::kFakeDeviceId);
1861
1862 // Test SetDevices() while not sending or playing.
1863 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1864
1865 // Test SetDevices() while sending and playing.
1866 EXPECT_TRUE(engine_.SetLocalMonitor(true));
1867 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1868 EXPECT_TRUE(channel_->SetPlayout(true));
1869 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1870 EXPECT_TRUE(voe_.GetSend(channel_num));
1871 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1872
1873 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1874
1875 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1876 EXPECT_TRUE(voe_.GetSend(channel_num));
1877 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1878
1879 // Test that failure to open newly selected devices does not prevent opening
1880 // ones after that.
1881 voe_.set_fail_start_recording_microphone(true);
1882 voe_.set_playout_fail_channel(channel_num);
1883 voe_.set_send_fail_channel(channel_num);
1884
1885 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1886
1887 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1888 EXPECT_FALSE(voe_.GetSend(channel_num));
1889 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1890
1891 voe_.set_fail_start_recording_microphone(false);
1892 voe_.set_playout_fail_channel(-1);
1893 voe_.set_send_fail_channel(-1);
1894
1895 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1896
1897 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1898 EXPECT_TRUE(voe_.GetSend(channel_num));
1899 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1900}
1901
1902// Test that we can set the devices to use even if we failed to
1903// open the initial ones.
1904TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1905 EXPECT_TRUE(SetupEngine());
1906 int channel_num = voe_.GetLastChannel();
1907 std::vector<cricket::AudioCodec> codecs;
1908 codecs.push_back(kPcmuCodec);
1909 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1910
1911 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1912 cricket::kFakeDefaultDeviceId);
1913 cricket::Device dev(cricket::kFakeDeviceName,
1914 cricket::kFakeDeviceId);
1915
1916 // Test that failure to open devices selected before starting
1917 // send/play does not prevent opening newly selected ones after that.
1918 voe_.set_fail_start_recording_microphone(true);
1919 voe_.set_playout_fail_channel(channel_num);
1920 voe_.set_send_fail_channel(channel_num);
1921
1922 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1923
1924 EXPECT_FALSE(engine_.SetLocalMonitor(true));
1925 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
1926 EXPECT_FALSE(channel_->SetPlayout(true));
1927 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1928 EXPECT_FALSE(voe_.GetSend(channel_num));
1929 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1930
1931 voe_.set_fail_start_recording_microphone(false);
1932 voe_.set_playout_fail_channel(-1);
1933 voe_.set_send_fail_channel(-1);
1934
1935 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1936
1937 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1938 EXPECT_TRUE(voe_.GetSend(channel_num));
1939 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1940}
1941
1942// Test that we can create a channel configured for multi-point conferences,
1943// and start sending/playing out on it.
1944TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
1945 EXPECT_TRUE(SetupEngine());
1946 int channel_num = voe_.GetLastChannel();
1947 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1948 std::vector<cricket::AudioCodec> codecs;
1949 codecs.push_back(kPcmuCodec);
1950 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1951 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1952 EXPECT_TRUE(voe_.GetSend(channel_num));
1953}
1954
1955// Test that we can create a channel configured for Codian bridges,
1956// and start sending/playing out on it.
1957TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
1958 EXPECT_TRUE(SetupEngine());
1959 int channel_num = voe_.GetLastChannel();
1960 webrtc::AgcConfig agc_config;
1961 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1962 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1963 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
1964 std::vector<cricket::AudioCodec> codecs;
1965 codecs.push_back(kPcmuCodec);
1966 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1967 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1968 EXPECT_TRUE(voe_.GetSend(channel_num));
1969 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1970 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
1971 EXPECT_TRUE(channel_->SetPlayout(true));
1972 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1973 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1974 EXPECT_FALSE(voe_.GetSend(channel_num));
1975 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1976 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
1977 EXPECT_TRUE(channel_->SetPlayout(false));
1978 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1979}
1980
wu@webrtc.org97077a32013-10-25 21:18:33 +00001981TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
1982 EXPECT_TRUE(SetupEngine());
1983 webrtc::AgcConfig agc_config;
1984 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1985 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1986
1987 cricket::AudioOptions options;
1988 options.tx_agc_target_dbov.Set(3);
1989 options.tx_agc_digital_compression_gain.Set(9);
1990 options.tx_agc_limiter.Set(true);
1991 options.auto_gain_control.Set(true);
1992 EXPECT_TRUE(engine_.SetOptions(options));
1993
1994 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1995 EXPECT_EQ(3, agc_config.targetLeveldBOv);
1996 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
1997 EXPECT_TRUE(agc_config.limiterEnable);
1998
1999 // Check interaction with adjust_agc_delta. Both should be respected, for
2000 // backwards compatibility.
2001 options.adjust_agc_delta.Set(-10);
2002 EXPECT_TRUE(engine_.SetOptions(options));
2003
2004 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2005 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2006}
2007
2008TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2009 EXPECT_TRUE(SetupEngine());
2010 int channel_num = voe_.GetLastChannel();
2011 cricket::AudioOptions options;
2012 options.rx_agc_target_dbov.Set(6);
2013 options.rx_agc_digital_compression_gain.Set(0);
2014 options.rx_agc_limiter.Set(true);
2015 options.rx_auto_gain_control.Set(true);
2016 EXPECT_TRUE(channel_->SetOptions(options));
2017
2018 webrtc::AgcConfig agc_config;
2019 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2020 channel_num, agc_config));
2021 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2022 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2023 EXPECT_TRUE(agc_config.limiterEnable);
2024}
2025
2026TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2027 EXPECT_TRUE(SetupEngine());
2028 cricket::AudioOptions options;
2029 options.recording_sample_rate.Set(48000u);
2030 options.playout_sample_rate.Set(44100u);
2031 EXPECT_TRUE(engine_.SetOptions(options));
2032
2033 unsigned int recording_sample_rate, playout_sample_rate;
2034 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2035 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2036 EXPECT_EQ(48000u, recording_sample_rate);
2037 EXPECT_EQ(44100u, playout_sample_rate);
2038}
2039
2040TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2041 EXPECT_TRUE(SetupEngine());
2042 engine_.SetLogging(talk_base::LS_INFO, "");
2043 EXPECT_EQ(
2044 // Info:
2045 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2046 // Warning:
2047 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2048 // Error:
2049 webrtc::kTraceError | webrtc::kTraceCritical,
2050 static_cast<int>(trace_wrapper_->filter_));
2051 // Now set it explicitly
2052 std::string filter =
2053 "tracefilter " + talk_base::ToString(webrtc::kTraceDefault);
2054 engine_.SetLogging(talk_base::LS_VERBOSE, filter.c_str());
2055 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2056 trace_wrapper_->filter_);
2057}
2058
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059// Test that we can set the outgoing SSRC properly.
2060// SSRC is set in SetupEngine by calling AddSendStream.
2061TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2062 EXPECT_TRUE(SetupEngine());
2063 int channel_num = voe_.GetLastChannel();
2064 unsigned int send_ssrc;
2065 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2066 EXPECT_NE(0U, send_ssrc);
2067 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2068 EXPECT_EQ(kSsrc1, send_ssrc);
2069}
2070
2071TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2072 // Setup. We need send codec to be set to get all stats.
2073 EXPECT_TRUE(SetupEngine());
2074 std::vector<cricket::AudioCodec> codecs;
2075 codecs.push_back(kPcmuCodec);
2076 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2077
2078 cricket::VoiceMediaInfo info;
2079 EXPECT_EQ(true, channel_->GetStats(&info));
2080 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002081 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002082 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2083 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2084 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2085 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2086 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2087 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2088 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2089 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
2090 // TODO(sriniv): Add testing for more fields. These are not populated
2091 // in FakeWebrtcVoiceEngine yet.
2092 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2093 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2094 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2095 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2096 // EXPECT_EQ(cricket::kIntStatValue,
2097 // info.senders[0].echo_return_loss_enhancement);
2098
2099 EXPECT_EQ(1u, info.receivers.size());
2100 // TODO(sriniv): Add testing for receiver fields.
2101}
2102
2103// Test that we can set the outgoing SSRC properly with multiple streams.
2104// SSRC is set in SetupEngine by calling AddSendStream.
2105TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2106 EXPECT_TRUE(SetupEngine());
2107 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2108 int channel_num1 = voe_.GetLastChannel();
2109 unsigned int send_ssrc;
2110 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2111 EXPECT_EQ(kSsrc1, send_ssrc);
2112
2113 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2114 int channel_num2 = voe_.GetLastChannel();
2115 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2116 EXPECT_EQ(kSsrc1, send_ssrc);
2117}
2118
2119// Test that the local SSRC is the same on sending and receiving channels if the
2120// receive channel is created before the send channel.
2121TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2122 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2123 channel_ = engine_.CreateChannel();
2124 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2125
2126 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2127 int receive_channel_num = voe_.GetLastChannel();
2128 EXPECT_TRUE(channel_->AddSendStream(
2129 cricket::StreamParams::CreateLegacy(1234)));
2130 int send_channel_num = voe_.GetLastChannel();
2131
2132 unsigned int ssrc = 0;
2133 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2134 EXPECT_EQ(1234U, ssrc);
2135 ssrc = 0;
2136 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2137 EXPECT_EQ(1234U, ssrc);
2138}
2139
2140// Test that we can properly receive packets.
2141TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2142 EXPECT_TRUE(SetupEngine());
2143 int channel_num = voe_.GetLastChannel();
2144 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2145 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2146 sizeof(kPcmuFrame)));
2147}
2148
2149// Test that we can properly receive packets on multiple streams.
2150TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2151 EXPECT_TRUE(SetupEngine());
2152 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2153 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2154 int channel_num1 = voe_.GetLastChannel();
2155 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2156 int channel_num2 = voe_.GetLastChannel();
2157 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2158 int channel_num3 = voe_.GetLastChannel();
2159 // Create packets with the right SSRCs.
2160 char packets[4][sizeof(kPcmuFrame)];
2161 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2162 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002163 talk_base::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002164 }
2165 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2166 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2167 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2168 DeliverPacket(packets[0], sizeof(packets[0]));
2169 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2170 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2171 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2172 DeliverPacket(packets[1], sizeof(packets[1]));
2173 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2174 sizeof(packets[1])));
2175 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2176 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2177 DeliverPacket(packets[2], sizeof(packets[2]));
2178 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2179 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2180 sizeof(packets[2])));
2181 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2182 DeliverPacket(packets[3], sizeof(packets[3]));
2183 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2184 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2185 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2186 sizeof(packets[3])));
2187 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2188 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2189 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2190}
2191
2192// Test that we properly handle failures to add a stream.
2193TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2194 EXPECT_TRUE(SetupEngine());
2195 voe_.set_fail_create_channel(true);
2196 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2197 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2198
2199 // In 1:1 call, we should not try to create a new channel.
2200 cricket::AudioOptions options_no_conference_;
2201 options_no_conference_.conference_mode.Set(false);
2202 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2203 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2204}
2205
2206// Test that AddRecvStream doesn't create new channel for 1:1 call.
2207TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2208 EXPECT_TRUE(SetupEngine());
2209 int channel_num = voe_.GetLastChannel();
2210 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2211 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2212}
2213
2214// Test that after adding a recv stream, we do not decode more codecs than
2215// those previously passed into SetRecvCodecs.
2216TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2217 EXPECT_TRUE(SetupEngine());
2218 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2219 std::vector<cricket::AudioCodec> codecs;
2220 codecs.push_back(kIsacCodec);
2221 codecs.push_back(kPcmuCodec);
2222 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2223 EXPECT_TRUE(channel_->AddRecvStream(
2224 cricket::StreamParams::CreateLegacy(kSsrc1)));
2225 int channel_num2 = voe_.GetLastChannel();
2226 webrtc::CodecInst gcodec;
2227 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2228 gcodec.plfreq = 32000;
2229 gcodec.channels = 2;
2230 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2231}
2232
2233// Test that we properly clean up any streams that were added, even if
2234// not explicitly removed.
2235TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2236 EXPECT_TRUE(SetupEngine());
2237 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2238 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2239 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2240 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2241 delete channel_;
2242 channel_ = NULL;
2243 EXPECT_EQ(0, voe_.GetNumChannels());
2244}
2245
wu@webrtc.org78187522013-10-07 23:32:02 +00002246TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2247 EXPECT_TRUE(SetupEngine());
2248 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2249}
2250
2251TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2252 EXPECT_TRUE(SetupEngine());
2253 // Stream 1 reuses default channel.
2254 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2255 // Manually delete default channel to simulate a failure.
2256 int default_channel = voe_.GetLastChannel();
2257 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2258 // Add recv stream 2 should fail because default channel is gone.
2259 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2260 int new_channel = voe_.GetLastChannel();
2261 EXPECT_NE(default_channel, new_channel);
2262 // The last created channel should have already been deleted.
2263 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2264}
2265
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002266// Test the InsertDtmf on default send stream as caller.
2267TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2268 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002269}
2270
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002271// Test the InsertDtmf on default send stream as callee
2272TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2273 TestInsertDtmf(0, false);
2274}
2275
2276// Test the InsertDtmf on specified send stream as caller.
2277TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2278 TestInsertDtmf(kSsrc1, true);
2279}
2280
2281// Test the InsertDtmf on specified send stream as callee.
2282TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2283 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002284}
2285
2286// Test that we can play a ringback tone properly in a single-stream call.
2287TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2288 EXPECT_TRUE(SetupEngine());
2289 int channel_num = voe_.GetLastChannel();
2290 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2291 // Check we fail if no ringback tone specified.
2292 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2293 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2294 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002295 EXPECT_TRUE(channel_->SetRingbackTone(
2296 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002297 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2298 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2299 // Check we can stop the tone manually.
2300 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2301 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2302 // Check we stop the tone if a packet arrives.
2303 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2304 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2305 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2306 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2307}
2308
2309// Test that we can play a ringback tone properly in a multi-stream call.
2310TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2311 EXPECT_TRUE(SetupEngine());
2312 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2313 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2314 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2315 int channel_num = voe_.GetLastChannel();
2316 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2317 // Check we fail if no ringback tone specified.
2318 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2319 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2320 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002321 EXPECT_TRUE(channel_->SetRingbackTone(
2322 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002323 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2324 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2325 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2326 // Check we can stop the tone manually.
2327 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2328 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2329 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2330 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2331 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2332 // Send a packet with SSRC 1; the tone should not stop.
2333 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2334 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2335 // Send a packet with SSRC 2; the tone should stop.
2336 char packet[sizeof(kPcmuFrame)];
2337 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2338 talk_base::SetBE32(packet + 8, 2);
2339 DeliverPacket(packet, sizeof(packet));
2340 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2341}
2342
2343// Tests creating soundclips, and make sure they come from the right engine.
2344TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2345 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002346 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002347 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002348 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349 ASSERT_TRUE(soundclip_ != NULL);
2350 EXPECT_EQ(0, voe_.GetNumChannels());
2351 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2352 int channel_num = voe_sc_.GetLastChannel();
2353 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2354 delete soundclip_;
2355 soundclip_ = NULL;
2356 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002357 // Make sure the soundclip engine is uninitialized on shutdown, now that
2358 // we've initialized it by creating a soundclip.
2359 engine_.Terminate();
2360 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002361}
2362
2363// Tests playing out a fake sound.
2364TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2365 static const char kZeroes[16000] = {};
2366 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2367 soundclip_ = engine_.CreateSoundclip();
2368 ASSERT_TRUE(soundclip_ != NULL);
2369 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2370}
2371
2372TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2373 talk_base::scoped_ptr<ChannelErrorListener> listener;
2374 cricket::WebRtcVoiceMediaChannel* media_channel;
2375 unsigned int ssrc = 0;
2376
2377 EXPECT_TRUE(SetupEngine());
2378 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2379 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2380
2381 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2382 listener.reset(new ChannelErrorListener(channel_));
2383
2384 // Test on WebRtc VoE channel.
2385 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2386 VE_SATURATION_WARNING);
2387 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2388 listener->error());
2389 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2390 EXPECT_EQ(ssrc, listener->ssrc());
2391
2392 listener->Reset();
2393 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2394 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2395 listener->error());
2396 EXPECT_EQ(0U, listener->ssrc());
2397
2398 // Add another stream and test on that.
2399 ++ssrc;
2400 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2401 ssrc)));
2402 listener->Reset();
2403 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2404 VE_SATURATION_WARNING);
2405 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2406 listener->error());
2407 EXPECT_EQ(ssrc, listener->ssrc());
2408
2409 // Testing a non-existing channel.
2410 listener->Reset();
2411 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2412 VE_SATURATION_WARNING);
2413 EXPECT_EQ(0, listener->error());
2414}
2415
2416TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2417 EXPECT_TRUE(SetupEngine());
2418 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2419 std::vector<cricket::AudioCodec> codecs;
2420 codecs.push_back(kPcmuCodec);
2421 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2422 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2423 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2424 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2425 EXPECT_TRUE(channel_->SetPlayout(true));
2426 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2427 EXPECT_TRUE(channel_->SetPlayout(false));
2428 EXPECT_FALSE(channel_->SetPlayout(true));
2429}
2430
2431// Test that the Registering/Unregistering with the
2432// webrtcvoiceengine works as expected
2433TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2434 EXPECT_TRUE(SetupEngine());
2435 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2436 EXPECT_TRUE(channel_->AddRecvStream(
2437 cricket::StreamParams::CreateLegacy(kSsrc2)));
2438 cricket::FakeMediaProcessor vp_1;
2439 cricket::FakeMediaProcessor vp_2;
2440
2441 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2442 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2443 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2444 voe_.TriggerProcessPacket(cricket::MPD_RX);
2445 voe_.TriggerProcessPacket(cricket::MPD_TX);
2446
2447 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2448 EXPECT_EQ(1, vp_1.voice_frame_count());
2449 EXPECT_EQ(1, vp_2.voice_frame_count());
2450
2451 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2452 &vp_2,
2453 cricket::MPD_RX));
2454 voe_.TriggerProcessPacket(cricket::MPD_RX);
2455 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2456 EXPECT_EQ(1, vp_2.voice_frame_count());
2457 EXPECT_EQ(2, vp_1.voice_frame_count());
2458
2459 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2460 &vp_1,
2461 cricket::MPD_RX));
2462 voe_.TriggerProcessPacket(cricket::MPD_RX);
2463 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2464 EXPECT_EQ(2, vp_1.voice_frame_count());
2465
2466 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2467 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2468 voe_.TriggerProcessPacket(cricket::MPD_RX);
2469 voe_.TriggerProcessPacket(cricket::MPD_TX);
2470 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2471 EXPECT_EQ(3, vp_1.voice_frame_count());
2472
2473 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2474 &vp_1,
2475 cricket::MPD_RX_AND_TX));
2476 voe_.TriggerProcessPacket(cricket::MPD_TX);
2477 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2478 EXPECT_EQ(3, vp_1.voice_frame_count());
2479 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2480 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2481 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2482
2483 // Test that we can register a processor on the receive channel on SSRC 0.
2484 // This tests the 1:1 case when the receive SSRC is unknown.
2485 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2486 voe_.TriggerProcessPacket(cricket::MPD_RX);
2487 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2488 EXPECT_EQ(4, vp_1.voice_frame_count());
2489 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2490 &vp_1,
2491 cricket::MPD_RX));
2492
2493 // The following tests test that FindChannelNumFromSsrc is doing
2494 // what we expect.
2495 // pick an invalid ssrc and make sure we can't register
2496 EXPECT_FALSE(engine_.RegisterProcessor(99,
2497 &vp_1,
2498 cricket::MPD_RX));
2499 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2500 EXPECT_TRUE(engine_.RegisterProcessor(1,
2501 &vp_1,
2502 cricket::MPD_RX));
2503 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2504 &vp_1,
2505 cricket::MPD_RX));
2506 EXPECT_FALSE(engine_.RegisterProcessor(1,
2507 &vp_1,
2508 cricket::MPD_TX));
2509 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2510}
2511
2512TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2513 EXPECT_TRUE(SetupEngine());
2514
2515 bool ec_enabled;
2516 webrtc::EcModes ec_mode;
2517 bool ec_metrics_enabled;
2518 webrtc::AecmModes aecm_mode;
2519 bool cng_enabled;
2520 bool agc_enabled;
2521 webrtc::AgcModes agc_mode;
2522 webrtc::AgcConfig agc_config;
2523 bool ns_enabled;
2524 webrtc::NsModes ns_mode;
2525 bool highpass_filter_enabled;
2526 bool stereo_swapping_enabled;
2527 bool typing_detection_enabled;
2528 voe_.GetEcStatus(ec_enabled, ec_mode);
2529 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2530 voe_.GetAecmMode(aecm_mode, cng_enabled);
2531 voe_.GetAgcStatus(agc_enabled, agc_mode);
2532 voe_.GetAgcConfig(agc_config);
2533 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_TRUE(ec_enabled);
2538 EXPECT_TRUE(ec_metrics_enabled);
2539 EXPECT_FALSE(cng_enabled);
2540 EXPECT_TRUE(agc_enabled);
2541 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2542 EXPECT_TRUE(ns_enabled);
2543 EXPECT_TRUE(highpass_filter_enabled);
2544 EXPECT_FALSE(stereo_swapping_enabled);
2545 EXPECT_TRUE(typing_detection_enabled);
2546 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2547 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2548
2549 // Nothing set, so all ignored.
2550 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002551 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002552 voe_.GetEcStatus(ec_enabled, ec_mode);
2553 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2554 voe_.GetAecmMode(aecm_mode, cng_enabled);
2555 voe_.GetAgcStatus(agc_enabled, agc_mode);
2556 voe_.GetAgcConfig(agc_config);
2557 voe_.GetNsStatus(ns_enabled, ns_mode);
2558 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2559 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2560 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2561 EXPECT_TRUE(ec_enabled);
2562 EXPECT_TRUE(ec_metrics_enabled);
2563 EXPECT_FALSE(cng_enabled);
2564 EXPECT_TRUE(agc_enabled);
2565 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2566 EXPECT_TRUE(ns_enabled);
2567 EXPECT_TRUE(highpass_filter_enabled);
2568 EXPECT_FALSE(stereo_swapping_enabled);
2569 EXPECT_TRUE(typing_detection_enabled);
2570 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2571 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2572
2573 // Turn echo cancellation off
2574 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002575 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002576 voe_.GetEcStatus(ec_enabled, ec_mode);
2577 EXPECT_FALSE(ec_enabled);
2578
2579 // Turn echo cancellation back on, with settings, and make sure
2580 // nothing else changed.
2581 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002582 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002583 voe_.GetEcStatus(ec_enabled, ec_mode);
2584 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2585 voe_.GetAecmMode(aecm_mode, cng_enabled);
2586 voe_.GetAgcStatus(agc_enabled, agc_mode);
2587 voe_.GetAgcConfig(agc_config);
2588 voe_.GetNsStatus(ns_enabled, ns_mode);
2589 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2590 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2591 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2592 EXPECT_TRUE(ec_enabled);
2593 EXPECT_TRUE(ec_metrics_enabled);
2594 EXPECT_TRUE(agc_enabled);
2595 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2596 EXPECT_TRUE(ns_enabled);
2597 EXPECT_TRUE(highpass_filter_enabled);
2598 EXPECT_FALSE(stereo_swapping_enabled);
2599 EXPECT_TRUE(typing_detection_enabled);
2600 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2601 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2602
2603 // Turn off AGC
2604 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002605 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002606 voe_.GetAgcStatus(agc_enabled, agc_mode);
2607 EXPECT_FALSE(agc_enabled);
2608
2609 // Turn AGC back on
2610 options.auto_gain_control.Set(true);
2611 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002612 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613 voe_.GetAgcStatus(agc_enabled, agc_mode);
2614 EXPECT_TRUE(agc_enabled);
2615 voe_.GetAgcConfig(agc_config);
2616 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2617
2618 // Turn off other options (and stereo swapping on).
2619 options.noise_suppression.Set(false);
2620 options.highpass_filter.Set(false);
2621 options.typing_detection.Set(false);
2622 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002623 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002624 voe_.GetNsStatus(ns_enabled, ns_mode);
2625 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2626 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2627 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2628 EXPECT_FALSE(ns_enabled);
2629 EXPECT_FALSE(highpass_filter_enabled);
2630 EXPECT_FALSE(typing_detection_enabled);
2631 EXPECT_TRUE(stereo_swapping_enabled);
2632
2633 // Turn on "conference mode" to ensure it has no impact.
2634 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002635 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002636 voe_.GetEcStatus(ec_enabled, ec_mode);
2637 voe_.GetNsStatus(ns_enabled, ns_mode);
2638 EXPECT_TRUE(ec_enabled);
2639 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2640 EXPECT_FALSE(ns_enabled);
2641 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2642}
2643
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002644TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002645 EXPECT_TRUE(SetupEngine());
2646
2647 bool ec_enabled;
2648 webrtc::EcModes ec_mode;
2649 bool ec_metrics_enabled;
2650 bool agc_enabled;
2651 webrtc::AgcModes agc_mode;
2652 bool ns_enabled;
2653 webrtc::NsModes ns_mode;
2654 bool highpass_filter_enabled;
2655 bool stereo_swapping_enabled;
2656 bool typing_detection_enabled;
2657
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002658 voe_.GetEcStatus(ec_enabled, ec_mode);
2659 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2660 voe_.GetAgcStatus(agc_enabled, agc_mode);
2661 voe_.GetNsStatus(ns_enabled, ns_mode);
2662 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2663 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2664 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2665 EXPECT_TRUE(ec_enabled);
2666 EXPECT_TRUE(agc_enabled);
2667 EXPECT_TRUE(ns_enabled);
2668 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002669 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002670 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002671}
2672
2673TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2674 webrtc::AgcConfig set_config = {0};
2675 set_config.targetLeveldBOv = 3;
2676 set_config.digitalCompressionGaindB = 9;
2677 set_config.limiterEnable = true;
2678 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2679 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2680
2681 webrtc::AgcConfig config = {0};
2682 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2683 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2684 EXPECT_EQ(set_config.digitalCompressionGaindB,
2685 config.digitalCompressionGaindB);
2686 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2687}
2688
2689
2690TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2691 EXPECT_TRUE(SetupEngine());
2692 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2693 engine_.CreateChannel());
2694 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2695 engine_.CreateChannel());
2696
2697 // Have to add a stream to make SetSend work.
2698 cricket::StreamParams stream1;
2699 stream1.ssrcs.push_back(1);
2700 channel1->AddSendStream(stream1);
2701 cricket::StreamParams stream2;
2702 stream2.ssrcs.push_back(2);
2703 channel2->AddSendStream(stream2);
2704
2705 // AEC and AGC and NS
2706 cricket::AudioOptions options_all;
2707 options_all.echo_cancellation.Set(true);
2708 options_all.auto_gain_control.Set(true);
2709 options_all.noise_suppression.Set(true);
2710
2711 ASSERT_TRUE(channel1->SetOptions(options_all));
2712 cricket::AudioOptions expected_options = options_all;
2713 cricket::AudioOptions actual_options;
2714 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2715 EXPECT_EQ(expected_options, actual_options);
2716 ASSERT_TRUE(channel2->SetOptions(options_all));
2717 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2718 EXPECT_EQ(expected_options, actual_options);
2719
2720 // unset NS
2721 cricket::AudioOptions options_no_ns;
2722 options_no_ns.noise_suppression.Set(false);
2723 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2724
2725 expected_options.echo_cancellation.Set(true);
2726 expected_options.auto_gain_control.Set(true);
2727 expected_options.noise_suppression.Set(false);
2728 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2729 EXPECT_EQ(expected_options, actual_options);
2730
2731 // unset AGC
2732 cricket::AudioOptions options_no_agc;
2733 options_no_agc.auto_gain_control.Set(false);
2734 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2735
2736 expected_options.echo_cancellation.Set(true);
2737 expected_options.auto_gain_control.Set(false);
2738 expected_options.noise_suppression.Set(true);
2739 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2740 EXPECT_EQ(expected_options, actual_options);
2741
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002742 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002743 bool ec_enabled;
2744 webrtc::EcModes ec_mode;
2745 bool agc_enabled;
2746 webrtc::AgcModes agc_mode;
2747 bool ns_enabled;
2748 webrtc::NsModes ns_mode;
2749 voe_.GetEcStatus(ec_enabled, ec_mode);
2750 voe_.GetAgcStatus(agc_enabled, agc_mode);
2751 voe_.GetNsStatus(ns_enabled, ns_mode);
2752 EXPECT_TRUE(ec_enabled);
2753 EXPECT_TRUE(agc_enabled);
2754 EXPECT_TRUE(ns_enabled);
2755
2756 channel1->SetSend(cricket::SEND_MICROPHONE);
2757 voe_.GetEcStatus(ec_enabled, ec_mode);
2758 voe_.GetAgcStatus(agc_enabled, agc_mode);
2759 voe_.GetNsStatus(ns_enabled, ns_mode);
2760 EXPECT_TRUE(ec_enabled);
2761 EXPECT_TRUE(agc_enabled);
2762 EXPECT_FALSE(ns_enabled);
2763
2764 channel1->SetSend(cricket::SEND_NOTHING);
2765 voe_.GetEcStatus(ec_enabled, ec_mode);
2766 voe_.GetAgcStatus(agc_enabled, agc_mode);
2767 voe_.GetNsStatus(ns_enabled, ns_mode);
2768 EXPECT_TRUE(ec_enabled);
2769 EXPECT_TRUE(agc_enabled);
2770 EXPECT_TRUE(ns_enabled);
2771
2772 channel2->SetSend(cricket::SEND_MICROPHONE);
2773 voe_.GetEcStatus(ec_enabled, ec_mode);
2774 voe_.GetAgcStatus(agc_enabled, agc_mode);
2775 voe_.GetNsStatus(ns_enabled, ns_mode);
2776 EXPECT_TRUE(ec_enabled);
2777 EXPECT_FALSE(agc_enabled);
2778 EXPECT_TRUE(ns_enabled);
2779
2780 channel2->SetSend(cricket::SEND_NOTHING);
2781 voe_.GetEcStatus(ec_enabled, ec_mode);
2782 voe_.GetAgcStatus(agc_enabled, agc_mode);
2783 voe_.GetNsStatus(ns_enabled, ns_mode);
2784 EXPECT_TRUE(ec_enabled);
2785 EXPECT_TRUE(agc_enabled);
2786 EXPECT_TRUE(ns_enabled);
2787
2788 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002789 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002790 cricket::AudioOptions options_no_agc_nor_ns;
2791 options_no_agc_nor_ns.auto_gain_control.Set(false);
2792 options_no_agc_nor_ns.noise_suppression.Set(false);
2793 channel2->SetSend(cricket::SEND_MICROPHONE);
2794 channel2->SetOptions(options_no_agc_nor_ns);
2795
2796 expected_options.echo_cancellation.Set(true);
2797 expected_options.auto_gain_control.Set(false);
2798 expected_options.noise_suppression.Set(false);
2799 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2800 EXPECT_EQ(expected_options, actual_options);
2801 voe_.GetEcStatus(ec_enabled, ec_mode);
2802 voe_.GetAgcStatus(agc_enabled, agc_mode);
2803 voe_.GetNsStatus(ns_enabled, ns_mode);
2804 EXPECT_TRUE(ec_enabled);
2805 EXPECT_FALSE(agc_enabled);
2806 EXPECT_FALSE(ns_enabled);
2807}
2808
wu@webrtc.orgde305012013-10-31 15:40:38 +00002809// This test verifies DSCP settings are properly applied on voice media channel.
2810TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2811 EXPECT_TRUE(SetupEngine());
2812 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel(
2813 engine_.CreateChannel());
2814 talk_base::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2815 new cricket::FakeNetworkInterface);
2816 channel->SetInterface(network_interface.get());
2817 cricket::AudioOptions options;
2818 options.dscp.Set(true);
2819 EXPECT_TRUE(channel->SetOptions(options));
2820 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00002821 // Verify previous value is not modified if dscp option is not set.
2822 cricket::AudioOptions options1;
2823 EXPECT_TRUE(channel->SetOptions(options1));
2824 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00002825 options.dscp.Set(false);
2826 EXPECT_TRUE(channel->SetOptions(options));
2827 EXPECT_EQ(talk_base::DSCP_DEFAULT, network_interface->dscp());
2828}
2829
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002830TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2831 cricket::WebRtcVoiceEngine engine;
2832 cricket::AudioOptions options = engine.GetOptions();
2833 // The default options should have at least a few things set. We purposefully
2834 // don't check the option values here, though.
2835 EXPECT_TRUE(options.echo_cancellation.IsSet());
2836 EXPECT_TRUE(options.auto_gain_control.IsSet());
2837 EXPECT_TRUE(options.noise_suppression.IsSet());
2838}
2839
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840// Test that GetReceiveChannelNum returns the default channel for the first
2841// recv stream in 1-1 calls.
2842TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2843 EXPECT_TRUE(SetupEngine());
2844 cricket::WebRtcVoiceMediaChannel* media_channel =
2845 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2846 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2847 EXPECT_EQ(media_channel->voe_channel(),
2848 media_channel->GetReceiveChannelNum(0));
2849 cricket::StreamParams stream;
2850 stream.ssrcs.push_back(kSsrc2);
2851 EXPECT_TRUE(channel_->AddRecvStream(stream));
2852 EXPECT_EQ(media_channel->voe_channel(),
2853 media_channel->GetReceiveChannelNum(kSsrc2));
2854}
2855
2856// Test that GetReceiveChannelNum doesn't return the default channel for the
2857// first recv stream in conference calls.
2858TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2859 EXPECT_TRUE(SetupEngine());
2860 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2861 cricket::StreamParams stream;
2862 stream.ssrcs.push_back(kSsrc2);
2863 EXPECT_TRUE(channel_->AddRecvStream(stream));
2864 cricket::WebRtcVoiceMediaChannel* media_channel =
2865 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2866 EXPECT_LT(media_channel->voe_channel(),
2867 media_channel->GetReceiveChannelNum(kSsrc2));
2868}
2869
2870TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2871 EXPECT_TRUE(SetupEngine());
2872 double left, right;
2873 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2874 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2875 EXPECT_DOUBLE_EQ(1, left);
2876 EXPECT_DOUBLE_EQ(2, right);
2877
2878 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2879 cricket::StreamParams stream;
2880 stream.ssrcs.push_back(kSsrc2);
2881 EXPECT_TRUE(channel_->AddRecvStream(stream));
2882
2883 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2884 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2885 EXPECT_DOUBLE_EQ(2, left);
2886 EXPECT_DOUBLE_EQ(1, right);
2887}
2888
2889
2890// Tests for the actual WebRtc VoE library.
2891
2892// Tests that the library initializes and shuts down properly.
2893TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2894 cricket::WebRtcVoiceEngine engine;
2895 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2896 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2897 EXPECT_TRUE(channel != NULL);
2898 delete channel;
2899 engine.Terminate();
2900
2901 // Reinit to catch regression where VoiceEngineObserver reference is lost
2902 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2903 engine.Terminate();
2904}
2905
2906// Tests that the logging from the library is cleartext.
2907TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
2908 cricket::WebRtcVoiceEngine engine;
2909 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2910 new talk_base::MemoryStream);
2911 size_t size = 0;
2912 bool cleartext = true;
2913 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2914 engine.SetLogging(talk_base::LS_VERBOSE, "");
2915 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2916 EXPECT_TRUE(stream->GetSize(&size));
2917 EXPECT_GT(size, 0U);
2918 engine.Terminate();
2919 talk_base::LogMessage::RemoveLogToStream(stream.get());
2920 const char* buf = stream->GetBuffer();
2921 for (size_t i = 0; i < size && cleartext; ++i) {
2922 int ch = static_cast<int>(buf[i]);
2923 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
2924 << std::hex << ch;
2925 cleartext = (isprint(ch) || isspace(ch));
2926 }
2927 EXPECT_TRUE(cleartext);
2928}
2929
2930// Tests we do not see any references to a monitor thread being spun up
2931// when initiating the engine.
2932TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
2933 cricket::WebRtcVoiceEngine engine;
2934 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2935 new talk_base::MemoryStream);
2936 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2937 engine.SetLogging(talk_base::LS_VERBOSE, "");
2938 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2939 engine.Terminate();
2940 talk_base::LogMessage::RemoveLogToStream(stream.get());
2941
2942 size_t size = 0;
2943 EXPECT_TRUE(stream->GetSize(&size));
2944 EXPECT_GT(size, 0U);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002945 const std::string logs(stream->GetBuffer(), size);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002946 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
2947}
2948
2949// Tests that the library is configured with the codecs we want.
2950TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
2951 cricket::WebRtcVoiceEngine engine;
2952 // Check codecs by name.
2953 EXPECT_TRUE(engine.FindCodec(
2954 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
2955 EXPECT_TRUE(engine.FindCodec(
2956 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
2957 EXPECT_TRUE(engine.FindCodec(
2958 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
2959 // Check that name matching is case-insensitive.
2960 EXPECT_TRUE(engine.FindCodec(
2961 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
2962 EXPECT_TRUE(engine.FindCodec(
2963 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
2964 EXPECT_TRUE(engine.FindCodec(
2965 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
2966 EXPECT_TRUE(engine.FindCodec(
2967 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
2968 EXPECT_TRUE(engine.FindCodec(
2969 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
2970 EXPECT_TRUE(engine.FindCodec(
2971 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 EXPECT_TRUE(engine.FindCodec(
2973 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
2974 EXPECT_TRUE(engine.FindCodec(
2975 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
2976 EXPECT_TRUE(engine.FindCodec(
2977 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
2978 EXPECT_TRUE(engine.FindCodec(
2979 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
2980 // Check codecs with an id by id.
2981 EXPECT_TRUE(engine.FindCodec(
2982 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
2983 EXPECT_TRUE(engine.FindCodec(
2984 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
2985 EXPECT_TRUE(engine.FindCodec(
2986 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
2987 EXPECT_TRUE(engine.FindCodec(
2988 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
2989 // Check sample/bitrate matching.
2990 EXPECT_TRUE(engine.FindCodec(
2991 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
2992 // Check that bad codecs fail.
2993 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
2994 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
2995 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
2996 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
2997 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
2999 for (std::vector<cricket::AudioCodec>::const_iterator it =
3000 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3001 if (it->name == "CN" && it->clockrate == 16000) {
3002 EXPECT_EQ(105, it->id);
3003 } else if (it->name == "CN" && it->clockrate == 32000) {
3004 EXPECT_EQ(106, it->id);
3005 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3006 EXPECT_EQ(103, it->id);
3007 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3008 EXPECT_EQ(104, it->id);
3009 } else if (it->name == "G722" && it->clockrate == 16000) {
3010 EXPECT_EQ(9, it->id);
3011 } else if (it->name == "telephone-event") {
3012 EXPECT_EQ(126, it->id);
3013 } else if (it->name == "red") {
3014 EXPECT_EQ(127, it->id);
3015 } else if (it->name == "opus") {
3016 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003017 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003018 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003019 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003020 EXPECT_EQ("60", it->params.find("maxptime")->second);
3021 }
3022 }
3023
3024 engine.Terminate();
3025}
3026
3027// Tests that VoE supports at least 32 channels
3028TEST(WebRtcVoiceEngineTest, Has32Channels) {
3029 cricket::WebRtcVoiceEngine engine;
3030 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3031
3032 cricket::VoiceMediaChannel* channels[32];
3033 int num_channels = 0;
3034
3035 while (num_channels < ARRAY_SIZE(channels)) {
3036 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3037 if (!channel)
3038 break;
3039
3040 channels[num_channels++] = channel;
3041 }
3042
3043 int expected = ARRAY_SIZE(channels);
3044 EXPECT_EQ(expected, num_channels);
3045
3046 while (num_channels > 0) {
3047 delete channels[--num_channels];
3048 }
3049
3050 engine.Terminate();
3051}
3052
3053// Test that we set our preferred codecs properly.
3054TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3055 cricket::WebRtcVoiceEngine engine;
3056 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3057 cricket::WebRtcVoiceMediaChannel channel(&engine);
3058 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3059}
3060
3061#ifdef WIN32
3062// Test our workarounds to WebRtc VoE' munging of the coinit count
3063TEST(WebRtcVoiceEngineTest, CoInitialize) {
3064 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3065
3066 // Initial refcount should be 0.
3067 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3068
3069 // Engine should start even with COM already inited.
3070 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3071 engine->Terminate();
3072 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3073 engine->Terminate();
3074
3075 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3076 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3077 // Decrement refcount to (hopefully) 0.
3078 CoUninitialize();
3079 CoUninitialize();
3080 delete engine;
3081
3082 // Ensure refcount is 0.
3083 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3084 CoUninitialize();
3085}
3086#endif
3087
3088
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00003089TEST_F(WebRtcVoiceEngineTestFake, SetExperimentalAcm) {
3090 EXPECT_TRUE(SetupEngine());
3091
3092 // By default experimental ACM should not be used.
3093 int media_channel = engine_.CreateMediaVoiceChannel();
3094 ASSERT_GE(media_channel, 0);
3095 EXPECT_FALSE(voe_.IsUsingExperimentalAcm(media_channel));
3096
3097 int soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3098 ASSERT_GE(soundclip_channel, 0);
3099 EXPECT_FALSE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
3100
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00003101 // Set options to use experimental ACM.
3102 cricket::AudioOptions options;
3103 options.experimental_acm.Set(true);
3104 ASSERT_TRUE(engine_.SetOptions(options));
3105 media_channel = engine_.CreateMediaVoiceChannel();
3106 ASSERT_GE(media_channel, 0);
3107 EXPECT_TRUE(voe_.IsUsingExperimentalAcm(media_channel));
3108
3109 soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3110 ASSERT_GE(soundclip_channel, 0);
3111 EXPECT_TRUE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
3112
3113 // Set option to use legacy ACM.
3114 options.experimental_acm.Set(false);
3115 ASSERT_TRUE(engine_.SetOptions(options));
3116 media_channel = engine_.CreateMediaVoiceChannel();
3117 ASSERT_GE(media_channel, 0);
3118 EXPECT_FALSE(voe_.IsUsingExperimentalAcm(media_channel));
3119
3120 soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3121 ASSERT_GE(soundclip_channel, 0);
3122 EXPECT_FALSE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00003123}