blob: f5b8260f020c78c161c0dac2f3854a8fecb74431 [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
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000029#include "webrtc/base/win32.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030#include <objbase.h>
31#endif
32
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000033#include "webrtc/base/byteorder.h"
34#include "webrtc/base/gunit.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035#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"
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +000041#include "talk/media/webrtc/webrtcvie.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042#include "talk/media/webrtc/webrtcvoiceengine.h"
43#include "talk/p2p/base/fakesession.h"
44#include "talk/session/media/channel.h"
45
46// Tests for the WebRtcVoiceEngine/VoiceChannel code.
47
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000048using cricket::kRtpAudioLevelHeaderExtension;
49using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
50
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
52static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
53static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
54static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
55static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
56static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
57static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
58static const cricket::AudioCodec
59 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
60static const cricket::AudioCodec* const kAudioCodecs[] = {
61 &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
62 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
63};
64const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
65static uint32 kSsrc1 = 0x99;
66static uint32 kSsrc2 = 0x98;
67
68class FakeVoEWrapper : public cricket::VoEWrapper {
69 public:
70 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
71 : cricket::VoEWrapper(engine, // processing
72 engine, // base
73 engine, // codec
74 engine, // dtmf
75 engine, // file
76 engine, // hw
77 engine, // media
78 engine, // neteq
79 engine, // network
80 engine, // rtp
81 engine, // sync
82 engine) { // volume
83 }
84};
85
wu@webrtc.org97077a32013-10-25 21:18:33 +000086class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 public:
88 virtual int SetTraceFilter(const unsigned int filter) {
wu@webrtc.org97077a32013-10-25 21:18:33 +000089 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090 return 0;
91 }
92 virtual int SetTraceFile(const char* fileNameUTF8) {
93 return 0;
94 }
95 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
96 return 0;
97 }
wu@webrtc.org97077a32013-10-25 21:18:33 +000098 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099};
100
101class WebRtcVoiceEngineTestFake : public testing::Test {
102 public:
103 class ChannelErrorListener : public sigslot::has_slots<> {
104 public:
105 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
106 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
107 ASSERT(channel != NULL);
108 channel->SignalMediaError.connect(
109 this, &ChannelErrorListener::OnVoiceChannelError);
110 }
111 void OnVoiceChannelError(uint32 ssrc,
112 cricket::VoiceMediaChannel::Error error) {
113 ssrc_ = ssrc;
114 error_ = error;
115 }
116 void Reset() {
117 ssrc_ = 0;
118 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
119 }
120 uint32 ssrc() const {
121 return ssrc_;
122 }
123 cricket::VoiceMediaChannel::Error error() const {
124 return error_;
125 }
126
127 private:
128 uint32 ssrc_;
129 cricket::VoiceMediaChannel::Error error_;
130 };
131
132 WebRtcVoiceEngineTestFake()
133 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
134 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000135 trace_wrapper_(new FakeVoETraceWrapper()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136 engine_(new FakeVoEWrapper(&voe_),
137 new FakeVoEWrapper(&voe_sc_),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000138 trace_wrapper_),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139 channel_(NULL), soundclip_(NULL) {
140 options_conference_.conference_mode.Set(true);
141 options_adjust_agc_.adjust_agc_delta.Set(-10);
142 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000143 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000144 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000145 return false;
146 }
147 channel_ = engine_.CreateChannel();
148 return (channel_ != NULL);
149 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000151 if (!SetupEngineWithoutStream()) {
152 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000154 return channel_->AddSendStream(
155 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000156 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000157 void SetupForMultiSendStream() {
158 EXPECT_TRUE(SetupEngine());
159 // Remove stream added in Setup, which is corresponding to default channel.
160 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000161 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000162 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
163 EXPECT_EQ(kSsrc1, default_send_ssrc);
164 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
165
166 // Verify the default channel still exists.
167 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
168 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169 void DeliverPacket(const void* data, int len) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000170 rtc::Buffer packet(data, len);
171 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 }
173 virtual void TearDown() {
174 delete soundclip_;
175 delete channel_;
176 engine_.Terminate();
177 }
178
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000179 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000180 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000181 channel_ = engine_.CreateChannel();
182 EXPECT_TRUE(channel_ != NULL);
183 if (caller) {
184 // if this is a caller, local description will be applied and add the
185 // send stream.
186 EXPECT_TRUE(channel_->AddSendStream(
187 cricket::StreamParams::CreateLegacy(kSsrc1)));
188 }
189 int channel_id = voe_.GetLastChannel();
190
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000191 // Test we can only InsertDtmf when the other side supports telephone-event.
192 std::vector<cricket::AudioCodec> codecs;
193 codecs.push_back(kPcmuCodec);
194 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
195 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
196 EXPECT_FALSE(channel_->CanInsertDtmf());
197 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
198 codecs.push_back(kTelephoneEventCodec);
199 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
200 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000201
202 if (!caller) {
203 // There's no active send channel yet.
204 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
205 EXPECT_TRUE(channel_->AddSendStream(
206 cricket::StreamParams::CreateLegacy(kSsrc1)));
207 }
208
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 // Check we fail if the ssrc is invalid.
210 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
211
212 // Test send
213 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
214 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
215 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
216
217 // Test play
218 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
219 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
220 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
221
222 // Test send and play
223 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
224 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
225 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
226 cricket::DF_PLAY | cricket::DF_SEND));
227 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
228 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
229 }
230
231 // Test that send bandwidth is set correctly.
232 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000233 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
234 // |expected_result| is the expected result from SetMaxSendBandwidth().
235 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000237 int max_bitrate,
238 bool expected_result,
239 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 int channel_num = voe_.GetLastChannel();
241 std::vector<cricket::AudioCodec> codecs;
242
243 codecs.push_back(codec);
244 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
245
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000246 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 EXPECT_EQ(expected_result, result);
248
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000249 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
251
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000252 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 }
254
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000255 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
256 EXPECT_TRUE(SetupEngineWithoutStream());
257 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000259 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000260 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000261
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000262 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000263 // Ensure unknown extensions won't cause an error.
264 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000265 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000266 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000267 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000268
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000269 // Ensure extensions stay off with an empty list of headers.
270 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000271 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000272 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000273
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000274 // Ensure extension is set properly.
275 const int id = 1;
276 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000277 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000278 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000279
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000280 // Ensure extension is set properly on new channel.
281 // The first stream to occupy the default channel.
282 EXPECT_TRUE(channel_->AddSendStream(
283 cricket::StreamParams::CreateLegacy(123)));
284 EXPECT_TRUE(channel_->AddSendStream(
285 cricket::StreamParams::CreateLegacy(234)));
286 int new_channel_num = voe_.GetLastChannel();
287 EXPECT_NE(channel_num, new_channel_num);
288 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000289
290 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000291 extensions.clear();
292 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000293 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
294 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000295 }
296
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000297 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
298 EXPECT_TRUE(SetupEngineWithoutStream());
299 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000300
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000301 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000302 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000303
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000304 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000305 // Ensure unknown extensions won't cause an error.
306 extensions.push_back(cricket::RtpHeaderExtension(
307 "urn:ietf:params:unknownextention", 1));
308 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000309 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000310
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000311 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000312 extensions.clear();
313 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000314 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000315
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000316 // Ensure extension is set properly.
317 const int id = 2;
318 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000319 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000320 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000321
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000322 // Ensure extension is set properly on new channel.
323 // The first stream to occupy the default channel.
324 EXPECT_TRUE(channel_->AddRecvStream(
325 cricket::StreamParams::CreateLegacy(345)));
326 EXPECT_TRUE(channel_->AddRecvStream(
327 cricket::StreamParams::CreateLegacy(456)));
328 int new_channel_num = voe_.GetLastChannel();
329 EXPECT_NE(channel_num, new_channel_num);
330 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
331
332 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000333 extensions.clear();
334 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000335 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
336 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000337 }
338
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 protected:
340 cricket::FakeWebRtcVoiceEngine voe_;
341 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000342 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 cricket::WebRtcVoiceEngine engine_;
344 cricket::VoiceMediaChannel* channel_;
345 cricket::SoundclipMedia* soundclip_;
346
347 cricket::AudioOptions options_conference_;
348 cricket::AudioOptions options_adjust_agc_;
349};
350
351// Tests that our stub library "works".
352TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
353 EXPECT_FALSE(voe_.IsInited());
354 EXPECT_FALSE(voe_sc_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000355 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000357 // The soundclip engine is lazily initialized.
358 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 engine_.Terminate();
360 EXPECT_FALSE(voe_.IsInited());
361 EXPECT_FALSE(voe_sc_.IsInited());
362}
363
364// Tests that we can create and destroy a channel.
365TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000366 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367 channel_ = engine_.CreateChannel();
368 EXPECT_TRUE(channel_ != NULL);
369}
370
371// Tests that we properly handle failures in CreateChannel.
372TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
373 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000374 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000375 channel_ = engine_.CreateChannel();
376 EXPECT_TRUE(channel_ == NULL);
377}
378
379// Tests that the list of supported codecs is created properly and ordered
380// correctly
381TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
382 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
383 ASSERT_FALSE(codecs.empty());
384 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
385 EXPECT_EQ(48000, codecs[0].clockrate);
386 EXPECT_EQ(2, codecs[0].channels);
387 EXPECT_EQ(64000, codecs[0].bitrate);
388 int pref = codecs[0].preference;
389 for (size_t i = 1; i < codecs.size(); ++i) {
390 EXPECT_GT(pref, codecs[i].preference);
391 pref = codecs[i].preference;
392 }
393}
394
395// Tests that we can find codecs by name or id, and that we interpret the
396// clockrate and bitrate fields properly.
397TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
398 cricket::AudioCodec codec;
399 webrtc::CodecInst codec_inst;
400 // Find PCMU with explicit clockrate and bitrate.
401 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
402 // Find ISAC with explicit clockrate and 0 bitrate.
403 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
404 // Find telephone-event with explicit clockrate and 0 bitrate.
405 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
406 // Find ISAC with a different payload id.
407 codec = kIsacCodec;
408 codec.id = 127;
409 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
410 EXPECT_EQ(codec.id, codec_inst.pltype);
411 // Find PCMU with a 0 clockrate.
412 codec = kPcmuCodec;
413 codec.clockrate = 0;
414 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
415 EXPECT_EQ(codec.id, codec_inst.pltype);
416 EXPECT_EQ(8000, codec_inst.plfreq);
417 // Find PCMU with a 0 bitrate.
418 codec = kPcmuCodec;
419 codec.bitrate = 0;
420 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
421 EXPECT_EQ(codec.id, codec_inst.pltype);
422 EXPECT_EQ(64000, codec_inst.rate);
423 // Find ISAC with an explicit bitrate.
424 codec = kIsacCodec;
425 codec.bitrate = 32000;
426 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
427 EXPECT_EQ(codec.id, codec_inst.pltype);
428 EXPECT_EQ(32000, codec_inst.rate);
429}
430
431// Test that we set our inbound codecs properly, including changing PT.
432TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
433 EXPECT_TRUE(SetupEngine());
434 int channel_num = voe_.GetLastChannel();
435 std::vector<cricket::AudioCodec> codecs;
436 codecs.push_back(kIsacCodec);
437 codecs.push_back(kPcmuCodec);
438 codecs.push_back(kTelephoneEventCodec);
439 codecs[0].id = 106; // collide with existing telephone-event
440 codecs[2].id = 126;
441 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
442 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000443 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 gcodec.plfreq = 16000;
445 gcodec.channels = 1;
446 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
447 EXPECT_EQ(106, gcodec.pltype);
448 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000449 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 "telephone-event");
451 gcodec.plfreq = 8000;
452 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
453 EXPECT_EQ(126, gcodec.pltype);
454 EXPECT_STREQ("telephone-event", gcodec.plname);
455}
456
457// Test that we fail to set an unknown inbound codec.
458TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
459 EXPECT_TRUE(SetupEngine());
460 std::vector<cricket::AudioCodec> codecs;
461 codecs.push_back(kIsacCodec);
462 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
463 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
464}
465
466// Test that we fail if we have duplicate types in the inbound list.
467TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
468 EXPECT_TRUE(SetupEngine());
469 std::vector<cricket::AudioCodec> codecs;
470 codecs.push_back(kIsacCodec);
471 codecs.push_back(kCn16000Codec);
472 codecs[1].id = kIsacCodec.id;
473 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
474}
475
476// Test that we can decode OPUS without stereo parameters.
477TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
478 EXPECT_TRUE(SetupEngine());
479 EXPECT_TRUE(channel_->SetOptions(options_conference_));
480 std::vector<cricket::AudioCodec> codecs;
481 codecs.push_back(kIsacCodec);
482 codecs.push_back(kPcmuCodec);
483 codecs.push_back(kOpusCodec);
484 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
485 EXPECT_TRUE(channel_->AddRecvStream(
486 cricket::StreamParams::CreateLegacy(kSsrc1)));
487 int channel_num2 = voe_.GetLastChannel();
488 webrtc::CodecInst opus;
489 engine_.FindWebRtcCodec(kOpusCodec, &opus);
490 // Even without stereo parameters, recv codecs still specify channels = 2.
491 EXPECT_EQ(2, opus.channels);
492 EXPECT_EQ(111, opus.pltype);
493 EXPECT_STREQ("opus", opus.plname);
494 opus.pltype = 0;
495 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
496 EXPECT_EQ(111, opus.pltype);
497}
498
499// Test that we can decode OPUS with stereo = 0.
500TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
501 EXPECT_TRUE(SetupEngine());
502 EXPECT_TRUE(channel_->SetOptions(options_conference_));
503 std::vector<cricket::AudioCodec> codecs;
504 codecs.push_back(kIsacCodec);
505 codecs.push_back(kPcmuCodec);
506 codecs.push_back(kOpusCodec);
507 codecs[2].params["stereo"] = "0";
508 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
509 EXPECT_TRUE(channel_->AddRecvStream(
510 cricket::StreamParams::CreateLegacy(kSsrc1)));
511 int channel_num2 = voe_.GetLastChannel();
512 webrtc::CodecInst opus;
513 engine_.FindWebRtcCodec(kOpusCodec, &opus);
514 // Even when stereo is off, recv codecs still specify channels = 2.
515 EXPECT_EQ(2, opus.channels);
516 EXPECT_EQ(111, opus.pltype);
517 EXPECT_STREQ("opus", opus.plname);
518 opus.pltype = 0;
519 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
520 EXPECT_EQ(111, opus.pltype);
521}
522
523// Test that we can decode OPUS with stereo = 1.
524TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
525 EXPECT_TRUE(SetupEngine());
526 EXPECT_TRUE(channel_->SetOptions(options_conference_));
527 std::vector<cricket::AudioCodec> codecs;
528 codecs.push_back(kIsacCodec);
529 codecs.push_back(kPcmuCodec);
530 codecs.push_back(kOpusCodec);
531 codecs[2].params["stereo"] = "1";
532 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
533 EXPECT_TRUE(channel_->AddRecvStream(
534 cricket::StreamParams::CreateLegacy(kSsrc1)));
535 int channel_num2 = voe_.GetLastChannel();
536 webrtc::CodecInst opus;
537 engine_.FindWebRtcCodec(kOpusCodec, &opus);
538 EXPECT_EQ(2, opus.channels);
539 EXPECT_EQ(111, opus.pltype);
540 EXPECT_STREQ("opus", opus.plname);
541 opus.pltype = 0;
542 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
543 EXPECT_EQ(111, opus.pltype);
544}
545
546// Test that changes to recv codecs are applied to all streams.
547TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
548 EXPECT_TRUE(SetupEngine());
549 EXPECT_TRUE(channel_->SetOptions(options_conference_));
550 std::vector<cricket::AudioCodec> codecs;
551 codecs.push_back(kIsacCodec);
552 codecs.push_back(kPcmuCodec);
553 codecs.push_back(kTelephoneEventCodec);
554 codecs[0].id = 106; // collide with existing telephone-event
555 codecs[2].id = 126;
556 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
557 EXPECT_TRUE(channel_->AddRecvStream(
558 cricket::StreamParams::CreateLegacy(kSsrc1)));
559 int channel_num2 = voe_.GetLastChannel();
560 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000561 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562 gcodec.plfreq = 16000;
563 gcodec.channels = 1;
564 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
565 EXPECT_EQ(106, gcodec.pltype);
566 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000567 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568 "telephone-event");
569 gcodec.plfreq = 8000;
570 gcodec.channels = 1;
571 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
572 EXPECT_EQ(126, gcodec.pltype);
573 EXPECT_STREQ("telephone-event", gcodec.plname);
574}
575
576TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
577 EXPECT_TRUE(SetupEngine());
578 EXPECT_TRUE(channel_->SetOptions(options_conference_));
579 std::vector<cricket::AudioCodec> codecs;
580 codecs.push_back(kIsacCodec);
581 codecs[0].id = 106; // collide with existing telephone-event
582
583 EXPECT_TRUE(channel_->AddRecvStream(
584 cricket::StreamParams::CreateLegacy(kSsrc1)));
585 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
586
587 int channel_num2 = voe_.GetLastChannel();
588 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000589 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590 gcodec.plfreq = 16000;
591 gcodec.channels = 1;
592 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
593 EXPECT_EQ(106, gcodec.pltype);
594 EXPECT_STREQ("ISAC", gcodec.plname);
595}
596
597// Test that we can apply the same set of codecs again while playing.
598TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
599 EXPECT_TRUE(SetupEngine());
600 int channel_num = voe_.GetLastChannel();
601 std::vector<cricket::AudioCodec> codecs;
602 codecs.push_back(kIsacCodec);
603 codecs.push_back(kCn16000Codec);
604 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
605 EXPECT_TRUE(channel_->SetPlayout(true));
606 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
607
608 // Changing the payload type of a codec should fail.
609 codecs[0].id = 127;
610 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
611 EXPECT_TRUE(voe_.GetPlayout(channel_num));
612}
613
614// Test that we can add a codec while playing.
615TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
616 EXPECT_TRUE(SetupEngine());
617 int channel_num = voe_.GetLastChannel();
618 std::vector<cricket::AudioCodec> codecs;
619 codecs.push_back(kIsacCodec);
620 codecs.push_back(kCn16000Codec);
621 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
622 EXPECT_TRUE(channel_->SetPlayout(true));
623
624 codecs.push_back(kOpusCodec);
625 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
626 EXPECT_TRUE(voe_.GetPlayout(channel_num));
627 webrtc::CodecInst gcodec;
628 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
629 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
630}
631
632TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
633 EXPECT_TRUE(SetupEngine());
634 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
635
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000636 // Test that when autobw is enabled, bitrate is kept as the default
637 // value. autobw is enabled for the following tests because the target
638 // bitrate is <= 0.
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, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642
643 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000644 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645
646 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000647 TestSendBandwidth(kCeltCodec, 0, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648
649 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000650 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651}
652
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000653TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000654 EXPECT_TRUE(SetupEngine());
655 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
656
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000657 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658
659 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000660 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
661 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662
663 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000664 TestSendBandwidth(kCeltCodec, 96000, true, 96000);
665 TestSendBandwidth(kCeltCodec, 32000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000666
667 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000668 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
669 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670}
671
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000672TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
673 EXPECT_TRUE(SetupEngine());
674 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
675
676 // Test that we can only set a maximum bitrate for a fixed-rate codec
677 // if it's bigger than the fixed rate.
678
679 // PCMU, fixed bitrate == 64000.
680 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
681 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
682 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
683 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
684 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
685 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
686 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
687}
688
689TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000690 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000691 channel_ = engine_.CreateChannel();
692 EXPECT_TRUE(channel_ != NULL);
693 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
694
695 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000696 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000697
698 EXPECT_TRUE(channel_->AddSendStream(
699 cricket::StreamParams::CreateLegacy(kSsrc1)));
700
701 int channel_num = voe_.GetLastChannel();
702 webrtc::CodecInst codec;
703 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
704 EXPECT_EQ(desired_bitrate, codec.rate);
705}
706
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707// Test that bitrate cannot be set for CBR codecs.
708// Bitrate is ignored if it is higher than the fixed bitrate.
709// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000710TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 EXPECT_TRUE(SetupEngine());
712 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
713
714 webrtc::CodecInst codec;
715 int channel_num = voe_.GetLastChannel();
716 std::vector<cricket::AudioCodec> codecs;
717
718 // PCMU, default bitrate == 64000.
719 codecs.push_back(kPcmuCodec);
720 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
721 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
722 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000723 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
725 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000726 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
728 EXPECT_EQ(64000, codec.rate);
729}
730
731// Test that we apply codecs properly.
732TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
733 EXPECT_TRUE(SetupEngine());
734 int channel_num = voe_.GetLastChannel();
735 std::vector<cricket::AudioCodec> codecs;
736 codecs.push_back(kIsacCodec);
737 codecs.push_back(kPcmuCodec);
738 codecs.push_back(kRedCodec);
739 codecs[0].id = 96;
740 codecs[0].bitrate = 48000;
741 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000742 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 webrtc::CodecInst gcodec;
744 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
745 EXPECT_EQ(96, gcodec.pltype);
746 EXPECT_EQ(48000, gcodec.rate);
747 EXPECT_STREQ("ISAC", gcodec.plname);
748 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000749 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
751 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
752 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
753}
754
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000755// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
756// to apply.
757TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
758 EXPECT_TRUE(SetupEngine());
759 std::vector<cricket::AudioCodec> codecs;
760 codecs.push_back(kIsacCodec);
761 codecs.push_back(kPcmuCodec);
762 codecs.push_back(kRedCodec);
763 codecs[0].id = 96;
764 codecs[0].bitrate = 48000;
765 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
766 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
767 // Calling SetSendCodec again with same codec which is already set.
768 // In this case media channel shouldn't send codec to VoE.
769 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
770 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
771}
772
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000773// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
775 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 std::vector<cricket::AudioCodec> codecs;
777 codecs.push_back(kOpusCodec);
778 codecs[0].bitrate = 0;
779 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000780 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781}
782
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000783// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
785 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786 std::vector<cricket::AudioCodec> codecs;
787 codecs.push_back(kOpusCodec);
788 codecs[0].bitrate = 0;
789 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000790 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791}
792
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000793// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
795 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 std::vector<cricket::AudioCodec> codecs;
797 codecs.push_back(kOpusCodec);
798 codecs[0].bitrate = 0;
799 codecs[0].channels = 0;
800 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000801 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802}
803
804// Test that if channel is 1 for opus and there's no stereo, we fail.
805TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
806 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807 std::vector<cricket::AudioCodec> codecs;
808 codecs.push_back(kOpusCodec);
809 codecs[0].bitrate = 0;
810 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000811 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812}
813
814// Test that if channel is 1 for opus and stereo=0, we fail.
815TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
816 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817 std::vector<cricket::AudioCodec> codecs;
818 codecs.push_back(kOpusCodec);
819 codecs[0].bitrate = 0;
820 codecs[0].channels = 1;
821 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000822 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that if channel is 1 for opus and stereo=1, we fail.
826TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
827 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 std::vector<cricket::AudioCodec> codecs;
829 codecs.push_back(kOpusCodec);
830 codecs[0].bitrate = 0;
831 codecs[0].channels = 1;
832 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000833 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000834}
835
836// Test that with bitrate=0 and no stereo,
837// channels and bitrate are 1 and 32000.
838TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
839 EXPECT_TRUE(SetupEngine());
840 int channel_num = voe_.GetLastChannel();
841 std::vector<cricket::AudioCodec> codecs;
842 codecs.push_back(kOpusCodec);
843 codecs[0].bitrate = 0;
844 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
845 webrtc::CodecInst gcodec;
846 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
847 EXPECT_STREQ("opus", gcodec.plname);
848 EXPECT_EQ(1, gcodec.channels);
849 EXPECT_EQ(32000, gcodec.rate);
850}
851
852// Test that with bitrate=0 and stereo=0,
853// channels and bitrate are 1 and 32000.
854TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
855 EXPECT_TRUE(SetupEngine());
856 int channel_num = voe_.GetLastChannel();
857 std::vector<cricket::AudioCodec> codecs;
858 codecs.push_back(kOpusCodec);
859 codecs[0].bitrate = 0;
860 codecs[0].params["stereo"] = "0";
861 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
862 webrtc::CodecInst gcodec;
863 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
864 EXPECT_STREQ("opus", gcodec.plname);
865 EXPECT_EQ(1, gcodec.channels);
866 EXPECT_EQ(32000, gcodec.rate);
867}
868
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000869// Test that with bitrate=invalid and stereo=0,
870// channels and bitrate are 1 and 32000.
871TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
872 EXPECT_TRUE(SetupEngine());
873 int channel_num = voe_.GetLastChannel();
874 std::vector<cricket::AudioCodec> codecs;
875 codecs.push_back(kOpusCodec);
876 codecs[0].params["stereo"] = "0";
877 webrtc::CodecInst gcodec;
878
879 // bitrate that's out of the range between 6000 and 510000 will be considered
880 // as invalid and ignored.
881 codecs[0].bitrate = 5999;
882 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
883 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
884 EXPECT_STREQ("opus", gcodec.plname);
885 EXPECT_EQ(1, gcodec.channels);
886 EXPECT_EQ(32000, gcodec.rate);
887
888 codecs[0].bitrate = 510001;
889 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
890 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
891 EXPECT_STREQ("opus", gcodec.plname);
892 EXPECT_EQ(1, gcodec.channels);
893 EXPECT_EQ(32000, gcodec.rate);
894}
895
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000896// Test that with bitrate=0 and stereo=1,
897// channels and bitrate are 2 and 64000.
898TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
899 EXPECT_TRUE(SetupEngine());
900 int channel_num = voe_.GetLastChannel();
901 std::vector<cricket::AudioCodec> codecs;
902 codecs.push_back(kOpusCodec);
903 codecs[0].bitrate = 0;
904 codecs[0].params["stereo"] = "1";
905 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
906 webrtc::CodecInst gcodec;
907 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
908 EXPECT_STREQ("opus", gcodec.plname);
909 EXPECT_EQ(2, gcodec.channels);
910 EXPECT_EQ(64000, gcodec.rate);
911}
912
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000913// Test that with bitrate=invalid and stereo=1,
914// channels and bitrate are 2 and 64000.
915TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
916 EXPECT_TRUE(SetupEngine());
917 int channel_num = voe_.GetLastChannel();
918 std::vector<cricket::AudioCodec> codecs;
919 codecs.push_back(kOpusCodec);
920 codecs[0].params["stereo"] = "1";
921 webrtc::CodecInst gcodec;
922
923 // bitrate that's out of the range between 6000 and 510000 will be considered
924 // as invalid and ignored.
925 codecs[0].bitrate = 5999;
926 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
927 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
928 EXPECT_STREQ("opus", gcodec.plname);
929 EXPECT_EQ(2, gcodec.channels);
930 EXPECT_EQ(64000, gcodec.rate);
931
932 codecs[0].bitrate = 510001;
933 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
934 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
935 EXPECT_STREQ("opus", gcodec.plname);
936 EXPECT_EQ(2, gcodec.channels);
937 EXPECT_EQ(64000, gcodec.rate);
938}
939
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000940// Test that with bitrate=N and stereo unset,
941// channels and bitrate are 1 and N.
942TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
943 EXPECT_TRUE(SetupEngine());
944 int channel_num = voe_.GetLastChannel();
945 std::vector<cricket::AudioCodec> codecs;
946 codecs.push_back(kOpusCodec);
947 codecs[0].bitrate = 96000;
948 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
949 webrtc::CodecInst gcodec;
950 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
951 EXPECT_EQ(111, gcodec.pltype);
952 EXPECT_EQ(96000, gcodec.rate);
953 EXPECT_STREQ("opus", gcodec.plname);
954 EXPECT_EQ(1, gcodec.channels);
955 EXPECT_EQ(48000, gcodec.plfreq);
956}
957
958// Test that with bitrate=N and stereo=0,
959// channels and bitrate are 1 and N.
960TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
961 EXPECT_TRUE(SetupEngine());
962 int channel_num = voe_.GetLastChannel();
963 std::vector<cricket::AudioCodec> codecs;
964 codecs.push_back(kOpusCodec);
965 codecs[0].bitrate = 30000;
966 codecs[0].params["stereo"] = "0";
967 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
968 webrtc::CodecInst gcodec;
969 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
970 EXPECT_EQ(1, gcodec.channels);
971 EXPECT_EQ(30000, gcodec.rate);
972 EXPECT_STREQ("opus", gcodec.plname);
973}
974
975// Test that with bitrate=N and without any parameters,
976// channels and bitrate are 1 and N.
977TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
978 EXPECT_TRUE(SetupEngine());
979 int channel_num = voe_.GetLastChannel();
980 std::vector<cricket::AudioCodec> codecs;
981 codecs.push_back(kOpusCodec);
982 codecs[0].bitrate = 30000;
983 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
984 webrtc::CodecInst gcodec;
985 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
986 EXPECT_EQ(1, gcodec.channels);
987 EXPECT_EQ(30000, gcodec.rate);
988 EXPECT_STREQ("opus", gcodec.plname);
989}
990
991// Test that with bitrate=N and stereo=1,
992// channels and bitrate are 2 and N.
993TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
994 EXPECT_TRUE(SetupEngine());
995 int channel_num = voe_.GetLastChannel();
996 std::vector<cricket::AudioCodec> codecs;
997 codecs.push_back(kOpusCodec);
998 codecs[0].bitrate = 30000;
999 codecs[0].params["stereo"] = "1";
1000 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1001 webrtc::CodecInst gcodec;
1002 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1003 EXPECT_EQ(2, gcodec.channels);
1004 EXPECT_EQ(30000, gcodec.rate);
1005 EXPECT_STREQ("opus", gcodec.plname);
1006}
1007
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001008// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1009// Also test that the "maxaveragebitrate" can't be set to values outside the
1010// range of 6000 and 510000
1011TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1012 EXPECT_TRUE(SetupEngine());
1013 int channel_num = voe_.GetLastChannel();
1014 std::vector<cricket::AudioCodec> codecs;
1015 codecs.push_back(kOpusCodec);
1016 codecs[0].bitrate = 30000;
1017 webrtc::CodecInst gcodec;
1018
1019 // Ignore if less than 6000.
1020 codecs[0].params["maxaveragebitrate"] = "5999";
1021 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1022 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1023 EXPECT_EQ(30000, gcodec.rate);
1024
1025 // Ignore if larger than 510000.
1026 codecs[0].params["maxaveragebitrate"] = "510001";
1027 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1028 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1029 EXPECT_EQ(30000, gcodec.rate);
1030
1031 codecs[0].params["maxaveragebitrate"] = "200000";
1032 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1033 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1034 EXPECT_EQ(200000, gcodec.rate);
1035}
1036
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001037// Test that we can enable NACK with opus as caller.
1038TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001039 EXPECT_TRUE(SetupEngine());
1040 int channel_num = voe_.GetLastChannel();
1041 std::vector<cricket::AudioCodec> codecs;
1042 codecs.push_back(kOpusCodec);
1043 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1044 cricket::kParamValueEmpty));
1045 EXPECT_FALSE(voe_.GetNACK(channel_num));
1046 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1047 EXPECT_TRUE(voe_.GetNACK(channel_num));
1048}
1049
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001050// Test that we can enable NACK with opus as callee.
1051TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001052 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001053 channel_ = engine_.CreateChannel();
1054 EXPECT_TRUE(channel_ != NULL);
1055
1056 int channel_num = voe_.GetLastChannel();
1057 std::vector<cricket::AudioCodec> codecs;
1058 codecs.push_back(kOpusCodec);
1059 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1060 cricket::kParamValueEmpty));
1061 EXPECT_FALSE(voe_.GetNACK(channel_num));
1062 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1063 EXPECT_FALSE(voe_.GetNACK(channel_num));
1064
1065 EXPECT_TRUE(channel_->AddSendStream(
1066 cricket::StreamParams::CreateLegacy(kSsrc1)));
1067 EXPECT_TRUE(voe_.GetNACK(channel_num));
1068}
1069
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001070// Test that we can enable NACK on receive streams.
1071TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1072 EXPECT_TRUE(SetupEngine());
1073 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1074 int channel_num1 = voe_.GetLastChannel();
1075 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1076 int channel_num2 = voe_.GetLastChannel();
1077 std::vector<cricket::AudioCodec> codecs;
1078 codecs.push_back(kOpusCodec);
1079 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1080 cricket::kParamValueEmpty));
1081 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1082 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1083 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1084 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1085 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1086}
1087
1088// Test that we can disable NACK.
1089TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1090 EXPECT_TRUE(SetupEngine());
1091 int channel_num = voe_.GetLastChannel();
1092 std::vector<cricket::AudioCodec> codecs;
1093 codecs.push_back(kOpusCodec);
1094 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1095 cricket::kParamValueEmpty));
1096 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1097 EXPECT_TRUE(voe_.GetNACK(channel_num));
1098
1099 codecs.clear();
1100 codecs.push_back(kOpusCodec);
1101 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1102 EXPECT_FALSE(voe_.GetNACK(channel_num));
1103}
1104
1105// Test that we can disable NACK on receive streams.
1106TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1107 EXPECT_TRUE(SetupEngine());
1108 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1109 int channel_num1 = voe_.GetLastChannel();
1110 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1111 int channel_num2 = voe_.GetLastChannel();
1112 std::vector<cricket::AudioCodec> codecs;
1113 codecs.push_back(kOpusCodec);
1114 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1115 cricket::kParamValueEmpty));
1116 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1117 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1118 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1119
1120 codecs.clear();
1121 codecs.push_back(kOpusCodec);
1122 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1123 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1124 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1125}
1126
1127// Test that NACK is enabled on a new receive stream.
1128TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1129 EXPECT_TRUE(SetupEngine());
1130 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1131 int channel_num = voe_.GetLastChannel();
1132 std::vector<cricket::AudioCodec> codecs;
1133 codecs.push_back(kIsacCodec);
1134 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1135 cricket::kParamValueEmpty));
1136 codecs.push_back(kCn16000Codec);
1137 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1138 EXPECT_TRUE(voe_.GetNACK(channel_num));
1139
1140 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1141 channel_num = voe_.GetLastChannel();
1142 EXPECT_TRUE(voe_.GetNACK(channel_num));
1143 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1144 channel_num = voe_.GetLastChannel();
1145 EXPECT_TRUE(voe_.GetNACK(channel_num));
1146}
1147
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001148#ifdef USE_WEBRTC_DEV_BRANCH
1149// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001150TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001151 EXPECT_TRUE(SetupEngine());
1152 int channel_num = voe_.GetLastChannel();
1153 std::vector<cricket::AudioCodec> codecs;
1154 codecs.push_back(kOpusCodec);
1155 codecs[0].bitrate = 0;
1156 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1157 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1158}
1159
1160// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001161TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001162 EXPECT_TRUE(SetupEngine());
1163 int channel_num = voe_.GetLastChannel();
1164 std::vector<cricket::AudioCodec> codecs;
1165 codecs.push_back(kOpusCodec);
1166 codecs[0].bitrate = 0;
1167 codecs[0].params["useinbandfec"] = "0";
1168 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1169 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1170 webrtc::CodecInst gcodec;
1171 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1172 EXPECT_STREQ("opus", gcodec.plname);
1173 EXPECT_EQ(1, gcodec.channels);
1174 EXPECT_EQ(32000, gcodec.rate);
1175}
1176
1177// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001178TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001179 EXPECT_TRUE(SetupEngine());
1180 int channel_num = voe_.GetLastChannel();
1181 std::vector<cricket::AudioCodec> codecs;
1182 codecs.push_back(kOpusCodec);
1183 codecs[0].bitrate = 0;
1184 codecs[0].params["useinbandfec"] = "1";
1185 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1186 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1187 webrtc::CodecInst gcodec;
1188 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1189 EXPECT_STREQ("opus", gcodec.plname);
1190 EXPECT_EQ(1, gcodec.channels);
1191 EXPECT_EQ(32000, gcodec.rate);
1192}
1193
1194// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001195TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001196 EXPECT_TRUE(SetupEngine());
1197 int channel_num = voe_.GetLastChannel();
1198 std::vector<cricket::AudioCodec> codecs;
1199 codecs.push_back(kOpusCodec);
1200 codecs[0].bitrate = 0;
1201 codecs[0].params["stereo"] = "1";
1202 codecs[0].params["useinbandfec"] = "1";
1203 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1204 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1205 webrtc::CodecInst gcodec;
1206 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1207 EXPECT_STREQ("opus", gcodec.plname);
1208 EXPECT_EQ(2, gcodec.channels);
1209 EXPECT_EQ(64000, gcodec.rate);
1210}
1211
1212// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001213TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001214 EXPECT_TRUE(SetupEngine());
1215 int channel_num = voe_.GetLastChannel();
1216 std::vector<cricket::AudioCodec> codecs;
1217 codecs.push_back(kIsacCodec);
1218 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1219 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1220}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001221
1222// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1223TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1224 EXPECT_TRUE(SetupEngine());
1225 int channel_num = voe_.GetLastChannel();
1226 std::vector<cricket::AudioCodec> codecs;
1227 codecs.push_back(kIsacCodec);
1228 codecs[0].params["useinbandfec"] = "1";
1229 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1230 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1231}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001232#endif // USE_WEBRTC_DEV_BRANCH
1233
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001234// Test that we can apply CELT with stereo mode but fail with mono mode.
1235TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1236 EXPECT_TRUE(SetupEngine());
1237 int channel_num = voe_.GetLastChannel();
1238 std::vector<cricket::AudioCodec> codecs;
1239 codecs.push_back(kCeltCodec);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001240 codecs.push_back(kIsacCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001241 codecs[0].id = 96;
1242 codecs[0].channels = 2;
1243 codecs[0].bitrate = 96000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001244 codecs[1].bitrate = 64000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001245 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1246 webrtc::CodecInst gcodec;
1247 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1248 EXPECT_EQ(96, gcodec.pltype);
1249 EXPECT_EQ(96000, gcodec.rate);
1250 EXPECT_EQ(2, gcodec.channels);
1251 EXPECT_STREQ("CELT", gcodec.plname);
1252 // Doesn't support mono, expect it to fall back to the next codec in the list.
1253 codecs[0].channels = 1;
1254 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1255 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001256 EXPECT_EQ(103, gcodec.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001257 EXPECT_EQ(1, gcodec.channels);
1258 EXPECT_EQ(64000, gcodec.rate);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001259 EXPECT_STREQ("ISAC", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001260}
1261
1262// Test that we can switch back and forth between CELT and ISAC with CN.
1263TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1264 EXPECT_TRUE(SetupEngine());
1265 int channel_num = voe_.GetLastChannel();
1266 std::vector<cricket::AudioCodec> celt_codecs;
1267 celt_codecs.push_back(kCeltCodec);
1268 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1269 webrtc::CodecInst gcodec;
1270 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1271 EXPECT_EQ(110, gcodec.pltype);
1272 EXPECT_STREQ("CELT", gcodec.plname);
1273
1274 std::vector<cricket::AudioCodec> isac_codecs;
1275 isac_codecs.push_back(kIsacCodec);
1276 isac_codecs.push_back(kCn16000Codec);
1277 isac_codecs.push_back(kCeltCodec);
1278 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1279 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1280 EXPECT_EQ(103, gcodec.pltype);
1281 EXPECT_STREQ("ISAC", gcodec.plname);
1282
1283 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1284 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1285 EXPECT_EQ(110, gcodec.pltype);
1286 EXPECT_STREQ("CELT", gcodec.plname);
1287}
1288
1289// Test that we handle various ways of specifying bitrate.
1290TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1291 EXPECT_TRUE(SetupEngine());
1292 int channel_num = voe_.GetLastChannel();
1293 std::vector<cricket::AudioCodec> codecs;
1294 codecs.push_back(kIsacCodec); // bitrate == 32000
1295 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1296 webrtc::CodecInst gcodec;
1297 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1298 EXPECT_EQ(103, gcodec.pltype);
1299 EXPECT_STREQ("ISAC", gcodec.plname);
1300 EXPECT_EQ(32000, gcodec.rate);
1301
1302 codecs[0].bitrate = 0; // bitrate == default
1303 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1304 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1305 EXPECT_EQ(103, gcodec.pltype);
1306 EXPECT_STREQ("ISAC", gcodec.plname);
1307 EXPECT_EQ(-1, gcodec.rate);
1308
1309 codecs[0].bitrate = 28000; // bitrate == 28000
1310 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1311 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1312 EXPECT_EQ(103, gcodec.pltype);
1313 EXPECT_STREQ("ISAC", gcodec.plname);
1314 EXPECT_EQ(28000, gcodec.rate);
1315
1316 codecs[0] = kPcmuCodec; // bitrate == 64000
1317 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1318 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1319 EXPECT_EQ(0, gcodec.pltype);
1320 EXPECT_STREQ("PCMU", gcodec.plname);
1321 EXPECT_EQ(64000, gcodec.rate);
1322
1323 codecs[0].bitrate = 0; // bitrate == default
1324 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1325 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1326 EXPECT_EQ(0, gcodec.pltype);
1327 EXPECT_STREQ("PCMU", gcodec.plname);
1328 EXPECT_EQ(64000, gcodec.rate);
1329
1330 codecs[0] = kOpusCodec;
1331 codecs[0].bitrate = 0; // bitrate == default
1332 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1333 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1334 EXPECT_EQ(111, gcodec.pltype);
1335 EXPECT_STREQ("opus", gcodec.plname);
1336 EXPECT_EQ(32000, gcodec.rate);
1337}
1338
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001339// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001340TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1341 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001342 std::vector<cricket::AudioCodec> codecs;
1343 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1344}
1345
1346// Test that we can set send codecs even with telephone-event codec as the first
1347// one on the list.
1348TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1349 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001350 int channel_num = voe_.GetLastChannel();
1351 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001352 codecs.push_back(kTelephoneEventCodec);
1353 codecs.push_back(kIsacCodec);
1354 codecs.push_back(kPcmuCodec);
1355 codecs[0].id = 98; // DTMF
1356 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001357 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1358 webrtc::CodecInst gcodec;
1359 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001360 EXPECT_EQ(96, gcodec.pltype);
1361 EXPECT_STREQ("ISAC", gcodec.plname);
1362 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1363}
1364
1365// Test that we can set send codecs even with CN codec as the first
1366// one on the list.
1367TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1368 EXPECT_TRUE(SetupEngine());
1369 int channel_num = voe_.GetLastChannel();
1370 std::vector<cricket::AudioCodec> codecs;
1371 codecs.push_back(kCn16000Codec);
1372 codecs.push_back(kIsacCodec);
1373 codecs.push_back(kPcmuCodec);
1374 codecs[0].id = 98; // wideband CN
1375 codecs[1].id = 96;
1376 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1377 webrtc::CodecInst gcodec;
1378 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1379 EXPECT_EQ(96, gcodec.pltype);
1380 EXPECT_STREQ("ISAC", gcodec.plname);
1381 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001382}
1383
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001384// Test that we set VAD and DTMF types correctly as caller.
1385TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001386 EXPECT_TRUE(SetupEngine());
1387 int channel_num = voe_.GetLastChannel();
1388 std::vector<cricket::AudioCodec> codecs;
1389 codecs.push_back(kIsacCodec);
1390 codecs.push_back(kPcmuCodec);
1391 // TODO(juberti): cn 32000
1392 codecs.push_back(kCn16000Codec);
1393 codecs.push_back(kCn8000Codec);
1394 codecs.push_back(kTelephoneEventCodec);
1395 codecs.push_back(kRedCodec);
1396 codecs[0].id = 96;
1397 codecs[2].id = 97; // wideband CN
1398 codecs[4].id = 98; // DTMF
1399 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1400 webrtc::CodecInst gcodec;
1401 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1402 EXPECT_EQ(96, gcodec.pltype);
1403 EXPECT_STREQ("ISAC", gcodec.plname);
1404 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001405 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1407 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1408 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1409}
1410
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001411// Test that we set VAD and DTMF types correctly as callee.
1412TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001413 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001414 channel_ = engine_.CreateChannel();
1415 EXPECT_TRUE(channel_ != NULL);
1416
1417 int channel_num = voe_.GetLastChannel();
1418 std::vector<cricket::AudioCodec> codecs;
1419 codecs.push_back(kIsacCodec);
1420 codecs.push_back(kPcmuCodec);
1421 // TODO(juberti): cn 32000
1422 codecs.push_back(kCn16000Codec);
1423 codecs.push_back(kCn8000Codec);
1424 codecs.push_back(kTelephoneEventCodec);
1425 codecs.push_back(kRedCodec);
1426 codecs[0].id = 96;
1427 codecs[2].id = 97; // wideband CN
1428 codecs[4].id = 98; // DTMF
1429 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1430 EXPECT_TRUE(channel_->AddSendStream(
1431 cricket::StreamParams::CreateLegacy(kSsrc1)));
1432
1433 webrtc::CodecInst gcodec;
1434 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1435 EXPECT_EQ(96, gcodec.pltype);
1436 EXPECT_STREQ("ISAC", gcodec.plname);
1437 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001438 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001439 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1440 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1441 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1442}
1443
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444// Test that we only apply VAD if we have a CN codec that matches the
1445// send codec clockrate.
1446TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1447 EXPECT_TRUE(SetupEngine());
1448 int channel_num = voe_.GetLastChannel();
1449 std::vector<cricket::AudioCodec> codecs;
1450 // Set ISAC(16K) and CN(16K). VAD should be activated.
1451 codecs.push_back(kIsacCodec);
1452 codecs.push_back(kCn16000Codec);
1453 codecs[1].id = 97;
1454 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1455 webrtc::CodecInst gcodec;
1456 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1457 EXPECT_STREQ("ISAC", gcodec.plname);
1458 EXPECT_TRUE(voe_.GetVAD(channel_num));
1459 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1460 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1461 codecs[0] = kPcmuCodec;
1462 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1463 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1464 EXPECT_STREQ("PCMU", gcodec.plname);
1465 EXPECT_FALSE(voe_.GetVAD(channel_num));
1466 // Set PCMU(8K) and CN(8K). VAD should be activated.
1467 codecs[1] = kCn8000Codec;
1468 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1469 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1470 EXPECT_STREQ("PCMU", gcodec.plname);
1471 EXPECT_TRUE(voe_.GetVAD(channel_num));
1472 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1473 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1474 codecs[0] = kIsacCodec;
1475 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1476 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1477 EXPECT_STREQ("ISAC", gcodec.plname);
1478 EXPECT_FALSE(voe_.GetVAD(channel_num));
1479}
1480
1481// Test that we perform case-insensitive matching of codec names.
1482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1483 EXPECT_TRUE(SetupEngine());
1484 int channel_num = voe_.GetLastChannel();
1485 std::vector<cricket::AudioCodec> codecs;
1486 codecs.push_back(kIsacCodec);
1487 codecs.push_back(kPcmuCodec);
1488 codecs.push_back(kCn16000Codec);
1489 codecs.push_back(kCn8000Codec);
1490 codecs.push_back(kTelephoneEventCodec);
1491 codecs.push_back(kRedCodec);
1492 codecs[0].name = "iSaC";
1493 codecs[0].id = 96;
1494 codecs[2].id = 97; // wideband CN
1495 codecs[4].id = 98; // DTMF
1496 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1497 webrtc::CodecInst gcodec;
1498 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1499 EXPECT_EQ(96, gcodec.pltype);
1500 EXPECT_STREQ("ISAC", gcodec.plname);
1501 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001502 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001503 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1504 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1505 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1506}
1507
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001508// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001510 EXPECT_TRUE(SetupEngine());
1511 int channel_num = voe_.GetLastChannel();
1512 std::vector<cricket::AudioCodec> codecs;
1513 codecs.push_back(kRedCodec);
1514 codecs.push_back(kIsacCodec);
1515 codecs.push_back(kPcmuCodec);
1516 codecs[0].id = 127;
1517 codecs[0].params[""] = "96/96";
1518 codecs[1].id = 96;
1519 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1520 webrtc::CodecInst gcodec;
1521 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1522 EXPECT_EQ(96, gcodec.pltype);
1523 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001524 EXPECT_TRUE(voe_.GetRED(channel_num));
1525 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001526}
1527
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001528// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001529TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001530 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001531 channel_ = engine_.CreateChannel();
1532 EXPECT_TRUE(channel_ != NULL);
1533
1534 int channel_num = voe_.GetLastChannel();
1535 std::vector<cricket::AudioCodec> codecs;
1536 codecs.push_back(kRedCodec);
1537 codecs.push_back(kIsacCodec);
1538 codecs.push_back(kPcmuCodec);
1539 codecs[0].id = 127;
1540 codecs[0].params[""] = "96/96";
1541 codecs[1].id = 96;
1542 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1543 EXPECT_TRUE(channel_->AddSendStream(
1544 cricket::StreamParams::CreateLegacy(kSsrc1)));
1545 webrtc::CodecInst gcodec;
1546 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1547 EXPECT_EQ(96, gcodec.pltype);
1548 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001549 EXPECT_TRUE(voe_.GetRED(channel_num));
1550 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001551}
1552
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001553// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1555 EXPECT_TRUE(SetupEngine());
1556 int channel_num = voe_.GetLastChannel();
1557 std::vector<cricket::AudioCodec> codecs;
1558 codecs.push_back(kRedCodec);
1559 codecs.push_back(kIsacCodec);
1560 codecs.push_back(kPcmuCodec);
1561 codecs[0].id = 127;
1562 codecs[1].id = 96;
1563 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1564 webrtc::CodecInst gcodec;
1565 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1566 EXPECT_EQ(96, gcodec.pltype);
1567 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001568 EXPECT_TRUE(voe_.GetRED(channel_num));
1569 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001570}
1571
1572// Test that we ignore RED if the parameters aren't named the way we expect.
1573TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1574 EXPECT_TRUE(SetupEngine());
1575 int channel_num = voe_.GetLastChannel();
1576 std::vector<cricket::AudioCodec> codecs;
1577 codecs.push_back(kRedCodec);
1578 codecs.push_back(kIsacCodec);
1579 codecs.push_back(kPcmuCodec);
1580 codecs[0].id = 127;
1581 codecs[0].params["ABC"] = "96/96";
1582 codecs[1].id = 96;
1583 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1584 webrtc::CodecInst gcodec;
1585 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1586 EXPECT_EQ(96, gcodec.pltype);
1587 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001588 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001589}
1590
1591// Test that we ignore RED if it uses different primary/secondary encoding.
1592TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1593 EXPECT_TRUE(SetupEngine());
1594 int channel_num = voe_.GetLastChannel();
1595 std::vector<cricket::AudioCodec> codecs;
1596 codecs.push_back(kRedCodec);
1597 codecs.push_back(kIsacCodec);
1598 codecs.push_back(kPcmuCodec);
1599 codecs[0].id = 127;
1600 codecs[0].params[""] = "96/0";
1601 codecs[1].id = 96;
1602 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1603 webrtc::CodecInst gcodec;
1604 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1605 EXPECT_EQ(96, gcodec.pltype);
1606 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001607 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608}
1609
1610// Test that we ignore RED if it uses more than 2 encodings.
1611TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1612 EXPECT_TRUE(SetupEngine());
1613 int channel_num = voe_.GetLastChannel();
1614 std::vector<cricket::AudioCodec> codecs;
1615 codecs.push_back(kRedCodec);
1616 codecs.push_back(kIsacCodec);
1617 codecs.push_back(kPcmuCodec);
1618 codecs[0].id = 127;
1619 codecs[0].params[""] = "96/96/96";
1620 codecs[1].id = 96;
1621 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1622 webrtc::CodecInst gcodec;
1623 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1624 EXPECT_EQ(96, gcodec.pltype);
1625 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001626 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001627}
1628
1629// Test that we ignore RED if it has bogus codec ids.
1630TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1631 EXPECT_TRUE(SetupEngine());
1632 int channel_num = voe_.GetLastChannel();
1633 std::vector<cricket::AudioCodec> codecs;
1634 codecs.push_back(kRedCodec);
1635 codecs.push_back(kIsacCodec);
1636 codecs.push_back(kPcmuCodec);
1637 codecs[0].id = 127;
1638 codecs[0].params[""] = "ABC/ABC";
1639 codecs[1].id = 96;
1640 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1641 webrtc::CodecInst gcodec;
1642 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1643 EXPECT_EQ(96, gcodec.pltype);
1644 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001645 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001646}
1647
1648// Test that we ignore RED if it refers to a codec that is not present.
1649TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1650 EXPECT_TRUE(SetupEngine());
1651 int channel_num = voe_.GetLastChannel();
1652 std::vector<cricket::AudioCodec> codecs;
1653 codecs.push_back(kRedCodec);
1654 codecs.push_back(kIsacCodec);
1655 codecs.push_back(kPcmuCodec);
1656 codecs[0].id = 127;
1657 codecs[0].params[""] = "97/97";
1658 codecs[1].id = 96;
1659 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1660 webrtc::CodecInst gcodec;
1661 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1662 EXPECT_EQ(96, gcodec.pltype);
1663 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001664 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001665}
1666
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001667// Test support for audio level header extension.
1668TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1669 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001670}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001671TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1672 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1673}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001674
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001675// Test support for absolute send time header extension.
1676TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1677 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1678}
1679TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1680 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001681}
1682
1683// Test that we can create a channel and start sending/playing out on it.
1684TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1685 EXPECT_TRUE(SetupEngine());
1686 int channel_num = voe_.GetLastChannel();
1687 std::vector<cricket::AudioCodec> codecs;
1688 codecs.push_back(kPcmuCodec);
1689 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1690 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1691 EXPECT_TRUE(voe_.GetSend(channel_num));
1692 EXPECT_TRUE(channel_->SetPlayout(true));
1693 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1694 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1695 EXPECT_FALSE(voe_.GetSend(channel_num));
1696 EXPECT_TRUE(channel_->SetPlayout(false));
1697 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1698}
1699
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001700// Test that we can add and remove send streams.
1701TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1702 SetupForMultiSendStream();
1703
1704 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1705
1706 // Set the global state for sending.
1707 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1708
1709 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1710 EXPECT_TRUE(channel_->AddSendStream(
1711 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1712
1713 // Verify that we are in a sending state for all the created streams.
1714 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1715 EXPECT_TRUE(voe_.GetSend(channel_num));
1716 }
1717
1718 // Remove the first send channel, which is the default channel. It will only
1719 // recycle the default channel but not delete it.
1720 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1721 // Stream should already be Removed from the send stream list.
1722 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1723 // But the default still exists.
1724 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1725
1726 // Delete the rest of send channel streams.
1727 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1728 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1729 // Stream should already be deleted.
1730 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1731 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1732 }
1733}
1734
1735// Test SetSendCodecs correctly configure the codecs in all send streams.
1736TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1737 SetupForMultiSendStream();
1738
1739 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1740 // Create send streams.
1741 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1742 EXPECT_TRUE(channel_->AddSendStream(
1743 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1744 }
1745
1746 std::vector<cricket::AudioCodec> codecs;
1747 // Set ISAC(16K) and CN(16K). VAD should be activated.
1748 codecs.push_back(kIsacCodec);
1749 codecs.push_back(kCn16000Codec);
1750 codecs[1].id = 97;
1751 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1752
1753 // Verify ISAC and VAD are corrected configured on all send channels.
1754 webrtc::CodecInst gcodec;
1755 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1756 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1757 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1758 EXPECT_STREQ("ISAC", gcodec.plname);
1759 EXPECT_TRUE(voe_.GetVAD(channel_num));
1760 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1761 }
1762
1763 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1764 codecs[0] = kPcmuCodec;
1765 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1766 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1767 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1768 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1769 EXPECT_STREQ("PCMU", gcodec.plname);
1770 EXPECT_FALSE(voe_.GetVAD(channel_num));
1771 }
1772}
1773
1774// Test we can SetSend on all send streams correctly.
1775TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1776 SetupForMultiSendStream();
1777
1778 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1779 // Create the send channels and they should be a SEND_NOTHING date.
1780 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1781 EXPECT_TRUE(channel_->AddSendStream(
1782 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1783 int channel_num = voe_.GetLastChannel();
1784 EXPECT_FALSE(voe_.GetSend(channel_num));
1785 }
1786
1787 // Set the global state for starting sending.
1788 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1789 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1790 // Verify that we are in a sending state for all the send streams.
1791 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1792 EXPECT_TRUE(voe_.GetSend(channel_num));
1793 }
1794
1795 // Set the global state for stopping sending.
1796 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1797 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1798 // Verify that we are in a stop state for all the send streams.
1799 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1800 EXPECT_FALSE(voe_.GetSend(channel_num));
1801 }
1802}
1803
1804// Test we can set the correct statistics on all send streams.
1805TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1806 SetupForMultiSendStream();
1807
1808 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1809 // Create send streams.
1810 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1811 EXPECT_TRUE(channel_->AddSendStream(
1812 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1813 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001814 // Create a receive stream to check that none of the send streams end up in
1815 // the receive stream stats.
1816 EXPECT_TRUE(channel_->AddRecvStream(
1817 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001818 // We need send codec to be set to get all stats.
1819 std::vector<cricket::AudioCodec> codecs;
1820 codecs.push_back(kPcmuCodec);
1821 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001822 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001823
1824 cricket::VoiceMediaInfo info;
1825 EXPECT_EQ(true, channel_->GetStats(&info));
1826 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1827
1828 // Verify the statistic information is correct.
1829 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001830 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001831 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1832 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1833 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1834 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1835 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1836 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1837 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1838 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001839 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001840 }
1841
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001842 EXPECT_EQ(0u, info.receivers.size());
1843 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1844 EXPECT_EQ(true, channel_->GetStats(&info));
1845
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001846 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001847 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
1848 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
1849 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
1850 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
1851 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001852}
1853
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001854// Test that we can add and remove receive streams, and do proper send/playout.
1855// We can receive on multiple streams while sending one stream.
1856TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001857 EXPECT_TRUE(SetupEngine());
1858 int channel_num1 = voe_.GetLastChannel();
1859
1860 // Start playout on the default channel.
1861 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1862 EXPECT_TRUE(channel_->SetPlayout(true));
1863 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1864
1865 // Adding another stream should disable playout on the default channel.
1866 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1867 int channel_num2 = voe_.GetLastChannel();
1868 std::vector<cricket::AudioCodec> codecs;
1869 codecs.push_back(kPcmuCodec);
1870 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1871 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1872 EXPECT_TRUE(voe_.GetSend(channel_num1));
1873 EXPECT_FALSE(voe_.GetSend(channel_num2));
1874
1875 // Make sure only the new channel is played out.
1876 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1877 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1878
1879 // Adding yet another stream should have stream 2 and 3 enabled for playout.
1880 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1881 int channel_num3 = voe_.GetLastChannel();
1882 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1883 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1884 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1885 EXPECT_FALSE(voe_.GetSend(channel_num3));
1886
1887 // Stop sending.
1888 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1889 EXPECT_FALSE(voe_.GetSend(channel_num1));
1890 EXPECT_FALSE(voe_.GetSend(channel_num2));
1891 EXPECT_FALSE(voe_.GetSend(channel_num3));
1892
1893 // Stop playout.
1894 EXPECT_TRUE(channel_->SetPlayout(false));
1895 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1896 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1897 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1898
1899 // Restart playout and make sure the default channel still is not played out.
1900 EXPECT_TRUE(channel_->SetPlayout(true));
1901 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1902 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1903 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1904
1905 // Now remove the new streams and verify that the default channel is
1906 // played out again.
1907 EXPECT_TRUE(channel_->RemoveRecvStream(3));
1908 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1909
1910 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1911}
1912
1913// Test that we can set the devices to use.
1914TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1915 EXPECT_TRUE(SetupEngine());
1916 int channel_num = voe_.GetLastChannel();
1917 std::vector<cricket::AudioCodec> codecs;
1918 codecs.push_back(kPcmuCodec);
1919 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1920
1921 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1922 cricket::kFakeDefaultDeviceId);
1923 cricket::Device dev(cricket::kFakeDeviceName,
1924 cricket::kFakeDeviceId);
1925
1926 // Test SetDevices() while not sending or playing.
1927 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1928
1929 // Test SetDevices() while sending and playing.
1930 EXPECT_TRUE(engine_.SetLocalMonitor(true));
1931 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1932 EXPECT_TRUE(channel_->SetPlayout(true));
1933 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1934 EXPECT_TRUE(voe_.GetSend(channel_num));
1935 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1936
1937 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1938
1939 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1940 EXPECT_TRUE(voe_.GetSend(channel_num));
1941 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1942
1943 // Test that failure to open newly selected devices does not prevent opening
1944 // ones after that.
1945 voe_.set_fail_start_recording_microphone(true);
1946 voe_.set_playout_fail_channel(channel_num);
1947 voe_.set_send_fail_channel(channel_num);
1948
1949 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1950
1951 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1952 EXPECT_FALSE(voe_.GetSend(channel_num));
1953 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1954
1955 voe_.set_fail_start_recording_microphone(false);
1956 voe_.set_playout_fail_channel(-1);
1957 voe_.set_send_fail_channel(-1);
1958
1959 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1960
1961 EXPECT_TRUE(voe_.GetRecordingMicrophone());
1962 EXPECT_TRUE(voe_.GetSend(channel_num));
1963 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1964}
1965
1966// Test that we can set the devices to use even if we failed to
1967// open the initial ones.
1968TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1969 EXPECT_TRUE(SetupEngine());
1970 int channel_num = voe_.GetLastChannel();
1971 std::vector<cricket::AudioCodec> codecs;
1972 codecs.push_back(kPcmuCodec);
1973 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1974
1975 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1976 cricket::kFakeDefaultDeviceId);
1977 cricket::Device dev(cricket::kFakeDeviceName,
1978 cricket::kFakeDeviceId);
1979
1980 // Test that failure to open devices selected before starting
1981 // send/play does not prevent opening newly selected ones after that.
1982 voe_.set_fail_start_recording_microphone(true);
1983 voe_.set_playout_fail_channel(channel_num);
1984 voe_.set_send_fail_channel(channel_num);
1985
1986 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1987
1988 EXPECT_FALSE(engine_.SetLocalMonitor(true));
1989 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
1990 EXPECT_FALSE(channel_->SetPlayout(true));
1991 EXPECT_FALSE(voe_.GetRecordingMicrophone());
1992 EXPECT_FALSE(voe_.GetSend(channel_num));
1993 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1994
1995 voe_.set_fail_start_recording_microphone(false);
1996 voe_.set_playout_fail_channel(-1);
1997 voe_.set_send_fail_channel(-1);
1998
1999 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2000
2001 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2002 EXPECT_TRUE(voe_.GetSend(channel_num));
2003 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2004}
2005
2006// Test that we can create a channel configured for multi-point conferences,
2007// and start sending/playing out on it.
2008TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2009 EXPECT_TRUE(SetupEngine());
2010 int channel_num = voe_.GetLastChannel();
2011 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2012 std::vector<cricket::AudioCodec> codecs;
2013 codecs.push_back(kPcmuCodec);
2014 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2015 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2016 EXPECT_TRUE(voe_.GetSend(channel_num));
2017}
2018
2019// Test that we can create a channel configured for Codian bridges,
2020// and start sending/playing out on it.
2021TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2022 EXPECT_TRUE(SetupEngine());
2023 int channel_num = voe_.GetLastChannel();
2024 webrtc::AgcConfig agc_config;
2025 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2026 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2027 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2028 std::vector<cricket::AudioCodec> codecs;
2029 codecs.push_back(kPcmuCodec);
2030 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2031 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2032 EXPECT_TRUE(voe_.GetSend(channel_num));
2033 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2034 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2035 EXPECT_TRUE(channel_->SetPlayout(true));
2036 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2037 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2038 EXPECT_FALSE(voe_.GetSend(channel_num));
2039 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2040 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2041 EXPECT_TRUE(channel_->SetPlayout(false));
2042 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2043}
2044
wu@webrtc.org97077a32013-10-25 21:18:33 +00002045TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2046 EXPECT_TRUE(SetupEngine());
2047 webrtc::AgcConfig agc_config;
2048 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2049 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2050
2051 cricket::AudioOptions options;
2052 options.tx_agc_target_dbov.Set(3);
2053 options.tx_agc_digital_compression_gain.Set(9);
2054 options.tx_agc_limiter.Set(true);
2055 options.auto_gain_control.Set(true);
2056 EXPECT_TRUE(engine_.SetOptions(options));
2057
2058 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2059 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2060 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2061 EXPECT_TRUE(agc_config.limiterEnable);
2062
2063 // Check interaction with adjust_agc_delta. Both should be respected, for
2064 // backwards compatibility.
2065 options.adjust_agc_delta.Set(-10);
2066 EXPECT_TRUE(engine_.SetOptions(options));
2067
2068 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2069 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2070}
2071
2072TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2073 EXPECT_TRUE(SetupEngine());
2074 int channel_num = voe_.GetLastChannel();
2075 cricket::AudioOptions options;
2076 options.rx_agc_target_dbov.Set(6);
2077 options.rx_agc_digital_compression_gain.Set(0);
2078 options.rx_agc_limiter.Set(true);
2079 options.rx_auto_gain_control.Set(true);
2080 EXPECT_TRUE(channel_->SetOptions(options));
2081
2082 webrtc::AgcConfig agc_config;
2083 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2084 channel_num, agc_config));
2085 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2086 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2087 EXPECT_TRUE(agc_config.limiterEnable);
2088}
2089
2090TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2091 EXPECT_TRUE(SetupEngine());
2092 cricket::AudioOptions options;
2093 options.recording_sample_rate.Set(48000u);
2094 options.playout_sample_rate.Set(44100u);
2095 EXPECT_TRUE(engine_.SetOptions(options));
2096
2097 unsigned int recording_sample_rate, playout_sample_rate;
2098 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2099 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2100 EXPECT_EQ(48000u, recording_sample_rate);
2101 EXPECT_EQ(44100u, playout_sample_rate);
2102}
2103
2104TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2105 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002106 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002107 EXPECT_EQ(
2108 // Info:
2109 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2110 // Warning:
2111 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2112 // Error:
2113 webrtc::kTraceError | webrtc::kTraceCritical,
2114 static_cast<int>(trace_wrapper_->filter_));
2115 // Now set it explicitly
2116 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002117 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2118 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002119 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2120 trace_wrapper_->filter_);
2121}
2122
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002123// Test that we can set the outgoing SSRC properly.
2124// SSRC is set in SetupEngine by calling AddSendStream.
2125TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2126 EXPECT_TRUE(SetupEngine());
2127 int channel_num = voe_.GetLastChannel();
2128 unsigned int send_ssrc;
2129 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2130 EXPECT_NE(0U, send_ssrc);
2131 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2132 EXPECT_EQ(kSsrc1, send_ssrc);
2133}
2134
2135TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2136 // Setup. We need send codec to be set to get all stats.
2137 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002138 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2139 // use a different SSRC.
2140 EXPECT_TRUE(channel_->AddRecvStream(
2141 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002142 std::vector<cricket::AudioCodec> codecs;
2143 codecs.push_back(kPcmuCodec);
2144 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002145 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002146
2147 cricket::VoiceMediaInfo info;
2148 EXPECT_EQ(true, channel_->GetStats(&info));
2149 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002150 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002151 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2152 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2153 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2154 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2155 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2156 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2157 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2158 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002159 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002160 // TODO(sriniv): Add testing for more fields. These are not populated
2161 // in FakeWebrtcVoiceEngine yet.
2162 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2163 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2164 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2165 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2166 // EXPECT_EQ(cricket::kIntStatValue,
2167 // info.senders[0].echo_return_loss_enhancement);
2168
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002169 EXPECT_EQ(0u, info.receivers.size());
2170 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2171 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002172 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002173
2174 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2175 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2176 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2177 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2178 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
2179 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180}
2181
2182// Test that we can set the outgoing SSRC properly with multiple streams.
2183// SSRC is set in SetupEngine by calling AddSendStream.
2184TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2185 EXPECT_TRUE(SetupEngine());
2186 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2187 int channel_num1 = voe_.GetLastChannel();
2188 unsigned int send_ssrc;
2189 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2190 EXPECT_EQ(kSsrc1, send_ssrc);
2191
2192 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2193 int channel_num2 = voe_.GetLastChannel();
2194 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2195 EXPECT_EQ(kSsrc1, send_ssrc);
2196}
2197
2198// Test that the local SSRC is the same on sending and receiving channels if the
2199// receive channel is created before the send channel.
2200TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002201 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202 channel_ = engine_.CreateChannel();
2203 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2204
2205 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2206 int receive_channel_num = voe_.GetLastChannel();
2207 EXPECT_TRUE(channel_->AddSendStream(
2208 cricket::StreamParams::CreateLegacy(1234)));
2209 int send_channel_num = voe_.GetLastChannel();
2210
2211 unsigned int ssrc = 0;
2212 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2213 EXPECT_EQ(1234U, ssrc);
2214 ssrc = 0;
2215 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2216 EXPECT_EQ(1234U, ssrc);
2217}
2218
2219// Test that we can properly receive packets.
2220TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2221 EXPECT_TRUE(SetupEngine());
2222 int channel_num = voe_.GetLastChannel();
2223 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2224 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2225 sizeof(kPcmuFrame)));
2226}
2227
2228// Test that we can properly receive packets on multiple streams.
2229TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2230 EXPECT_TRUE(SetupEngine());
2231 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2232 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2233 int channel_num1 = voe_.GetLastChannel();
2234 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2235 int channel_num2 = voe_.GetLastChannel();
2236 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2237 int channel_num3 = voe_.GetLastChannel();
2238 // Create packets with the right SSRCs.
2239 char packets[4][sizeof(kPcmuFrame)];
2240 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2241 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002242 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002243 }
2244 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2245 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2246 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2247 DeliverPacket(packets[0], sizeof(packets[0]));
2248 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2249 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2250 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2251 DeliverPacket(packets[1], sizeof(packets[1]));
2252 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2253 sizeof(packets[1])));
2254 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2255 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2256 DeliverPacket(packets[2], sizeof(packets[2]));
2257 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2258 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2259 sizeof(packets[2])));
2260 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2261 DeliverPacket(packets[3], sizeof(packets[3]));
2262 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2263 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2264 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2265 sizeof(packets[3])));
2266 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2267 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2268 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2269}
2270
2271// Test that we properly handle failures to add a stream.
2272TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2273 EXPECT_TRUE(SetupEngine());
2274 voe_.set_fail_create_channel(true);
2275 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2276 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2277
2278 // In 1:1 call, we should not try to create a new channel.
2279 cricket::AudioOptions options_no_conference_;
2280 options_no_conference_.conference_mode.Set(false);
2281 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2282 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2283}
2284
2285// Test that AddRecvStream doesn't create new channel for 1:1 call.
2286TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2287 EXPECT_TRUE(SetupEngine());
2288 int channel_num = voe_.GetLastChannel();
2289 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2290 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2291}
2292
2293// Test that after adding a recv stream, we do not decode more codecs than
2294// those previously passed into SetRecvCodecs.
2295TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2296 EXPECT_TRUE(SetupEngine());
2297 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2298 std::vector<cricket::AudioCodec> codecs;
2299 codecs.push_back(kIsacCodec);
2300 codecs.push_back(kPcmuCodec);
2301 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2302 EXPECT_TRUE(channel_->AddRecvStream(
2303 cricket::StreamParams::CreateLegacy(kSsrc1)));
2304 int channel_num2 = voe_.GetLastChannel();
2305 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002306 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307 gcodec.plfreq = 32000;
2308 gcodec.channels = 2;
2309 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2310}
2311
2312// Test that we properly clean up any streams that were added, even if
2313// not explicitly removed.
2314TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2315 EXPECT_TRUE(SetupEngine());
2316 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2317 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2318 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2319 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2320 delete channel_;
2321 channel_ = NULL;
2322 EXPECT_EQ(0, voe_.GetNumChannels());
2323}
2324
wu@webrtc.org78187522013-10-07 23:32:02 +00002325TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2326 EXPECT_TRUE(SetupEngine());
2327 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2328}
2329
2330TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2331 EXPECT_TRUE(SetupEngine());
2332 // Stream 1 reuses default channel.
2333 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2334 // Manually delete default channel to simulate a failure.
2335 int default_channel = voe_.GetLastChannel();
2336 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2337 // Add recv stream 2 should fail because default channel is gone.
2338 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2339 int new_channel = voe_.GetLastChannel();
2340 EXPECT_NE(default_channel, new_channel);
2341 // The last created channel should have already been deleted.
2342 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2343}
2344
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002345// Test the InsertDtmf on default send stream as caller.
2346TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2347 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002348}
2349
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002350// Test the InsertDtmf on default send stream as callee
2351TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2352 TestInsertDtmf(0, false);
2353}
2354
2355// Test the InsertDtmf on specified send stream as caller.
2356TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2357 TestInsertDtmf(kSsrc1, true);
2358}
2359
2360// Test the InsertDtmf on specified send stream as callee.
2361TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2362 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363}
2364
2365// Test that we can play a ringback tone properly in a single-stream call.
2366TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2367 EXPECT_TRUE(SetupEngine());
2368 int channel_num = voe_.GetLastChannel();
2369 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2370 // Check we fail if no ringback tone specified.
2371 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2372 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2373 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002374 EXPECT_TRUE(channel_->SetRingbackTone(
2375 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002376 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2377 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2378 // Check we can stop the tone manually.
2379 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2380 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2381 // Check we stop the tone if a packet arrives.
2382 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2383 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2384 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2385 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2386}
2387
2388// Test that we can play a ringback tone properly in a multi-stream call.
2389TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2390 EXPECT_TRUE(SetupEngine());
2391 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2392 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2393 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2394 int channel_num = voe_.GetLastChannel();
2395 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2396 // Check we fail if no ringback tone specified.
2397 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2398 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2399 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002400 EXPECT_TRUE(channel_->SetRingbackTone(
2401 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002402 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2403 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2404 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2405 // Check we can stop the tone manually.
2406 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2407 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2408 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2409 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2410 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2411 // Send a packet with SSRC 1; the tone should not stop.
2412 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2413 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2414 // Send a packet with SSRC 2; the tone should stop.
2415 char packet[sizeof(kPcmuFrame)];
2416 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002417 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418 DeliverPacket(packet, sizeof(packet));
2419 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2420}
2421
2422// Tests creating soundclips, and make sure they come from the right engine.
2423TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002424 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002425 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002426 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002427 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428 ASSERT_TRUE(soundclip_ != NULL);
2429 EXPECT_EQ(0, voe_.GetNumChannels());
2430 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2431 int channel_num = voe_sc_.GetLastChannel();
2432 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2433 delete soundclip_;
2434 soundclip_ = NULL;
2435 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002436 // Make sure the soundclip engine is uninitialized on shutdown, now that
2437 // we've initialized it by creating a soundclip.
2438 engine_.Terminate();
2439 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440}
2441
2442// Tests playing out a fake sound.
2443TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2444 static const char kZeroes[16000] = {};
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002445 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002446 soundclip_ = engine_.CreateSoundclip();
2447 ASSERT_TRUE(soundclip_ != NULL);
2448 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2449}
2450
2451TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002452 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 cricket::WebRtcVoiceMediaChannel* media_channel;
2454 unsigned int ssrc = 0;
2455
2456 EXPECT_TRUE(SetupEngine());
2457 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2458 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2459
2460 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2461 listener.reset(new ChannelErrorListener(channel_));
2462
2463 // Test on WebRtc VoE channel.
2464 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2465 VE_SATURATION_WARNING);
2466 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2467 listener->error());
2468 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2469 EXPECT_EQ(ssrc, listener->ssrc());
2470
2471 listener->Reset();
2472 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2473 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2474 listener->error());
2475 EXPECT_EQ(0U, listener->ssrc());
2476
2477 // Add another stream and test on that.
2478 ++ssrc;
2479 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2480 ssrc)));
2481 listener->Reset();
2482 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2483 VE_SATURATION_WARNING);
2484 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2485 listener->error());
2486 EXPECT_EQ(ssrc, listener->ssrc());
2487
2488 // Testing a non-existing channel.
2489 listener->Reset();
2490 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2491 VE_SATURATION_WARNING);
2492 EXPECT_EQ(0, listener->error());
2493}
2494
2495TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2496 EXPECT_TRUE(SetupEngine());
2497 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2498 std::vector<cricket::AudioCodec> codecs;
2499 codecs.push_back(kPcmuCodec);
2500 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2501 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2502 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2503 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2504 EXPECT_TRUE(channel_->SetPlayout(true));
2505 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2506 EXPECT_TRUE(channel_->SetPlayout(false));
2507 EXPECT_FALSE(channel_->SetPlayout(true));
2508}
2509
2510// Test that the Registering/Unregistering with the
2511// webrtcvoiceengine works as expected
2512TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2513 EXPECT_TRUE(SetupEngine());
2514 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2515 EXPECT_TRUE(channel_->AddRecvStream(
2516 cricket::StreamParams::CreateLegacy(kSsrc2)));
2517 cricket::FakeMediaProcessor vp_1;
2518 cricket::FakeMediaProcessor vp_2;
2519
2520 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2521 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2522 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2523 voe_.TriggerProcessPacket(cricket::MPD_RX);
2524 voe_.TriggerProcessPacket(cricket::MPD_TX);
2525
2526 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2527 EXPECT_EQ(1, vp_1.voice_frame_count());
2528 EXPECT_EQ(1, vp_2.voice_frame_count());
2529
2530 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2531 &vp_2,
2532 cricket::MPD_RX));
2533 voe_.TriggerProcessPacket(cricket::MPD_RX);
2534 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2535 EXPECT_EQ(1, vp_2.voice_frame_count());
2536 EXPECT_EQ(2, vp_1.voice_frame_count());
2537
2538 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2539 &vp_1,
2540 cricket::MPD_RX));
2541 voe_.TriggerProcessPacket(cricket::MPD_RX);
2542 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2543 EXPECT_EQ(2, vp_1.voice_frame_count());
2544
2545 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2546 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2547 voe_.TriggerProcessPacket(cricket::MPD_RX);
2548 voe_.TriggerProcessPacket(cricket::MPD_TX);
2549 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2550 EXPECT_EQ(3, vp_1.voice_frame_count());
2551
2552 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2553 &vp_1,
2554 cricket::MPD_RX_AND_TX));
2555 voe_.TriggerProcessPacket(cricket::MPD_TX);
2556 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2557 EXPECT_EQ(3, vp_1.voice_frame_count());
2558 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2559 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2560 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2561
2562 // Test that we can register a processor on the receive channel on SSRC 0.
2563 // This tests the 1:1 case when the receive SSRC is unknown.
2564 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2565 voe_.TriggerProcessPacket(cricket::MPD_RX);
2566 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2567 EXPECT_EQ(4, vp_1.voice_frame_count());
2568 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2569 &vp_1,
2570 cricket::MPD_RX));
2571
2572 // The following tests test that FindChannelNumFromSsrc is doing
2573 // what we expect.
2574 // pick an invalid ssrc and make sure we can't register
2575 EXPECT_FALSE(engine_.RegisterProcessor(99,
2576 &vp_1,
2577 cricket::MPD_RX));
2578 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2579 EXPECT_TRUE(engine_.RegisterProcessor(1,
2580 &vp_1,
2581 cricket::MPD_RX));
2582 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2583 &vp_1,
2584 cricket::MPD_RX));
2585 EXPECT_FALSE(engine_.RegisterProcessor(1,
2586 &vp_1,
2587 cricket::MPD_TX));
2588 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2589}
2590
2591TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2592 EXPECT_TRUE(SetupEngine());
2593
2594 bool ec_enabled;
2595 webrtc::EcModes ec_mode;
2596 bool ec_metrics_enabled;
2597 webrtc::AecmModes aecm_mode;
2598 bool cng_enabled;
2599 bool agc_enabled;
2600 webrtc::AgcModes agc_mode;
2601 webrtc::AgcConfig agc_config;
2602 bool ns_enabled;
2603 webrtc::NsModes ns_mode;
2604 bool highpass_filter_enabled;
2605 bool stereo_swapping_enabled;
2606 bool typing_detection_enabled;
2607 voe_.GetEcStatus(ec_enabled, ec_mode);
2608 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2609 voe_.GetAecmMode(aecm_mode, cng_enabled);
2610 voe_.GetAgcStatus(agc_enabled, agc_mode);
2611 voe_.GetAgcConfig(agc_config);
2612 voe_.GetNsStatus(ns_enabled, ns_mode);
2613 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2614 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2615 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2616 EXPECT_TRUE(ec_enabled);
2617 EXPECT_TRUE(ec_metrics_enabled);
2618 EXPECT_FALSE(cng_enabled);
2619 EXPECT_TRUE(agc_enabled);
2620 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2621 EXPECT_TRUE(ns_enabled);
2622 EXPECT_TRUE(highpass_filter_enabled);
2623 EXPECT_FALSE(stereo_swapping_enabled);
2624 EXPECT_TRUE(typing_detection_enabled);
2625 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2626 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2627
2628 // Nothing set, so all ignored.
2629 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002630 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002631 voe_.GetEcStatus(ec_enabled, ec_mode);
2632 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2633 voe_.GetAecmMode(aecm_mode, cng_enabled);
2634 voe_.GetAgcStatus(agc_enabled, agc_mode);
2635 voe_.GetAgcConfig(agc_config);
2636 voe_.GetNsStatus(ns_enabled, ns_mode);
2637 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2638 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2639 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2640 EXPECT_TRUE(ec_enabled);
2641 EXPECT_TRUE(ec_metrics_enabled);
2642 EXPECT_FALSE(cng_enabled);
2643 EXPECT_TRUE(agc_enabled);
2644 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2645 EXPECT_TRUE(ns_enabled);
2646 EXPECT_TRUE(highpass_filter_enabled);
2647 EXPECT_FALSE(stereo_swapping_enabled);
2648 EXPECT_TRUE(typing_detection_enabled);
2649 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2650 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2651
2652 // Turn echo cancellation off
2653 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002654 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002655 voe_.GetEcStatus(ec_enabled, ec_mode);
2656 EXPECT_FALSE(ec_enabled);
2657
2658 // Turn echo cancellation back on, with settings, and make sure
2659 // nothing else changed.
2660 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002661 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002662 voe_.GetEcStatus(ec_enabled, ec_mode);
2663 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2664 voe_.GetAecmMode(aecm_mode, cng_enabled);
2665 voe_.GetAgcStatus(agc_enabled, agc_mode);
2666 voe_.GetAgcConfig(agc_config);
2667 voe_.GetNsStatus(ns_enabled, ns_mode);
2668 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2669 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2670 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2671 EXPECT_TRUE(ec_enabled);
2672 EXPECT_TRUE(ec_metrics_enabled);
2673 EXPECT_TRUE(agc_enabled);
2674 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2675 EXPECT_TRUE(ns_enabled);
2676 EXPECT_TRUE(highpass_filter_enabled);
2677 EXPECT_FALSE(stereo_swapping_enabled);
2678 EXPECT_TRUE(typing_detection_enabled);
2679 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2680 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2681
2682 // Turn off AGC
2683 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002684 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002685 voe_.GetAgcStatus(agc_enabled, agc_mode);
2686 EXPECT_FALSE(agc_enabled);
2687
2688 // Turn AGC back on
2689 options.auto_gain_control.Set(true);
2690 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002691 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002692 voe_.GetAgcStatus(agc_enabled, agc_mode);
2693 EXPECT_TRUE(agc_enabled);
2694 voe_.GetAgcConfig(agc_config);
2695 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2696
2697 // Turn off other options (and stereo swapping on).
2698 options.noise_suppression.Set(false);
2699 options.highpass_filter.Set(false);
2700 options.typing_detection.Set(false);
2701 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002702 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002703 voe_.GetNsStatus(ns_enabled, ns_mode);
2704 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2705 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2706 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2707 EXPECT_FALSE(ns_enabled);
2708 EXPECT_FALSE(highpass_filter_enabled);
2709 EXPECT_FALSE(typing_detection_enabled);
2710 EXPECT_TRUE(stereo_swapping_enabled);
2711
2712 // Turn on "conference mode" to ensure it has no impact.
2713 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002714 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715 voe_.GetEcStatus(ec_enabled, ec_mode);
2716 voe_.GetNsStatus(ns_enabled, ns_mode);
2717 EXPECT_TRUE(ec_enabled);
2718 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2719 EXPECT_FALSE(ns_enabled);
2720 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2721}
2722
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002723TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002724 EXPECT_TRUE(SetupEngine());
2725
2726 bool ec_enabled;
2727 webrtc::EcModes ec_mode;
2728 bool ec_metrics_enabled;
2729 bool agc_enabled;
2730 webrtc::AgcModes agc_mode;
2731 bool ns_enabled;
2732 webrtc::NsModes ns_mode;
2733 bool highpass_filter_enabled;
2734 bool stereo_swapping_enabled;
2735 bool typing_detection_enabled;
2736
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002737 voe_.GetEcStatus(ec_enabled, ec_mode);
2738 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2739 voe_.GetAgcStatus(agc_enabled, agc_mode);
2740 voe_.GetNsStatus(ns_enabled, ns_mode);
2741 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2742 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2743 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2744 EXPECT_TRUE(ec_enabled);
2745 EXPECT_TRUE(agc_enabled);
2746 EXPECT_TRUE(ns_enabled);
2747 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002748 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002749 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002750}
2751
2752TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2753 webrtc::AgcConfig set_config = {0};
2754 set_config.targetLeveldBOv = 3;
2755 set_config.digitalCompressionGaindB = 9;
2756 set_config.limiterEnable = true;
2757 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002758 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002759
2760 webrtc::AgcConfig config = {0};
2761 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2762 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2763 EXPECT_EQ(set_config.digitalCompressionGaindB,
2764 config.digitalCompressionGaindB);
2765 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2766}
2767
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002768TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2769 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002770 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002771 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002772 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002773 engine_.CreateChannel());
2774
2775 // Have to add a stream to make SetSend work.
2776 cricket::StreamParams stream1;
2777 stream1.ssrcs.push_back(1);
2778 channel1->AddSendStream(stream1);
2779 cricket::StreamParams stream2;
2780 stream2.ssrcs.push_back(2);
2781 channel2->AddSendStream(stream2);
2782
2783 // AEC and AGC and NS
2784 cricket::AudioOptions options_all;
2785 options_all.echo_cancellation.Set(true);
2786 options_all.auto_gain_control.Set(true);
2787 options_all.noise_suppression.Set(true);
2788
2789 ASSERT_TRUE(channel1->SetOptions(options_all));
2790 cricket::AudioOptions expected_options = options_all;
2791 cricket::AudioOptions actual_options;
2792 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2793 EXPECT_EQ(expected_options, actual_options);
2794 ASSERT_TRUE(channel2->SetOptions(options_all));
2795 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2796 EXPECT_EQ(expected_options, actual_options);
2797
2798 // unset NS
2799 cricket::AudioOptions options_no_ns;
2800 options_no_ns.noise_suppression.Set(false);
2801 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2802
2803 expected_options.echo_cancellation.Set(true);
2804 expected_options.auto_gain_control.Set(true);
2805 expected_options.noise_suppression.Set(false);
2806 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2807 EXPECT_EQ(expected_options, actual_options);
2808
2809 // unset AGC
2810 cricket::AudioOptions options_no_agc;
2811 options_no_agc.auto_gain_control.Set(false);
2812 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2813
2814 expected_options.echo_cancellation.Set(true);
2815 expected_options.auto_gain_control.Set(false);
2816 expected_options.noise_suppression.Set(true);
2817 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2818 EXPECT_EQ(expected_options, actual_options);
2819
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002820 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002821 bool ec_enabled;
2822 webrtc::EcModes ec_mode;
2823 bool agc_enabled;
2824 webrtc::AgcModes agc_mode;
2825 bool ns_enabled;
2826 webrtc::NsModes ns_mode;
2827 voe_.GetEcStatus(ec_enabled, ec_mode);
2828 voe_.GetAgcStatus(agc_enabled, agc_mode);
2829 voe_.GetNsStatus(ns_enabled, ns_mode);
2830 EXPECT_TRUE(ec_enabled);
2831 EXPECT_TRUE(agc_enabled);
2832 EXPECT_TRUE(ns_enabled);
2833
2834 channel1->SetSend(cricket::SEND_MICROPHONE);
2835 voe_.GetEcStatus(ec_enabled, ec_mode);
2836 voe_.GetAgcStatus(agc_enabled, agc_mode);
2837 voe_.GetNsStatus(ns_enabled, ns_mode);
2838 EXPECT_TRUE(ec_enabled);
2839 EXPECT_TRUE(agc_enabled);
2840 EXPECT_FALSE(ns_enabled);
2841
2842 channel1->SetSend(cricket::SEND_NOTHING);
2843 voe_.GetEcStatus(ec_enabled, ec_mode);
2844 voe_.GetAgcStatus(agc_enabled, agc_mode);
2845 voe_.GetNsStatus(ns_enabled, ns_mode);
2846 EXPECT_TRUE(ec_enabled);
2847 EXPECT_TRUE(agc_enabled);
2848 EXPECT_TRUE(ns_enabled);
2849
2850 channel2->SetSend(cricket::SEND_MICROPHONE);
2851 voe_.GetEcStatus(ec_enabled, ec_mode);
2852 voe_.GetAgcStatus(agc_enabled, agc_mode);
2853 voe_.GetNsStatus(ns_enabled, ns_mode);
2854 EXPECT_TRUE(ec_enabled);
2855 EXPECT_FALSE(agc_enabled);
2856 EXPECT_TRUE(ns_enabled);
2857
2858 channel2->SetSend(cricket::SEND_NOTHING);
2859 voe_.GetEcStatus(ec_enabled, ec_mode);
2860 voe_.GetAgcStatus(agc_enabled, agc_mode);
2861 voe_.GetNsStatus(ns_enabled, ns_mode);
2862 EXPECT_TRUE(ec_enabled);
2863 EXPECT_TRUE(agc_enabled);
2864 EXPECT_TRUE(ns_enabled);
2865
2866 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002867 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868 cricket::AudioOptions options_no_agc_nor_ns;
2869 options_no_agc_nor_ns.auto_gain_control.Set(false);
2870 options_no_agc_nor_ns.noise_suppression.Set(false);
2871 channel2->SetSend(cricket::SEND_MICROPHONE);
2872 channel2->SetOptions(options_no_agc_nor_ns);
2873
2874 expected_options.echo_cancellation.Set(true);
2875 expected_options.auto_gain_control.Set(false);
2876 expected_options.noise_suppression.Set(false);
2877 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2878 EXPECT_EQ(expected_options, actual_options);
2879 voe_.GetEcStatus(ec_enabled, ec_mode);
2880 voe_.GetAgcStatus(agc_enabled, agc_mode);
2881 voe_.GetNsStatus(ns_enabled, ns_mode);
2882 EXPECT_TRUE(ec_enabled);
2883 EXPECT_FALSE(agc_enabled);
2884 EXPECT_FALSE(ns_enabled);
2885}
2886
wu@webrtc.orgde305012013-10-31 15:40:38 +00002887// This test verifies DSCP settings are properly applied on voice media channel.
2888TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2889 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002890 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
wu@webrtc.orgde305012013-10-31 15:40:38 +00002891 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002892 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00002893 new cricket::FakeNetworkInterface);
2894 channel->SetInterface(network_interface.get());
2895 cricket::AudioOptions options;
2896 options.dscp.Set(true);
2897 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002898 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00002899 // Verify previous value is not modified if dscp option is not set.
2900 cricket::AudioOptions options1;
2901 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002902 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00002903 options.dscp.Set(false);
2904 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002905 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00002906}
2907
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002908TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2909 cricket::WebRtcVoiceEngine engine;
2910 cricket::AudioOptions options = engine.GetOptions();
2911 // The default options should have at least a few things set. We purposefully
2912 // don't check the option values here, though.
2913 EXPECT_TRUE(options.echo_cancellation.IsSet());
2914 EXPECT_TRUE(options.auto_gain_control.IsSet());
2915 EXPECT_TRUE(options.noise_suppression.IsSet());
2916}
2917
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002918// Test that GetReceiveChannelNum returns the default channel for the first
2919// recv stream in 1-1 calls.
2920TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2921 EXPECT_TRUE(SetupEngine());
2922 cricket::WebRtcVoiceMediaChannel* media_channel =
2923 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2924 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2925 EXPECT_EQ(media_channel->voe_channel(),
2926 media_channel->GetReceiveChannelNum(0));
2927 cricket::StreamParams stream;
2928 stream.ssrcs.push_back(kSsrc2);
2929 EXPECT_TRUE(channel_->AddRecvStream(stream));
2930 EXPECT_EQ(media_channel->voe_channel(),
2931 media_channel->GetReceiveChannelNum(kSsrc2));
2932}
2933
2934// Test that GetReceiveChannelNum doesn't return the default channel for the
2935// first recv stream in conference calls.
2936TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2937 EXPECT_TRUE(SetupEngine());
2938 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2939 cricket::StreamParams stream;
2940 stream.ssrcs.push_back(kSsrc2);
2941 EXPECT_TRUE(channel_->AddRecvStream(stream));
2942 cricket::WebRtcVoiceMediaChannel* media_channel =
2943 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2944 EXPECT_LT(media_channel->voe_channel(),
2945 media_channel->GetReceiveChannelNum(kSsrc2));
2946}
2947
2948TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2949 EXPECT_TRUE(SetupEngine());
2950 double left, right;
2951 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2952 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2953 EXPECT_DOUBLE_EQ(1, left);
2954 EXPECT_DOUBLE_EQ(2, right);
2955
2956 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2957 cricket::StreamParams stream;
2958 stream.ssrcs.push_back(kSsrc2);
2959 EXPECT_TRUE(channel_->AddRecvStream(stream));
2960
2961 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2962 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2963 EXPECT_DOUBLE_EQ(2, left);
2964 EXPECT_DOUBLE_EQ(1, right);
2965}
2966
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002967// Tests for the actual WebRtc VoE library.
2968
2969// Tests that the library initializes and shuts down properly.
2970TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2971 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002972 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002973 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2974 EXPECT_TRUE(channel != NULL);
2975 delete channel;
2976 engine.Terminate();
2977
2978 // Reinit to catch regression where VoiceEngineObserver reference is lost
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002979 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980 engine.Terminate();
2981}
2982
2983// Tests that the logging from the library is cleartext.
2984TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
2985 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002986 rtc::scoped_ptr<rtc::MemoryStream> stream(
2987 new rtc::MemoryStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002988 size_t size = 0;
2989 bool cleartext = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002990 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
2991 engine.SetLogging(rtc::LS_VERBOSE, "");
2992 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993 EXPECT_TRUE(stream->GetSize(&size));
2994 EXPECT_GT(size, 0U);
2995 engine.Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002996 rtc::LogMessage::RemoveLogToStream(stream.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002997 const char* buf = stream->GetBuffer();
2998 for (size_t i = 0; i < size && cleartext; ++i) {
2999 int ch = static_cast<int>(buf[i]);
3000 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
3001 << std::hex << ch;
3002 cleartext = (isprint(ch) || isspace(ch));
3003 }
3004 EXPECT_TRUE(cleartext);
3005}
3006
3007// Tests we do not see any references to a monitor thread being spun up
3008// when initiating the engine.
3009TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
3010 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003011 rtc::scoped_ptr<rtc::MemoryStream> stream(
3012 new rtc::MemoryStream);
3013 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3014 engine.SetLogging(rtc::LS_VERBOSE, "");
3015 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003016 engine.Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003017 rtc::LogMessage::RemoveLogToStream(stream.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003018
3019 size_t size = 0;
3020 EXPECT_TRUE(stream->GetSize(&size));
3021 EXPECT_GT(size, 0U);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003022 const std::string logs(stream->GetBuffer(), size);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003023 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
3024}
3025
3026// Tests that the library is configured with the codecs we want.
3027TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3028 cricket::WebRtcVoiceEngine engine;
3029 // Check codecs by name.
3030 EXPECT_TRUE(engine.FindCodec(
3031 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3032 EXPECT_TRUE(engine.FindCodec(
3033 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3034 EXPECT_TRUE(engine.FindCodec(
3035 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3036 // Check that name matching is case-insensitive.
3037 EXPECT_TRUE(engine.FindCodec(
3038 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3039 EXPECT_TRUE(engine.FindCodec(
3040 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3041 EXPECT_TRUE(engine.FindCodec(
3042 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3043 EXPECT_TRUE(engine.FindCodec(
3044 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3045 EXPECT_TRUE(engine.FindCodec(
3046 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
3047 EXPECT_TRUE(engine.FindCodec(
3048 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003049 EXPECT_TRUE(engine.FindCodec(
3050 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3051 EXPECT_TRUE(engine.FindCodec(
3052 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3053 EXPECT_TRUE(engine.FindCodec(
3054 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3055 EXPECT_TRUE(engine.FindCodec(
3056 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3057 // Check codecs with an id by id.
3058 EXPECT_TRUE(engine.FindCodec(
3059 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3060 EXPECT_TRUE(engine.FindCodec(
3061 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3062 EXPECT_TRUE(engine.FindCodec(
3063 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
3064 EXPECT_TRUE(engine.FindCodec(
3065 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3066 // Check sample/bitrate matching.
3067 EXPECT_TRUE(engine.FindCodec(
3068 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3069 // Check that bad codecs fail.
3070 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3071 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3072 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3073 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3074 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003075 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3076 for (std::vector<cricket::AudioCodec>::const_iterator it =
3077 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3078 if (it->name == "CN" && it->clockrate == 16000) {
3079 EXPECT_EQ(105, it->id);
3080 } else if (it->name == "CN" && it->clockrate == 32000) {
3081 EXPECT_EQ(106, it->id);
3082 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3083 EXPECT_EQ(103, it->id);
3084 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3085 EXPECT_EQ(104, it->id);
3086 } else if (it->name == "G722" && it->clockrate == 16000) {
3087 EXPECT_EQ(9, it->id);
3088 } else if (it->name == "telephone-event") {
3089 EXPECT_EQ(126, it->id);
3090 } else if (it->name == "red") {
3091 EXPECT_EQ(127, it->id);
3092 } else if (it->name == "opus") {
3093 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003094 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003095 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003096 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003097 EXPECT_EQ("60", it->params.find("maxptime")->second);
3098 }
3099 }
3100
3101 engine.Terminate();
3102}
3103
3104// Tests that VoE supports at least 32 channels
3105TEST(WebRtcVoiceEngineTest, Has32Channels) {
3106 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003107 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003108
3109 cricket::VoiceMediaChannel* channels[32];
3110 int num_channels = 0;
3111
3112 while (num_channels < ARRAY_SIZE(channels)) {
3113 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3114 if (!channel)
3115 break;
3116
3117 channels[num_channels++] = channel;
3118 }
3119
3120 int expected = ARRAY_SIZE(channels);
3121 EXPECT_EQ(expected, num_channels);
3122
3123 while (num_channels > 0) {
3124 delete channels[--num_channels];
3125 }
3126
3127 engine.Terminate();
3128}
3129
3130// Test that we set our preferred codecs properly.
3131TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3132 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003133 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003134 cricket::WebRtcVoiceMediaChannel channel(&engine);
3135 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3136}
3137
3138#ifdef WIN32
3139// Test our workarounds to WebRtc VoE' munging of the coinit count
3140TEST(WebRtcVoiceEngineTest, CoInitialize) {
3141 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3142
3143 // Initial refcount should be 0.
3144 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3145
3146 // Engine should start even with COM already inited.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003147 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003148 engine->Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003149 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003150 engine->Terminate();
3151
3152 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3153 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3154 // Decrement refcount to (hopefully) 0.
3155 CoUninitialize();
3156 CoUninitialize();
3157 delete engine;
3158
3159 // Ensure refcount is 0.
3160 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3161 CoUninitialize();
3162}
3163#endif
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003164
3165TEST_F(WebRtcVoiceEngineTestFake, ChangeCombinedAudioVideoBweOption) {
3166 // Test that changing the combined_audio_video_bwe option results in the
3167 // expected state changes in VoiceEngine.
3168 cricket::ViEWrapper vie;
3169 const int kVieCh = 667;
3170
3171 EXPECT_TRUE(SetupEngine());
3172 cricket::WebRtcVoiceMediaChannel* media_channel =
3173 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3174 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(),
3175 kVieCh));
3176 EXPECT_TRUE(media_channel->AddRecvStream(
3177 cricket::StreamParams::CreateLegacy(2)));
3178 int recv_ch = voe_.GetLastChannel();
3179
3180 // Combined BWE should not be set up yet.
3181 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3182 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3183
3184 // Enable combined BWE option - now it should be set up.
3185 cricket::AudioOptions options;
3186 options.combined_audio_video_bwe.Set(true);
3187 EXPECT_TRUE(media_channel->SetOptions(options));
3188 EXPECT_EQ(vie.network(), voe_.GetViENetwork(recv_ch));
3189 EXPECT_EQ(kVieCh, voe_.GetVideoChannel(recv_ch));
3190
3191 // Disable combined BWE option - should be disabled again.
3192 options.combined_audio_video_bwe.Set(false);
3193 EXPECT_TRUE(media_channel->SetOptions(options));
3194 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3195 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3196
3197 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3198}
3199
3200TEST_F(WebRtcVoiceEngineTestFake, SetupSharedBandwidthEstimation) {
3201 // Test that calling SetupSharedBandwidthEstimation() on the voice media
3202 // channel results in the expected state changes in VoiceEngine.
3203 cricket::ViEWrapper vie1;
3204 cricket::ViEWrapper vie2;
3205 const int kVieCh1 = 667;
3206 const int kVieCh2 = 70;
3207
3208 EXPECT_TRUE(SetupEngine());
3209 cricket::WebRtcVoiceMediaChannel* media_channel =
3210 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3211 cricket::AudioOptions options;
3212 options.combined_audio_video_bwe.Set(true);
3213 EXPECT_TRUE(media_channel->SetOptions(options));
3214 EXPECT_TRUE(media_channel->AddRecvStream(
3215 cricket::StreamParams::CreateLegacy(2)));
3216 int recv_ch = voe_.GetLastChannel();
3217
3218 // Combined BWE should not be set up yet.
3219 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3220 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3221
3222 // Register - should be enabled.
3223 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie1.engine(),
3224 kVieCh1));
3225 EXPECT_EQ(vie1.network(), voe_.GetViENetwork(recv_ch));
3226 EXPECT_EQ(kVieCh1, voe_.GetVideoChannel(recv_ch));
3227
3228 // Re-register - should still be enabled.
3229 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie2.engine(),
3230 kVieCh2));
3231 EXPECT_EQ(vie2.network(), voe_.GetViENetwork(recv_ch));
3232 EXPECT_EQ(kVieCh2, voe_.GetVideoChannel(recv_ch));
3233
3234 // Unregister - should be disabled again.
3235 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3236 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3237 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3238}
3239
3240TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
3241 // Test that adding receive streams after enabling combined bandwidth
3242 // estimation will correctly configure each channel.
3243 cricket::ViEWrapper vie;
3244 const int kVieCh = 667;
3245
3246 EXPECT_TRUE(SetupEngine());
3247 cricket::WebRtcVoiceMediaChannel* media_channel =
3248 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3249 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(),
3250 kVieCh));
3251 cricket::AudioOptions options;
3252 options.combined_audio_video_bwe.Set(true);
3253 EXPECT_TRUE(media_channel->SetOptions(options));
3254
3255 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3256 int voe_channels[ARRAY_SIZE(kSsrcs)] = {0};
3257 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3258 EXPECT_TRUE(media_channel->AddRecvStream(
3259 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3260 int recv_ch = media_channel->GetReceiveChannelNum(kSsrcs[i]);
3261 EXPECT_NE(-1, recv_ch);
3262 voe_channels[i] = recv_ch;
3263 EXPECT_EQ(vie.network(), voe_.GetViENetwork(recv_ch));
3264 EXPECT_EQ(kVieCh, voe_.GetVideoChannel(recv_ch));
3265 }
3266
3267 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3268
3269 for (unsigned int i = 0; i < ARRAY_SIZE(voe_channels); ++i) {
3270 EXPECT_EQ(NULL, voe_.GetViENetwork(voe_channels[i]));
3271 EXPECT_EQ(-1, voe_.GetVideoChannel(voe_channels[i]));
3272 }
3273}