blob: 4e0f339fba3116ea4bf616e8a6ea860711a103cb [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
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000249 void TestSetSendRtpHeaderExtensions(int channel_id) {
250 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000252 // Ensure extensions are off by default.
253 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000254 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000255
256 // Ensure unknown extensions won't cause an error.
257 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000258 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000259 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000260 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000261 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000262
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000263 // Ensure extensions stay off with an empty list of headers.
264 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000265 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000266 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000267 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000268
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000269 // Ensure audio levels are enabled if the audio-level header is specified
270 // (but AST is still off).
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000271 extensions.push_back(cricket::RtpHeaderExtension(
272 "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
273 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000274 EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000275 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000276
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000277 // Ensure audio level and AST are enabled if the extensions are specified.
278 extensions.push_back(cricket::RtpHeaderExtension(
279 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", 12));
280 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
281 EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id));
282 EXPECT_EQ(12, voe_.GetSendAbsoluteSenderTimeId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000283
284 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000285 extensions.clear();
286 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000287 EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000288 EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000289 }
290
291 void TestSetRecvRtpHeaderExtensions(int channel_id) {
292 std::vector<cricket::RtpHeaderExtension> extensions;
293
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000294 // Ensure extensions are off by default.
295 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000296
297 // Ensure unknown extensions won't cause an error.
298 extensions.push_back(cricket::RtpHeaderExtension(
299 "urn:ietf:params:unknownextention", 1));
300 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000301 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000302
303 // An empty list shouldn't cause any headers to be enabled.
304 extensions.clear();
305 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000306 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000307
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000308 // Nor should indicating we can receive the absolute sender time header.
309 extensions.push_back(cricket::RtpHeaderExtension(
310 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", 11));
311 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
312 EXPECT_EQ(11, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000313
314 // Resetting to an empty list shouldn't cause any headers to be enabled.
315 extensions.clear();
316 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000317 EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000318 }
319
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 protected:
321 cricket::FakeWebRtcVoiceEngine voe_;
322 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000323 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 cricket::WebRtcVoiceEngine engine_;
325 cricket::VoiceMediaChannel* channel_;
326 cricket::SoundclipMedia* soundclip_;
327
328 cricket::AudioOptions options_conference_;
329 cricket::AudioOptions options_adjust_agc_;
330};
331
332// Tests that our stub library "works".
333TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
334 EXPECT_FALSE(voe_.IsInited());
335 EXPECT_FALSE(voe_sc_.IsInited());
336 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
337 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000338 // The soundclip engine is lazily initialized.
339 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340 engine_.Terminate();
341 EXPECT_FALSE(voe_.IsInited());
342 EXPECT_FALSE(voe_sc_.IsInited());
343}
344
345// Tests that we can create and destroy a channel.
346TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
347 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
348 channel_ = engine_.CreateChannel();
349 EXPECT_TRUE(channel_ != NULL);
350}
351
352// Tests that we properly handle failures in CreateChannel.
353TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
354 voe_.set_fail_create_channel(true);
355 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
356 channel_ = engine_.CreateChannel();
357 EXPECT_TRUE(channel_ == NULL);
358}
359
360// Tests that the list of supported codecs is created properly and ordered
361// correctly
362TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
363 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
364 ASSERT_FALSE(codecs.empty());
365 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
366 EXPECT_EQ(48000, codecs[0].clockrate);
367 EXPECT_EQ(2, codecs[0].channels);
368 EXPECT_EQ(64000, codecs[0].bitrate);
369 int pref = codecs[0].preference;
370 for (size_t i = 1; i < codecs.size(); ++i) {
371 EXPECT_GT(pref, codecs[i].preference);
372 pref = codecs[i].preference;
373 }
374}
375
376// Tests that we can find codecs by name or id, and that we interpret the
377// clockrate and bitrate fields properly.
378TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
379 cricket::AudioCodec codec;
380 webrtc::CodecInst codec_inst;
381 // Find PCMU with explicit clockrate and bitrate.
382 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
383 // Find ISAC with explicit clockrate and 0 bitrate.
384 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
385 // Find telephone-event with explicit clockrate and 0 bitrate.
386 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
387 // Find ISAC with a different payload id.
388 codec = kIsacCodec;
389 codec.id = 127;
390 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
391 EXPECT_EQ(codec.id, codec_inst.pltype);
392 // Find PCMU with a 0 clockrate.
393 codec = kPcmuCodec;
394 codec.clockrate = 0;
395 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
396 EXPECT_EQ(codec.id, codec_inst.pltype);
397 EXPECT_EQ(8000, codec_inst.plfreq);
398 // Find PCMU with a 0 bitrate.
399 codec = kPcmuCodec;
400 codec.bitrate = 0;
401 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
402 EXPECT_EQ(codec.id, codec_inst.pltype);
403 EXPECT_EQ(64000, codec_inst.rate);
404 // Find ISAC with an explicit bitrate.
405 codec = kIsacCodec;
406 codec.bitrate = 32000;
407 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
408 EXPECT_EQ(codec.id, codec_inst.pltype);
409 EXPECT_EQ(32000, codec_inst.rate);
410}
411
412// Test that we set our inbound codecs properly, including changing PT.
413TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
414 EXPECT_TRUE(SetupEngine());
415 int channel_num = voe_.GetLastChannel();
416 std::vector<cricket::AudioCodec> codecs;
417 codecs.push_back(kIsacCodec);
418 codecs.push_back(kPcmuCodec);
419 codecs.push_back(kTelephoneEventCodec);
420 codecs[0].id = 106; // collide with existing telephone-event
421 codecs[2].id = 126;
422 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
423 webrtc::CodecInst gcodec;
424 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
425 gcodec.plfreq = 16000;
426 gcodec.channels = 1;
427 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
428 EXPECT_EQ(106, gcodec.pltype);
429 EXPECT_STREQ("ISAC", gcodec.plname);
430 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
431 "telephone-event");
432 gcodec.plfreq = 8000;
433 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
434 EXPECT_EQ(126, gcodec.pltype);
435 EXPECT_STREQ("telephone-event", gcodec.plname);
436}
437
438// Test that we fail to set an unknown inbound codec.
439TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
440 EXPECT_TRUE(SetupEngine());
441 std::vector<cricket::AudioCodec> codecs;
442 codecs.push_back(kIsacCodec);
443 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
444 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
445}
446
447// Test that we fail if we have duplicate types in the inbound list.
448TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
449 EXPECT_TRUE(SetupEngine());
450 std::vector<cricket::AudioCodec> codecs;
451 codecs.push_back(kIsacCodec);
452 codecs.push_back(kCn16000Codec);
453 codecs[1].id = kIsacCodec.id;
454 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
455}
456
457// Test that we can decode OPUS without stereo parameters.
458TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
459 EXPECT_TRUE(SetupEngine());
460 EXPECT_TRUE(channel_->SetOptions(options_conference_));
461 std::vector<cricket::AudioCodec> codecs;
462 codecs.push_back(kIsacCodec);
463 codecs.push_back(kPcmuCodec);
464 codecs.push_back(kOpusCodec);
465 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
466 EXPECT_TRUE(channel_->AddRecvStream(
467 cricket::StreamParams::CreateLegacy(kSsrc1)));
468 int channel_num2 = voe_.GetLastChannel();
469 webrtc::CodecInst opus;
470 engine_.FindWebRtcCodec(kOpusCodec, &opus);
471 // Even without stereo parameters, recv codecs still specify channels = 2.
472 EXPECT_EQ(2, opus.channels);
473 EXPECT_EQ(111, opus.pltype);
474 EXPECT_STREQ("opus", opus.plname);
475 opus.pltype = 0;
476 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
477 EXPECT_EQ(111, opus.pltype);
478}
479
480// Test that we can decode OPUS with stereo = 0.
481TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
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 codecs[2].params["stereo"] = "0";
489 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
490 EXPECT_TRUE(channel_->AddRecvStream(
491 cricket::StreamParams::CreateLegacy(kSsrc1)));
492 int channel_num2 = voe_.GetLastChannel();
493 webrtc::CodecInst opus;
494 engine_.FindWebRtcCodec(kOpusCodec, &opus);
495 // Even when stereo is off, recv codecs still specify channels = 2.
496 EXPECT_EQ(2, opus.channels);
497 EXPECT_EQ(111, opus.pltype);
498 EXPECT_STREQ("opus", opus.plname);
499 opus.pltype = 0;
500 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
501 EXPECT_EQ(111, opus.pltype);
502}
503
504// Test that we can decode OPUS with stereo = 1.
505TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
506 EXPECT_TRUE(SetupEngine());
507 EXPECT_TRUE(channel_->SetOptions(options_conference_));
508 std::vector<cricket::AudioCodec> codecs;
509 codecs.push_back(kIsacCodec);
510 codecs.push_back(kPcmuCodec);
511 codecs.push_back(kOpusCodec);
512 codecs[2].params["stereo"] = "1";
513 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
514 EXPECT_TRUE(channel_->AddRecvStream(
515 cricket::StreamParams::CreateLegacy(kSsrc1)));
516 int channel_num2 = voe_.GetLastChannel();
517 webrtc::CodecInst opus;
518 engine_.FindWebRtcCodec(kOpusCodec, &opus);
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 changes to recv codecs are applied to all streams.
528TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
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(kTelephoneEventCodec);
535 codecs[0].id = 106; // collide with existing telephone-event
536 codecs[2].id = 126;
537 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
538 EXPECT_TRUE(channel_->AddRecvStream(
539 cricket::StreamParams::CreateLegacy(kSsrc1)));
540 int channel_num2 = voe_.GetLastChannel();
541 webrtc::CodecInst gcodec;
542 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
543 gcodec.plfreq = 16000;
544 gcodec.channels = 1;
545 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
546 EXPECT_EQ(106, gcodec.pltype);
547 EXPECT_STREQ("ISAC", gcodec.plname);
548 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
549 "telephone-event");
550 gcodec.plfreq = 8000;
551 gcodec.channels = 1;
552 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
553 EXPECT_EQ(126, gcodec.pltype);
554 EXPECT_STREQ("telephone-event", gcodec.plname);
555}
556
557TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
558 EXPECT_TRUE(SetupEngine());
559 EXPECT_TRUE(channel_->SetOptions(options_conference_));
560 std::vector<cricket::AudioCodec> codecs;
561 codecs.push_back(kIsacCodec);
562 codecs[0].id = 106; // collide with existing telephone-event
563
564 EXPECT_TRUE(channel_->AddRecvStream(
565 cricket::StreamParams::CreateLegacy(kSsrc1)));
566 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
567
568 int channel_num2 = voe_.GetLastChannel();
569 webrtc::CodecInst gcodec;
570 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
571 gcodec.plfreq = 16000;
572 gcodec.channels = 1;
573 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
574 EXPECT_EQ(106, gcodec.pltype);
575 EXPECT_STREQ("ISAC", gcodec.plname);
576}
577
578// Test that we can apply the same set of codecs again while playing.
579TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
580 EXPECT_TRUE(SetupEngine());
581 int channel_num = voe_.GetLastChannel();
582 std::vector<cricket::AudioCodec> codecs;
583 codecs.push_back(kIsacCodec);
584 codecs.push_back(kCn16000Codec);
585 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
586 EXPECT_TRUE(channel_->SetPlayout(true));
587 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
588
589 // Changing the payload type of a codec should fail.
590 codecs[0].id = 127;
591 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
592 EXPECT_TRUE(voe_.GetPlayout(channel_num));
593}
594
595// Test that we can add a codec while playing.
596TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
597 EXPECT_TRUE(SetupEngine());
598 int channel_num = voe_.GetLastChannel();
599 std::vector<cricket::AudioCodec> codecs;
600 codecs.push_back(kIsacCodec);
601 codecs.push_back(kCn16000Codec);
602 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
603 EXPECT_TRUE(channel_->SetPlayout(true));
604
605 codecs.push_back(kOpusCodec);
606 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
607 EXPECT_TRUE(voe_.GetPlayout(channel_num));
608 webrtc::CodecInst gcodec;
609 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
610 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
611}
612
613TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
614 EXPECT_TRUE(SetupEngine());
615 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
616
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000617 // Test that when autobw is enabled, bitrate is kept as the default
618 // value. autobw is enabled for the following tests because the target
619 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620
621 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000622 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623
624 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000625 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000626
627 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000628 TestSendBandwidth(kCeltCodec, 0, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629
630 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000631 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632}
633
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000634TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635 EXPECT_TRUE(SetupEngine());
636 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
637
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000638 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639
640 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000641 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
642 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000643
644 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000645 TestSendBandwidth(kCeltCodec, 96000, true, 96000);
646 TestSendBandwidth(kCeltCodec, 32000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000647
648 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000649 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
650 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651}
652
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000653TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
654 EXPECT_TRUE(SetupEngine());
655 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
656
657 // Test that we can only set a maximum bitrate for a fixed-rate codec
658 // if it's bigger than the fixed rate.
659
660 // PCMU, fixed bitrate == 64000.
661 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
662 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
663 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
664 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
665 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
666 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
667 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
668}
669
670TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000671 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
672 channel_ = engine_.CreateChannel();
673 EXPECT_TRUE(channel_ != NULL);
674 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
675
676 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000677 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000678
679 EXPECT_TRUE(channel_->AddSendStream(
680 cricket::StreamParams::CreateLegacy(kSsrc1)));
681
682 int channel_num = voe_.GetLastChannel();
683 webrtc::CodecInst codec;
684 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
685 EXPECT_EQ(desired_bitrate, codec.rate);
686}
687
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688// Test that bitrate cannot be set for CBR codecs.
689// Bitrate is ignored if it is higher than the fixed bitrate.
690// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000691TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 EXPECT_TRUE(SetupEngine());
693 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
694
695 webrtc::CodecInst codec;
696 int channel_num = voe_.GetLastChannel();
697 std::vector<cricket::AudioCodec> codecs;
698
699 // PCMU, default bitrate == 64000.
700 codecs.push_back(kPcmuCodec);
701 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
702 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
703 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000704 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
706 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000707 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
709 EXPECT_EQ(64000, codec.rate);
710}
711
712// Test that we apply codecs properly.
713TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
714 EXPECT_TRUE(SetupEngine());
715 int channel_num = voe_.GetLastChannel();
716 std::vector<cricket::AudioCodec> codecs;
717 codecs.push_back(kIsacCodec);
718 codecs.push_back(kPcmuCodec);
719 codecs.push_back(kRedCodec);
720 codecs[0].id = 96;
721 codecs[0].bitrate = 48000;
722 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000723 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 webrtc::CodecInst gcodec;
725 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
726 EXPECT_EQ(96, gcodec.pltype);
727 EXPECT_EQ(48000, gcodec.rate);
728 EXPECT_STREQ("ISAC", gcodec.plname);
729 EXPECT_FALSE(voe_.GetVAD(channel_num));
730 EXPECT_FALSE(voe_.GetFEC(channel_num));
731 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
732 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
733 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
734}
735
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000736// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
737// to apply.
738TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
739 EXPECT_TRUE(SetupEngine());
740 std::vector<cricket::AudioCodec> codecs;
741 codecs.push_back(kIsacCodec);
742 codecs.push_back(kPcmuCodec);
743 codecs.push_back(kRedCodec);
744 codecs[0].id = 96;
745 codecs[0].bitrate = 48000;
746 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
747 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
748 // Calling SetSendCodec again with same codec which is already set.
749 // In this case media channel shouldn't send codec to VoE.
750 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
751 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
752}
753
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000754// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
756 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000757 std::vector<cricket::AudioCodec> codecs;
758 codecs.push_back(kOpusCodec);
759 codecs[0].bitrate = 0;
760 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000761 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000762}
763
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000764// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
766 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767 std::vector<cricket::AudioCodec> codecs;
768 codecs.push_back(kOpusCodec);
769 codecs[0].bitrate = 0;
770 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000771 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000772}
773
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000774// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
776 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777 std::vector<cricket::AudioCodec> codecs;
778 codecs.push_back(kOpusCodec);
779 codecs[0].bitrate = 0;
780 codecs[0].channels = 0;
781 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000782 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783}
784
785// Test that if channel is 1 for opus and there's no stereo, we fail.
786TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
787 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 std::vector<cricket::AudioCodec> codecs;
789 codecs.push_back(kOpusCodec);
790 codecs[0].bitrate = 0;
791 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000792 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000793}
794
795// Test that if channel is 1 for opus and stereo=0, we fail.
796TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
797 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798 std::vector<cricket::AudioCodec> codecs;
799 codecs.push_back(kOpusCodec);
800 codecs[0].bitrate = 0;
801 codecs[0].channels = 1;
802 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000803 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that if channel is 1 for opus and stereo=1, we fail.
807TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
808 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809 std::vector<cricket::AudioCodec> codecs;
810 codecs.push_back(kOpusCodec);
811 codecs[0].bitrate = 0;
812 codecs[0].channels = 1;
813 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000814 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000815}
816
817// Test that with bitrate=0 and no stereo,
818// channels and bitrate are 1 and 32000.
819TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
820 EXPECT_TRUE(SetupEngine());
821 int channel_num = voe_.GetLastChannel();
822 std::vector<cricket::AudioCodec> codecs;
823 codecs.push_back(kOpusCodec);
824 codecs[0].bitrate = 0;
825 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
826 webrtc::CodecInst gcodec;
827 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
828 EXPECT_STREQ("opus", gcodec.plname);
829 EXPECT_EQ(1, gcodec.channels);
830 EXPECT_EQ(32000, gcodec.rate);
831}
832
833// Test that with bitrate=0 and stereo=0,
834// channels and bitrate are 1 and 32000.
835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
836 EXPECT_TRUE(SetupEngine());
837 int channel_num = voe_.GetLastChannel();
838 std::vector<cricket::AudioCodec> codecs;
839 codecs.push_back(kOpusCodec);
840 codecs[0].bitrate = 0;
841 codecs[0].params["stereo"] = "0";
842 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
843 webrtc::CodecInst gcodec;
844 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
845 EXPECT_STREQ("opus", gcodec.plname);
846 EXPECT_EQ(1, gcodec.channels);
847 EXPECT_EQ(32000, gcodec.rate);
848}
849
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000850// Test that with bitrate=invalid and stereo=0,
851// channels and bitrate are 1 and 32000.
852TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
853 EXPECT_TRUE(SetupEngine());
854 int channel_num = voe_.GetLastChannel();
855 std::vector<cricket::AudioCodec> codecs;
856 codecs.push_back(kOpusCodec);
857 codecs[0].params["stereo"] = "0";
858 webrtc::CodecInst gcodec;
859
860 // bitrate that's out of the range between 6000 and 510000 will be considered
861 // as invalid and ignored.
862 codecs[0].bitrate = 5999;
863 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
864 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
865 EXPECT_STREQ("opus", gcodec.plname);
866 EXPECT_EQ(1, gcodec.channels);
867 EXPECT_EQ(32000, gcodec.rate);
868
869 codecs[0].bitrate = 510001;
870 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
871 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
872 EXPECT_STREQ("opus", gcodec.plname);
873 EXPECT_EQ(1, gcodec.channels);
874 EXPECT_EQ(32000, gcodec.rate);
875}
876
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000877// Test that with bitrate=0 and stereo=1,
878// channels and bitrate are 2 and 64000.
879TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
880 EXPECT_TRUE(SetupEngine());
881 int channel_num = voe_.GetLastChannel();
882 std::vector<cricket::AudioCodec> codecs;
883 codecs.push_back(kOpusCodec);
884 codecs[0].bitrate = 0;
885 codecs[0].params["stereo"] = "1";
886 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
887 webrtc::CodecInst gcodec;
888 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
889 EXPECT_STREQ("opus", gcodec.plname);
890 EXPECT_EQ(2, gcodec.channels);
891 EXPECT_EQ(64000, gcodec.rate);
892}
893
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000894// Test that with bitrate=invalid and stereo=1,
895// channels and bitrate are 2 and 64000.
896TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
897 EXPECT_TRUE(SetupEngine());
898 int channel_num = voe_.GetLastChannel();
899 std::vector<cricket::AudioCodec> codecs;
900 codecs.push_back(kOpusCodec);
901 codecs[0].params["stereo"] = "1";
902 webrtc::CodecInst gcodec;
903
904 // bitrate that's out of the range between 6000 and 510000 will be considered
905 // as invalid and ignored.
906 codecs[0].bitrate = 5999;
907 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
908 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
909 EXPECT_STREQ("opus", gcodec.plname);
910 EXPECT_EQ(2, gcodec.channels);
911 EXPECT_EQ(64000, gcodec.rate);
912
913 codecs[0].bitrate = 510001;
914 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
915 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
916 EXPECT_STREQ("opus", gcodec.plname);
917 EXPECT_EQ(2, gcodec.channels);
918 EXPECT_EQ(64000, gcodec.rate);
919}
920
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921// Test that with bitrate=N and stereo unset,
922// channels and bitrate are 1 and N.
923TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
924 EXPECT_TRUE(SetupEngine());
925 int channel_num = voe_.GetLastChannel();
926 std::vector<cricket::AudioCodec> codecs;
927 codecs.push_back(kOpusCodec);
928 codecs[0].bitrate = 96000;
929 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
930 webrtc::CodecInst gcodec;
931 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
932 EXPECT_EQ(111, gcodec.pltype);
933 EXPECT_EQ(96000, gcodec.rate);
934 EXPECT_STREQ("opus", gcodec.plname);
935 EXPECT_EQ(1, gcodec.channels);
936 EXPECT_EQ(48000, gcodec.plfreq);
937}
938
939// Test that with bitrate=N and stereo=0,
940// channels and bitrate are 1 and N.
941TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
942 EXPECT_TRUE(SetupEngine());
943 int channel_num = voe_.GetLastChannel();
944 std::vector<cricket::AudioCodec> codecs;
945 codecs.push_back(kOpusCodec);
946 codecs[0].bitrate = 30000;
947 codecs[0].params["stereo"] = "0";
948 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
949 webrtc::CodecInst gcodec;
950 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
951 EXPECT_EQ(1, gcodec.channels);
952 EXPECT_EQ(30000, gcodec.rate);
953 EXPECT_STREQ("opus", gcodec.plname);
954}
955
956// Test that with bitrate=N and without any parameters,
957// channels and bitrate are 1 and N.
958TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
959 EXPECT_TRUE(SetupEngine());
960 int channel_num = voe_.GetLastChannel();
961 std::vector<cricket::AudioCodec> codecs;
962 codecs.push_back(kOpusCodec);
963 codecs[0].bitrate = 30000;
964 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
965 webrtc::CodecInst gcodec;
966 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
967 EXPECT_EQ(1, gcodec.channels);
968 EXPECT_EQ(30000, gcodec.rate);
969 EXPECT_STREQ("opus", gcodec.plname);
970}
971
972// Test that with bitrate=N and stereo=1,
973// channels and bitrate are 2 and N.
974TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
975 EXPECT_TRUE(SetupEngine());
976 int channel_num = voe_.GetLastChannel();
977 std::vector<cricket::AudioCodec> codecs;
978 codecs.push_back(kOpusCodec);
979 codecs[0].bitrate = 30000;
980 codecs[0].params["stereo"] = "1";
981 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
982 webrtc::CodecInst gcodec;
983 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
984 EXPECT_EQ(2, gcodec.channels);
985 EXPECT_EQ(30000, gcodec.rate);
986 EXPECT_STREQ("opus", gcodec.plname);
987}
988
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000989// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
990// Also test that the "maxaveragebitrate" can't be set to values outside the
991// range of 6000 and 510000
992TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
993 EXPECT_TRUE(SetupEngine());
994 int channel_num = voe_.GetLastChannel();
995 std::vector<cricket::AudioCodec> codecs;
996 codecs.push_back(kOpusCodec);
997 codecs[0].bitrate = 30000;
998 webrtc::CodecInst gcodec;
999
1000 // Ignore if less than 6000.
1001 codecs[0].params["maxaveragebitrate"] = "5999";
1002 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1003 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1004 EXPECT_EQ(30000, gcodec.rate);
1005
1006 // Ignore if larger than 510000.
1007 codecs[0].params["maxaveragebitrate"] = "510001";
1008 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1009 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1010 EXPECT_EQ(30000, gcodec.rate);
1011
1012 codecs[0].params["maxaveragebitrate"] = "200000";
1013 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1014 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1015 EXPECT_EQ(200000, gcodec.rate);
1016}
1017
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001018// Test that we can enable NACK with opus as caller.
1019TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001020 EXPECT_TRUE(SetupEngine());
1021 int channel_num = voe_.GetLastChannel();
1022 std::vector<cricket::AudioCodec> codecs;
1023 codecs.push_back(kOpusCodec);
1024 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1025 cricket::kParamValueEmpty));
1026 EXPECT_FALSE(voe_.GetNACK(channel_num));
1027 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1028 EXPECT_TRUE(voe_.GetNACK(channel_num));
1029}
1030
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001031// Test that we can enable NACK with opus as callee.
1032TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1033 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1034 channel_ = engine_.CreateChannel();
1035 EXPECT_TRUE(channel_ != NULL);
1036
1037 int channel_num = voe_.GetLastChannel();
1038 std::vector<cricket::AudioCodec> codecs;
1039 codecs.push_back(kOpusCodec);
1040 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1041 cricket::kParamValueEmpty));
1042 EXPECT_FALSE(voe_.GetNACK(channel_num));
1043 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1044 EXPECT_FALSE(voe_.GetNACK(channel_num));
1045
1046 EXPECT_TRUE(channel_->AddSendStream(
1047 cricket::StreamParams::CreateLegacy(kSsrc1)));
1048 EXPECT_TRUE(voe_.GetNACK(channel_num));
1049}
1050
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001051// Test that we can enable NACK on receive streams.
1052TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1053 EXPECT_TRUE(SetupEngine());
1054 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1055 int channel_num1 = voe_.GetLastChannel();
1056 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1057 int channel_num2 = voe_.GetLastChannel();
1058 std::vector<cricket::AudioCodec> codecs;
1059 codecs.push_back(kOpusCodec);
1060 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1061 cricket::kParamValueEmpty));
1062 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1063 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1064 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1065 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1066 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1067}
1068
1069// Test that we can disable NACK.
1070TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1071 EXPECT_TRUE(SetupEngine());
1072 int channel_num = voe_.GetLastChannel();
1073 std::vector<cricket::AudioCodec> codecs;
1074 codecs.push_back(kOpusCodec);
1075 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1076 cricket::kParamValueEmpty));
1077 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1078 EXPECT_TRUE(voe_.GetNACK(channel_num));
1079
1080 codecs.clear();
1081 codecs.push_back(kOpusCodec);
1082 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1083 EXPECT_FALSE(voe_.GetNACK(channel_num));
1084}
1085
1086// Test that we can disable NACK on receive streams.
1087TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1088 EXPECT_TRUE(SetupEngine());
1089 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1090 int channel_num1 = voe_.GetLastChannel();
1091 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1092 int channel_num2 = voe_.GetLastChannel();
1093 std::vector<cricket::AudioCodec> codecs;
1094 codecs.push_back(kOpusCodec);
1095 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1096 cricket::kParamValueEmpty));
1097 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1098 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1099 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1100
1101 codecs.clear();
1102 codecs.push_back(kOpusCodec);
1103 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1104 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1105 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1106}
1107
1108// Test that NACK is enabled on a new receive stream.
1109TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1110 EXPECT_TRUE(SetupEngine());
1111 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1112 int channel_num = voe_.GetLastChannel();
1113 std::vector<cricket::AudioCodec> codecs;
1114 codecs.push_back(kIsacCodec);
1115 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1116 cricket::kParamValueEmpty));
1117 codecs.push_back(kCn16000Codec);
1118 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1119 EXPECT_TRUE(voe_.GetNACK(channel_num));
1120
1121 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1122 channel_num = voe_.GetLastChannel();
1123 EXPECT_TRUE(voe_.GetNACK(channel_num));
1124 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1125 channel_num = voe_.GetLastChannel();
1126 EXPECT_TRUE(voe_.GetNACK(channel_num));
1127}
1128
1129// Test that we can apply CELT with stereo mode but fail with mono mode.
1130TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1131 EXPECT_TRUE(SetupEngine());
1132 int channel_num = voe_.GetLastChannel();
1133 std::vector<cricket::AudioCodec> codecs;
1134 codecs.push_back(kCeltCodec);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001135 codecs.push_back(kIsacCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001136 codecs[0].id = 96;
1137 codecs[0].channels = 2;
1138 codecs[0].bitrate = 96000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001139 codecs[1].bitrate = 64000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1141 webrtc::CodecInst gcodec;
1142 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1143 EXPECT_EQ(96, gcodec.pltype);
1144 EXPECT_EQ(96000, gcodec.rate);
1145 EXPECT_EQ(2, gcodec.channels);
1146 EXPECT_STREQ("CELT", gcodec.plname);
1147 // Doesn't support mono, expect it to fall back to the next codec in the list.
1148 codecs[0].channels = 1;
1149 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1150 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001151 EXPECT_EQ(103, gcodec.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001152 EXPECT_EQ(1, gcodec.channels);
1153 EXPECT_EQ(64000, gcodec.rate);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001154 EXPECT_STREQ("ISAC", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001155}
1156
1157// Test that we can switch back and forth between CELT and ISAC with CN.
1158TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1159 EXPECT_TRUE(SetupEngine());
1160 int channel_num = voe_.GetLastChannel();
1161 std::vector<cricket::AudioCodec> celt_codecs;
1162 celt_codecs.push_back(kCeltCodec);
1163 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1164 webrtc::CodecInst gcodec;
1165 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1166 EXPECT_EQ(110, gcodec.pltype);
1167 EXPECT_STREQ("CELT", gcodec.plname);
1168
1169 std::vector<cricket::AudioCodec> isac_codecs;
1170 isac_codecs.push_back(kIsacCodec);
1171 isac_codecs.push_back(kCn16000Codec);
1172 isac_codecs.push_back(kCeltCodec);
1173 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1174 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1175 EXPECT_EQ(103, gcodec.pltype);
1176 EXPECT_STREQ("ISAC", gcodec.plname);
1177
1178 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1179 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1180 EXPECT_EQ(110, gcodec.pltype);
1181 EXPECT_STREQ("CELT", gcodec.plname);
1182}
1183
1184// Test that we handle various ways of specifying bitrate.
1185TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1186 EXPECT_TRUE(SetupEngine());
1187 int channel_num = voe_.GetLastChannel();
1188 std::vector<cricket::AudioCodec> codecs;
1189 codecs.push_back(kIsacCodec); // bitrate == 32000
1190 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1191 webrtc::CodecInst gcodec;
1192 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1193 EXPECT_EQ(103, gcodec.pltype);
1194 EXPECT_STREQ("ISAC", gcodec.plname);
1195 EXPECT_EQ(32000, gcodec.rate);
1196
1197 codecs[0].bitrate = 0; // bitrate == default
1198 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1199 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1200 EXPECT_EQ(103, gcodec.pltype);
1201 EXPECT_STREQ("ISAC", gcodec.plname);
1202 EXPECT_EQ(-1, gcodec.rate);
1203
1204 codecs[0].bitrate = 28000; // bitrate == 28000
1205 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1206 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1207 EXPECT_EQ(103, gcodec.pltype);
1208 EXPECT_STREQ("ISAC", gcodec.plname);
1209 EXPECT_EQ(28000, gcodec.rate);
1210
1211 codecs[0] = kPcmuCodec; // bitrate == 64000
1212 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1213 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1214 EXPECT_EQ(0, gcodec.pltype);
1215 EXPECT_STREQ("PCMU", gcodec.plname);
1216 EXPECT_EQ(64000, gcodec.rate);
1217
1218 codecs[0].bitrate = 0; // bitrate == default
1219 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1220 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1221 EXPECT_EQ(0, gcodec.pltype);
1222 EXPECT_STREQ("PCMU", gcodec.plname);
1223 EXPECT_EQ(64000, gcodec.rate);
1224
1225 codecs[0] = kOpusCodec;
1226 codecs[0].bitrate = 0; // bitrate == default
1227 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1228 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1229 EXPECT_EQ(111, gcodec.pltype);
1230 EXPECT_STREQ("opus", gcodec.plname);
1231 EXPECT_EQ(32000, gcodec.rate);
1232}
1233
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001234// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001235TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1236 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001237 std::vector<cricket::AudioCodec> codecs;
1238 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1239}
1240
1241// Test that we can set send codecs even with telephone-event codec as the first
1242// one on the list.
1243TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1244 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001245 int channel_num = voe_.GetLastChannel();
1246 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001247 codecs.push_back(kTelephoneEventCodec);
1248 codecs.push_back(kIsacCodec);
1249 codecs.push_back(kPcmuCodec);
1250 codecs[0].id = 98; // DTMF
1251 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001252 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1253 webrtc::CodecInst gcodec;
1254 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001255 EXPECT_EQ(96, gcodec.pltype);
1256 EXPECT_STREQ("ISAC", gcodec.plname);
1257 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1258}
1259
1260// Test that we can set send codecs even with CN codec as the first
1261// one on the list.
1262TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1263 EXPECT_TRUE(SetupEngine());
1264 int channel_num = voe_.GetLastChannel();
1265 std::vector<cricket::AudioCodec> codecs;
1266 codecs.push_back(kCn16000Codec);
1267 codecs.push_back(kIsacCodec);
1268 codecs.push_back(kPcmuCodec);
1269 codecs[0].id = 98; // wideband CN
1270 codecs[1].id = 96;
1271 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1272 webrtc::CodecInst gcodec;
1273 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1274 EXPECT_EQ(96, gcodec.pltype);
1275 EXPECT_STREQ("ISAC", gcodec.plname);
1276 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001277}
1278
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001279// Test that we set VAD and DTMF types correctly as caller.
1280TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001281 EXPECT_TRUE(SetupEngine());
1282 int channel_num = voe_.GetLastChannel();
1283 std::vector<cricket::AudioCodec> codecs;
1284 codecs.push_back(kIsacCodec);
1285 codecs.push_back(kPcmuCodec);
1286 // TODO(juberti): cn 32000
1287 codecs.push_back(kCn16000Codec);
1288 codecs.push_back(kCn8000Codec);
1289 codecs.push_back(kTelephoneEventCodec);
1290 codecs.push_back(kRedCodec);
1291 codecs[0].id = 96;
1292 codecs[2].id = 97; // wideband CN
1293 codecs[4].id = 98; // DTMF
1294 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1295 webrtc::CodecInst gcodec;
1296 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1297 EXPECT_EQ(96, gcodec.pltype);
1298 EXPECT_STREQ("ISAC", gcodec.plname);
1299 EXPECT_TRUE(voe_.GetVAD(channel_num));
1300 EXPECT_FALSE(voe_.GetFEC(channel_num));
1301 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1302 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1303 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1304}
1305
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001306// Test that we set VAD and DTMF types correctly as callee.
1307TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1308 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1309 channel_ = engine_.CreateChannel();
1310 EXPECT_TRUE(channel_ != NULL);
1311
1312 int channel_num = voe_.GetLastChannel();
1313 std::vector<cricket::AudioCodec> codecs;
1314 codecs.push_back(kIsacCodec);
1315 codecs.push_back(kPcmuCodec);
1316 // TODO(juberti): cn 32000
1317 codecs.push_back(kCn16000Codec);
1318 codecs.push_back(kCn8000Codec);
1319 codecs.push_back(kTelephoneEventCodec);
1320 codecs.push_back(kRedCodec);
1321 codecs[0].id = 96;
1322 codecs[2].id = 97; // wideband CN
1323 codecs[4].id = 98; // DTMF
1324 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1325 EXPECT_TRUE(channel_->AddSendStream(
1326 cricket::StreamParams::CreateLegacy(kSsrc1)));
1327
1328 webrtc::CodecInst gcodec;
1329 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1330 EXPECT_EQ(96, gcodec.pltype);
1331 EXPECT_STREQ("ISAC", gcodec.plname);
1332 EXPECT_TRUE(voe_.GetVAD(channel_num));
1333 EXPECT_FALSE(voe_.GetFEC(channel_num));
1334 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1335 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1336 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1337}
1338
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001339// Test that we only apply VAD if we have a CN codec that matches the
1340// send codec clockrate.
1341TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1342 EXPECT_TRUE(SetupEngine());
1343 int channel_num = voe_.GetLastChannel();
1344 std::vector<cricket::AudioCodec> codecs;
1345 // Set ISAC(16K) and CN(16K). VAD should be activated.
1346 codecs.push_back(kIsacCodec);
1347 codecs.push_back(kCn16000Codec);
1348 codecs[1].id = 97;
1349 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1350 webrtc::CodecInst gcodec;
1351 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1352 EXPECT_STREQ("ISAC", gcodec.plname);
1353 EXPECT_TRUE(voe_.GetVAD(channel_num));
1354 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1355 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1356 codecs[0] = kPcmuCodec;
1357 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1358 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1359 EXPECT_STREQ("PCMU", gcodec.plname);
1360 EXPECT_FALSE(voe_.GetVAD(channel_num));
1361 // Set PCMU(8K) and CN(8K). VAD should be activated.
1362 codecs[1] = kCn8000Codec;
1363 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1364 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1365 EXPECT_STREQ("PCMU", gcodec.plname);
1366 EXPECT_TRUE(voe_.GetVAD(channel_num));
1367 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1368 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1369 codecs[0] = kIsacCodec;
1370 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1371 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1372 EXPECT_STREQ("ISAC", gcodec.plname);
1373 EXPECT_FALSE(voe_.GetVAD(channel_num));
1374}
1375
1376// Test that we perform case-insensitive matching of codec names.
1377TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1378 EXPECT_TRUE(SetupEngine());
1379 int channel_num = voe_.GetLastChannel();
1380 std::vector<cricket::AudioCodec> codecs;
1381 codecs.push_back(kIsacCodec);
1382 codecs.push_back(kPcmuCodec);
1383 codecs.push_back(kCn16000Codec);
1384 codecs.push_back(kCn8000Codec);
1385 codecs.push_back(kTelephoneEventCodec);
1386 codecs.push_back(kRedCodec);
1387 codecs[0].name = "iSaC";
1388 codecs[0].id = 96;
1389 codecs[2].id = 97; // wideband CN
1390 codecs[4].id = 98; // DTMF
1391 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1392 webrtc::CodecInst gcodec;
1393 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1394 EXPECT_EQ(96, gcodec.pltype);
1395 EXPECT_STREQ("ISAC", gcodec.plname);
1396 EXPECT_TRUE(voe_.GetVAD(channel_num));
1397 EXPECT_FALSE(voe_.GetFEC(channel_num));
1398 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1399 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1400 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1401}
1402
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001403// Test that we set up FEC correctly as caller.
1404TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001405 EXPECT_TRUE(SetupEngine());
1406 int channel_num = voe_.GetLastChannel();
1407 std::vector<cricket::AudioCodec> codecs;
1408 codecs.push_back(kRedCodec);
1409 codecs.push_back(kIsacCodec);
1410 codecs.push_back(kPcmuCodec);
1411 codecs[0].id = 127;
1412 codecs[0].params[""] = "96/96";
1413 codecs[1].id = 96;
1414 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1415 webrtc::CodecInst gcodec;
1416 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1417 EXPECT_EQ(96, gcodec.pltype);
1418 EXPECT_STREQ("ISAC", gcodec.plname);
1419 EXPECT_TRUE(voe_.GetFEC(channel_num));
1420 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1421}
1422
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001423// Test that we set up FEC correctly as callee.
1424TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1425 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
1426 channel_ = engine_.CreateChannel();
1427 EXPECT_TRUE(channel_ != NULL);
1428
1429 int channel_num = voe_.GetLastChannel();
1430 std::vector<cricket::AudioCodec> codecs;
1431 codecs.push_back(kRedCodec);
1432 codecs.push_back(kIsacCodec);
1433 codecs.push_back(kPcmuCodec);
1434 codecs[0].id = 127;
1435 codecs[0].params[""] = "96/96";
1436 codecs[1].id = 96;
1437 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1438 EXPECT_TRUE(channel_->AddSendStream(
1439 cricket::StreamParams::CreateLegacy(kSsrc1)));
1440 webrtc::CodecInst gcodec;
1441 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1442 EXPECT_EQ(96, gcodec.pltype);
1443 EXPECT_STREQ("ISAC", gcodec.plname);
1444 EXPECT_TRUE(voe_.GetFEC(channel_num));
1445 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1446}
1447
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448// Test that we set up FEC correctly if params are omitted.
1449TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1450 EXPECT_TRUE(SetupEngine());
1451 int channel_num = voe_.GetLastChannel();
1452 std::vector<cricket::AudioCodec> codecs;
1453 codecs.push_back(kRedCodec);
1454 codecs.push_back(kIsacCodec);
1455 codecs.push_back(kPcmuCodec);
1456 codecs[0].id = 127;
1457 codecs[1].id = 96;
1458 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1459 webrtc::CodecInst gcodec;
1460 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1461 EXPECT_EQ(96, gcodec.pltype);
1462 EXPECT_STREQ("ISAC", gcodec.plname);
1463 EXPECT_TRUE(voe_.GetFEC(channel_num));
1464 EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
1465}
1466
1467// Test that we ignore RED if the parameters aren't named the way we expect.
1468TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1469 EXPECT_TRUE(SetupEngine());
1470 int channel_num = voe_.GetLastChannel();
1471 std::vector<cricket::AudioCodec> codecs;
1472 codecs.push_back(kRedCodec);
1473 codecs.push_back(kIsacCodec);
1474 codecs.push_back(kPcmuCodec);
1475 codecs[0].id = 127;
1476 codecs[0].params["ABC"] = "96/96";
1477 codecs[1].id = 96;
1478 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1479 webrtc::CodecInst gcodec;
1480 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1481 EXPECT_EQ(96, gcodec.pltype);
1482 EXPECT_STREQ("ISAC", gcodec.plname);
1483 EXPECT_FALSE(voe_.GetFEC(channel_num));
1484}
1485
1486// Test that we ignore RED if it uses different primary/secondary encoding.
1487TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1488 EXPECT_TRUE(SetupEngine());
1489 int channel_num = voe_.GetLastChannel();
1490 std::vector<cricket::AudioCodec> codecs;
1491 codecs.push_back(kRedCodec);
1492 codecs.push_back(kIsacCodec);
1493 codecs.push_back(kPcmuCodec);
1494 codecs[0].id = 127;
1495 codecs[0].params[""] = "96/0";
1496 codecs[1].id = 96;
1497 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1498 webrtc::CodecInst gcodec;
1499 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1500 EXPECT_EQ(96, gcodec.pltype);
1501 EXPECT_STREQ("ISAC", gcodec.plname);
1502 EXPECT_FALSE(voe_.GetFEC(channel_num));
1503}
1504
1505// Test that we ignore RED if it uses more than 2 encodings.
1506TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1507 EXPECT_TRUE(SetupEngine());
1508 int channel_num = voe_.GetLastChannel();
1509 std::vector<cricket::AudioCodec> codecs;
1510 codecs.push_back(kRedCodec);
1511 codecs.push_back(kIsacCodec);
1512 codecs.push_back(kPcmuCodec);
1513 codecs[0].id = 127;
1514 codecs[0].params[""] = "96/96/96";
1515 codecs[1].id = 96;
1516 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1517 webrtc::CodecInst gcodec;
1518 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1519 EXPECT_EQ(96, gcodec.pltype);
1520 EXPECT_STREQ("ISAC", gcodec.plname);
1521 EXPECT_FALSE(voe_.GetFEC(channel_num));
1522}
1523
1524// Test that we ignore RED if it has bogus codec ids.
1525TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1526 EXPECT_TRUE(SetupEngine());
1527 int channel_num = voe_.GetLastChannel();
1528 std::vector<cricket::AudioCodec> codecs;
1529 codecs.push_back(kRedCodec);
1530 codecs.push_back(kIsacCodec);
1531 codecs.push_back(kPcmuCodec);
1532 codecs[0].id = 127;
1533 codecs[0].params[""] = "ABC/ABC";
1534 codecs[1].id = 96;
1535 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1536 webrtc::CodecInst gcodec;
1537 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1538 EXPECT_EQ(96, gcodec.pltype);
1539 EXPECT_STREQ("ISAC", gcodec.plname);
1540 EXPECT_FALSE(voe_.GetFEC(channel_num));
1541}
1542
1543// Test that we ignore RED if it refers to a codec that is not present.
1544TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1545 EXPECT_TRUE(SetupEngine());
1546 int channel_num = voe_.GetLastChannel();
1547 std::vector<cricket::AudioCodec> codecs;
1548 codecs.push_back(kRedCodec);
1549 codecs.push_back(kIsacCodec);
1550 codecs.push_back(kPcmuCodec);
1551 codecs[0].id = 127;
1552 codecs[0].params[""] = "97/97";
1553 codecs[1].id = 96;
1554 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1555 webrtc::CodecInst gcodec;
1556 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1557 EXPECT_EQ(96, gcodec.pltype);
1558 EXPECT_STREQ("ISAC", gcodec.plname);
1559 EXPECT_FALSE(voe_.GetFEC(channel_num));
1560}
1561
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562// Test that we support setting certain send header extensions.
1563TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
1564 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001565 TestSetSendRtpHeaderExtensions(voe_.GetLastChannel());
1566}
1567
1568// Test that we support setting recv header extensions.
1569TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
1570 EXPECT_TRUE(SetupEngine());
1571 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1572 TestSetRecvRtpHeaderExtensions(voe_.GetLastChannel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573}
1574
1575// Test that we can create a channel and start sending/playing out on it.
1576TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1577 EXPECT_TRUE(SetupEngine());
1578 int channel_num = voe_.GetLastChannel();
1579 std::vector<cricket::AudioCodec> codecs;
1580 codecs.push_back(kPcmuCodec);
1581 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1582 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1583 EXPECT_TRUE(voe_.GetSend(channel_num));
1584 EXPECT_TRUE(channel_->SetPlayout(true));
1585 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1586 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1587 EXPECT_FALSE(voe_.GetSend(channel_num));
1588 EXPECT_TRUE(channel_->SetPlayout(false));
1589 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1590}
1591
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001592// Test that we can add and remove send streams.
1593TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1594 SetupForMultiSendStream();
1595
1596 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1597
1598 // Set the global state for sending.
1599 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1600
1601 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1602 EXPECT_TRUE(channel_->AddSendStream(
1603 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1604
1605 // Verify that we are in a sending state for all the created streams.
1606 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1607 EXPECT_TRUE(voe_.GetSend(channel_num));
1608 }
1609
1610 // Remove the first send channel, which is the default channel. It will only
1611 // recycle the default channel but not delete it.
1612 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1613 // Stream should already be Removed from the send stream list.
1614 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1615 // But the default still exists.
1616 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1617
1618 // Delete the rest of send channel streams.
1619 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1620 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1621 // Stream should already be deleted.
1622 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1623 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1624 }
1625}
1626
1627// Test SetSendCodecs correctly configure the codecs in all send streams.
1628TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1629 SetupForMultiSendStream();
1630
1631 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1632 // Create send streams.
1633 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1634 EXPECT_TRUE(channel_->AddSendStream(
1635 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1636 }
1637
1638 std::vector<cricket::AudioCodec> codecs;
1639 // Set ISAC(16K) and CN(16K). VAD should be activated.
1640 codecs.push_back(kIsacCodec);
1641 codecs.push_back(kCn16000Codec);
1642 codecs[1].id = 97;
1643 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1644
1645 // Verify ISAC and VAD are corrected configured on all send channels.
1646 webrtc::CodecInst gcodec;
1647 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1648 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1649 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1650 EXPECT_STREQ("ISAC", gcodec.plname);
1651 EXPECT_TRUE(voe_.GetVAD(channel_num));
1652 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1653 }
1654
1655 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1656 codecs[0] = kPcmuCodec;
1657 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1658 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1659 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1660 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1661 EXPECT_STREQ("PCMU", gcodec.plname);
1662 EXPECT_FALSE(voe_.GetVAD(channel_num));
1663 }
1664}
1665
1666// Test we can SetSend on all send streams correctly.
1667TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1668 SetupForMultiSendStream();
1669
1670 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1671 // Create the send channels and they should be a SEND_NOTHING date.
1672 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1673 EXPECT_TRUE(channel_->AddSendStream(
1674 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1675 int channel_num = voe_.GetLastChannel();
1676 EXPECT_FALSE(voe_.GetSend(channel_num));
1677 }
1678
1679 // Set the global state for starting sending.
1680 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1681 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1682 // Verify that we are in a sending state for all the send streams.
1683 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1684 EXPECT_TRUE(voe_.GetSend(channel_num));
1685 }
1686
1687 // Set the global state for stopping sending.
1688 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1689 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1690 // Verify that we are in a stop state for all the send streams.
1691 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1692 EXPECT_FALSE(voe_.GetSend(channel_num));
1693 }
1694}
1695
1696// Test we can set the correct statistics on all send streams.
1697TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1698 SetupForMultiSendStream();
1699
1700 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1701 // Create send streams.
1702 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1703 EXPECT_TRUE(channel_->AddSendStream(
1704 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1705 }
1706
1707 // We need send codec to be set to get all stats.
1708 std::vector<cricket::AudioCodec> codecs;
1709 codecs.push_back(kPcmuCodec);
1710 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1711
1712 cricket::VoiceMediaInfo info;
1713 EXPECT_EQ(true, channel_->GetStats(&info));
1714 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1715
1716 // Verify the statistic information is correct.
1717 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001718 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001719 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1720 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1721 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1722 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1723 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1724 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1725 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1726 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1727 }
1728
1729 EXPECT_EQ(1u, info.receivers.size());
1730}
1731
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001732// Test that we support setting header extensions on multiple send streams.
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001733TEST_F(WebRtcVoiceEngineTestFake,
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001734 SetSendRtpHeaderExtensionsWithMultipleSendStreams) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001735 SetupForMultiSendStream();
1736
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001737 static const uint32 kSsrcs[] = {1, 2, 3, 4};
1738 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001739 EXPECT_TRUE(channel_->AddSendStream(
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001740 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001741 }
1742
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001743 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1744 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs[i]);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001745 TestSetSendRtpHeaderExtensions(channel_num);
1746 }
1747}
1748
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001749// Test that we support setting header extensions on multiple receive streams.
1750TEST_F(WebRtcVoiceEngineTestFake,
1751 SetRecvRtpHeaderExtensionsWithMultipleRecvStreams) {
1752 EXPECT_TRUE(SetupEngine());
1753
1754 static const uint32 kSsrcs[] = {1, 2, 3, 4};
1755 int channel_ids[ARRAY_SIZE(kSsrcs)] = {0};
1756 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1757 EXPECT_TRUE(channel_->AddRecvStream(
1758 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
1759 channel_ids[i] = voe_.GetLastChannel();
1760 }
1761
1762 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
1763 TestSetRecvRtpHeaderExtensions(channel_ids[i]);
1764 }
1765}
1766
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001767// Test that we can add and remove receive streams, and do proper send/playout.
1768// We can receive on multiple streams while sending one stream.
1769TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770 EXPECT_TRUE(SetupEngine());
1771 int channel_num1 = voe_.GetLastChannel();
1772
1773 // Start playout on the default channel.
1774 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1775 EXPECT_TRUE(channel_->SetPlayout(true));
1776 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1777
1778 // Adding another stream should disable playout on the default channel.
1779 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1780 int channel_num2 = voe_.GetLastChannel();
1781 std::vector<cricket::AudioCodec> codecs;
1782 codecs.push_back(kPcmuCodec);
1783 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1784 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1785 EXPECT_TRUE(voe_.GetSend(channel_num1));
1786 EXPECT_FALSE(voe_.GetSend(channel_num2));
1787
1788 // Make sure only the new channel is played out.
1789 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1790 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1791
1792 // Adding yet another stream should have stream 2 and 3 enabled for playout.
1793 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1794 int channel_num3 = voe_.GetLastChannel();
1795 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1796 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1797 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1798 EXPECT_FALSE(voe_.GetSend(channel_num3));
1799
1800 // Stop sending.
1801 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1802 EXPECT_FALSE(voe_.GetSend(channel_num1));
1803 EXPECT_FALSE(voe_.GetSend(channel_num2));
1804 EXPECT_FALSE(voe_.GetSend(channel_num3));
1805
1806 // Stop playout.
1807 EXPECT_TRUE(channel_->SetPlayout(false));
1808 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1809 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1810 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1811
1812 // Restart playout and make sure the default channel still is not played out.
1813 EXPECT_TRUE(channel_->SetPlayout(true));
1814 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1815 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1816 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1817
1818 // Now remove the new streams and verify that the default channel is
1819 // played out again.
1820 EXPECT_TRUE(channel_->RemoveRecvStream(3));
1821 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1822
1823 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1824}
1825
1826// Test that we can set the devices to use.
1827TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1828 EXPECT_TRUE(SetupEngine());
1829 int channel_num = voe_.GetLastChannel();
1830 std::vector<cricket::AudioCodec> codecs;
1831 codecs.push_back(kPcmuCodec);
1832 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1833
1834 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1835 cricket::kFakeDefaultDeviceId);
1836 cricket::Device dev(cricket::kFakeDeviceName,
1837 cricket::kFakeDeviceId);
1838
1839 // Test SetDevices() while not sending or playing.
1840 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1841
1842 // Test SetDevices() while sending and playing.
1843 EXPECT_TRUE(engine_.SetLocalMonitor(true));
1844 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1845 EXPECT_TRUE(channel_->SetPlayout(true));
1846 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1847 EXPECT_TRUE(voe_.GetSend(channel_num));
1848 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1849
1850 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1851
1852 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1853 EXPECT_TRUE(voe_.GetSend(channel_num));
1854 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1855
1856 // Test that failure to open newly selected devices does not prevent opening
1857 // ones after that.
1858 voe_.set_fail_start_recording_microphone(true);
1859 voe_.set_playout_fail_channel(channel_num);
1860 voe_.set_send_fail_channel(channel_num);
1861
1862 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1863
1864 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1865 EXPECT_FALSE(voe_.GetSend(channel_num));
1866 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1867
1868 voe_.set_fail_start_recording_microphone(false);
1869 voe_.set_playout_fail_channel(-1);
1870 voe_.set_send_fail_channel(-1);
1871
1872 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1873
1874 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1875 EXPECT_TRUE(voe_.GetSend(channel_num));
1876 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1877}
1878
1879// Test that we can set the devices to use even if we failed to
1880// open the initial ones.
1881TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1882 EXPECT_TRUE(SetupEngine());
1883 int channel_num = voe_.GetLastChannel();
1884 std::vector<cricket::AudioCodec> codecs;
1885 codecs.push_back(kPcmuCodec);
1886 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1887
1888 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1889 cricket::kFakeDefaultDeviceId);
1890 cricket::Device dev(cricket::kFakeDeviceName,
1891 cricket::kFakeDeviceId);
1892
1893 // Test that failure to open devices selected before starting
1894 // send/play does not prevent opening newly selected ones after that.
1895 voe_.set_fail_start_recording_microphone(true);
1896 voe_.set_playout_fail_channel(channel_num);
1897 voe_.set_send_fail_channel(channel_num);
1898
1899 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1900
1901 EXPECT_FALSE(engine_.SetLocalMonitor(true));
1902 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
1903 EXPECT_FALSE(channel_->SetPlayout(true));
1904 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1905 EXPECT_FALSE(voe_.GetSend(channel_num));
1906 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1907
1908 voe_.set_fail_start_recording_microphone(false);
1909 voe_.set_playout_fail_channel(-1);
1910 voe_.set_send_fail_channel(-1);
1911
1912 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1913
1914 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1915 EXPECT_TRUE(voe_.GetSend(channel_num));
1916 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1917}
1918
1919// Test that we can create a channel configured for multi-point conferences,
1920// and start sending/playing out on it.
1921TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
1922 EXPECT_TRUE(SetupEngine());
1923 int channel_num = voe_.GetLastChannel();
1924 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1925 std::vector<cricket::AudioCodec> codecs;
1926 codecs.push_back(kPcmuCodec);
1927 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1928 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1929 EXPECT_TRUE(voe_.GetSend(channel_num));
1930}
1931
1932// Test that we can create a channel configured for Codian bridges,
1933// and start sending/playing out on it.
1934TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
1935 EXPECT_TRUE(SetupEngine());
1936 int channel_num = voe_.GetLastChannel();
1937 webrtc::AgcConfig agc_config;
1938 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1939 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1940 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
1941 std::vector<cricket::AudioCodec> codecs;
1942 codecs.push_back(kPcmuCodec);
1943 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1944 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1945 EXPECT_TRUE(voe_.GetSend(channel_num));
1946 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1947 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
1948 EXPECT_TRUE(channel_->SetPlayout(true));
1949 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1950 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1951 EXPECT_FALSE(voe_.GetSend(channel_num));
1952 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1953 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
1954 EXPECT_TRUE(channel_->SetPlayout(false));
1955 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1956}
1957
wu@webrtc.org97077a32013-10-25 21:18:33 +00001958TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
1959 EXPECT_TRUE(SetupEngine());
1960 webrtc::AgcConfig agc_config;
1961 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1962 EXPECT_EQ(0, agc_config.targetLeveldBOv);
1963
1964 cricket::AudioOptions options;
1965 options.tx_agc_target_dbov.Set(3);
1966 options.tx_agc_digital_compression_gain.Set(9);
1967 options.tx_agc_limiter.Set(true);
1968 options.auto_gain_control.Set(true);
1969 EXPECT_TRUE(engine_.SetOptions(options));
1970
1971 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1972 EXPECT_EQ(3, agc_config.targetLeveldBOv);
1973 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
1974 EXPECT_TRUE(agc_config.limiterEnable);
1975
1976 // Check interaction with adjust_agc_delta. Both should be respected, for
1977 // backwards compatibility.
1978 options.adjust_agc_delta.Set(-10);
1979 EXPECT_TRUE(engine_.SetOptions(options));
1980
1981 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
1982 EXPECT_EQ(13, agc_config.targetLeveldBOv);
1983}
1984
1985TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
1986 EXPECT_TRUE(SetupEngine());
1987 int channel_num = voe_.GetLastChannel();
1988 cricket::AudioOptions options;
1989 options.rx_agc_target_dbov.Set(6);
1990 options.rx_agc_digital_compression_gain.Set(0);
1991 options.rx_agc_limiter.Set(true);
1992 options.rx_auto_gain_control.Set(true);
1993 EXPECT_TRUE(channel_->SetOptions(options));
1994
1995 webrtc::AgcConfig agc_config;
1996 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
1997 channel_num, agc_config));
1998 EXPECT_EQ(6, agc_config.targetLeveldBOv);
1999 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2000 EXPECT_TRUE(agc_config.limiterEnable);
2001}
2002
2003TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2004 EXPECT_TRUE(SetupEngine());
2005 cricket::AudioOptions options;
2006 options.recording_sample_rate.Set(48000u);
2007 options.playout_sample_rate.Set(44100u);
2008 EXPECT_TRUE(engine_.SetOptions(options));
2009
2010 unsigned int recording_sample_rate, playout_sample_rate;
2011 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2012 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2013 EXPECT_EQ(48000u, recording_sample_rate);
2014 EXPECT_EQ(44100u, playout_sample_rate);
2015}
2016
2017TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2018 EXPECT_TRUE(SetupEngine());
2019 engine_.SetLogging(talk_base::LS_INFO, "");
2020 EXPECT_EQ(
2021 // Info:
2022 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2023 // Warning:
2024 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2025 // Error:
2026 webrtc::kTraceError | webrtc::kTraceCritical,
2027 static_cast<int>(trace_wrapper_->filter_));
2028 // Now set it explicitly
2029 std::string filter =
2030 "tracefilter " + talk_base::ToString(webrtc::kTraceDefault);
2031 engine_.SetLogging(talk_base::LS_VERBOSE, filter.c_str());
2032 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2033 trace_wrapper_->filter_);
2034}
2035
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002036// Test that we can set the outgoing SSRC properly.
2037// SSRC is set in SetupEngine by calling AddSendStream.
2038TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2039 EXPECT_TRUE(SetupEngine());
2040 int channel_num = voe_.GetLastChannel();
2041 unsigned int send_ssrc;
2042 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2043 EXPECT_NE(0U, send_ssrc);
2044 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2045 EXPECT_EQ(kSsrc1, send_ssrc);
2046}
2047
2048TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2049 // Setup. We need send codec to be set to get all stats.
2050 EXPECT_TRUE(SetupEngine());
2051 std::vector<cricket::AudioCodec> codecs;
2052 codecs.push_back(kPcmuCodec);
2053 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2054
2055 cricket::VoiceMediaInfo info;
2056 EXPECT_EQ(true, channel_->GetStats(&info));
2057 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002058 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2060 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2061 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2062 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2063 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2064 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2065 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2066 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
2067 // TODO(sriniv): Add testing for more fields. These are not populated
2068 // in FakeWebrtcVoiceEngine yet.
2069 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2070 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2071 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2072 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2073 // EXPECT_EQ(cricket::kIntStatValue,
2074 // info.senders[0].echo_return_loss_enhancement);
2075
2076 EXPECT_EQ(1u, info.receivers.size());
2077 // TODO(sriniv): Add testing for receiver fields.
2078}
2079
2080// Test that we can set the outgoing SSRC properly with multiple streams.
2081// SSRC is set in SetupEngine by calling AddSendStream.
2082TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2083 EXPECT_TRUE(SetupEngine());
2084 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2085 int channel_num1 = voe_.GetLastChannel();
2086 unsigned int send_ssrc;
2087 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2088 EXPECT_EQ(kSsrc1, send_ssrc);
2089
2090 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2091 int channel_num2 = voe_.GetLastChannel();
2092 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2093 EXPECT_EQ(kSsrc1, send_ssrc);
2094}
2095
2096// Test that the local SSRC is the same on sending and receiving channels if the
2097// receive channel is created before the send channel.
2098TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2099 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2100 channel_ = engine_.CreateChannel();
2101 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2102
2103 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2104 int receive_channel_num = voe_.GetLastChannel();
2105 EXPECT_TRUE(channel_->AddSendStream(
2106 cricket::StreamParams::CreateLegacy(1234)));
2107 int send_channel_num = voe_.GetLastChannel();
2108
2109 unsigned int ssrc = 0;
2110 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2111 EXPECT_EQ(1234U, ssrc);
2112 ssrc = 0;
2113 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2114 EXPECT_EQ(1234U, ssrc);
2115}
2116
2117// Test that we can properly receive packets.
2118TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2119 EXPECT_TRUE(SetupEngine());
2120 int channel_num = voe_.GetLastChannel();
2121 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2122 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2123 sizeof(kPcmuFrame)));
2124}
2125
2126// Test that we can properly receive packets on multiple streams.
2127TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2128 EXPECT_TRUE(SetupEngine());
2129 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2130 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2131 int channel_num1 = voe_.GetLastChannel();
2132 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2133 int channel_num2 = voe_.GetLastChannel();
2134 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2135 int channel_num3 = voe_.GetLastChannel();
2136 // Create packets with the right SSRCs.
2137 char packets[4][sizeof(kPcmuFrame)];
2138 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2139 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002140 talk_base::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002141 }
2142 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2143 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2144 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2145 DeliverPacket(packets[0], sizeof(packets[0]));
2146 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2147 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2148 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2149 DeliverPacket(packets[1], sizeof(packets[1]));
2150 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2151 sizeof(packets[1])));
2152 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2153 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2154 DeliverPacket(packets[2], sizeof(packets[2]));
2155 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2156 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2157 sizeof(packets[2])));
2158 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2159 DeliverPacket(packets[3], sizeof(packets[3]));
2160 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2161 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2162 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2163 sizeof(packets[3])));
2164 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2165 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2166 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2167}
2168
2169// Test that we properly handle failures to add a stream.
2170TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2171 EXPECT_TRUE(SetupEngine());
2172 voe_.set_fail_create_channel(true);
2173 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2174 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2175
2176 // In 1:1 call, we should not try to create a new channel.
2177 cricket::AudioOptions options_no_conference_;
2178 options_no_conference_.conference_mode.Set(false);
2179 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2180 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2181}
2182
2183// Test that AddRecvStream doesn't create new channel for 1:1 call.
2184TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2185 EXPECT_TRUE(SetupEngine());
2186 int channel_num = voe_.GetLastChannel();
2187 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2188 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2189}
2190
2191// Test that after adding a recv stream, we do not decode more codecs than
2192// those previously passed into SetRecvCodecs.
2193TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2194 EXPECT_TRUE(SetupEngine());
2195 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2196 std::vector<cricket::AudioCodec> codecs;
2197 codecs.push_back(kIsacCodec);
2198 codecs.push_back(kPcmuCodec);
2199 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2200 EXPECT_TRUE(channel_->AddRecvStream(
2201 cricket::StreamParams::CreateLegacy(kSsrc1)));
2202 int channel_num2 = voe_.GetLastChannel();
2203 webrtc::CodecInst gcodec;
2204 talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2205 gcodec.plfreq = 32000;
2206 gcodec.channels = 2;
2207 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2208}
2209
2210// Test that we properly clean up any streams that were added, even if
2211// not explicitly removed.
2212TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2213 EXPECT_TRUE(SetupEngine());
2214 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2215 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2216 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2217 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2218 delete channel_;
2219 channel_ = NULL;
2220 EXPECT_EQ(0, voe_.GetNumChannels());
2221}
2222
wu@webrtc.org78187522013-10-07 23:32:02 +00002223TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2224 EXPECT_TRUE(SetupEngine());
2225 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2226}
2227
2228TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2229 EXPECT_TRUE(SetupEngine());
2230 // Stream 1 reuses default channel.
2231 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2232 // Manually delete default channel to simulate a failure.
2233 int default_channel = voe_.GetLastChannel();
2234 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2235 // Add recv stream 2 should fail because default channel is gone.
2236 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2237 int new_channel = voe_.GetLastChannel();
2238 EXPECT_NE(default_channel, new_channel);
2239 // The last created channel should have already been deleted.
2240 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2241}
2242
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002243// Test the InsertDtmf on default send stream as caller.
2244TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2245 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002246}
2247
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002248// Test the InsertDtmf on default send stream as callee
2249TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2250 TestInsertDtmf(0, false);
2251}
2252
2253// Test the InsertDtmf on specified send stream as caller.
2254TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2255 TestInsertDtmf(kSsrc1, true);
2256}
2257
2258// Test the InsertDtmf on specified send stream as callee.
2259TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2260 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002261}
2262
2263// Test that we can play a ringback tone properly in a single-stream call.
2264TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2265 EXPECT_TRUE(SetupEngine());
2266 int channel_num = voe_.GetLastChannel();
2267 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2268 // Check we fail if no ringback tone specified.
2269 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2270 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2271 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002272 EXPECT_TRUE(channel_->SetRingbackTone(
2273 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2275 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2276 // Check we can stop the tone manually.
2277 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2278 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2279 // Check we stop the tone if a packet arrives.
2280 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2281 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2282 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2283 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2284}
2285
2286// Test that we can play a ringback tone properly in a multi-stream call.
2287TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2288 EXPECT_TRUE(SetupEngine());
2289 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2290 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2291 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2292 int channel_num = voe_.GetLastChannel();
2293 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2294 // Check we fail if no ringback tone specified.
2295 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2296 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2297 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002298 EXPECT_TRUE(channel_->SetRingbackTone(
2299 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2301 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2302 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2303 // Check we can stop the tone manually.
2304 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2305 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2306 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2307 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2308 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2309 // Send a packet with SSRC 1; the tone should not stop.
2310 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2311 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2312 // Send a packet with SSRC 2; the tone should stop.
2313 char packet[sizeof(kPcmuFrame)];
2314 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2315 talk_base::SetBE32(packet + 8, 2);
2316 DeliverPacket(packet, sizeof(packet));
2317 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2318}
2319
2320// Tests creating soundclips, and make sure they come from the right engine.
2321TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2322 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002323 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002324 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002325 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002326 ASSERT_TRUE(soundclip_ != NULL);
2327 EXPECT_EQ(0, voe_.GetNumChannels());
2328 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2329 int channel_num = voe_sc_.GetLastChannel();
2330 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2331 delete soundclip_;
2332 soundclip_ = NULL;
2333 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002334 // Make sure the soundclip engine is uninitialized on shutdown, now that
2335 // we've initialized it by creating a soundclip.
2336 engine_.Terminate();
2337 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002338}
2339
2340// Tests playing out a fake sound.
2341TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2342 static const char kZeroes[16000] = {};
2343 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2344 soundclip_ = engine_.CreateSoundclip();
2345 ASSERT_TRUE(soundclip_ != NULL);
2346 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2347}
2348
2349TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2350 talk_base::scoped_ptr<ChannelErrorListener> listener;
2351 cricket::WebRtcVoiceMediaChannel* media_channel;
2352 unsigned int ssrc = 0;
2353
2354 EXPECT_TRUE(SetupEngine());
2355 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2356 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2357
2358 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2359 listener.reset(new ChannelErrorListener(channel_));
2360
2361 // Test on WebRtc VoE channel.
2362 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2363 VE_SATURATION_WARNING);
2364 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2365 listener->error());
2366 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2367 EXPECT_EQ(ssrc, listener->ssrc());
2368
2369 listener->Reset();
2370 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2371 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2372 listener->error());
2373 EXPECT_EQ(0U, listener->ssrc());
2374
2375 // Add another stream and test on that.
2376 ++ssrc;
2377 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2378 ssrc)));
2379 listener->Reset();
2380 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2381 VE_SATURATION_WARNING);
2382 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2383 listener->error());
2384 EXPECT_EQ(ssrc, listener->ssrc());
2385
2386 // Testing a non-existing channel.
2387 listener->Reset();
2388 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2389 VE_SATURATION_WARNING);
2390 EXPECT_EQ(0, listener->error());
2391}
2392
2393TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2394 EXPECT_TRUE(SetupEngine());
2395 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2396 std::vector<cricket::AudioCodec> codecs;
2397 codecs.push_back(kPcmuCodec);
2398 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2399 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2400 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2401 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2402 EXPECT_TRUE(channel_->SetPlayout(true));
2403 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2404 EXPECT_TRUE(channel_->SetPlayout(false));
2405 EXPECT_FALSE(channel_->SetPlayout(true));
2406}
2407
2408// Test that the Registering/Unregistering with the
2409// webrtcvoiceengine works as expected
2410TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2411 EXPECT_TRUE(SetupEngine());
2412 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2413 EXPECT_TRUE(channel_->AddRecvStream(
2414 cricket::StreamParams::CreateLegacy(kSsrc2)));
2415 cricket::FakeMediaProcessor vp_1;
2416 cricket::FakeMediaProcessor vp_2;
2417
2418 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2419 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2420 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2421 voe_.TriggerProcessPacket(cricket::MPD_RX);
2422 voe_.TriggerProcessPacket(cricket::MPD_TX);
2423
2424 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2425 EXPECT_EQ(1, vp_1.voice_frame_count());
2426 EXPECT_EQ(1, vp_2.voice_frame_count());
2427
2428 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2429 &vp_2,
2430 cricket::MPD_RX));
2431 voe_.TriggerProcessPacket(cricket::MPD_RX);
2432 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2433 EXPECT_EQ(1, vp_2.voice_frame_count());
2434 EXPECT_EQ(2, vp_1.voice_frame_count());
2435
2436 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2437 &vp_1,
2438 cricket::MPD_RX));
2439 voe_.TriggerProcessPacket(cricket::MPD_RX);
2440 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2441 EXPECT_EQ(2, vp_1.voice_frame_count());
2442
2443 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2444 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2445 voe_.TriggerProcessPacket(cricket::MPD_RX);
2446 voe_.TriggerProcessPacket(cricket::MPD_TX);
2447 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2448 EXPECT_EQ(3, vp_1.voice_frame_count());
2449
2450 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2451 &vp_1,
2452 cricket::MPD_RX_AND_TX));
2453 voe_.TriggerProcessPacket(cricket::MPD_TX);
2454 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2455 EXPECT_EQ(3, vp_1.voice_frame_count());
2456 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2457 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2458 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2459
2460 // Test that we can register a processor on the receive channel on SSRC 0.
2461 // This tests the 1:1 case when the receive SSRC is unknown.
2462 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2463 voe_.TriggerProcessPacket(cricket::MPD_RX);
2464 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2465 EXPECT_EQ(4, vp_1.voice_frame_count());
2466 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2467 &vp_1,
2468 cricket::MPD_RX));
2469
2470 // The following tests test that FindChannelNumFromSsrc is doing
2471 // what we expect.
2472 // pick an invalid ssrc and make sure we can't register
2473 EXPECT_FALSE(engine_.RegisterProcessor(99,
2474 &vp_1,
2475 cricket::MPD_RX));
2476 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2477 EXPECT_TRUE(engine_.RegisterProcessor(1,
2478 &vp_1,
2479 cricket::MPD_RX));
2480 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2481 &vp_1,
2482 cricket::MPD_RX));
2483 EXPECT_FALSE(engine_.RegisterProcessor(1,
2484 &vp_1,
2485 cricket::MPD_TX));
2486 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2487}
2488
2489TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2490 EXPECT_TRUE(SetupEngine());
2491
2492 bool ec_enabled;
2493 webrtc::EcModes ec_mode;
2494 bool ec_metrics_enabled;
2495 webrtc::AecmModes aecm_mode;
2496 bool cng_enabled;
2497 bool agc_enabled;
2498 webrtc::AgcModes agc_mode;
2499 webrtc::AgcConfig agc_config;
2500 bool ns_enabled;
2501 webrtc::NsModes ns_mode;
2502 bool highpass_filter_enabled;
2503 bool stereo_swapping_enabled;
2504 bool typing_detection_enabled;
2505 voe_.GetEcStatus(ec_enabled, ec_mode);
2506 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2507 voe_.GetAecmMode(aecm_mode, cng_enabled);
2508 voe_.GetAgcStatus(agc_enabled, agc_mode);
2509 voe_.GetAgcConfig(agc_config);
2510 voe_.GetNsStatus(ns_enabled, ns_mode);
2511 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2512 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2513 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2514 EXPECT_TRUE(ec_enabled);
2515 EXPECT_TRUE(ec_metrics_enabled);
2516 EXPECT_FALSE(cng_enabled);
2517 EXPECT_TRUE(agc_enabled);
2518 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2519 EXPECT_TRUE(ns_enabled);
2520 EXPECT_TRUE(highpass_filter_enabled);
2521 EXPECT_FALSE(stereo_swapping_enabled);
2522 EXPECT_TRUE(typing_detection_enabled);
2523 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2524 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2525
2526 // Nothing set, so all ignored.
2527 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002528 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002529 voe_.GetEcStatus(ec_enabled, ec_mode);
2530 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2531 voe_.GetAecmMode(aecm_mode, cng_enabled);
2532 voe_.GetAgcStatus(agc_enabled, agc_mode);
2533 voe_.GetAgcConfig(agc_config);
2534 voe_.GetNsStatus(ns_enabled, ns_mode);
2535 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2536 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2537 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2538 EXPECT_TRUE(ec_enabled);
2539 EXPECT_TRUE(ec_metrics_enabled);
2540 EXPECT_FALSE(cng_enabled);
2541 EXPECT_TRUE(agc_enabled);
2542 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2543 EXPECT_TRUE(ns_enabled);
2544 EXPECT_TRUE(highpass_filter_enabled);
2545 EXPECT_FALSE(stereo_swapping_enabled);
2546 EXPECT_TRUE(typing_detection_enabled);
2547 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2548 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2549
2550 // Turn echo cancellation off
2551 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002552 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002553 voe_.GetEcStatus(ec_enabled, ec_mode);
2554 EXPECT_FALSE(ec_enabled);
2555
2556 // Turn echo cancellation back on, with settings, and make sure
2557 // nothing else changed.
2558 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002559 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002560 voe_.GetEcStatus(ec_enabled, ec_mode);
2561 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2562 voe_.GetAecmMode(aecm_mode, cng_enabled);
2563 voe_.GetAgcStatus(agc_enabled, agc_mode);
2564 voe_.GetAgcConfig(agc_config);
2565 voe_.GetNsStatus(ns_enabled, ns_mode);
2566 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2567 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2568 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2569 EXPECT_TRUE(ec_enabled);
2570 EXPECT_TRUE(ec_metrics_enabled);
2571 EXPECT_TRUE(agc_enabled);
2572 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2573 EXPECT_TRUE(ns_enabled);
2574 EXPECT_TRUE(highpass_filter_enabled);
2575 EXPECT_FALSE(stereo_swapping_enabled);
2576 EXPECT_TRUE(typing_detection_enabled);
2577 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2578 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2579
2580 // Turn off AGC
2581 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002582 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002583 voe_.GetAgcStatus(agc_enabled, agc_mode);
2584 EXPECT_FALSE(agc_enabled);
2585
2586 // Turn AGC back on
2587 options.auto_gain_control.Set(true);
2588 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002589 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002590 voe_.GetAgcStatus(agc_enabled, agc_mode);
2591 EXPECT_TRUE(agc_enabled);
2592 voe_.GetAgcConfig(agc_config);
2593 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2594
2595 // Turn off other options (and stereo swapping on).
2596 options.noise_suppression.Set(false);
2597 options.highpass_filter.Set(false);
2598 options.typing_detection.Set(false);
2599 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002600 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002601 voe_.GetNsStatus(ns_enabled, ns_mode);
2602 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2603 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2604 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2605 EXPECT_FALSE(ns_enabled);
2606 EXPECT_FALSE(highpass_filter_enabled);
2607 EXPECT_FALSE(typing_detection_enabled);
2608 EXPECT_TRUE(stereo_swapping_enabled);
2609
2610 // Turn on "conference mode" to ensure it has no impact.
2611 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002612 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613 voe_.GetEcStatus(ec_enabled, ec_mode);
2614 voe_.GetNsStatus(ns_enabled, ns_mode);
2615 EXPECT_TRUE(ec_enabled);
2616 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2617 EXPECT_FALSE(ns_enabled);
2618 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2619}
2620
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002621TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002622 EXPECT_TRUE(SetupEngine());
2623
2624 bool ec_enabled;
2625 webrtc::EcModes ec_mode;
2626 bool ec_metrics_enabled;
2627 bool agc_enabled;
2628 webrtc::AgcModes agc_mode;
2629 bool ns_enabled;
2630 webrtc::NsModes ns_mode;
2631 bool highpass_filter_enabled;
2632 bool stereo_swapping_enabled;
2633 bool typing_detection_enabled;
2634
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002635 voe_.GetEcStatus(ec_enabled, ec_mode);
2636 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2637 voe_.GetAgcStatus(agc_enabled, agc_mode);
2638 voe_.GetNsStatus(ns_enabled, ns_mode);
2639 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2640 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2641 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2642 EXPECT_TRUE(ec_enabled);
2643 EXPECT_TRUE(agc_enabled);
2644 EXPECT_TRUE(ns_enabled);
2645 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002646 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002647 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002648}
2649
2650TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2651 webrtc::AgcConfig set_config = {0};
2652 set_config.targetLeveldBOv = 3;
2653 set_config.digitalCompressionGaindB = 9;
2654 set_config.limiterEnable = true;
2655 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2656 EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
2657
2658 webrtc::AgcConfig config = {0};
2659 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2660 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2661 EXPECT_EQ(set_config.digitalCompressionGaindB,
2662 config.digitalCompressionGaindB);
2663 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2664}
2665
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002666TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2667 EXPECT_TRUE(SetupEngine());
2668 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2669 engine_.CreateChannel());
2670 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2671 engine_.CreateChannel());
2672
2673 // Have to add a stream to make SetSend work.
2674 cricket::StreamParams stream1;
2675 stream1.ssrcs.push_back(1);
2676 channel1->AddSendStream(stream1);
2677 cricket::StreamParams stream2;
2678 stream2.ssrcs.push_back(2);
2679 channel2->AddSendStream(stream2);
2680
2681 // AEC and AGC and NS
2682 cricket::AudioOptions options_all;
2683 options_all.echo_cancellation.Set(true);
2684 options_all.auto_gain_control.Set(true);
2685 options_all.noise_suppression.Set(true);
2686
2687 ASSERT_TRUE(channel1->SetOptions(options_all));
2688 cricket::AudioOptions expected_options = options_all;
2689 cricket::AudioOptions actual_options;
2690 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2691 EXPECT_EQ(expected_options, actual_options);
2692 ASSERT_TRUE(channel2->SetOptions(options_all));
2693 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2694 EXPECT_EQ(expected_options, actual_options);
2695
2696 // unset NS
2697 cricket::AudioOptions options_no_ns;
2698 options_no_ns.noise_suppression.Set(false);
2699 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2700
2701 expected_options.echo_cancellation.Set(true);
2702 expected_options.auto_gain_control.Set(true);
2703 expected_options.noise_suppression.Set(false);
2704 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2705 EXPECT_EQ(expected_options, actual_options);
2706
2707 // unset AGC
2708 cricket::AudioOptions options_no_agc;
2709 options_no_agc.auto_gain_control.Set(false);
2710 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2711
2712 expected_options.echo_cancellation.Set(true);
2713 expected_options.auto_gain_control.Set(false);
2714 expected_options.noise_suppression.Set(true);
2715 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2716 EXPECT_EQ(expected_options, actual_options);
2717
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002718 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002719 bool ec_enabled;
2720 webrtc::EcModes ec_mode;
2721 bool agc_enabled;
2722 webrtc::AgcModes agc_mode;
2723 bool ns_enabled;
2724 webrtc::NsModes ns_mode;
2725 voe_.GetEcStatus(ec_enabled, ec_mode);
2726 voe_.GetAgcStatus(agc_enabled, agc_mode);
2727 voe_.GetNsStatus(ns_enabled, ns_mode);
2728 EXPECT_TRUE(ec_enabled);
2729 EXPECT_TRUE(agc_enabled);
2730 EXPECT_TRUE(ns_enabled);
2731
2732 channel1->SetSend(cricket::SEND_MICROPHONE);
2733 voe_.GetEcStatus(ec_enabled, ec_mode);
2734 voe_.GetAgcStatus(agc_enabled, agc_mode);
2735 voe_.GetNsStatus(ns_enabled, ns_mode);
2736 EXPECT_TRUE(ec_enabled);
2737 EXPECT_TRUE(agc_enabled);
2738 EXPECT_FALSE(ns_enabled);
2739
2740 channel1->SetSend(cricket::SEND_NOTHING);
2741 voe_.GetEcStatus(ec_enabled, ec_mode);
2742 voe_.GetAgcStatus(agc_enabled, agc_mode);
2743 voe_.GetNsStatus(ns_enabled, ns_mode);
2744 EXPECT_TRUE(ec_enabled);
2745 EXPECT_TRUE(agc_enabled);
2746 EXPECT_TRUE(ns_enabled);
2747
2748 channel2->SetSend(cricket::SEND_MICROPHONE);
2749 voe_.GetEcStatus(ec_enabled, ec_mode);
2750 voe_.GetAgcStatus(agc_enabled, agc_mode);
2751 voe_.GetNsStatus(ns_enabled, ns_mode);
2752 EXPECT_TRUE(ec_enabled);
2753 EXPECT_FALSE(agc_enabled);
2754 EXPECT_TRUE(ns_enabled);
2755
2756 channel2->SetSend(cricket::SEND_NOTHING);
2757 voe_.GetEcStatus(ec_enabled, ec_mode);
2758 voe_.GetAgcStatus(agc_enabled, agc_mode);
2759 voe_.GetNsStatus(ns_enabled, ns_mode);
2760 EXPECT_TRUE(ec_enabled);
2761 EXPECT_TRUE(agc_enabled);
2762 EXPECT_TRUE(ns_enabled);
2763
2764 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002765 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002766 cricket::AudioOptions options_no_agc_nor_ns;
2767 options_no_agc_nor_ns.auto_gain_control.Set(false);
2768 options_no_agc_nor_ns.noise_suppression.Set(false);
2769 channel2->SetSend(cricket::SEND_MICROPHONE);
2770 channel2->SetOptions(options_no_agc_nor_ns);
2771
2772 expected_options.echo_cancellation.Set(true);
2773 expected_options.auto_gain_control.Set(false);
2774 expected_options.noise_suppression.Set(false);
2775 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2776 EXPECT_EQ(expected_options, actual_options);
2777 voe_.GetEcStatus(ec_enabled, ec_mode);
2778 voe_.GetAgcStatus(agc_enabled, agc_mode);
2779 voe_.GetNsStatus(ns_enabled, ns_mode);
2780 EXPECT_TRUE(ec_enabled);
2781 EXPECT_FALSE(agc_enabled);
2782 EXPECT_FALSE(ns_enabled);
2783}
2784
wu@webrtc.orgde305012013-10-31 15:40:38 +00002785// This test verifies DSCP settings are properly applied on voice media channel.
2786TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2787 EXPECT_TRUE(SetupEngine());
2788 talk_base::scoped_ptr<cricket::VoiceMediaChannel> channel(
2789 engine_.CreateChannel());
2790 talk_base::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2791 new cricket::FakeNetworkInterface);
2792 channel->SetInterface(network_interface.get());
2793 cricket::AudioOptions options;
2794 options.dscp.Set(true);
2795 EXPECT_TRUE(channel->SetOptions(options));
2796 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00002797 // Verify previous value is not modified if dscp option is not set.
2798 cricket::AudioOptions options1;
2799 EXPECT_TRUE(channel->SetOptions(options1));
2800 EXPECT_EQ(talk_base::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00002801 options.dscp.Set(false);
2802 EXPECT_TRUE(channel->SetOptions(options));
2803 EXPECT_EQ(talk_base::DSCP_DEFAULT, network_interface->dscp());
2804}
2805
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002806TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2807 cricket::WebRtcVoiceEngine engine;
2808 cricket::AudioOptions options = engine.GetOptions();
2809 // The default options should have at least a few things set. We purposefully
2810 // don't check the option values here, though.
2811 EXPECT_TRUE(options.echo_cancellation.IsSet());
2812 EXPECT_TRUE(options.auto_gain_control.IsSet());
2813 EXPECT_TRUE(options.noise_suppression.IsSet());
2814}
2815
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002816// Test that GetReceiveChannelNum returns the default channel for the first
2817// recv stream in 1-1 calls.
2818TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2819 EXPECT_TRUE(SetupEngine());
2820 cricket::WebRtcVoiceMediaChannel* media_channel =
2821 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2822 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2823 EXPECT_EQ(media_channel->voe_channel(),
2824 media_channel->GetReceiveChannelNum(0));
2825 cricket::StreamParams stream;
2826 stream.ssrcs.push_back(kSsrc2);
2827 EXPECT_TRUE(channel_->AddRecvStream(stream));
2828 EXPECT_EQ(media_channel->voe_channel(),
2829 media_channel->GetReceiveChannelNum(kSsrc2));
2830}
2831
2832// Test that GetReceiveChannelNum doesn't return the default channel for the
2833// first recv stream in conference calls.
2834TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2835 EXPECT_TRUE(SetupEngine());
2836 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2837 cricket::StreamParams stream;
2838 stream.ssrcs.push_back(kSsrc2);
2839 EXPECT_TRUE(channel_->AddRecvStream(stream));
2840 cricket::WebRtcVoiceMediaChannel* media_channel =
2841 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2842 EXPECT_LT(media_channel->voe_channel(),
2843 media_channel->GetReceiveChannelNum(kSsrc2));
2844}
2845
2846TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2847 EXPECT_TRUE(SetupEngine());
2848 double left, right;
2849 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2850 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2851 EXPECT_DOUBLE_EQ(1, left);
2852 EXPECT_DOUBLE_EQ(2, right);
2853
2854 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2855 cricket::StreamParams stream;
2856 stream.ssrcs.push_back(kSsrc2);
2857 EXPECT_TRUE(channel_->AddRecvStream(stream));
2858
2859 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2860 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2861 EXPECT_DOUBLE_EQ(2, left);
2862 EXPECT_DOUBLE_EQ(1, right);
2863}
2864
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002865// Tests for the actual WebRtc VoE library.
2866
2867// Tests that the library initializes and shuts down properly.
2868TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2869 cricket::WebRtcVoiceEngine engine;
2870 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2871 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2872 EXPECT_TRUE(channel != NULL);
2873 delete channel;
2874 engine.Terminate();
2875
2876 // Reinit to catch regression where VoiceEngineObserver reference is lost
2877 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2878 engine.Terminate();
2879}
2880
2881// Tests that the logging from the library is cleartext.
2882TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
2883 cricket::WebRtcVoiceEngine engine;
2884 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2885 new talk_base::MemoryStream);
2886 size_t size = 0;
2887 bool cleartext = true;
2888 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2889 engine.SetLogging(talk_base::LS_VERBOSE, "");
2890 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2891 EXPECT_TRUE(stream->GetSize(&size));
2892 EXPECT_GT(size, 0U);
2893 engine.Terminate();
2894 talk_base::LogMessage::RemoveLogToStream(stream.get());
2895 const char* buf = stream->GetBuffer();
2896 for (size_t i = 0; i < size && cleartext; ++i) {
2897 int ch = static_cast<int>(buf[i]);
2898 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
2899 << std::hex << ch;
2900 cleartext = (isprint(ch) || isspace(ch));
2901 }
2902 EXPECT_TRUE(cleartext);
2903}
2904
2905// Tests we do not see any references to a monitor thread being spun up
2906// when initiating the engine.
2907TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
2908 cricket::WebRtcVoiceEngine engine;
2909 talk_base::scoped_ptr<talk_base::MemoryStream> stream(
2910 new talk_base::MemoryStream);
2911 talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
2912 engine.SetLogging(talk_base::LS_VERBOSE, "");
2913 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
2914 engine.Terminate();
2915 talk_base::LogMessage::RemoveLogToStream(stream.get());
2916
2917 size_t size = 0;
2918 EXPECT_TRUE(stream->GetSize(&size));
2919 EXPECT_GT(size, 0U);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002920 const std::string logs(stream->GetBuffer(), size);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002921 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
2922}
2923
2924// Tests that the library is configured with the codecs we want.
2925TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
2926 cricket::WebRtcVoiceEngine engine;
2927 // Check codecs by name.
2928 EXPECT_TRUE(engine.FindCodec(
2929 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
2930 EXPECT_TRUE(engine.FindCodec(
2931 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
2932 EXPECT_TRUE(engine.FindCodec(
2933 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
2934 // Check that name matching is case-insensitive.
2935 EXPECT_TRUE(engine.FindCodec(
2936 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
2937 EXPECT_TRUE(engine.FindCodec(
2938 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
2939 EXPECT_TRUE(engine.FindCodec(
2940 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
2941 EXPECT_TRUE(engine.FindCodec(
2942 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
2943 EXPECT_TRUE(engine.FindCodec(
2944 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
2945 EXPECT_TRUE(engine.FindCodec(
2946 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947 EXPECT_TRUE(engine.FindCodec(
2948 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
2949 EXPECT_TRUE(engine.FindCodec(
2950 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
2951 EXPECT_TRUE(engine.FindCodec(
2952 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
2953 EXPECT_TRUE(engine.FindCodec(
2954 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
2955 // Check codecs with an id by id.
2956 EXPECT_TRUE(engine.FindCodec(
2957 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
2958 EXPECT_TRUE(engine.FindCodec(
2959 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
2960 EXPECT_TRUE(engine.FindCodec(
2961 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
2962 EXPECT_TRUE(engine.FindCodec(
2963 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
2964 // Check sample/bitrate matching.
2965 EXPECT_TRUE(engine.FindCodec(
2966 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
2967 // Check that bad codecs fail.
2968 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
2969 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
2970 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
2971 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
2972 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002973 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
2974 for (std::vector<cricket::AudioCodec>::const_iterator it =
2975 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
2976 if (it->name == "CN" && it->clockrate == 16000) {
2977 EXPECT_EQ(105, it->id);
2978 } else if (it->name == "CN" && it->clockrate == 32000) {
2979 EXPECT_EQ(106, it->id);
2980 } else if (it->name == "ISAC" && it->clockrate == 16000) {
2981 EXPECT_EQ(103, it->id);
2982 } else if (it->name == "ISAC" && it->clockrate == 32000) {
2983 EXPECT_EQ(104, it->id);
2984 } else if (it->name == "G722" && it->clockrate == 16000) {
2985 EXPECT_EQ(9, it->id);
2986 } else if (it->name == "telephone-event") {
2987 EXPECT_EQ(126, it->id);
2988 } else if (it->name == "red") {
2989 EXPECT_EQ(127, it->id);
2990 } else if (it->name == "opus") {
2991 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002992 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002994 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995 EXPECT_EQ("60", it->params.find("maxptime")->second);
2996 }
2997 }
2998
2999 engine.Terminate();
3000}
3001
3002// Tests that VoE supports at least 32 channels
3003TEST(WebRtcVoiceEngineTest, Has32Channels) {
3004 cricket::WebRtcVoiceEngine engine;
3005 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3006
3007 cricket::VoiceMediaChannel* channels[32];
3008 int num_channels = 0;
3009
3010 while (num_channels < ARRAY_SIZE(channels)) {
3011 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3012 if (!channel)
3013 break;
3014
3015 channels[num_channels++] = channel;
3016 }
3017
3018 int expected = ARRAY_SIZE(channels);
3019 EXPECT_EQ(expected, num_channels);
3020
3021 while (num_channels > 0) {
3022 delete channels[--num_channels];
3023 }
3024
3025 engine.Terminate();
3026}
3027
3028// Test that we set our preferred codecs properly.
3029TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3030 cricket::WebRtcVoiceEngine engine;
3031 EXPECT_TRUE(engine.Init(talk_base::Thread::Current()));
3032 cricket::WebRtcVoiceMediaChannel channel(&engine);
3033 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3034}
3035
3036#ifdef WIN32
3037// Test our workarounds to WebRtc VoE' munging of the coinit count
3038TEST(WebRtcVoiceEngineTest, CoInitialize) {
3039 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3040
3041 // Initial refcount should be 0.
3042 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3043
3044 // Engine should start even with COM already inited.
3045 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3046 engine->Terminate();
3047 EXPECT_TRUE(engine->Init(talk_base::Thread::Current()));
3048 engine->Terminate();
3049
3050 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3051 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3052 // Decrement refcount to (hopefully) 0.
3053 CoUninitialize();
3054 CoUninitialize();
3055 delete engine;
3056
3057 // Ensure refcount is 0.
3058 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3059 CoUninitialize();
3060}
3061#endif
3062