blob: eba25be5831d8dae2177419879fb185deef69149 [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));
746 webrtc::CodecInst gcodec;
747 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
748 EXPECT_EQ(96, gcodec.pltype);
749 EXPECT_EQ(48000, gcodec.rate);
750 EXPECT_STREQ("ISAC", gcodec.plname);
751 EXPECT_FALSE(voe_.GetVAD(channel_num));
752 EXPECT_FALSE(voe_.GetFEC(channel_num));
753 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
754 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
755 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
756}
757
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000758// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000759TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
760 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761 std::vector<cricket::AudioCodec> codecs;
762 codecs.push_back(kOpusCodec);
763 codecs[0].bitrate = 0;
764 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000765 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766}
767
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000768// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000769TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
770 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771 std::vector<cricket::AudioCodec> codecs;
772 codecs.push_back(kOpusCodec);
773 codecs[0].bitrate = 0;
774 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000775 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776}
777
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000778// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
780 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781 std::vector<cricket::AudioCodec> codecs;
782 codecs.push_back(kOpusCodec);
783 codecs[0].bitrate = 0;
784 codecs[0].channels = 0;
785 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000786 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787}
788
789// Test that if channel is 1 for opus and there's no stereo, we fail.
790TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
791 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000792 std::vector<cricket::AudioCodec> codecs;
793 codecs.push_back(kOpusCodec);
794 codecs[0].bitrate = 0;
795 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000796 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000797}
798
799// Test that if channel is 1 for opus and stereo=0, we fail.
800TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
801 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802 std::vector<cricket::AudioCodec> codecs;
803 codecs.push_back(kOpusCodec);
804 codecs[0].bitrate = 0;
805 codecs[0].channels = 1;
806 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000807 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000808}
809
810// Test that if channel is 1 for opus and stereo=1, we fail.
811TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
812 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000813 std::vector<cricket::AudioCodec> codecs;
814 codecs.push_back(kOpusCodec);
815 codecs[0].bitrate = 0;
816 codecs[0].channels = 1;
817 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000818 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819}
820
821// Test that with bitrate=0 and no stereo,
822// channels and bitrate are 1 and 32000.
823TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
824 EXPECT_TRUE(SetupEngine());
825 int channel_num = voe_.GetLastChannel();
826 std::vector<cricket::AudioCodec> codecs;
827 codecs.push_back(kOpusCodec);
828 codecs[0].bitrate = 0;
829 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
830 webrtc::CodecInst gcodec;
831 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
832 EXPECT_STREQ("opus", gcodec.plname);
833 EXPECT_EQ(1, gcodec.channels);
834 EXPECT_EQ(32000, gcodec.rate);
835}
836
837// Test that with bitrate=0 and stereo=0,
838// channels and bitrate are 1 and 32000.
839TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
840 EXPECT_TRUE(SetupEngine());
841 int channel_num = voe_.GetLastChannel();
842 std::vector<cricket::AudioCodec> codecs;
843 codecs.push_back(kOpusCodec);
844 codecs[0].bitrate = 0;
845 codecs[0].params["stereo"] = "0";
846 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
847 webrtc::CodecInst gcodec;
848 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
849 EXPECT_STREQ("opus", gcodec.plname);
850 EXPECT_EQ(1, gcodec.channels);
851 EXPECT_EQ(32000, gcodec.rate);
852}
853
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000854// Test that with bitrate=invalid and stereo=0,
855// channels and bitrate are 1 and 32000.
856TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
857 EXPECT_TRUE(SetupEngine());
858 int channel_num = voe_.GetLastChannel();
859 std::vector<cricket::AudioCodec> codecs;
860 codecs.push_back(kOpusCodec);
861 codecs[0].params["stereo"] = "0";
862 webrtc::CodecInst gcodec;
863
864 // bitrate that's out of the range between 6000 and 510000 will be considered
865 // as invalid and ignored.
866 codecs[0].bitrate = 5999;
867 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
868 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
869 EXPECT_STREQ("opus", gcodec.plname);
870 EXPECT_EQ(1, gcodec.channels);
871 EXPECT_EQ(32000, gcodec.rate);
872
873 codecs[0].bitrate = 510001;
874 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
875 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
876 EXPECT_STREQ("opus", gcodec.plname);
877 EXPECT_EQ(1, gcodec.channels);
878 EXPECT_EQ(32000, gcodec.rate);
879}
880
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000881// Test that with bitrate=0 and stereo=1,
882// channels and bitrate are 2 and 64000.
883TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
884 EXPECT_TRUE(SetupEngine());
885 int channel_num = voe_.GetLastChannel();
886 std::vector<cricket::AudioCodec> codecs;
887 codecs.push_back(kOpusCodec);
888 codecs[0].bitrate = 0;
889 codecs[0].params["stereo"] = "1";
890 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
891 webrtc::CodecInst gcodec;
892 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
893 EXPECT_STREQ("opus", gcodec.plname);
894 EXPECT_EQ(2, gcodec.channels);
895 EXPECT_EQ(64000, gcodec.rate);
896}
897
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000898// Test that with bitrate=invalid and stereo=1,
899// channels and bitrate are 2 and 64000.
900TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
901 EXPECT_TRUE(SetupEngine());
902 int channel_num = voe_.GetLastChannel();
903 std::vector<cricket::AudioCodec> codecs;
904 codecs.push_back(kOpusCodec);
905 codecs[0].params["stereo"] = "1";
906 webrtc::CodecInst gcodec;
907
908 // bitrate that's out of the range between 6000 and 510000 will be considered
909 // as invalid and ignored.
910 codecs[0].bitrate = 5999;
911 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
912 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
913 EXPECT_STREQ("opus", gcodec.plname);
914 EXPECT_EQ(2, gcodec.channels);
915 EXPECT_EQ(64000, gcodec.rate);
916
917 codecs[0].bitrate = 510001;
918 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
919 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
920 EXPECT_STREQ("opus", gcodec.plname);
921 EXPECT_EQ(2, gcodec.channels);
922 EXPECT_EQ(64000, gcodec.rate);
923}
924
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000925// Test that with bitrate=N and stereo unset,
926// channels and bitrate are 1 and N.
927TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
928 EXPECT_TRUE(SetupEngine());
929 int channel_num = voe_.GetLastChannel();
930 std::vector<cricket::AudioCodec> codecs;
931 codecs.push_back(kOpusCodec);
932 codecs[0].bitrate = 96000;
933 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
934 webrtc::CodecInst gcodec;
935 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
936 EXPECT_EQ(111, gcodec.pltype);
937 EXPECT_EQ(96000, gcodec.rate);
938 EXPECT_STREQ("opus", gcodec.plname);
939 EXPECT_EQ(1, gcodec.channels);
940 EXPECT_EQ(48000, gcodec.plfreq);
941}
942
943// Test that with bitrate=N and stereo=0,
944// channels and bitrate are 1 and N.
945TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
946 EXPECT_TRUE(SetupEngine());
947 int channel_num = voe_.GetLastChannel();
948 std::vector<cricket::AudioCodec> codecs;
949 codecs.push_back(kOpusCodec);
950 codecs[0].bitrate = 30000;
951 codecs[0].params["stereo"] = "0";
952 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
953 webrtc::CodecInst gcodec;
954 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
955 EXPECT_EQ(1, gcodec.channels);
956 EXPECT_EQ(30000, gcodec.rate);
957 EXPECT_STREQ("opus", gcodec.plname);
958}
959
960// Test that with bitrate=N and without any parameters,
961// channels and bitrate are 1 and N.
962TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
963 EXPECT_TRUE(SetupEngine());
964 int channel_num = voe_.GetLastChannel();
965 std::vector<cricket::AudioCodec> codecs;
966 codecs.push_back(kOpusCodec);
967 codecs[0].bitrate = 30000;
968 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
969 webrtc::CodecInst gcodec;
970 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
971 EXPECT_EQ(1, gcodec.channels);
972 EXPECT_EQ(30000, gcodec.rate);
973 EXPECT_STREQ("opus", gcodec.plname);
974}
975
976// Test that with bitrate=N and stereo=1,
977// channels and bitrate are 2 and N.
978TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
979 EXPECT_TRUE(SetupEngine());
980 int channel_num = voe_.GetLastChannel();
981 std::vector<cricket::AudioCodec> codecs;
982 codecs.push_back(kOpusCodec);
983 codecs[0].bitrate = 30000;
984 codecs[0].params["stereo"] = "1";
985 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
986 webrtc::CodecInst gcodec;
987 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
988 EXPECT_EQ(2, gcodec.channels);
989 EXPECT_EQ(30000, gcodec.rate);
990 EXPECT_STREQ("opus", gcodec.plname);
991}
992
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000993// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
994// Also test that the "maxaveragebitrate" can't be set to values outside the
995// range of 6000 and 510000
996TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
997 EXPECT_TRUE(SetupEngine());
998 int channel_num = voe_.GetLastChannel();
999 std::vector<cricket::AudioCodec> codecs;
1000 codecs.push_back(kOpusCodec);
1001 codecs[0].bitrate = 30000;
1002 webrtc::CodecInst gcodec;
1003
1004 // Ignore if less than 6000.
1005 codecs[0].params["maxaveragebitrate"] = "5999";
1006 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1007 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1008 EXPECT_EQ(30000, gcodec.rate);
1009
1010 // Ignore if larger than 510000.
1011 codecs[0].params["maxaveragebitrate"] = "510001";
1012 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1013 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1014 EXPECT_EQ(30000, gcodec.rate);
1015
1016 codecs[0].params["maxaveragebitrate"] = "200000";
1017 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1018 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1019 EXPECT_EQ(200000, gcodec.rate);
1020}
1021
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001022// Test that we can enable NACK with opus as caller.
1023TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 EXPECT_TRUE(SetupEngine());
1025 int channel_num = voe_.GetLastChannel();
1026 std::vector<cricket::AudioCodec> codecs;
1027 codecs.push_back(kOpusCodec);
1028 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1029 cricket::kParamValueEmpty));
1030 EXPECT_FALSE(voe_.GetNACK(channel_num));
1031 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1032 EXPECT_TRUE(voe_.GetNACK(channel_num));
1033}
1034
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001035// Test that we can enable NACK with opus as callee.
1036TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1037 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1038 channel_ = engine_.CreateChannel();
1039 EXPECT_TRUE(channel_ != NULL);
1040
1041 int channel_num = voe_.GetLastChannel();
1042 std::vector<cricket::AudioCodec> codecs;
1043 codecs.push_back(kOpusCodec);
1044 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1045 cricket::kParamValueEmpty));
1046 EXPECT_FALSE(voe_.GetNACK(channel_num));
1047 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1048 EXPECT_FALSE(voe_.GetNACK(channel_num));
1049
1050 EXPECT_TRUE(channel_->AddSendStream(
1051 cricket::StreamParams::CreateLegacy(kSsrc1)));
1052 EXPECT_TRUE(voe_.GetNACK(channel_num));
1053}
1054
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001055// Test that we can enable NACK on receive streams.
1056TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1057 EXPECT_TRUE(SetupEngine());
1058 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1059 int channel_num1 = voe_.GetLastChannel();
1060 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1061 int channel_num2 = voe_.GetLastChannel();
1062 std::vector<cricket::AudioCodec> codecs;
1063 codecs.push_back(kOpusCodec);
1064 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1065 cricket::kParamValueEmpty));
1066 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1067 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1068 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1069 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1070 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1071}
1072
1073// Test that we can disable NACK.
1074TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1075 EXPECT_TRUE(SetupEngine());
1076 int channel_num = voe_.GetLastChannel();
1077 std::vector<cricket::AudioCodec> codecs;
1078 codecs.push_back(kOpusCodec);
1079 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1080 cricket::kParamValueEmpty));
1081 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1082 EXPECT_TRUE(voe_.GetNACK(channel_num));
1083
1084 codecs.clear();
1085 codecs.push_back(kOpusCodec);
1086 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1087 EXPECT_FALSE(voe_.GetNACK(channel_num));
1088}
1089
1090// Test that we can disable NACK on receive streams.
1091TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1092 EXPECT_TRUE(SetupEngine());
1093 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1094 int channel_num1 = voe_.GetLastChannel();
1095 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1096 int channel_num2 = voe_.GetLastChannel();
1097 std::vector<cricket::AudioCodec> codecs;
1098 codecs.push_back(kOpusCodec);
1099 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1100 cricket::kParamValueEmpty));
1101 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1102 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1103 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1104
1105 codecs.clear();
1106 codecs.push_back(kOpusCodec);
1107 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1108 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1109 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1110}
1111
1112// Test that NACK is enabled on a new receive stream.
1113TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1114 EXPECT_TRUE(SetupEngine());
1115 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1116 int channel_num = voe_.GetLastChannel();
1117 std::vector<cricket::AudioCodec> codecs;
1118 codecs.push_back(kIsacCodec);
1119 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1120 cricket::kParamValueEmpty));
1121 codecs.push_back(kCn16000Codec);
1122 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1123 EXPECT_TRUE(voe_.GetNACK(channel_num));
1124
1125 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1126 channel_num = voe_.GetLastChannel();
1127 EXPECT_TRUE(voe_.GetNACK(channel_num));
1128 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1129 channel_num = voe_.GetLastChannel();
1130 EXPECT_TRUE(voe_.GetNACK(channel_num));
1131}
1132
1133// Test that we can apply CELT with stereo mode but fail with mono mode.
1134TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1135 EXPECT_TRUE(SetupEngine());
1136 int channel_num = voe_.GetLastChannel();
1137 std::vector<cricket::AudioCodec> codecs;
1138 codecs.push_back(kCeltCodec);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001139 codecs.push_back(kIsacCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 codecs[0].id = 96;
1141 codecs[0].channels = 2;
1142 codecs[0].bitrate = 96000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001143 codecs[1].bitrate = 64000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001144 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1145 webrtc::CodecInst gcodec;
1146 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1147 EXPECT_EQ(96, gcodec.pltype);
1148 EXPECT_EQ(96000, gcodec.rate);
1149 EXPECT_EQ(2, gcodec.channels);
1150 EXPECT_STREQ("CELT", gcodec.plname);
1151 // Doesn't support mono, expect it to fall back to the next codec in the list.
1152 codecs[0].channels = 1;
1153 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1154 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001155 EXPECT_EQ(103, gcodec.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001156 EXPECT_EQ(1, gcodec.channels);
1157 EXPECT_EQ(64000, gcodec.rate);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001158 EXPECT_STREQ("ISAC", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001159}
1160
1161// Test that we can switch back and forth between CELT and ISAC with CN.
1162TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1163 EXPECT_TRUE(SetupEngine());
1164 int channel_num = voe_.GetLastChannel();
1165 std::vector<cricket::AudioCodec> celt_codecs;
1166 celt_codecs.push_back(kCeltCodec);
1167 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1168 webrtc::CodecInst gcodec;
1169 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1170 EXPECT_EQ(110, gcodec.pltype);
1171 EXPECT_STREQ("CELT", gcodec.plname);
1172
1173 std::vector<cricket::AudioCodec> isac_codecs;
1174 isac_codecs.push_back(kIsacCodec);
1175 isac_codecs.push_back(kCn16000Codec);
1176 isac_codecs.push_back(kCeltCodec);
1177 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1178 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1179 EXPECT_EQ(103, gcodec.pltype);
1180 EXPECT_STREQ("ISAC", gcodec.plname);
1181
1182 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1183 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1184 EXPECT_EQ(110, gcodec.pltype);
1185 EXPECT_STREQ("CELT", gcodec.plname);
1186}
1187
1188// Test that we handle various ways of specifying bitrate.
1189TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1190 EXPECT_TRUE(SetupEngine());
1191 int channel_num = voe_.GetLastChannel();
1192 std::vector<cricket::AudioCodec> codecs;
1193 codecs.push_back(kIsacCodec); // bitrate == 32000
1194 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1195 webrtc::CodecInst gcodec;
1196 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1197 EXPECT_EQ(103, gcodec.pltype);
1198 EXPECT_STREQ("ISAC", gcodec.plname);
1199 EXPECT_EQ(32000, gcodec.rate);
1200
1201 codecs[0].bitrate = 0; // bitrate == default
1202 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1203 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1204 EXPECT_EQ(103, gcodec.pltype);
1205 EXPECT_STREQ("ISAC", gcodec.plname);
1206 EXPECT_EQ(-1, gcodec.rate);
1207
1208 codecs[0].bitrate = 28000; // bitrate == 28000
1209 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1210 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1211 EXPECT_EQ(103, gcodec.pltype);
1212 EXPECT_STREQ("ISAC", gcodec.plname);
1213 EXPECT_EQ(28000, gcodec.rate);
1214
1215 codecs[0] = kPcmuCodec; // bitrate == 64000
1216 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1217 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1218 EXPECT_EQ(0, gcodec.pltype);
1219 EXPECT_STREQ("PCMU", gcodec.plname);
1220 EXPECT_EQ(64000, gcodec.rate);
1221
1222 codecs[0].bitrate = 0; // bitrate == default
1223 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1224 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1225 EXPECT_EQ(0, gcodec.pltype);
1226 EXPECT_STREQ("PCMU", gcodec.plname);
1227 EXPECT_EQ(64000, gcodec.rate);
1228
1229 codecs[0] = kOpusCodec;
1230 codecs[0].bitrate = 0; // bitrate == default
1231 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1232 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1233 EXPECT_EQ(111, gcodec.pltype);
1234 EXPECT_STREQ("opus", gcodec.plname);
1235 EXPECT_EQ(32000, gcodec.rate);
1236}
1237
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001238// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001239TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1240 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001241 std::vector<cricket::AudioCodec> codecs;
1242 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1243}
1244
1245// Test that we can set send codecs even with telephone-event codec as the first
1246// one on the list.
1247TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1248 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001249 int channel_num = voe_.GetLastChannel();
1250 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001251 codecs.push_back(kTelephoneEventCodec);
1252 codecs.push_back(kIsacCodec);
1253 codecs.push_back(kPcmuCodec);
1254 codecs[0].id = 98; // DTMF
1255 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001256 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1257 webrtc::CodecInst gcodec;
1258 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001259 EXPECT_EQ(96, gcodec.pltype);
1260 EXPECT_STREQ("ISAC", gcodec.plname);
1261 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1262}
1263
1264// Test that we can set send codecs even with CN codec as the first
1265// one on the list.
1266TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1267 EXPECT_TRUE(SetupEngine());
1268 int channel_num = voe_.GetLastChannel();
1269 std::vector<cricket::AudioCodec> codecs;
1270 codecs.push_back(kCn16000Codec);
1271 codecs.push_back(kIsacCodec);
1272 codecs.push_back(kPcmuCodec);
1273 codecs[0].id = 98; // wideband CN
1274 codecs[1].id = 96;
1275 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1276 webrtc::CodecInst gcodec;
1277 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1278 EXPECT_EQ(96, gcodec.pltype);
1279 EXPECT_STREQ("ISAC", gcodec.plname);
1280 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001281}
1282
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001283// Test that we set VAD and DTMF types correctly as caller.
1284TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001285 EXPECT_TRUE(SetupEngine());
1286 int channel_num = voe_.GetLastChannel();
1287 std::vector<cricket::AudioCodec> codecs;
1288 codecs.push_back(kIsacCodec);
1289 codecs.push_back(kPcmuCodec);
1290 // TODO(juberti): cn 32000
1291 codecs.push_back(kCn16000Codec);
1292 codecs.push_back(kCn8000Codec);
1293 codecs.push_back(kTelephoneEventCodec);
1294 codecs.push_back(kRedCodec);
1295 codecs[0].id = 96;
1296 codecs[2].id = 97; // wideband CN
1297 codecs[4].id = 98; // DTMF
1298 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1299 webrtc::CodecInst gcodec;
1300 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1301 EXPECT_EQ(96, gcodec.pltype);
1302 EXPECT_STREQ("ISAC", gcodec.plname);
1303 EXPECT_TRUE(voe_.GetVAD(channel_num));
1304 EXPECT_FALSE(voe_.GetFEC(channel_num));
1305 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1306 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1307 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1308}
1309
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001310// Test that we set VAD and DTMF types correctly as callee.
1311TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1312 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1313 channel_ = engine_.CreateChannel();
1314 EXPECT_TRUE(channel_ != NULL);
1315
1316 int channel_num = voe_.GetLastChannel();
1317 std::vector<cricket::AudioCodec> codecs;
1318 codecs.push_back(kIsacCodec);
1319 codecs.push_back(kPcmuCodec);
1320 // TODO(juberti): cn 32000
1321 codecs.push_back(kCn16000Codec);
1322 codecs.push_back(kCn8000Codec);
1323 codecs.push_back(kTelephoneEventCodec);
1324 codecs.push_back(kRedCodec);
1325 codecs[0].id = 96;
1326 codecs[2].id = 97; // wideband CN
1327 codecs[4].id = 98; // DTMF
1328 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1329 EXPECT_TRUE(channel_->AddSendStream(
1330 cricket::StreamParams::CreateLegacy(kSsrc1)));
1331
1332 webrtc::CodecInst gcodec;
1333 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1334 EXPECT_EQ(96, gcodec.pltype);
1335 EXPECT_STREQ("ISAC", gcodec.plname);
1336 EXPECT_TRUE(voe_.GetVAD(channel_num));
1337 EXPECT_FALSE(voe_.GetFEC(channel_num));
1338 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1339 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1340 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1341}
1342
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001343// Test that we only apply VAD if we have a CN codec that matches the
1344// send codec clockrate.
1345TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1346 EXPECT_TRUE(SetupEngine());
1347 int channel_num = voe_.GetLastChannel();
1348 std::vector<cricket::AudioCodec> codecs;
1349 // Set ISAC(16K) and CN(16K). VAD should be activated.
1350 codecs.push_back(kIsacCodec);
1351 codecs.push_back(kCn16000Codec);
1352 codecs[1].id = 97;
1353 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1354 webrtc::CodecInst gcodec;
1355 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1356 EXPECT_STREQ("ISAC", gcodec.plname);
1357 EXPECT_TRUE(voe_.GetVAD(channel_num));
1358 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1359 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1360 codecs[0] = kPcmuCodec;
1361 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1362 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1363 EXPECT_STREQ("PCMU", gcodec.plname);
1364 EXPECT_FALSE(voe_.GetVAD(channel_num));
1365 // Set PCMU(8K) and CN(8K). VAD should be activated.
1366 codecs[1] = kCn8000Codec;
1367 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1368 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1369 EXPECT_STREQ("PCMU", gcodec.plname);
1370 EXPECT_TRUE(voe_.GetVAD(channel_num));
1371 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1372 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1373 codecs[0] = kIsacCodec;
1374 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1375 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1376 EXPECT_STREQ("ISAC", gcodec.plname);
1377 EXPECT_FALSE(voe_.GetVAD(channel_num));
1378}
1379
1380// Test that we perform case-insensitive matching of codec names.
1381TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1382 EXPECT_TRUE(SetupEngine());
1383 int channel_num = voe_.GetLastChannel();
1384 std::vector<cricket::AudioCodec> codecs;
1385 codecs.push_back(kIsacCodec);
1386 codecs.push_back(kPcmuCodec);
1387 codecs.push_back(kCn16000Codec);
1388 codecs.push_back(kCn8000Codec);
1389 codecs.push_back(kTelephoneEventCodec);
1390 codecs.push_back(kRedCodec);
1391 codecs[0].name = "iSaC";
1392 codecs[0].id = 96;
1393 codecs[2].id = 97; // wideband CN
1394 codecs[4].id = 98; // DTMF
1395 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1396 webrtc::CodecInst gcodec;
1397 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1398 EXPECT_EQ(96, gcodec.pltype);
1399 EXPECT_STREQ("ISAC", gcodec.plname);
1400 EXPECT_TRUE(voe_.GetVAD(channel_num));
1401 EXPECT_FALSE(voe_.GetFEC(channel_num));
1402 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1403 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1404 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1405}
1406
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001407// Test that we set up FEC correctly as caller.
1408TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409 EXPECT_TRUE(SetupEngine());
1410 int channel_num = voe_.GetLastChannel();
1411 std::vector<cricket::AudioCodec> codecs;
1412 codecs.push_back(kRedCodec);
1413 codecs.push_back(kIsacCodec);
1414 codecs.push_back(kPcmuCodec);
1415 codecs[0].id = 127;
1416 codecs[0].params[""] = "96/96";
1417 codecs[1].id = 96;
1418 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1419 webrtc::CodecInst gcodec;
1420 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1421 EXPECT_EQ(96, gcodec.pltype);
1422 EXPECT_STREQ("ISAC", gcodec.plname);
1423 EXPECT_TRUE(voe_.GetFEC(channel_num));
1424 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1425}
1426
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001427// Test that we set up FEC correctly as callee.
1428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1429 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1430 channel_ = engine_.CreateChannel();
1431 EXPECT_TRUE(channel_ != NULL);
1432
1433 int channel_num = voe_.GetLastChannel();
1434 std::vector<cricket::AudioCodec> codecs;
1435 codecs.push_back(kRedCodec);
1436 codecs.push_back(kIsacCodec);
1437 codecs.push_back(kPcmuCodec);
1438 codecs[0].id = 127;
1439 codecs[0].params[""] = "96/96";
1440 codecs[1].id = 96;
1441 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1442 EXPECT_TRUE(channel_->AddSendStream(
1443 cricket::StreamParams::CreateLegacy(kSsrc1)));
1444 webrtc::CodecInst gcodec;
1445 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1446 EXPECT_EQ(96, gcodec.pltype);
1447 EXPECT_STREQ("ISAC", gcodec.plname);
1448 EXPECT_TRUE(voe_.GetFEC(channel_num));
1449 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1450}
1451
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452// Test that we set up FEC correctly if params are omitted.
1453TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1454 EXPECT_TRUE(SetupEngine());
1455 int channel_num = voe_.GetLastChannel();
1456 std::vector<cricket::AudioCodec> codecs;
1457 codecs.push_back(kRedCodec);
1458 codecs.push_back(kIsacCodec);
1459 codecs.push_back(kPcmuCodec);
1460 codecs[0].id = 127;
1461 codecs[1].id = 96;
1462 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
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
1471// Test that we ignore RED if the parameters aren't named the way we expect.
1472TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
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[0].params["ABC"] = "96/96";
1481 codecs[1].id = 96;
1482 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1483 webrtc::CodecInst gcodec;
1484 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1485 EXPECT_EQ(96, gcodec.pltype);
1486 EXPECT_STREQ("ISAC", gcodec.plname);
1487 EXPECT_FALSE(voe_.GetFEC(channel_num));
1488}
1489
1490// Test that we ignore RED if it uses different primary/secondary encoding.
1491TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
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[""] = "96/0";
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 more than 2 encodings.
1510TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
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/96/96";
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 has bogus codec ids.
1529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
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[""] = "ABC/ABC";
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 refers to a codec that is not present.
1548TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
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[""] = "97/97";
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
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566// Test that we support setting certain send header extensions.
1567TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
1568 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001569 TestSetSendRtpHeaderExtensions(voe_.GetLastChannel());
1570}
1571
1572// Test that we support setting recv header extensions.
1573TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
1574 EXPECT_TRUE(SetupEngine());
1575 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1576 TestSetRecvRtpHeaderExtensions(voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577}
1578
1579// Test that we can create a channel and start sending/playing out on it.
1580TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1581 EXPECT_TRUE(SetupEngine());
1582 int channel_num = voe_.GetLastChannel();
1583 std::vector<cricket::AudioCodec> codecs;
1584 codecs.push_back(kPcmuCodec);
1585 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1586 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1587 EXPECT_TRUE(voe_.GetSend(channel_num));
1588 EXPECT_TRUE(channel_->SetPlayout(true));
1589 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1590 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1591 EXPECT_FALSE(voe_.GetSend(channel_num));
1592 EXPECT_TRUE(channel_->SetPlayout(false));
1593 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1594}
1595
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001596// Test that we can add and remove send streams.
1597TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1598 SetupForMultiSendStream();
1599
1600 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1601
1602 // Set the global state for sending.
1603 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1604
1605 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1606 EXPECT_TRUE(channel_->AddSendStream(
1607 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1608
1609 // Verify that we are in a sending state for all the created streams.
1610 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1611 EXPECT_TRUE(voe_.GetSend(channel_num));
1612 }
1613
1614 // Remove the first send channel, which is the default channel. It will only
1615 // recycle the default channel but not delete it.
1616 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1617 // Stream should already be Removed from the send stream list.
1618 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1619 // But the default still exists.
1620 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1621
1622 // Delete the rest of send channel streams.
1623 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1624 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1625 // Stream should already be deleted.
1626 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1627 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1628 }
1629}
1630
1631// Test SetSendCodecs correctly configure the codecs in all send streams.
1632TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1633 SetupForMultiSendStream();
1634
1635 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1636 // Create send streams.
1637 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1638 EXPECT_TRUE(channel_->AddSendStream(
1639 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1640 }
1641
1642 std::vector<cricket::AudioCodec> codecs;
1643 // Set ISAC(16K) and CN(16K). VAD should be activated.
1644 codecs.push_back(kIsacCodec);
1645 codecs.push_back(kCn16000Codec);
1646 codecs[1].id = 97;
1647 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1648
1649 // Verify ISAC and VAD are corrected configured on all send channels.
1650 webrtc::CodecInst gcodec;
1651 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1652 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1653 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1654 EXPECT_STREQ("ISAC", gcodec.plname);
1655 EXPECT_TRUE(voe_.GetVAD(channel_num));
1656 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1657 }
1658
1659 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1660 codecs[0] = kPcmuCodec;
1661 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1662 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1663 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1664 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1665 EXPECT_STREQ("PCMU", gcodec.plname);
1666 EXPECT_FALSE(voe_.GetVAD(channel_num));
1667 }
1668}
1669
1670// Test we can SetSend on all send streams correctly.
1671TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1672 SetupForMultiSendStream();
1673
1674 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1675 // Create the send channels and they should be a SEND_NOTHING date.
1676 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1677 EXPECT_TRUE(channel_->AddSendStream(
1678 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1679 int channel_num = voe_.GetLastChannel();
1680 EXPECT_FALSE(voe_.GetSend(channel_num));
1681 }
1682
1683 // Set the global state for starting sending.
1684 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1685 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1686 // Verify that we are in a sending state for all the send streams.
1687 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1688 EXPECT_TRUE(voe_.GetSend(channel_num));
1689 }
1690
1691 // Set the global state for stopping sending.
1692 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1693 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1694 // Verify that we are in a stop state for all the send streams.
1695 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1696 EXPECT_FALSE(voe_.GetSend(channel_num));
1697 }
1698}
1699
1700// Test we can set the correct statistics on all send streams.
1701TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1702 SetupForMultiSendStream();
1703
1704 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1705 // Create send streams.
1706 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1707 EXPECT_TRUE(channel_->AddSendStream(
1708 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1709 }
1710
1711 // We need send codec to be set to get all stats.
1712 std::vector<cricket::AudioCodec> codecs;
1713 codecs.push_back(kPcmuCodec);
1714 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1715
1716 cricket::VoiceMediaInfo info;
1717 EXPECT_EQ(true, channel_->GetStats(&info));
1718 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1719
1720 // Verify the statistic information is correct.
1721 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001722 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001723 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1724 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1725 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1726 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1727 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1728 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1729 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1730 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1731 }
1732
1733 EXPECT_EQ(1u, info.receivers.size());
1734}
1735
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001736// Test that we support setting header extensions on multiple send streams.
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001737TEST_F(WebRtcVoiceEngineTestFake,
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001738 SetSendRtpHeaderExtensionsWithMultipleSendStreams) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001739 SetupForMultiSendStream();
1740
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001741 static const uint32 kSsrcs[] = {1, 2, 3, 4};
1742 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001743 EXPECT_TRUE(channel_->AddSendStream(
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001744 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001745 }
1746
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001747 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1748 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs[i]);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001749 TestSetSendRtpHeaderExtensions(channel_num);
1750 }
1751}
1752
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001753// Test that we support setting header extensions on multiple receive streams.
1754TEST_F(WebRtcVoiceEngineTestFake,
1755 SetRecvRtpHeaderExtensionsWithMultipleRecvStreams) {
1756 EXPECT_TRUE(SetupEngine());
1757
1758 static const uint32 kSsrcs[] = {1, 2, 3, 4};
1759 int channel_ids[ARRAY_SIZE(kSsrcs)] = {0};
1760 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1761 EXPECT_TRUE(channel_->AddRecvStream(
1762 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
1763 channel_ids[i] = voe_.GetLastChannel();
1764 }
1765
1766 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1767 TestSetRecvRtpHeaderExtensions(channel_ids[i]);
1768 }
1769}
1770
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001771// Test that we can add and remove receive streams, and do proper send/playout.
1772// We can receive on multiple streams while sending one stream.
1773TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774 EXPECT_TRUE(SetupEngine());
1775 int channel_num1 = voe_.GetLastChannel();
1776
1777 // Start playout on the default channel.
1778 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1779 EXPECT_TRUE(channel_->SetPlayout(true));
1780 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1781
1782 // Adding another stream should disable playout on the default channel.
1783 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1784 int channel_num2 = voe_.GetLastChannel();
1785 std::vector<cricket::AudioCodec> codecs;
1786 codecs.push_back(kPcmuCodec);
1787 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1788 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1789 EXPECT_TRUE(voe_.GetSend(channel_num1));
1790 EXPECT_FALSE(voe_.GetSend(channel_num2));
1791
1792 // Make sure only the new channel is played out.
1793 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1794 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1795
1796 // Adding yet another stream should have stream 2 and 3 enabled for playout.
1797 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1798 int channel_num3 = voe_.GetLastChannel();
1799 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1800 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1801 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1802 EXPECT_FALSE(voe_.GetSend(channel_num3));
1803
1804 // Stop sending.
1805 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1806 EXPECT_FALSE(voe_.GetSend(channel_num1));
1807 EXPECT_FALSE(voe_.GetSend(channel_num2));
1808 EXPECT_FALSE(voe_.GetSend(channel_num3));
1809
1810 // Stop playout.
1811 EXPECT_TRUE(channel_->SetPlayout(false));
1812 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1813 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1814 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1815
1816 // Restart playout and make sure the default channel still is not played out.
1817 EXPECT_TRUE(channel_->SetPlayout(true));
1818 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1819 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1820 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1821
1822 // Now remove the new streams and verify that the default channel is
1823 // played out again.
1824 EXPECT_TRUE(channel_->RemoveRecvStream(3));
1825 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1826
1827 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1828}
1829
1830// Test that we can set the devices to use.
1831TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1832 EXPECT_TRUE(SetupEngine());
1833 int channel_num = voe_.GetLastChannel();
1834 std::vector<cricket::AudioCodec> codecs;
1835 codecs.push_back(kPcmuCodec);
1836 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1837
1838 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1839 cricket::kFakeDefaultDeviceId);
1840 cricket::Device dev(cricket::kFakeDeviceName,
1841 cricket::kFakeDeviceId);
1842
1843 // Test SetDevices() while not sending or playing.
1844 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1845
1846 // Test SetDevices() while sending and playing.
1847 EXPECT_TRUE(engine_.SetLocalMonitor(true));
1848 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1849 EXPECT_TRUE(channel_->SetPlayout(true));
1850 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1851 EXPECT_TRUE(voe_.GetSend(channel_num));
1852 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1853
1854 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1855
1856 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1857 EXPECT_TRUE(voe_.GetSend(channel_num));
1858 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1859
1860 // Test that failure to open newly selected devices does not prevent opening
1861 // ones after that.
1862 voe_.set_fail_start_recording_microphone(true);
1863 voe_.set_playout_fail_channel(channel_num);
1864 voe_.set_send_fail_channel(channel_num);
1865
1866 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1867
1868 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1869 EXPECT_FALSE(voe_.GetSend(channel_num));
1870 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1871
1872 voe_.set_fail_start_recording_microphone(false);
1873 voe_.set_playout_fail_channel(-1);
1874 voe_.set_send_fail_channel(-1);
1875
1876 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1877
1878 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1879 EXPECT_TRUE(voe_.GetSend(channel_num));
1880 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1881}
1882
1883// Test that we can set the devices to use even if we failed to
1884// open the initial ones.
1885TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1886 EXPECT_TRUE(SetupEngine());
1887 int channel_num = voe_.GetLastChannel();
1888 std::vector<cricket::AudioCodec> codecs;
1889 codecs.push_back(kPcmuCodec);
1890 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1891
1892 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1893 cricket::kFakeDefaultDeviceId);
1894 cricket::Device dev(cricket::kFakeDeviceName,
1895 cricket::kFakeDeviceId);
1896
1897 // Test that failure to open devices selected before starting
1898 // send/play does not prevent opening newly selected ones after that.
1899 voe_.set_fail_start_recording_microphone(true);
1900 voe_.set_playout_fail_channel(channel_num);
1901 voe_.set_send_fail_channel(channel_num);
1902
1903 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1904
1905 EXPECT_FALSE(engine_.SetLocalMonitor(true));
1906 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
1907 EXPECT_FALSE(channel_->SetPlayout(true));
1908 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1909 EXPECT_FALSE(voe_.GetSend(channel_num));
1910 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1911
1912 voe_.set_fail_start_recording_microphone(false);
1913 voe_.set_playout_fail_channel(-1);
1914 voe_.set_send_fail_channel(-1);
1915
1916 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1917
1918 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1919 EXPECT_TRUE(voe_.GetSend(channel_num));
1920 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1921}
1922
1923// Test that we can create a channel configured for multi-point conferences,
1924// and start sending/playing out on it.
1925TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
1926 EXPECT_TRUE(SetupEngine());
1927 int channel_num = voe_.GetLastChannel();
1928 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1929 std::vector<cricket::AudioCodec> codecs;
1930 codecs.push_back(kPcmuCodec);
1931 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1932 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1933 EXPECT_TRUE(voe_.GetSend(channel_num));
1934}
1935
1936// Test that we can create a channel configured for Codian bridges,
1937// and start sending/playing out on it.
1938TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
1939 EXPECT_TRUE(SetupEngine());
1940 int channel_num = voe_.GetLastChannel();
1941 webrtc::AgcConfig agc_config;
1942 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1943 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1944 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
1945 std::vector<cricket::AudioCodec> codecs;
1946 codecs.push_back(kPcmuCodec);
1947 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1948 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1949 EXPECT_TRUE(voe_.GetSend(channel_num));
1950 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1951 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
1952 EXPECT_TRUE(channel_->SetPlayout(true));
1953 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1954 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1955 EXPECT_FALSE(voe_.GetSend(channel_num));
1956 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1957 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
1958 EXPECT_TRUE(channel_->SetPlayout(false));
1959 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1960}
1961
wu@webrtc.org97077a32013-10-25 21:18:33 +00001962TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
1963 EXPECT_TRUE(SetupEngine());
1964 webrtc::AgcConfig agc_config;
1965 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1966 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1967
1968 cricket::AudioOptions options;
1969 options.tx_agc_target_dbov.Set(3);
1970 options.tx_agc_digital_compression_gain.Set(9);
1971 options.tx_agc_limiter.Set(true);
1972 options.auto_gain_control.Set(true);
1973 EXPECT_TRUE(engine_.SetOptions(options));
1974
1975 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1976 EXPECT_EQ(3, agc_config.targetLeveldBOv);
1977 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
1978 EXPECT_TRUE(agc_config.limiterEnable);
1979
1980 // Check interaction with adjust_agc_delta. Both should be respected, for
1981 // backwards compatibility.
1982 options.adjust_agc_delta.Set(-10);
1983 EXPECT_TRUE(engine_.SetOptions(options));
1984
1985 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1986 EXPECT_EQ(13, agc_config.targetLeveldBOv);
1987}
1988
1989TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
1990 EXPECT_TRUE(SetupEngine());
1991 int channel_num = voe_.GetLastChannel();
1992 cricket::AudioOptions options;
1993 options.rx_agc_target_dbov.Set(6);
1994 options.rx_agc_digital_compression_gain.Set(0);
1995 options.rx_agc_limiter.Set(true);
1996 options.rx_auto_gain_control.Set(true);
1997 EXPECT_TRUE(channel_->SetOptions(options));
1998
1999 webrtc::AgcConfig agc_config;
2000 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2001 channel_num, agc_config));
2002 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2003 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2004 EXPECT_TRUE(agc_config.limiterEnable);
2005}
2006
2007TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2008 EXPECT_TRUE(SetupEngine());
2009 cricket::AudioOptions options;
2010 options.recording_sample_rate.Set(48000u);
2011 options.playout_sample_rate.Set(44100u);
2012 EXPECT_TRUE(engine_.SetOptions(options));
2013
2014 unsigned int recording_sample_rate, playout_sample_rate;
2015 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2016 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2017 EXPECT_EQ(48000u, recording_sample_rate);
2018 EXPECT_EQ(44100u, playout_sample_rate);
2019}
2020
2021TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2022 EXPECT_TRUE(SetupEngine());
2023 engine_.SetLogging(talk_base::LS_INFO, "");
2024 EXPECT_EQ(
2025 // Info:
2026 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2027 // Warning:
2028 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2029 // Error:
2030 webrtc::kTraceError | webrtc::kTraceCritical,
2031 static_cast<int>(trace_wrapper_->filter_));
2032 // Now set it explicitly
2033 std::string filter =
2034 "tracefilter " + talk_base::ToString(webrtc::kTraceDefault);
2035 engine_.SetLogging(talk_base::LS_VERBOSE, filter.c_str());
2036 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2037 trace_wrapper_->filter_);
2038}
2039
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002040// Test that we can set the outgoing SSRC properly.
2041// SSRC is set in SetupEngine by calling AddSendStream.
2042TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2043 EXPECT_TRUE(SetupEngine());
2044 int channel_num = voe_.GetLastChannel();
2045 unsigned int send_ssrc;
2046 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2047 EXPECT_NE(0U, send_ssrc);
2048 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2049 EXPECT_EQ(kSsrc1, send_ssrc);
2050}
2051
2052TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2053 // Setup. We need send codec to be set to get all stats.
2054 EXPECT_TRUE(SetupEngine());
2055 std::vector<cricket::AudioCodec> codecs;
2056 codecs.push_back(kPcmuCodec);
2057 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2058
2059 cricket::VoiceMediaInfo info;
2060 EXPECT_EQ(true, channel_->GetStats(&info));
2061 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002062 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002063 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2064 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2065 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2066 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2067 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2068 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2069 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2070 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
2071 // TODO(sriniv): Add testing for more fields. These are not populated
2072 // in FakeWebrtcVoiceEngine yet.
2073 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2074 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2075 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2076 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2077 // EXPECT_EQ(cricket::kIntStatValue,
2078 // info.senders[0].echo_return_loss_enhancement);
2079
2080 EXPECT_EQ(1u, info.receivers.size());
2081 // TODO(sriniv): Add testing for receiver fields.
2082}
2083
2084// Test that we can set the outgoing SSRC properly with multiple streams.
2085// SSRC is set in SetupEngine by calling AddSendStream.
2086TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2087 EXPECT_TRUE(SetupEngine());
2088 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2089 int channel_num1 = voe_.GetLastChannel();
2090 unsigned int send_ssrc;
2091 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2092 EXPECT_EQ(kSsrc1, send_ssrc);
2093
2094 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2095 int channel_num2 = voe_.GetLastChannel();
2096 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2097 EXPECT_EQ(kSsrc1, send_ssrc);
2098}
2099
2100// Test that the local SSRC is the same on sending and receiving channels if the
2101// receive channel is created before the send channel.
2102TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2103 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2104 channel_ = engine_.CreateChannel();
2105 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2106
2107 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2108 int receive_channel_num = voe_.GetLastChannel();
2109 EXPECT_TRUE(channel_->AddSendStream(
2110 cricket::StreamParams::CreateLegacy(1234)));
2111 int send_channel_num = voe_.GetLastChannel();
2112
2113 unsigned int ssrc = 0;
2114 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2115 EXPECT_EQ(1234U, ssrc);
2116 ssrc = 0;
2117 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2118 EXPECT_EQ(1234U, ssrc);
2119}
2120
2121// Test that we can properly receive packets.
2122TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2123 EXPECT_TRUE(SetupEngine());
2124 int channel_num = voe_.GetLastChannel();
2125 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2126 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2127 sizeof(kPcmuFrame)));
2128}
2129
2130// Test that we can properly receive packets on multiple streams.
2131TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2132 EXPECT_TRUE(SetupEngine());
2133 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2134 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2135 int channel_num1 = voe_.GetLastChannel();
2136 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2137 int channel_num2 = voe_.GetLastChannel();
2138 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2139 int channel_num3 = voe_.GetLastChannel();
2140 // Create packets with the right SSRCs.
2141 char packets[4][sizeof(kPcmuFrame)];
2142 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2143 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002144 talk_base::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002145 }
2146 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2147 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2148 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2149 DeliverPacket(packets[0], sizeof(packets[0]));
2150 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2151 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2152 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2153 DeliverPacket(packets[1], sizeof(packets[1]));
2154 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2155 sizeof(packets[1])));
2156 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2157 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2158 DeliverPacket(packets[2], sizeof(packets[2]));
2159 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2160 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2161 sizeof(packets[2])));
2162 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2163 DeliverPacket(packets[3], sizeof(packets[3]));
2164 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2165 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2166 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2167 sizeof(packets[3])));
2168 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2169 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2170 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2171}
2172
2173// Test that we properly handle failures to add a stream.
2174TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2175 EXPECT_TRUE(SetupEngine());
2176 voe_.set_fail_create_channel(true);
2177 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2178 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2179
2180 // In 1:1 call, we should not try to create a new channel.
2181 cricket::AudioOptions options_no_conference_;
2182 options_no_conference_.conference_mode.Set(false);
2183 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2184 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2185}
2186
2187// Test that AddRecvStream doesn't create new channel for 1:1 call.
2188TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2189 EXPECT_TRUE(SetupEngine());
2190 int channel_num = voe_.GetLastChannel();
2191 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2192 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2193}
2194
2195// Test that after adding a recv stream, we do not decode more codecs than
2196// those previously passed into SetRecvCodecs.
2197TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2198 EXPECT_TRUE(SetupEngine());
2199 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2200 std::vector<cricket::AudioCodec> codecs;
2201 codecs.push_back(kIsacCodec);
2202 codecs.push_back(kPcmuCodec);
2203 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2204 EXPECT_TRUE(channel_->AddRecvStream(
2205 cricket::StreamParams::CreateLegacy(kSsrc1)));
2206 int channel_num2 = voe_.GetLastChannel();
2207 webrtc::CodecInst gcodec;
2208 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2209 gcodec.plfreq = 32000;
2210 gcodec.channels = 2;
2211 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2212}
2213
2214// Test that we properly clean up any streams that were added, even if
2215// not explicitly removed.
2216TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2217 EXPECT_TRUE(SetupEngine());
2218 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2219 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2220 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2221 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2222 delete channel_;
2223 channel_ = NULL;
2224 EXPECT_EQ(0, voe_.GetNumChannels());
2225}
2226
wu@webrtc.org78187522013-10-07 23:32:02 +00002227TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2228 EXPECT_TRUE(SetupEngine());
2229 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2230}
2231
2232TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2233 EXPECT_TRUE(SetupEngine());
2234 // Stream 1 reuses default channel.
2235 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2236 // Manually delete default channel to simulate a failure.
2237 int default_channel = voe_.GetLastChannel();
2238 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2239 // Add recv stream 2 should fail because default channel is gone.
2240 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2241 int new_channel = voe_.GetLastChannel();
2242 EXPECT_NE(default_channel, new_channel);
2243 // The last created channel should have already been deleted.
2244 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2245}
2246
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002247// Test the InsertDtmf on default send stream as caller.
2248TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2249 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002250}
2251
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002252// Test the InsertDtmf on default send stream as callee
2253TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2254 TestInsertDtmf(0, false);
2255}
2256
2257// Test the InsertDtmf on specified send stream as caller.
2258TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2259 TestInsertDtmf(kSsrc1, true);
2260}
2261
2262// Test the InsertDtmf on specified send stream as callee.
2263TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2264 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002265}
2266
2267// Test that we can play a ringback tone properly in a single-stream call.
2268TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2269 EXPECT_TRUE(SetupEngine());
2270 int channel_num = voe_.GetLastChannel();
2271 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2272 // Check we fail if no ringback tone specified.
2273 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2274 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2275 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002276 EXPECT_TRUE(channel_->SetRingbackTone(
2277 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002278 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2279 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2280 // Check we can stop the tone manually.
2281 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2282 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2283 // Check we stop the tone if a packet arrives.
2284 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2285 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2286 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2287 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2288}
2289
2290// Test that we can play a ringback tone properly in a multi-stream call.
2291TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2292 EXPECT_TRUE(SetupEngine());
2293 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2294 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2295 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2296 int channel_num = voe_.GetLastChannel();
2297 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2298 // Check we fail if no ringback tone specified.
2299 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2300 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2301 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002302 EXPECT_TRUE(channel_->SetRingbackTone(
2303 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2305 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2306 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2307 // Check we can stop the tone manually.
2308 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2309 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2310 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2311 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2312 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2313 // Send a packet with SSRC 1; the tone should not stop.
2314 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2315 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2316 // Send a packet with SSRC 2; the tone should stop.
2317 char packet[sizeof(kPcmuFrame)];
2318 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2319 talk_base::SetBE32(packet + 8, 2);
2320 DeliverPacket(packet, sizeof(packet));
2321 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2322}
2323
2324// Tests creating soundclips, and make sure they come from the right engine.
2325TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2326 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002327 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002328 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002329 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002330 ASSERT_TRUE(soundclip_ != NULL);
2331 EXPECT_EQ(0, voe_.GetNumChannels());
2332 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2333 int channel_num = voe_sc_.GetLastChannel();
2334 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2335 delete soundclip_;
2336 soundclip_ = NULL;
2337 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002338 // Make sure the soundclip engine is uninitialized on shutdown, now that
2339 // we've initialized it by creating a soundclip.
2340 engine_.Terminate();
2341 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002342}
2343
2344// Tests playing out a fake sound.
2345TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2346 static const char kZeroes[16000] = {};
2347 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2348 soundclip_ = engine_.CreateSoundclip();
2349 ASSERT_TRUE(soundclip_ != NULL);
2350 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2351}
2352
2353TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2354 talk_base::scoped_ptr<ChannelErrorListener> listener;
2355 cricket::WebRtcVoiceMediaChannel* media_channel;
2356 unsigned int ssrc = 0;
2357
2358 EXPECT_TRUE(SetupEngine());
2359 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2360 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2361
2362 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2363 listener.reset(new ChannelErrorListener(channel_));
2364
2365 // Test on WebRtc VoE channel.
2366 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2367 VE_SATURATION_WARNING);
2368 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2369 listener->error());
2370 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2371 EXPECT_EQ(ssrc, listener->ssrc());
2372
2373 listener->Reset();
2374 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2375 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2376 listener->error());
2377 EXPECT_EQ(0U, listener->ssrc());
2378
2379 // Add another stream and test on that.
2380 ++ssrc;
2381 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2382 ssrc)));
2383 listener->Reset();
2384 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2385 VE_SATURATION_WARNING);
2386 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2387 listener->error());
2388 EXPECT_EQ(ssrc, listener->ssrc());
2389
2390 // Testing a non-existing channel.
2391 listener->Reset();
2392 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2393 VE_SATURATION_WARNING);
2394 EXPECT_EQ(0, listener->error());
2395}
2396
2397TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2398 EXPECT_TRUE(SetupEngine());
2399 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2400 std::vector<cricket::AudioCodec> codecs;
2401 codecs.push_back(kPcmuCodec);
2402 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2403 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2404 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2405 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2406 EXPECT_TRUE(channel_->SetPlayout(true));
2407 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2408 EXPECT_TRUE(channel_->SetPlayout(false));
2409 EXPECT_FALSE(channel_->SetPlayout(true));
2410}
2411
2412// Test that the Registering/Unregistering with the
2413// webrtcvoiceengine works as expected
2414TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2415 EXPECT_TRUE(SetupEngine());
2416 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2417 EXPECT_TRUE(channel_->AddRecvStream(
2418 cricket::StreamParams::CreateLegacy(kSsrc2)));
2419 cricket::FakeMediaProcessor vp_1;
2420 cricket::FakeMediaProcessor vp_2;
2421
2422 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2423 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2424 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2425 voe_.TriggerProcessPacket(cricket::MPD_RX);
2426 voe_.TriggerProcessPacket(cricket::MPD_TX);
2427
2428 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2429 EXPECT_EQ(1, vp_1.voice_frame_count());
2430 EXPECT_EQ(1, vp_2.voice_frame_count());
2431
2432 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2433 &vp_2,
2434 cricket::MPD_RX));
2435 voe_.TriggerProcessPacket(cricket::MPD_RX);
2436 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2437 EXPECT_EQ(1, vp_2.voice_frame_count());
2438 EXPECT_EQ(2, vp_1.voice_frame_count());
2439
2440 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2441 &vp_1,
2442 cricket::MPD_RX));
2443 voe_.TriggerProcessPacket(cricket::MPD_RX);
2444 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2445 EXPECT_EQ(2, vp_1.voice_frame_count());
2446
2447 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2448 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2449 voe_.TriggerProcessPacket(cricket::MPD_RX);
2450 voe_.TriggerProcessPacket(cricket::MPD_TX);
2451 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2452 EXPECT_EQ(3, vp_1.voice_frame_count());
2453
2454 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2455 &vp_1,
2456 cricket::MPD_RX_AND_TX));
2457 voe_.TriggerProcessPacket(cricket::MPD_TX);
2458 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2459 EXPECT_EQ(3, vp_1.voice_frame_count());
2460 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2461 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2462 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2463
2464 // Test that we can register a processor on the receive channel on SSRC 0.
2465 // This tests the 1:1 case when the receive SSRC is unknown.
2466 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2467 voe_.TriggerProcessPacket(cricket::MPD_RX);
2468 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2469 EXPECT_EQ(4, vp_1.voice_frame_count());
2470 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2471 &vp_1,
2472 cricket::MPD_RX));
2473
2474 // The following tests test that FindChannelNumFromSsrc is doing
2475 // what we expect.
2476 // pick an invalid ssrc and make sure we can't register
2477 EXPECT_FALSE(engine_.RegisterProcessor(99,
2478 &vp_1,
2479 cricket::MPD_RX));
2480 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2481 EXPECT_TRUE(engine_.RegisterProcessor(1,
2482 &vp_1,
2483 cricket::MPD_RX));
2484 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2485 &vp_1,
2486 cricket::MPD_RX));
2487 EXPECT_FALSE(engine_.RegisterProcessor(1,
2488 &vp_1,
2489 cricket::MPD_TX));
2490 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2491}
2492
2493TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2494 EXPECT_TRUE(SetupEngine());
2495
2496 bool ec_enabled;
2497 webrtc::EcModes ec_mode;
2498 bool ec_metrics_enabled;
2499 webrtc::AecmModes aecm_mode;
2500 bool cng_enabled;
2501 bool agc_enabled;
2502 webrtc::AgcModes agc_mode;
2503 webrtc::AgcConfig agc_config;
2504 bool ns_enabled;
2505 webrtc::NsModes ns_mode;
2506 bool highpass_filter_enabled;
2507 bool stereo_swapping_enabled;
2508 bool typing_detection_enabled;
2509 voe_.GetEcStatus(ec_enabled, ec_mode);
2510 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2511 voe_.GetAecmMode(aecm_mode, cng_enabled);
2512 voe_.GetAgcStatus(agc_enabled, agc_mode);
2513 voe_.GetAgcConfig(agc_config);
2514 voe_.GetNsStatus(ns_enabled, ns_mode);
2515 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2516 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2517 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2518 EXPECT_TRUE(ec_enabled);
2519 EXPECT_TRUE(ec_metrics_enabled);
2520 EXPECT_FALSE(cng_enabled);
2521 EXPECT_TRUE(agc_enabled);
2522 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2523 EXPECT_TRUE(ns_enabled);
2524 EXPECT_TRUE(highpass_filter_enabled);
2525 EXPECT_FALSE(stereo_swapping_enabled);
2526 EXPECT_TRUE(typing_detection_enabled);
2527 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2528 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2529
2530 // Nothing set, so all ignored.
2531 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002532 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002533 voe_.GetEcStatus(ec_enabled, ec_mode);
2534 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2535 voe_.GetAecmMode(aecm_mode, cng_enabled);
2536 voe_.GetAgcStatus(agc_enabled, agc_mode);
2537 voe_.GetAgcConfig(agc_config);
2538 voe_.GetNsStatus(ns_enabled, ns_mode);
2539 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2540 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2541 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2542 EXPECT_TRUE(ec_enabled);
2543 EXPECT_TRUE(ec_metrics_enabled);
2544 EXPECT_FALSE(cng_enabled);
2545 EXPECT_TRUE(agc_enabled);
2546 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2547 EXPECT_TRUE(ns_enabled);
2548 EXPECT_TRUE(highpass_filter_enabled);
2549 EXPECT_FALSE(stereo_swapping_enabled);
2550 EXPECT_TRUE(typing_detection_enabled);
2551 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2552 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2553
2554 // Turn echo cancellation off
2555 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002556 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 voe_.GetEcStatus(ec_enabled, ec_mode);
2558 EXPECT_FALSE(ec_enabled);
2559
2560 // Turn echo cancellation back on, with settings, and make sure
2561 // nothing else changed.
2562 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002563 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002564 voe_.GetEcStatus(ec_enabled, ec_mode);
2565 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2566 voe_.GetAecmMode(aecm_mode, cng_enabled);
2567 voe_.GetAgcStatus(agc_enabled, agc_mode);
2568 voe_.GetAgcConfig(agc_config);
2569 voe_.GetNsStatus(ns_enabled, ns_mode);
2570 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2571 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2572 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2573 EXPECT_TRUE(ec_enabled);
2574 EXPECT_TRUE(ec_metrics_enabled);
2575 EXPECT_TRUE(agc_enabled);
2576 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2577 EXPECT_TRUE(ns_enabled);
2578 EXPECT_TRUE(highpass_filter_enabled);
2579 EXPECT_FALSE(stereo_swapping_enabled);
2580 EXPECT_TRUE(typing_detection_enabled);
2581 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2582 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2583
2584 // Turn off AGC
2585 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002586 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002587 voe_.GetAgcStatus(agc_enabled, agc_mode);
2588 EXPECT_FALSE(agc_enabled);
2589
2590 // Turn AGC back on
2591 options.auto_gain_control.Set(true);
2592 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002593 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002594 voe_.GetAgcStatus(agc_enabled, agc_mode);
2595 EXPECT_TRUE(agc_enabled);
2596 voe_.GetAgcConfig(agc_config);
2597 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2598
2599 // Turn off other options (and stereo swapping on).
2600 options.noise_suppression.Set(false);
2601 options.highpass_filter.Set(false);
2602 options.typing_detection.Set(false);
2603 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002604 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002605 voe_.GetNsStatus(ns_enabled, ns_mode);
2606 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2607 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2608 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2609 EXPECT_FALSE(ns_enabled);
2610 EXPECT_FALSE(highpass_filter_enabled);
2611 EXPECT_FALSE(typing_detection_enabled);
2612 EXPECT_TRUE(stereo_swapping_enabled);
2613
2614 // Turn on "conference mode" to ensure it has no impact.
2615 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002616 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002617 voe_.GetEcStatus(ec_enabled, ec_mode);
2618 voe_.GetNsStatus(ns_enabled, ns_mode);
2619 EXPECT_TRUE(ec_enabled);
2620 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2621 EXPECT_FALSE(ns_enabled);
2622 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2623}
2624
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002625TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626 EXPECT_TRUE(SetupEngine());
2627
2628 bool ec_enabled;
2629 webrtc::EcModes ec_mode;
2630 bool ec_metrics_enabled;
2631 bool agc_enabled;
2632 webrtc::AgcModes agc_mode;
2633 bool ns_enabled;
2634 webrtc::NsModes ns_mode;
2635 bool highpass_filter_enabled;
2636 bool stereo_swapping_enabled;
2637 bool typing_detection_enabled;
2638
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002639 voe_.GetEcStatus(ec_enabled, ec_mode);
2640 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2641 voe_.GetAgcStatus(agc_enabled, agc_mode);
2642 voe_.GetNsStatus(ns_enabled, ns_mode);
2643 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2644 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2645 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2646 EXPECT_TRUE(ec_enabled);
2647 EXPECT_TRUE(agc_enabled);
2648 EXPECT_TRUE(ns_enabled);
2649 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002650 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652}
2653
2654TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2655 webrtc::AgcConfig set_config = {0};
2656 set_config.targetLeveldBOv = 3;
2657 set_config.digitalCompressionGaindB = 9;
2658 set_config.limiterEnable = true;
2659 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2660 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2661
2662 webrtc::AgcConfig config = {0};
2663 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2664 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2665 EXPECT_EQ(set_config.digitalCompressionGaindB,
2666 config.digitalCompressionGaindB);
2667 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2668}
2669
2670
2671TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2672 EXPECT_TRUE(SetupEngine());
2673 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2674 engine_.CreateChannel());
2675 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2676 engine_.CreateChannel());
2677
2678 // Have to add a stream to make SetSend work.
2679 cricket::StreamParams stream1;
2680 stream1.ssrcs.push_back(1);
2681 channel1->AddSendStream(stream1);
2682 cricket::StreamParams stream2;
2683 stream2.ssrcs.push_back(2);
2684 channel2->AddSendStream(stream2);
2685
2686 // AEC and AGC and NS
2687 cricket::AudioOptions options_all;
2688 options_all.echo_cancellation.Set(true);
2689 options_all.auto_gain_control.Set(true);
2690 options_all.noise_suppression.Set(true);
2691
2692 ASSERT_TRUE(channel1->SetOptions(options_all));
2693 cricket::AudioOptions expected_options = options_all;
2694 cricket::AudioOptions actual_options;
2695 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2696 EXPECT_EQ(expected_options, actual_options);
2697 ASSERT_TRUE(channel2->SetOptions(options_all));
2698 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2699 EXPECT_EQ(expected_options, actual_options);
2700
2701 // unset NS
2702 cricket::AudioOptions options_no_ns;
2703 options_no_ns.noise_suppression.Set(false);
2704 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2705
2706 expected_options.echo_cancellation.Set(true);
2707 expected_options.auto_gain_control.Set(true);
2708 expected_options.noise_suppression.Set(false);
2709 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2710 EXPECT_EQ(expected_options, actual_options);
2711
2712 // unset AGC
2713 cricket::AudioOptions options_no_agc;
2714 options_no_agc.auto_gain_control.Set(false);
2715 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2716
2717 expected_options.echo_cancellation.Set(true);
2718 expected_options.auto_gain_control.Set(false);
2719 expected_options.noise_suppression.Set(true);
2720 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2721 EXPECT_EQ(expected_options, actual_options);
2722
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002723 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002724 bool ec_enabled;
2725 webrtc::EcModes ec_mode;
2726 bool agc_enabled;
2727 webrtc::AgcModes agc_mode;
2728 bool ns_enabled;
2729 webrtc::NsModes ns_mode;
2730 voe_.GetEcStatus(ec_enabled, ec_mode);
2731 voe_.GetAgcStatus(agc_enabled, agc_mode);
2732 voe_.GetNsStatus(ns_enabled, ns_mode);
2733 EXPECT_TRUE(ec_enabled);
2734 EXPECT_TRUE(agc_enabled);
2735 EXPECT_TRUE(ns_enabled);
2736
2737 channel1->SetSend(cricket::SEND_MICROPHONE);
2738 voe_.GetEcStatus(ec_enabled, ec_mode);
2739 voe_.GetAgcStatus(agc_enabled, agc_mode);
2740 voe_.GetNsStatus(ns_enabled, ns_mode);
2741 EXPECT_TRUE(ec_enabled);
2742 EXPECT_TRUE(agc_enabled);
2743 EXPECT_FALSE(ns_enabled);
2744
2745 channel1->SetSend(cricket::SEND_NOTHING);
2746 voe_.GetEcStatus(ec_enabled, ec_mode);
2747 voe_.GetAgcStatus(agc_enabled, agc_mode);
2748 voe_.GetNsStatus(ns_enabled, ns_mode);
2749 EXPECT_TRUE(ec_enabled);
2750 EXPECT_TRUE(agc_enabled);
2751 EXPECT_TRUE(ns_enabled);
2752
2753 channel2->SetSend(cricket::SEND_MICROPHONE);
2754 voe_.GetEcStatus(ec_enabled, ec_mode);
2755 voe_.GetAgcStatus(agc_enabled, agc_mode);
2756 voe_.GetNsStatus(ns_enabled, ns_mode);
2757 EXPECT_TRUE(ec_enabled);
2758 EXPECT_FALSE(agc_enabled);
2759 EXPECT_TRUE(ns_enabled);
2760
2761 channel2->SetSend(cricket::SEND_NOTHING);
2762 voe_.GetEcStatus(ec_enabled, ec_mode);
2763 voe_.GetAgcStatus(agc_enabled, agc_mode);
2764 voe_.GetNsStatus(ns_enabled, ns_mode);
2765 EXPECT_TRUE(ec_enabled);
2766 EXPECT_TRUE(agc_enabled);
2767 EXPECT_TRUE(ns_enabled);
2768
2769 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002770 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002771 cricket::AudioOptions options_no_agc_nor_ns;
2772 options_no_agc_nor_ns.auto_gain_control.Set(false);
2773 options_no_agc_nor_ns.noise_suppression.Set(false);
2774 channel2->SetSend(cricket::SEND_MICROPHONE);
2775 channel2->SetOptions(options_no_agc_nor_ns);
2776
2777 expected_options.echo_cancellation.Set(true);
2778 expected_options.auto_gain_control.Set(false);
2779 expected_options.noise_suppression.Set(false);
2780 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2781 EXPECT_EQ(expected_options, actual_options);
2782 voe_.GetEcStatus(ec_enabled, ec_mode);
2783 voe_.GetAgcStatus(agc_enabled, agc_mode);
2784 voe_.GetNsStatus(ns_enabled, ns_mode);
2785 EXPECT_TRUE(ec_enabled);
2786 EXPECT_FALSE(agc_enabled);
2787 EXPECT_FALSE(ns_enabled);
2788}
2789
wu@webrtc.orgde305012013-10-31 15:40:38 +00002790// This test verifies DSCP settings are properly applied on voice media channel.
2791TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2792 EXPECT_TRUE(SetupEngine());
2793 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel(
2794 engine_.CreateChannel());
2795 talk_base::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2796 new cricket::FakeNetworkInterface);
2797 channel->SetInterface(network_interface.get());
2798 cricket::AudioOptions options;
2799 options.dscp.Set(true);
2800 EXPECT_TRUE(channel->SetOptions(options));
2801 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00002802 // Verify previous value is not modified if dscp option is not set.
2803 cricket::AudioOptions options1;
2804 EXPECT_TRUE(channel->SetOptions(options1));
2805 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00002806 options.dscp.Set(false);
2807 EXPECT_TRUE(channel->SetOptions(options));
2808 EXPECT_EQ(talk_base::DSCP_DEFAULT, network_interface->dscp());
2809}
2810
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002811TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2812 cricket::WebRtcVoiceEngine engine;
2813 cricket::AudioOptions options = engine.GetOptions();
2814 // The default options should have at least a few things set. We purposefully
2815 // don't check the option values here, though.
2816 EXPECT_TRUE(options.echo_cancellation.IsSet());
2817 EXPECT_TRUE(options.auto_gain_control.IsSet());
2818 EXPECT_TRUE(options.noise_suppression.IsSet());
2819}
2820
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002821// Test that GetReceiveChannelNum returns the default channel for the first
2822// recv stream in 1-1 calls.
2823TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2824 EXPECT_TRUE(SetupEngine());
2825 cricket::WebRtcVoiceMediaChannel* media_channel =
2826 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2827 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2828 EXPECT_EQ(media_channel->voe_channel(),
2829 media_channel->GetReceiveChannelNum(0));
2830 cricket::StreamParams stream;
2831 stream.ssrcs.push_back(kSsrc2);
2832 EXPECT_TRUE(channel_->AddRecvStream(stream));
2833 EXPECT_EQ(media_channel->voe_channel(),
2834 media_channel->GetReceiveChannelNum(kSsrc2));
2835}
2836
2837// Test that GetReceiveChannelNum doesn't return the default channel for the
2838// first recv stream in conference calls.
2839TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2840 EXPECT_TRUE(SetupEngine());
2841 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2842 cricket::StreamParams stream;
2843 stream.ssrcs.push_back(kSsrc2);
2844 EXPECT_TRUE(channel_->AddRecvStream(stream));
2845 cricket::WebRtcVoiceMediaChannel* media_channel =
2846 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2847 EXPECT_LT(media_channel->voe_channel(),
2848 media_channel->GetReceiveChannelNum(kSsrc2));
2849}
2850
2851TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2852 EXPECT_TRUE(SetupEngine());
2853 double left, right;
2854 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2855 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2856 EXPECT_DOUBLE_EQ(1, left);
2857 EXPECT_DOUBLE_EQ(2, right);
2858
2859 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2860 cricket::StreamParams stream;
2861 stream.ssrcs.push_back(kSsrc2);
2862 EXPECT_TRUE(channel_->AddRecvStream(stream));
2863
2864 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2865 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2866 EXPECT_DOUBLE_EQ(2, left);
2867 EXPECT_DOUBLE_EQ(1, right);
2868}
2869
2870
2871// Tests for the actual WebRtc VoE library.
2872
2873// Tests that the library initializes and shuts down properly.
2874TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2875 cricket::WebRtcVoiceEngine engine;
2876 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2877 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2878 EXPECT_TRUE(channel != NULL);
2879 delete channel;
2880 engine.Terminate();
2881
2882 // Reinit to catch regression where VoiceEngineObserver reference is lost
2883 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2884 engine.Terminate();
2885}
2886
2887// Tests that the logging from the library is cleartext.
2888TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
2889 cricket::WebRtcVoiceEngine engine;
2890 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2891 new talk_base::MemoryStream);
2892 size_t size = 0;
2893 bool cleartext = true;
2894 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2895 engine.SetLogging(talk_base::LS_VERBOSE, "");
2896 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2897 EXPECT_TRUE(stream->GetSize(&size));
2898 EXPECT_GT(size, 0U);
2899 engine.Terminate();
2900 talk_base::LogMessage::RemoveLogToStream(stream.get());
2901 const char* buf = stream->GetBuffer();
2902 for (size_t i = 0; i < size && cleartext; ++i) {
2903 int ch = static_cast<int>(buf[i]);
2904 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
2905 << std::hex << ch;
2906 cleartext = (isprint(ch) || isspace(ch));
2907 }
2908 EXPECT_TRUE(cleartext);
2909}
2910
2911// Tests we do not see any references to a monitor thread being spun up
2912// when initiating the engine.
2913TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
2914 cricket::WebRtcVoiceEngine engine;
2915 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2916 new talk_base::MemoryStream);
2917 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2918 engine.SetLogging(talk_base::LS_VERBOSE, "");
2919 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2920 engine.Terminate();
2921 talk_base::LogMessage::RemoveLogToStream(stream.get());
2922
2923 size_t size = 0;
2924 EXPECT_TRUE(stream->GetSize(&size));
2925 EXPECT_GT(size, 0U);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002926 const std::string logs(stream->GetBuffer(), size);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002927 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
2928}
2929
2930// Tests that the library is configured with the codecs we want.
2931TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
2932 cricket::WebRtcVoiceEngine engine;
2933 // Check codecs by name.
2934 EXPECT_TRUE(engine.FindCodec(
2935 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
2936 EXPECT_TRUE(engine.FindCodec(
2937 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
2938 EXPECT_TRUE(engine.FindCodec(
2939 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
2940 // Check that name matching is case-insensitive.
2941 EXPECT_TRUE(engine.FindCodec(
2942 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
2943 EXPECT_TRUE(engine.FindCodec(
2944 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
2945 EXPECT_TRUE(engine.FindCodec(
2946 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
2947 EXPECT_TRUE(engine.FindCodec(
2948 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
2949 EXPECT_TRUE(engine.FindCodec(
2950 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
2951 EXPECT_TRUE(engine.FindCodec(
2952 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953 EXPECT_TRUE(engine.FindCodec(
2954 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
2955 EXPECT_TRUE(engine.FindCodec(
2956 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
2957 EXPECT_TRUE(engine.FindCodec(
2958 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
2959 EXPECT_TRUE(engine.FindCodec(
2960 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
2961 // Check codecs with an id by id.
2962 EXPECT_TRUE(engine.FindCodec(
2963 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
2964 EXPECT_TRUE(engine.FindCodec(
2965 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
2966 EXPECT_TRUE(engine.FindCodec(
2967 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
2968 EXPECT_TRUE(engine.FindCodec(
2969 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
2970 // Check sample/bitrate matching.
2971 EXPECT_TRUE(engine.FindCodec(
2972 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
2973 // Check that bad codecs fail.
2974 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
2975 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
2976 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
2977 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
2978 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
2980 for (std::vector<cricket::AudioCodec>::const_iterator it =
2981 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
2982 if (it->name == "CN" && it->clockrate == 16000) {
2983 EXPECT_EQ(105, it->id);
2984 } else if (it->name == "CN" && it->clockrate == 32000) {
2985 EXPECT_EQ(106, it->id);
2986 } else if (it->name == "ISAC" && it->clockrate == 16000) {
2987 EXPECT_EQ(103, it->id);
2988 } else if (it->name == "ISAC" && it->clockrate == 32000) {
2989 EXPECT_EQ(104, it->id);
2990 } else if (it->name == "G722" && it->clockrate == 16000) {
2991 EXPECT_EQ(9, it->id);
2992 } else if (it->name == "telephone-event") {
2993 EXPECT_EQ(126, it->id);
2994 } else if (it->name == "red") {
2995 EXPECT_EQ(127, it->id);
2996 } else if (it->name == "opus") {
2997 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002998 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003000 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003001 EXPECT_EQ("60", it->params.find("maxptime")->second);
3002 }
3003 }
3004
3005 engine.Terminate();
3006}
3007
3008// Tests that VoE supports at least 32 channels
3009TEST(WebRtcVoiceEngineTest, Has32Channels) {
3010 cricket::WebRtcVoiceEngine engine;
3011 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3012
3013 cricket::VoiceMediaChannel* channels[32];
3014 int num_channels = 0;
3015
3016 while (num_channels < ARRAY_SIZE(channels)) {
3017 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3018 if (!channel)
3019 break;
3020
3021 channels[num_channels++] = channel;
3022 }
3023
3024 int expected = ARRAY_SIZE(channels);
3025 EXPECT_EQ(expected, num_channels);
3026
3027 while (num_channels > 0) {
3028 delete channels[--num_channels];
3029 }
3030
3031 engine.Terminate();
3032}
3033
3034// Test that we set our preferred codecs properly.
3035TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3036 cricket::WebRtcVoiceEngine engine;
3037 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3038 cricket::WebRtcVoiceMediaChannel channel(&engine);
3039 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3040}
3041
3042#ifdef WIN32
3043// Test our workarounds to WebRtc VoE' munging of the coinit count
3044TEST(WebRtcVoiceEngineTest, CoInitialize) {
3045 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3046
3047 // Initial refcount should be 0.
3048 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3049
3050 // Engine should start even with COM already inited.
3051 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3052 engine->Terminate();
3053 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3054 engine->Terminate();
3055
3056 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3057 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3058 // Decrement refcount to (hopefully) 0.
3059 CoUninitialize();
3060 CoUninitialize();
3061 delete engine;
3062
3063 // Ensure refcount is 0.
3064 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3065 CoUninitialize();
3066}
3067#endif
3068
3069
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00003070TEST_F(WebRtcVoiceEngineTestFake, SetExperimentalAcm) {
3071 EXPECT_TRUE(SetupEngine());
3072
3073 // By default experimental ACM should not be used.
3074 int media_channel = engine_.CreateMediaVoiceChannel();
3075 ASSERT_GE(media_channel, 0);
3076 EXPECT_FALSE(voe_.IsUsingExperimentalAcm(media_channel));
3077
3078 int soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3079 ASSERT_GE(soundclip_channel, 0);
3080 EXPECT_FALSE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
3081
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00003082 // Set options to use experimental ACM.
3083 cricket::AudioOptions options;
3084 options.experimental_acm.Set(true);
3085 ASSERT_TRUE(engine_.SetOptions(options));
3086 media_channel = engine_.CreateMediaVoiceChannel();
3087 ASSERT_GE(media_channel, 0);
3088 EXPECT_TRUE(voe_.IsUsingExperimentalAcm(media_channel));
3089
3090 soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3091 ASSERT_GE(soundclip_channel, 0);
3092 EXPECT_TRUE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
3093
3094 // Set option to use legacy ACM.
3095 options.experimental_acm.Set(false);
3096 ASSERT_TRUE(engine_.SetOptions(options));
3097 media_channel = engine_.CreateMediaVoiceChannel();
3098 ASSERT_GE(media_channel, 0);
3099 EXPECT_FALSE(voe_.IsUsingExperimentalAcm(media_channel));
3100
3101 soundclip_channel = engine_.CreateSoundclipVoiceChannel();
3102 ASSERT_GE(soundclip_channel, 0);
3103 EXPECT_FALSE(voe_sc_.IsUsingExperimentalAcm(soundclip_channel));
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00003104}