blob: 0ea260c092272aab571d704771e36dcc6e48fd11 [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"
Fredrik Solenberg4b60c732015-05-07 14:07:48 +020040#include "talk/media/webrtc/fakewebrtccall.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +000042#include "talk/media/webrtc/webrtcvie.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043#include "talk/media/webrtc/webrtcvoiceengine.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044#include "webrtc/p2p/base/fakesession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045#include "talk/session/media/channel.h"
46
47// Tests for the WebRtcVoiceEngine/VoiceChannel code.
48
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000049using cricket::kRtpAudioLevelHeaderExtension;
50using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
51
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
53static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +000055static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
56static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
58static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
59static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
60static const cricket::AudioCodec
61 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
62static const cricket::AudioCodec* const kAudioCodecs[] = {
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +000063 &kPcmuCodec, &kIsacCodec, &kOpusCodec, &kG722CodecVoE, &kRedCodec,
64 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065};
66const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
67static uint32 kSsrc1 = 0x99;
68static uint32 kSsrc2 = 0x98;
69
70class FakeVoEWrapper : public cricket::VoEWrapper {
71 public:
72 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
73 : cricket::VoEWrapper(engine, // processing
74 engine, // base
75 engine, // codec
76 engine, // dtmf
77 engine, // file
78 engine, // hw
79 engine, // media
80 engine, // neteq
81 engine, // network
82 engine, // rtp
83 engine, // sync
84 engine) { // volume
85 }
86};
87
wu@webrtc.org97077a32013-10-25 21:18:33 +000088class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 public:
90 virtual int SetTraceFilter(const unsigned int filter) {
wu@webrtc.org97077a32013-10-25 21:18:33 +000091 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092 return 0;
93 }
94 virtual int SetTraceFile(const char* fileNameUTF8) {
95 return 0;
96 }
97 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
98 return 0;
99 }
wu@webrtc.org97077a32013-10-25 21:18:33 +0000100 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101};
102
103class WebRtcVoiceEngineTestFake : public testing::Test {
104 public:
105 class ChannelErrorListener : public sigslot::has_slots<> {
106 public:
107 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
108 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
109 ASSERT(channel != NULL);
110 channel->SignalMediaError.connect(
111 this, &ChannelErrorListener::OnVoiceChannelError);
112 }
113 void OnVoiceChannelError(uint32 ssrc,
114 cricket::VoiceMediaChannel::Error error) {
115 ssrc_ = ssrc;
116 error_ = error;
117 }
118 void Reset() {
119 ssrc_ = 0;
120 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
121 }
122 uint32 ssrc() const {
123 return ssrc_;
124 }
125 cricket::VoiceMediaChannel::Error error() const {
126 return error_;
127 }
128
129 private:
130 uint32 ssrc_;
131 cricket::VoiceMediaChannel::Error error_;
132 };
133
134 WebRtcVoiceEngineTestFake()
135 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
136 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000137 trace_wrapper_(new FakeVoETraceWrapper()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138 engine_(new FakeVoEWrapper(&voe_),
139 new FakeVoEWrapper(&voe_sc_),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000140 trace_wrapper_),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000141 channel_(NULL), soundclip_(NULL) {
142 options_conference_.conference_mode.Set(true);
143 options_adjust_agc_.adjust_agc_delta.Set(-10);
144 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000145 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000146 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000147 return false;
148 }
149 channel_ = engine_.CreateChannel();
150 return (channel_ != NULL);
151 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000153 if (!SetupEngineWithoutStream()) {
154 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000155 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000156 return channel_->AddSendStream(
157 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000159 void SetupForMultiSendStream() {
160 EXPECT_TRUE(SetupEngine());
161 // Remove stream added in Setup, which is corresponding to default channel.
162 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000163 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000164 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
165 EXPECT_EQ(kSsrc1, default_send_ssrc);
166 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
167
168 // Verify the default channel still exists.
169 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
170 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 void DeliverPacket(const void* data, int len) {
Karl Wiberg94784372015-04-20 14:03:07 +0200172 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000173 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 }
175 virtual void TearDown() {
176 delete soundclip_;
177 delete channel_;
178 engine_.Terminate();
179 }
180
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000181 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000182 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000183 channel_ = engine_.CreateChannel();
184 EXPECT_TRUE(channel_ != NULL);
185 if (caller) {
186 // if this is a caller, local description will be applied and add the
187 // send stream.
188 EXPECT_TRUE(channel_->AddSendStream(
189 cricket::StreamParams::CreateLegacy(kSsrc1)));
190 }
191 int channel_id = voe_.GetLastChannel();
192
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193 // Test we can only InsertDtmf when the other side supports telephone-event.
194 std::vector<cricket::AudioCodec> codecs;
195 codecs.push_back(kPcmuCodec);
196 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
197 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
198 EXPECT_FALSE(channel_->CanInsertDtmf());
199 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
200 codecs.push_back(kTelephoneEventCodec);
201 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
202 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000203
204 if (!caller) {
205 // There's no active send channel yet.
206 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
207 EXPECT_TRUE(channel_->AddSendStream(
208 cricket::StreamParams::CreateLegacy(kSsrc1)));
209 }
210
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 // Check we fail if the ssrc is invalid.
212 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
213
214 // Test send
215 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
216 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
217 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
218
219 // Test play
220 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
221 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
222 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
223
224 // Test send and play
225 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
226 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
227 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
228 cricket::DF_PLAY | cricket::DF_SEND));
229 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
230 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
231 }
232
233 // Test that send bandwidth is set correctly.
234 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000235 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
236 // |expected_result| is the expected result from SetMaxSendBandwidth().
237 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000239 int max_bitrate,
240 bool expected_result,
241 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 int channel_num = voe_.GetLastChannel();
243 std::vector<cricket::AudioCodec> codecs;
244
245 codecs.push_back(codec);
246 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
247
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000248 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 EXPECT_EQ(expected_result, result);
250
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000251 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
253
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000254 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 }
256
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000257 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
258 EXPECT_TRUE(SetupEngineWithoutStream());
259 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000260
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000261 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000262 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000263
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000264 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000265 // Ensure unknown extensions won't cause an error.
266 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000267 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000268 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000269 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000270
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000271 // Ensure extensions stay off with an empty list of headers.
272 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000273 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000274 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000275
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000276 // Ensure extension is set properly.
277 const int id = 1;
278 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000279 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000280 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000281
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000282 // Ensure extension is set properly on new channel.
283 // The first stream to occupy the default channel.
284 EXPECT_TRUE(channel_->AddSendStream(
285 cricket::StreamParams::CreateLegacy(123)));
286 EXPECT_TRUE(channel_->AddSendStream(
287 cricket::StreamParams::CreateLegacy(234)));
288 int new_channel_num = voe_.GetLastChannel();
289 EXPECT_NE(channel_num, new_channel_num);
290 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000291
292 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000293 extensions.clear();
294 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000295 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
296 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000297 }
298
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000299 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
300 EXPECT_TRUE(SetupEngineWithoutStream());
301 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000302
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000303 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000304 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000305
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000306 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000307 // Ensure unknown extensions won't cause an error.
308 extensions.push_back(cricket::RtpHeaderExtension(
309 "urn:ietf:params:unknownextention", 1));
310 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000311 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000312
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000313 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000314 extensions.clear();
315 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000316 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000317
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000318 // Ensure extension is set properly.
319 const int id = 2;
320 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000321 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000322 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000323
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000324 // Ensure extension is set properly on new channel.
325 // The first stream to occupy the default channel.
326 EXPECT_TRUE(channel_->AddRecvStream(
327 cricket::StreamParams::CreateLegacy(345)));
328 EXPECT_TRUE(channel_->AddRecvStream(
329 cricket::StreamParams::CreateLegacy(456)));
330 int new_channel_num = voe_.GetLastChannel();
331 EXPECT_NE(channel_num, new_channel_num);
332 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
333
334 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000335 extensions.clear();
336 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000337 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
338 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000339 }
340
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 protected:
342 cricket::FakeWebRtcVoiceEngine voe_;
343 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000344 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 cricket::WebRtcVoiceEngine engine_;
346 cricket::VoiceMediaChannel* channel_;
347 cricket::SoundclipMedia* soundclip_;
348
349 cricket::AudioOptions options_conference_;
350 cricket::AudioOptions options_adjust_agc_;
351};
352
353// Tests that our stub library "works".
354TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
355 EXPECT_FALSE(voe_.IsInited());
356 EXPECT_FALSE(voe_sc_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000357 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000359 // The soundclip engine is lazily initialized.
360 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361 engine_.Terminate();
362 EXPECT_FALSE(voe_.IsInited());
363 EXPECT_FALSE(voe_sc_.IsInited());
364}
365
366// Tests that we can create and destroy a channel.
367TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000368 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 channel_ = engine_.CreateChannel();
370 EXPECT_TRUE(channel_ != NULL);
371}
372
373// Tests that we properly handle failures in CreateChannel.
374TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
375 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000376 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 channel_ = engine_.CreateChannel();
378 EXPECT_TRUE(channel_ == NULL);
379}
380
381// Tests that the list of supported codecs is created properly and ordered
382// correctly
383TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
384 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
385 ASSERT_FALSE(codecs.empty());
386 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
387 EXPECT_EQ(48000, codecs[0].clockrate);
388 EXPECT_EQ(2, codecs[0].channels);
389 EXPECT_EQ(64000, codecs[0].bitrate);
390 int pref = codecs[0].preference;
391 for (size_t i = 1; i < codecs.size(); ++i) {
392 EXPECT_GT(pref, codecs[i].preference);
393 pref = codecs[i].preference;
394 }
395}
396
397// Tests that we can find codecs by name or id, and that we interpret the
398// clockrate and bitrate fields properly.
399TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
400 cricket::AudioCodec codec;
401 webrtc::CodecInst codec_inst;
402 // Find PCMU with explicit clockrate and bitrate.
403 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
404 // Find ISAC with explicit clockrate and 0 bitrate.
405 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
406 // Find telephone-event with explicit clockrate and 0 bitrate.
407 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
408 // Find ISAC with a different payload id.
409 codec = kIsacCodec;
410 codec.id = 127;
411 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
412 EXPECT_EQ(codec.id, codec_inst.pltype);
413 // Find PCMU with a 0 clockrate.
414 codec = kPcmuCodec;
415 codec.clockrate = 0;
416 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
417 EXPECT_EQ(codec.id, codec_inst.pltype);
418 EXPECT_EQ(8000, codec_inst.plfreq);
419 // Find PCMU with a 0 bitrate.
420 codec = kPcmuCodec;
421 codec.bitrate = 0;
422 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
423 EXPECT_EQ(codec.id, codec_inst.pltype);
424 EXPECT_EQ(64000, codec_inst.rate);
425 // Find ISAC with an explicit bitrate.
426 codec = kIsacCodec;
427 codec.bitrate = 32000;
428 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
429 EXPECT_EQ(codec.id, codec_inst.pltype);
430 EXPECT_EQ(32000, codec_inst.rate);
431}
432
433// Test that we set our inbound codecs properly, including changing PT.
434TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
435 EXPECT_TRUE(SetupEngine());
436 int channel_num = voe_.GetLastChannel();
437 std::vector<cricket::AudioCodec> codecs;
438 codecs.push_back(kIsacCodec);
439 codecs.push_back(kPcmuCodec);
440 codecs.push_back(kTelephoneEventCodec);
441 codecs[0].id = 106; // collide with existing telephone-event
442 codecs[2].id = 126;
443 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
444 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000445 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000446 gcodec.plfreq = 16000;
447 gcodec.channels = 1;
448 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
449 EXPECT_EQ(106, gcodec.pltype);
450 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000451 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000452 "telephone-event");
453 gcodec.plfreq = 8000;
454 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
455 EXPECT_EQ(126, gcodec.pltype);
456 EXPECT_STREQ("telephone-event", gcodec.plname);
457}
458
459// Test that we fail to set an unknown inbound codec.
460TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
461 EXPECT_TRUE(SetupEngine());
462 std::vector<cricket::AudioCodec> codecs;
463 codecs.push_back(kIsacCodec);
464 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
465 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
466}
467
468// Test that we fail if we have duplicate types in the inbound list.
469TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
470 EXPECT_TRUE(SetupEngine());
471 std::vector<cricket::AudioCodec> codecs;
472 codecs.push_back(kIsacCodec);
473 codecs.push_back(kCn16000Codec);
474 codecs[1].id = kIsacCodec.id;
475 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
476}
477
478// Test that we can decode OPUS without stereo parameters.
479TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
480 EXPECT_TRUE(SetupEngine());
481 EXPECT_TRUE(channel_->SetOptions(options_conference_));
482 std::vector<cricket::AudioCodec> codecs;
483 codecs.push_back(kIsacCodec);
484 codecs.push_back(kPcmuCodec);
485 codecs.push_back(kOpusCodec);
486 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
487 EXPECT_TRUE(channel_->AddRecvStream(
488 cricket::StreamParams::CreateLegacy(kSsrc1)));
489 int channel_num2 = voe_.GetLastChannel();
490 webrtc::CodecInst opus;
491 engine_.FindWebRtcCodec(kOpusCodec, &opus);
492 // Even without stereo parameters, recv codecs still specify channels = 2.
493 EXPECT_EQ(2, opus.channels);
494 EXPECT_EQ(111, opus.pltype);
495 EXPECT_STREQ("opus", opus.plname);
496 opus.pltype = 0;
497 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
498 EXPECT_EQ(111, opus.pltype);
499}
500
501// Test that we can decode OPUS with stereo = 0.
502TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
503 EXPECT_TRUE(SetupEngine());
504 EXPECT_TRUE(channel_->SetOptions(options_conference_));
505 std::vector<cricket::AudioCodec> codecs;
506 codecs.push_back(kIsacCodec);
507 codecs.push_back(kPcmuCodec);
508 codecs.push_back(kOpusCodec);
509 codecs[2].params["stereo"] = "0";
510 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
511 EXPECT_TRUE(channel_->AddRecvStream(
512 cricket::StreamParams::CreateLegacy(kSsrc1)));
513 int channel_num2 = voe_.GetLastChannel();
514 webrtc::CodecInst opus;
515 engine_.FindWebRtcCodec(kOpusCodec, &opus);
516 // Even when stereo is off, recv codecs still specify channels = 2.
517 EXPECT_EQ(2, opus.channels);
518 EXPECT_EQ(111, opus.pltype);
519 EXPECT_STREQ("opus", opus.plname);
520 opus.pltype = 0;
521 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
522 EXPECT_EQ(111, opus.pltype);
523}
524
525// Test that we can decode OPUS with stereo = 1.
526TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
527 EXPECT_TRUE(SetupEngine());
528 EXPECT_TRUE(channel_->SetOptions(options_conference_));
529 std::vector<cricket::AudioCodec> codecs;
530 codecs.push_back(kIsacCodec);
531 codecs.push_back(kPcmuCodec);
532 codecs.push_back(kOpusCodec);
533 codecs[2].params["stereo"] = "1";
534 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
535 EXPECT_TRUE(channel_->AddRecvStream(
536 cricket::StreamParams::CreateLegacy(kSsrc1)));
537 int channel_num2 = voe_.GetLastChannel();
538 webrtc::CodecInst opus;
539 engine_.FindWebRtcCodec(kOpusCodec, &opus);
540 EXPECT_EQ(2, opus.channels);
541 EXPECT_EQ(111, opus.pltype);
542 EXPECT_STREQ("opus", opus.plname);
543 opus.pltype = 0;
544 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
545 EXPECT_EQ(111, opus.pltype);
546}
547
548// Test that changes to recv codecs are applied to all streams.
549TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
550 EXPECT_TRUE(SetupEngine());
551 EXPECT_TRUE(channel_->SetOptions(options_conference_));
552 std::vector<cricket::AudioCodec> codecs;
553 codecs.push_back(kIsacCodec);
554 codecs.push_back(kPcmuCodec);
555 codecs.push_back(kTelephoneEventCodec);
556 codecs[0].id = 106; // collide with existing telephone-event
557 codecs[2].id = 126;
558 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
559 EXPECT_TRUE(channel_->AddRecvStream(
560 cricket::StreamParams::CreateLegacy(kSsrc1)));
561 int channel_num2 = voe_.GetLastChannel();
562 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000563 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 gcodec.plfreq = 16000;
565 gcodec.channels = 1;
566 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
567 EXPECT_EQ(106, gcodec.pltype);
568 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000569 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 "telephone-event");
571 gcodec.plfreq = 8000;
572 gcodec.channels = 1;
573 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
574 EXPECT_EQ(126, gcodec.pltype);
575 EXPECT_STREQ("telephone-event", gcodec.plname);
576}
577
578TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
579 EXPECT_TRUE(SetupEngine());
580 EXPECT_TRUE(channel_->SetOptions(options_conference_));
581 std::vector<cricket::AudioCodec> codecs;
582 codecs.push_back(kIsacCodec);
583 codecs[0].id = 106; // collide with existing telephone-event
584
585 EXPECT_TRUE(channel_->AddRecvStream(
586 cricket::StreamParams::CreateLegacy(kSsrc1)));
587 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
588
589 int channel_num2 = voe_.GetLastChannel();
590 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000591 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592 gcodec.plfreq = 16000;
593 gcodec.channels = 1;
594 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
595 EXPECT_EQ(106, gcodec.pltype);
596 EXPECT_STREQ("ISAC", gcodec.plname);
597}
598
599// Test that we can apply the same set of codecs again while playing.
600TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
601 EXPECT_TRUE(SetupEngine());
602 int channel_num = voe_.GetLastChannel();
603 std::vector<cricket::AudioCodec> codecs;
604 codecs.push_back(kIsacCodec);
605 codecs.push_back(kCn16000Codec);
606 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
607 EXPECT_TRUE(channel_->SetPlayout(true));
608 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
609
610 // Changing the payload type of a codec should fail.
611 codecs[0].id = 127;
612 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
613 EXPECT_TRUE(voe_.GetPlayout(channel_num));
614}
615
616// Test that we can add a codec while playing.
617TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
618 EXPECT_TRUE(SetupEngine());
619 int channel_num = voe_.GetLastChannel();
620 std::vector<cricket::AudioCodec> codecs;
621 codecs.push_back(kIsacCodec);
622 codecs.push_back(kCn16000Codec);
623 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
624 EXPECT_TRUE(channel_->SetPlayout(true));
625
626 codecs.push_back(kOpusCodec);
627 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
628 EXPECT_TRUE(voe_.GetPlayout(channel_num));
629 webrtc::CodecInst gcodec;
630 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
631 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
632}
633
634TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
635 EXPECT_TRUE(SetupEngine());
636 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
637
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000638 // Test that when autobw is enabled, bitrate is kept as the default
639 // value. autobw is enabled for the following tests because the target
640 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000641
642 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000643 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000644
645 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000646 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000647
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000649 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650}
651
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000652TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653 EXPECT_TRUE(SetupEngine());
654 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
655
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000656 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657
658 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000659 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
660 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000663 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
664 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665}
666
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000667TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
668 EXPECT_TRUE(SetupEngine());
669 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
670
671 // Test that we can only set a maximum bitrate for a fixed-rate codec
672 // if it's bigger than the fixed rate.
673
674 // PCMU, fixed bitrate == 64000.
675 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
676 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
677 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
678 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
679 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
680 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
681 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
682}
683
684TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000685 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000686 channel_ = engine_.CreateChannel();
687 EXPECT_TRUE(channel_ != NULL);
688 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
689
690 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000691 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000692
693 EXPECT_TRUE(channel_->AddSendStream(
694 cricket::StreamParams::CreateLegacy(kSsrc1)));
695
696 int channel_num = voe_.GetLastChannel();
697 webrtc::CodecInst codec;
698 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
699 EXPECT_EQ(desired_bitrate, codec.rate);
700}
701
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702// Test that bitrate cannot be set for CBR codecs.
703// Bitrate is ignored if it is higher than the fixed bitrate.
704// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000705TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706 EXPECT_TRUE(SetupEngine());
707 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
708
709 webrtc::CodecInst codec;
710 int channel_num = voe_.GetLastChannel();
711 std::vector<cricket::AudioCodec> codecs;
712
713 // PCMU, default bitrate == 64000.
714 codecs.push_back(kPcmuCodec);
715 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
716 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
717 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000718 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
720 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000721 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
723 EXPECT_EQ(64000, codec.rate);
724}
725
726// Test that we apply codecs properly.
727TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
728 EXPECT_TRUE(SetupEngine());
729 int channel_num = voe_.GetLastChannel();
730 std::vector<cricket::AudioCodec> codecs;
731 codecs.push_back(kIsacCodec);
732 codecs.push_back(kPcmuCodec);
733 codecs.push_back(kRedCodec);
734 codecs[0].id = 96;
735 codecs[0].bitrate = 48000;
736 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000737 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 webrtc::CodecInst gcodec;
739 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
740 EXPECT_EQ(96, gcodec.pltype);
741 EXPECT_EQ(48000, gcodec.rate);
742 EXPECT_STREQ("ISAC", gcodec.plname);
743 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000744 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000745 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
746 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
747 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
748}
749
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000750// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
751// to apply.
752TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
753 EXPECT_TRUE(SetupEngine());
754 std::vector<cricket::AudioCodec> codecs;
755 codecs.push_back(kIsacCodec);
756 codecs.push_back(kPcmuCodec);
757 codecs.push_back(kRedCodec);
758 codecs[0].id = 96;
759 codecs[0].bitrate = 48000;
760 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
761 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
762 // Calling SetSendCodec again with same codec which is already set.
763 // In this case media channel shouldn't send codec to VoE.
764 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
765 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
766}
767
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +0000768// Verify that G722 is set with 16000 samples per second to WebRTC.
769TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
770 EXPECT_TRUE(SetupEngine());
771 int channel_num = voe_.GetLastChannel();
772 std::vector<cricket::AudioCodec> codecs;
773 codecs.push_back(kG722CodecSdp);
774 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
775 webrtc::CodecInst gcodec;
776 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
777 EXPECT_STREQ("G722", gcodec.plname);
778 EXPECT_EQ(1, gcodec.channels);
779 EXPECT_EQ(16000, gcodec.plfreq);
780}
781
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000782// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
784 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785 std::vector<cricket::AudioCodec> codecs;
786 codecs.push_back(kOpusCodec);
787 codecs[0].bitrate = 0;
788 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000789 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790}
791
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000792// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000793TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
794 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795 std::vector<cricket::AudioCodec> codecs;
796 codecs.push_back(kOpusCodec);
797 codecs[0].bitrate = 0;
798 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000799 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800}
801
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000802// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000803TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
804 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000805 std::vector<cricket::AudioCodec> codecs;
806 codecs.push_back(kOpusCodec);
807 codecs[0].bitrate = 0;
808 codecs[0].channels = 0;
809 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000810 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811}
812
813// Test that if channel is 1 for opus and there's no stereo, we fail.
814TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
815 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000816 std::vector<cricket::AudioCodec> codecs;
817 codecs.push_back(kOpusCodec);
818 codecs[0].bitrate = 0;
819 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000820 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000821}
822
823// Test that if channel is 1 for opus and stereo=0, we fail.
824TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
825 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826 std::vector<cricket::AudioCodec> codecs;
827 codecs.push_back(kOpusCodec);
828 codecs[0].bitrate = 0;
829 codecs[0].channels = 1;
830 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000831 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832}
833
834// Test that if channel is 1 for opus and stereo=1, we fail.
835TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
836 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837 std::vector<cricket::AudioCodec> codecs;
838 codecs.push_back(kOpusCodec);
839 codecs[0].bitrate = 0;
840 codecs[0].channels = 1;
841 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000842 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000843}
844
845// Test that with bitrate=0 and no stereo,
846// channels and bitrate are 1 and 32000.
847TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
848 EXPECT_TRUE(SetupEngine());
849 int channel_num = voe_.GetLastChannel();
850 std::vector<cricket::AudioCodec> codecs;
851 codecs.push_back(kOpusCodec);
852 codecs[0].bitrate = 0;
853 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
854 webrtc::CodecInst gcodec;
855 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
856 EXPECT_STREQ("opus", gcodec.plname);
857 EXPECT_EQ(1, gcodec.channels);
858 EXPECT_EQ(32000, gcodec.rate);
859}
860
861// Test that with bitrate=0 and stereo=0,
862// channels and bitrate are 1 and 32000.
863TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
864 EXPECT_TRUE(SetupEngine());
865 int channel_num = voe_.GetLastChannel();
866 std::vector<cricket::AudioCodec> codecs;
867 codecs.push_back(kOpusCodec);
868 codecs[0].bitrate = 0;
869 codecs[0].params["stereo"] = "0";
870 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
871 webrtc::CodecInst gcodec;
872 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
873 EXPECT_STREQ("opus", gcodec.plname);
874 EXPECT_EQ(1, gcodec.channels);
875 EXPECT_EQ(32000, gcodec.rate);
876}
877
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000878// Test that with bitrate=invalid and stereo=0,
879// channels and bitrate are 1 and 32000.
880TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
881 EXPECT_TRUE(SetupEngine());
882 int channel_num = voe_.GetLastChannel();
883 std::vector<cricket::AudioCodec> codecs;
884 codecs.push_back(kOpusCodec);
885 codecs[0].params["stereo"] = "0";
886 webrtc::CodecInst gcodec;
887
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000888 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000889 codecs[0].bitrate = 5999;
890 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
891 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
892 EXPECT_STREQ("opus", gcodec.plname);
893 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000894 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000895
896 codecs[0].bitrate = 510001;
897 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
898 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
899 EXPECT_STREQ("opus", gcodec.plname);
900 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000901 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000902}
903
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904// Test that with bitrate=0 and stereo=1,
905// channels and bitrate are 2 and 64000.
906TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
907 EXPECT_TRUE(SetupEngine());
908 int channel_num = voe_.GetLastChannel();
909 std::vector<cricket::AudioCodec> codecs;
910 codecs.push_back(kOpusCodec);
911 codecs[0].bitrate = 0;
912 codecs[0].params["stereo"] = "1";
913 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
914 webrtc::CodecInst gcodec;
915 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
916 EXPECT_STREQ("opus", gcodec.plname);
917 EXPECT_EQ(2, gcodec.channels);
918 EXPECT_EQ(64000, gcodec.rate);
919}
920
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000921// Test that with bitrate=invalid and stereo=1,
922// channels and bitrate are 2 and 64000.
923TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
924 EXPECT_TRUE(SetupEngine());
925 int channel_num = voe_.GetLastChannel();
926 std::vector<cricket::AudioCodec> codecs;
927 codecs.push_back(kOpusCodec);
928 codecs[0].params["stereo"] = "1";
929 webrtc::CodecInst gcodec;
930
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000931 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000932 codecs[0].bitrate = 5999;
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);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000937 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000938
939 codecs[0].bitrate = 510001;
940 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
941 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
942 EXPECT_STREQ("opus", gcodec.plname);
943 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000944 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000945}
946
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947// Test that with bitrate=N and stereo unset,
948// channels and bitrate are 1 and N.
949TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
950 EXPECT_TRUE(SetupEngine());
951 int channel_num = voe_.GetLastChannel();
952 std::vector<cricket::AudioCodec> codecs;
953 codecs.push_back(kOpusCodec);
954 codecs[0].bitrate = 96000;
955 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
956 webrtc::CodecInst gcodec;
957 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
958 EXPECT_EQ(111, gcodec.pltype);
959 EXPECT_EQ(96000, gcodec.rate);
960 EXPECT_STREQ("opus", gcodec.plname);
961 EXPECT_EQ(1, gcodec.channels);
962 EXPECT_EQ(48000, gcodec.plfreq);
963}
964
965// Test that with bitrate=N and stereo=0,
966// channels and bitrate are 1 and N.
967TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
968 EXPECT_TRUE(SetupEngine());
969 int channel_num = voe_.GetLastChannel();
970 std::vector<cricket::AudioCodec> codecs;
971 codecs.push_back(kOpusCodec);
972 codecs[0].bitrate = 30000;
973 codecs[0].params["stereo"] = "0";
974 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
975 webrtc::CodecInst gcodec;
976 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
977 EXPECT_EQ(1, gcodec.channels);
978 EXPECT_EQ(30000, gcodec.rate);
979 EXPECT_STREQ("opus", gcodec.plname);
980}
981
982// Test that with bitrate=N and without any parameters,
983// channels and bitrate are 1 and N.
984TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
985 EXPECT_TRUE(SetupEngine());
986 int channel_num = voe_.GetLastChannel();
987 std::vector<cricket::AudioCodec> codecs;
988 codecs.push_back(kOpusCodec);
989 codecs[0].bitrate = 30000;
990 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
991 webrtc::CodecInst gcodec;
992 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
993 EXPECT_EQ(1, gcodec.channels);
994 EXPECT_EQ(30000, gcodec.rate);
995 EXPECT_STREQ("opus", gcodec.plname);
996}
997
998// Test that with bitrate=N and stereo=1,
999// channels and bitrate are 2 and N.
1000TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
1001 EXPECT_TRUE(SetupEngine());
1002 int channel_num = voe_.GetLastChannel();
1003 std::vector<cricket::AudioCodec> codecs;
1004 codecs.push_back(kOpusCodec);
1005 codecs[0].bitrate = 30000;
1006 codecs[0].params["stereo"] = "1";
1007 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1008 webrtc::CodecInst gcodec;
1009 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1010 EXPECT_EQ(2, gcodec.channels);
1011 EXPECT_EQ(30000, gcodec.rate);
1012 EXPECT_STREQ("opus", gcodec.plname);
1013}
1014
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001015// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1016// Also test that the "maxaveragebitrate" can't be set to values outside the
1017// range of 6000 and 510000
1018TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1019 EXPECT_TRUE(SetupEngine());
1020 int channel_num = voe_.GetLastChannel();
1021 std::vector<cricket::AudioCodec> codecs;
1022 codecs.push_back(kOpusCodec);
1023 codecs[0].bitrate = 30000;
1024 webrtc::CodecInst gcodec;
1025
1026 // Ignore if less than 6000.
1027 codecs[0].params["maxaveragebitrate"] = "5999";
1028 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1029 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001030 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001031
1032 // Ignore if larger than 510000.
1033 codecs[0].params["maxaveragebitrate"] = "510001";
1034 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1035 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001036 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001037
1038 codecs[0].params["maxaveragebitrate"] = "200000";
1039 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1040 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1041 EXPECT_EQ(200000, gcodec.rate);
1042}
1043
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001044// Test that we can enable NACK with opus as caller.
1045TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001046 EXPECT_TRUE(SetupEngine());
1047 int channel_num = voe_.GetLastChannel();
1048 std::vector<cricket::AudioCodec> codecs;
1049 codecs.push_back(kOpusCodec);
1050 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1051 cricket::kParamValueEmpty));
1052 EXPECT_FALSE(voe_.GetNACK(channel_num));
1053 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1054 EXPECT_TRUE(voe_.GetNACK(channel_num));
1055}
1056
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001057// Test that we can enable NACK with opus as callee.
1058TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001059 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001060 channel_ = engine_.CreateChannel();
1061 EXPECT_TRUE(channel_ != NULL);
1062
1063 int channel_num = voe_.GetLastChannel();
1064 std::vector<cricket::AudioCodec> codecs;
1065 codecs.push_back(kOpusCodec);
1066 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1067 cricket::kParamValueEmpty));
1068 EXPECT_FALSE(voe_.GetNACK(channel_num));
1069 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1070 EXPECT_FALSE(voe_.GetNACK(channel_num));
1071
1072 EXPECT_TRUE(channel_->AddSendStream(
1073 cricket::StreamParams::CreateLegacy(kSsrc1)));
1074 EXPECT_TRUE(voe_.GetNACK(channel_num));
1075}
1076
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001077// Test that we can enable NACK on receive streams.
1078TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1079 EXPECT_TRUE(SetupEngine());
1080 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1081 int channel_num1 = voe_.GetLastChannel();
1082 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1083 int channel_num2 = voe_.GetLastChannel();
1084 std::vector<cricket::AudioCodec> codecs;
1085 codecs.push_back(kOpusCodec);
1086 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1087 cricket::kParamValueEmpty));
1088 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1089 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1090 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1091 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1092 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1093}
1094
1095// Test that we can disable NACK.
1096TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1097 EXPECT_TRUE(SetupEngine());
1098 int channel_num = voe_.GetLastChannel();
1099 std::vector<cricket::AudioCodec> codecs;
1100 codecs.push_back(kOpusCodec);
1101 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1102 cricket::kParamValueEmpty));
1103 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1104 EXPECT_TRUE(voe_.GetNACK(channel_num));
1105
1106 codecs.clear();
1107 codecs.push_back(kOpusCodec);
1108 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1109 EXPECT_FALSE(voe_.GetNACK(channel_num));
1110}
1111
1112// Test that we can disable NACK on receive streams.
1113TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1114 EXPECT_TRUE(SetupEngine());
1115 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1116 int channel_num1 = voe_.GetLastChannel();
1117 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1118 int channel_num2 = voe_.GetLastChannel();
1119 std::vector<cricket::AudioCodec> codecs;
1120 codecs.push_back(kOpusCodec);
1121 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1122 cricket::kParamValueEmpty));
1123 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1124 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1125 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1126
1127 codecs.clear();
1128 codecs.push_back(kOpusCodec);
1129 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1130 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1131 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1132}
1133
1134// Test that NACK is enabled on a new receive stream.
1135TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1136 EXPECT_TRUE(SetupEngine());
1137 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1138 int channel_num = voe_.GetLastChannel();
1139 std::vector<cricket::AudioCodec> codecs;
1140 codecs.push_back(kIsacCodec);
1141 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1142 cricket::kParamValueEmpty));
1143 codecs.push_back(kCn16000Codec);
1144 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1145 EXPECT_TRUE(voe_.GetNACK(channel_num));
1146
1147 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1148 channel_num = voe_.GetLastChannel();
1149 EXPECT_TRUE(voe_.GetNACK(channel_num));
1150 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1151 channel_num = voe_.GetLastChannel();
1152 EXPECT_TRUE(voe_.GetNACK(channel_num));
1153}
1154
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001155// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001156TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001157 EXPECT_TRUE(SetupEngine());
1158 int channel_num = voe_.GetLastChannel();
1159 std::vector<cricket::AudioCodec> codecs;
1160 codecs.push_back(kOpusCodec);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001161 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1162 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1163}
1164
1165// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001166TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001167 EXPECT_TRUE(SetupEngine());
1168 int channel_num = voe_.GetLastChannel();
1169 std::vector<cricket::AudioCodec> codecs;
1170 codecs.push_back(kOpusCodec);
1171 codecs[0].bitrate = 0;
1172 codecs[0].params["useinbandfec"] = "0";
1173 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1174 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1175 webrtc::CodecInst gcodec;
1176 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1177 EXPECT_STREQ("opus", gcodec.plname);
1178 EXPECT_EQ(1, gcodec.channels);
1179 EXPECT_EQ(32000, gcodec.rate);
1180}
1181
1182// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001183TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001184 EXPECT_TRUE(SetupEngine());
1185 int channel_num = voe_.GetLastChannel();
1186 std::vector<cricket::AudioCodec> codecs;
1187 codecs.push_back(kOpusCodec);
1188 codecs[0].bitrate = 0;
1189 codecs[0].params["useinbandfec"] = "1";
1190 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1191 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1192 webrtc::CodecInst gcodec;
1193 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1194 EXPECT_STREQ("opus", gcodec.plname);
1195 EXPECT_EQ(1, gcodec.channels);
1196 EXPECT_EQ(32000, gcodec.rate);
1197}
1198
1199// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001200TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001201 EXPECT_TRUE(SetupEngine());
1202 int channel_num = voe_.GetLastChannel();
1203 std::vector<cricket::AudioCodec> codecs;
1204 codecs.push_back(kOpusCodec);
1205 codecs[0].bitrate = 0;
1206 codecs[0].params["stereo"] = "1";
1207 codecs[0].params["useinbandfec"] = "1";
1208 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1209 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1210 webrtc::CodecInst gcodec;
1211 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1212 EXPECT_STREQ("opus", gcodec.plname);
1213 EXPECT_EQ(2, gcodec.channels);
1214 EXPECT_EQ(64000, gcodec.rate);
1215}
1216
1217// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001218TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001219 EXPECT_TRUE(SetupEngine());
1220 int channel_num = voe_.GetLastChannel();
1221 std::vector<cricket::AudioCodec> codecs;
1222 codecs.push_back(kIsacCodec);
1223 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1224 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1225}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001226
1227// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1228TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1229 EXPECT_TRUE(SetupEngine());
1230 int channel_num = voe_.GetLastChannel();
1231 std::vector<cricket::AudioCodec> codecs;
1232 codecs.push_back(kIsacCodec);
1233 codecs[0].params["useinbandfec"] = "1";
1234 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1235 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1236}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001237
1238// Test that Opus FEC status can be changed.
1239TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1240 EXPECT_TRUE(SetupEngine());
1241 int channel_num = voe_.GetLastChannel();
1242 std::vector<cricket::AudioCodec> codecs;
1243 codecs.push_back(kOpusCodec);
1244 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1245 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1246 codecs[0].params["useinbandfec"] = "1";
1247 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1248 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1249}
1250
1251// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1252TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1253 EXPECT_TRUE(SetupEngine());
1254 int channel_num = voe_.GetLastChannel();
1255 std::vector<cricket::AudioCodec> codecs;
1256 codecs.push_back(kOpusCodec);
1257 codecs[0].bitrate = 0;
1258 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1259 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1260 EXPECT_EQ(cricket::kOpusBandwidthNb,
1261 voe_.GetMaxEncodingBandwidth(channel_num));
1262 webrtc::CodecInst gcodec;
1263 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1264 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001265
1266 EXPECT_EQ(12000, gcodec.rate);
1267 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1268 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1269 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1270 EXPECT_EQ(24000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001271}
1272
1273// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1274TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1275 EXPECT_TRUE(SetupEngine());
1276 int channel_num = voe_.GetLastChannel();
1277 std::vector<cricket::AudioCodec> codecs;
1278 codecs.push_back(kOpusCodec);
1279 codecs[0].bitrate = 0;
1280 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1281 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1282 EXPECT_EQ(cricket::kOpusBandwidthMb,
1283 voe_.GetMaxEncodingBandwidth(channel_num));
1284 webrtc::CodecInst gcodec;
1285 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1286 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001287
1288 EXPECT_EQ(20000, gcodec.rate);
1289 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1290 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1291 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1292 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001293}
1294
1295// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1296TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1297 EXPECT_TRUE(SetupEngine());
1298 int channel_num = voe_.GetLastChannel();
1299 std::vector<cricket::AudioCodec> codecs;
1300 codecs.push_back(kOpusCodec);
1301 codecs[0].bitrate = 0;
1302 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1303 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1304 EXPECT_EQ(cricket::kOpusBandwidthWb,
1305 voe_.GetMaxEncodingBandwidth(channel_num));
1306 webrtc::CodecInst gcodec;
1307 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1308 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001309
1310 EXPECT_EQ(20000, gcodec.rate);
1311 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1312 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1313 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1314 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001315}
1316
1317// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1318TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1319 EXPECT_TRUE(SetupEngine());
1320 int channel_num = voe_.GetLastChannel();
1321 std::vector<cricket::AudioCodec> codecs;
1322 codecs.push_back(kOpusCodec);
1323 codecs[0].bitrate = 0;
1324 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1325 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1326 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1327 voe_.GetMaxEncodingBandwidth(channel_num));
1328 webrtc::CodecInst gcodec;
1329 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1330 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001331
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001332 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001333 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1334 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1335 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1336 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001337}
1338
1339// Test 24000 < maxplaybackrate triggers Opus full band mode.
1340TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1341 EXPECT_TRUE(SetupEngine());
1342 int channel_num = voe_.GetLastChannel();
1343 std::vector<cricket::AudioCodec> codecs;
1344 codecs.push_back(kOpusCodec);
1345 codecs[0].bitrate = 0;
1346 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1347 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1348 EXPECT_EQ(cricket::kOpusBandwidthFb,
1349 voe_.GetMaxEncodingBandwidth(channel_num));
1350 webrtc::CodecInst gcodec;
1351 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1352 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001353
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001354 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001355 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1356 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1357 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1358 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001359}
1360
1361// Test Opus that without maxplaybackrate, default playback rate is used.
1362TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1363 EXPECT_TRUE(SetupEngine());
1364 int channel_num = voe_.GetLastChannel();
1365 std::vector<cricket::AudioCodec> codecs;
1366 codecs.push_back(kOpusCodec);
1367 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1368 EXPECT_EQ(cricket::kOpusBandwidthFb,
1369 voe_.GetMaxEncodingBandwidth(channel_num));
1370}
1371
1372// Test the with non-Opus, maxplaybackrate has no effect.
1373TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1374 EXPECT_TRUE(SetupEngine());
1375 int channel_num = voe_.GetLastChannel();
1376 std::vector<cricket::AudioCodec> codecs;
1377 codecs.push_back(kIsacCodec);
1378 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1379 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1380 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1381}
1382
1383// Test maxplaybackrate can be set on two streams.
1384TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1385 EXPECT_TRUE(SetupEngine());
1386 int channel_num = voe_.GetLastChannel();
1387 std::vector<cricket::AudioCodec> codecs;
1388 codecs.push_back(kOpusCodec);
1389 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1390 // Default bandwidth is 24000.
1391 EXPECT_EQ(cricket::kOpusBandwidthFb,
1392 voe_.GetMaxEncodingBandwidth(channel_num));
1393
1394 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1395
1396 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1397 EXPECT_EQ(cricket::kOpusBandwidthNb,
1398 voe_.GetMaxEncodingBandwidth(channel_num));
1399
1400 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1401 channel_num = voe_.GetLastChannel();
1402 EXPECT_EQ(cricket::kOpusBandwidthNb,
1403 voe_.GetMaxEncodingBandwidth(channel_num));
1404}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001405
Minyue Li7100dcd2015-03-27 05:05:59 +01001406// Test that with usedtx=0, Opus DTX is off.
1407TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1408 EXPECT_TRUE(SetupEngine());
1409 int channel_num = voe_.GetLastChannel();
1410 std::vector<cricket::AudioCodec> codecs;
1411 codecs.push_back(kOpusCodec);
1412 codecs[0].params["usedtx"] = "0";
1413 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1414 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1415}
1416
1417// Test that with usedtx=1, Opus DTX is on.
1418TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1419 EXPECT_TRUE(SetupEngine());
1420 int channel_num = voe_.GetLastChannel();
1421 std::vector<cricket::AudioCodec> codecs;
1422 codecs.push_back(kOpusCodec);
1423 codecs[0].params["usedtx"] = "1";
1424 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1425 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1426 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1427}
1428
1429// Test that usedtx=1 works with stereo Opus.
1430TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1431 EXPECT_TRUE(SetupEngine());
1432 int channel_num = voe_.GetLastChannel();
1433 std::vector<cricket::AudioCodec> codecs;
1434 codecs.push_back(kOpusCodec);
1435 codecs[0].params["usedtx"] = "1";
1436 codecs[0].params["stereo"] = "1";
1437 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1438 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1439 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1440}
1441
1442// Test that usedtx=1 does not work with non Opus.
1443TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1444 EXPECT_TRUE(SetupEngine());
1445 int channel_num = voe_.GetLastChannel();
1446 std::vector<cricket::AudioCodec> codecs;
1447 codecs.push_back(kIsacCodec);
1448 codecs[0].params["usedtx"] = "1";
1449 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1450 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1451}
1452
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001453// Test that we can switch back and forth between Opus and ISAC with CN.
1454TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455 EXPECT_TRUE(SetupEngine());
1456 int channel_num = voe_.GetLastChannel();
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001457 std::vector<cricket::AudioCodec> opus_codecs;
1458 opus_codecs.push_back(kOpusCodec);
1459 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460 webrtc::CodecInst gcodec;
1461 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001462 EXPECT_EQ(111, gcodec.pltype);
1463 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001464
1465 std::vector<cricket::AudioCodec> isac_codecs;
1466 isac_codecs.push_back(kIsacCodec);
1467 isac_codecs.push_back(kCn16000Codec);
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001468 isac_codecs.push_back(kOpusCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1470 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1471 EXPECT_EQ(103, gcodec.pltype);
1472 EXPECT_STREQ("ISAC", gcodec.plname);
1473
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001474 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001475 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001476 EXPECT_EQ(111, gcodec.pltype);
1477 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001478}
1479
1480// Test that we handle various ways of specifying bitrate.
1481TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1482 EXPECT_TRUE(SetupEngine());
1483 int channel_num = voe_.GetLastChannel();
1484 std::vector<cricket::AudioCodec> codecs;
1485 codecs.push_back(kIsacCodec); // bitrate == 32000
1486 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1487 webrtc::CodecInst gcodec;
1488 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1489 EXPECT_EQ(103, gcodec.pltype);
1490 EXPECT_STREQ("ISAC", gcodec.plname);
1491 EXPECT_EQ(32000, gcodec.rate);
1492
1493 codecs[0].bitrate = 0; // bitrate == default
1494 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1495 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1496 EXPECT_EQ(103, gcodec.pltype);
1497 EXPECT_STREQ("ISAC", gcodec.plname);
1498 EXPECT_EQ(-1, gcodec.rate);
1499
1500 codecs[0].bitrate = 28000; // bitrate == 28000
1501 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1502 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1503 EXPECT_EQ(103, gcodec.pltype);
1504 EXPECT_STREQ("ISAC", gcodec.plname);
1505 EXPECT_EQ(28000, gcodec.rate);
1506
1507 codecs[0] = kPcmuCodec; // bitrate == 64000
1508 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1509 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1510 EXPECT_EQ(0, gcodec.pltype);
1511 EXPECT_STREQ("PCMU", gcodec.plname);
1512 EXPECT_EQ(64000, gcodec.rate);
1513
1514 codecs[0].bitrate = 0; // bitrate == default
1515 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1516 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1517 EXPECT_EQ(0, gcodec.pltype);
1518 EXPECT_STREQ("PCMU", gcodec.plname);
1519 EXPECT_EQ(64000, gcodec.rate);
1520
1521 codecs[0] = kOpusCodec;
1522 codecs[0].bitrate = 0; // bitrate == default
1523 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1524 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1525 EXPECT_EQ(111, gcodec.pltype);
1526 EXPECT_STREQ("opus", gcodec.plname);
1527 EXPECT_EQ(32000, gcodec.rate);
1528}
1529
Brave Yao5225dd82015-03-26 07:39:19 +08001530// Test that we could set packet size specified in kCodecParamPTime.
1531TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1532 EXPECT_TRUE(SetupEngine());
1533 int channel_num = voe_.GetLastChannel();
1534 std::vector<cricket::AudioCodec> codecs;
1535 codecs.push_back(kOpusCodec);
1536 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1537 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1538 webrtc::CodecInst gcodec;
1539 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1540 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1541
1542 codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Value below range.
1543 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1544 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1545 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1546
1547 codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Value beyond range.
1548 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1549 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1550 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1551
1552 codecs[0] = kIsacCodec; // Also try Isac, and with unsupported size.
1553 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1554 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1555 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1556 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1557
1558 codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1559 codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1560 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1561 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1562 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1563}
1564
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001565// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1567 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001568 std::vector<cricket::AudioCodec> codecs;
1569 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1570}
1571
1572// Test that we can set send codecs even with telephone-event codec as the first
1573// one on the list.
1574TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1575 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576 int channel_num = voe_.GetLastChannel();
1577 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001578 codecs.push_back(kTelephoneEventCodec);
1579 codecs.push_back(kIsacCodec);
1580 codecs.push_back(kPcmuCodec);
1581 codecs[0].id = 98; // DTMF
1582 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1584 webrtc::CodecInst gcodec;
1585 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001586 EXPECT_EQ(96, gcodec.pltype);
1587 EXPECT_STREQ("ISAC", gcodec.plname);
1588 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1589}
1590
1591// Test that we can set send codecs even with CN codec as the first
1592// one on the list.
1593TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1594 EXPECT_TRUE(SetupEngine());
1595 int channel_num = voe_.GetLastChannel();
1596 std::vector<cricket::AudioCodec> codecs;
1597 codecs.push_back(kCn16000Codec);
1598 codecs.push_back(kIsacCodec);
1599 codecs.push_back(kPcmuCodec);
1600 codecs[0].id = 98; // wideband CN
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);
1607 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608}
1609
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001610// Test that we set VAD and DTMF types correctly as caller.
1611TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612 EXPECT_TRUE(SetupEngine());
1613 int channel_num = voe_.GetLastChannel();
1614 std::vector<cricket::AudioCodec> codecs;
1615 codecs.push_back(kIsacCodec);
1616 codecs.push_back(kPcmuCodec);
1617 // TODO(juberti): cn 32000
1618 codecs.push_back(kCn16000Codec);
1619 codecs.push_back(kCn8000Codec);
1620 codecs.push_back(kTelephoneEventCodec);
1621 codecs.push_back(kRedCodec);
1622 codecs[0].id = 96;
1623 codecs[2].id = 97; // wideband CN
1624 codecs[4].id = 98; // DTMF
1625 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1626 webrtc::CodecInst gcodec;
1627 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1628 EXPECT_EQ(96, gcodec.pltype);
1629 EXPECT_STREQ("ISAC", gcodec.plname);
1630 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001631 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1633 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1634 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1635}
1636
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001637// Test that we set VAD and DTMF types correctly as callee.
1638TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001639 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001640 channel_ = engine_.CreateChannel();
1641 EXPECT_TRUE(channel_ != NULL);
1642
1643 int channel_num = voe_.GetLastChannel();
1644 std::vector<cricket::AudioCodec> codecs;
1645 codecs.push_back(kIsacCodec);
1646 codecs.push_back(kPcmuCodec);
1647 // TODO(juberti): cn 32000
1648 codecs.push_back(kCn16000Codec);
1649 codecs.push_back(kCn8000Codec);
1650 codecs.push_back(kTelephoneEventCodec);
1651 codecs.push_back(kRedCodec);
1652 codecs[0].id = 96;
1653 codecs[2].id = 97; // wideband CN
1654 codecs[4].id = 98; // DTMF
1655 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1656 EXPECT_TRUE(channel_->AddSendStream(
1657 cricket::StreamParams::CreateLegacy(kSsrc1)));
1658
1659 webrtc::CodecInst gcodec;
1660 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1661 EXPECT_EQ(96, gcodec.pltype);
1662 EXPECT_STREQ("ISAC", gcodec.plname);
1663 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001664 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001665 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1666 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1667 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1668}
1669
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001670// Test that we only apply VAD if we have a CN codec that matches the
1671// send codec clockrate.
1672TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1673 EXPECT_TRUE(SetupEngine());
1674 int channel_num = voe_.GetLastChannel();
1675 std::vector<cricket::AudioCodec> codecs;
1676 // Set ISAC(16K) and CN(16K). VAD should be activated.
1677 codecs.push_back(kIsacCodec);
1678 codecs.push_back(kCn16000Codec);
1679 codecs[1].id = 97;
1680 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1681 webrtc::CodecInst gcodec;
1682 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1683 EXPECT_STREQ("ISAC", gcodec.plname);
1684 EXPECT_TRUE(voe_.GetVAD(channel_num));
1685 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1686 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1687 codecs[0] = kPcmuCodec;
1688 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1689 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1690 EXPECT_STREQ("PCMU", gcodec.plname);
1691 EXPECT_FALSE(voe_.GetVAD(channel_num));
1692 // Set PCMU(8K) and CN(8K). VAD should be activated.
1693 codecs[1] = kCn8000Codec;
1694 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1695 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1696 EXPECT_STREQ("PCMU", gcodec.plname);
1697 EXPECT_TRUE(voe_.GetVAD(channel_num));
1698 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
Brave Yao5225dd82015-03-26 07:39:19 +08001699 // Set ISAC(16K) and CN(8K). VAD should not be activated.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001700 codecs[0] = kIsacCodec;
1701 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1702 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1703 EXPECT_STREQ("ISAC", gcodec.plname);
1704 EXPECT_FALSE(voe_.GetVAD(channel_num));
1705}
1706
1707// Test that we perform case-insensitive matching of codec names.
1708TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1709 EXPECT_TRUE(SetupEngine());
1710 int channel_num = voe_.GetLastChannel();
1711 std::vector<cricket::AudioCodec> codecs;
1712 codecs.push_back(kIsacCodec);
1713 codecs.push_back(kPcmuCodec);
1714 codecs.push_back(kCn16000Codec);
1715 codecs.push_back(kCn8000Codec);
1716 codecs.push_back(kTelephoneEventCodec);
1717 codecs.push_back(kRedCodec);
1718 codecs[0].name = "iSaC";
1719 codecs[0].id = 96;
1720 codecs[2].id = 97; // wideband CN
1721 codecs[4].id = 98; // DTMF
1722 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1723 webrtc::CodecInst gcodec;
1724 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1725 EXPECT_EQ(96, gcodec.pltype);
1726 EXPECT_STREQ("ISAC", gcodec.plname);
1727 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001728 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1730 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1731 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1732}
1733
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001734// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001735TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001736 EXPECT_TRUE(SetupEngine());
1737 int channel_num = voe_.GetLastChannel();
1738 std::vector<cricket::AudioCodec> codecs;
1739 codecs.push_back(kRedCodec);
1740 codecs.push_back(kIsacCodec);
1741 codecs.push_back(kPcmuCodec);
1742 codecs[0].id = 127;
1743 codecs[0].params[""] = "96/96";
1744 codecs[1].id = 96;
1745 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1746 webrtc::CodecInst gcodec;
1747 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1748 EXPECT_EQ(96, gcodec.pltype);
1749 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001750 EXPECT_TRUE(voe_.GetRED(channel_num));
1751 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001752}
1753
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001754// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001755TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001756 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001757 channel_ = engine_.CreateChannel();
1758 EXPECT_TRUE(channel_ != NULL);
1759
1760 int channel_num = voe_.GetLastChannel();
1761 std::vector<cricket::AudioCodec> codecs;
1762 codecs.push_back(kRedCodec);
1763 codecs.push_back(kIsacCodec);
1764 codecs.push_back(kPcmuCodec);
1765 codecs[0].id = 127;
1766 codecs[0].params[""] = "96/96";
1767 codecs[1].id = 96;
1768 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1769 EXPECT_TRUE(channel_->AddSendStream(
1770 cricket::StreamParams::CreateLegacy(kSsrc1)));
1771 webrtc::CodecInst gcodec;
1772 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1773 EXPECT_EQ(96, gcodec.pltype);
1774 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001775 EXPECT_TRUE(voe_.GetRED(channel_num));
1776 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001777}
1778
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001779// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001780TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1781 EXPECT_TRUE(SetupEngine());
1782 int channel_num = voe_.GetLastChannel();
1783 std::vector<cricket::AudioCodec> codecs;
1784 codecs.push_back(kRedCodec);
1785 codecs.push_back(kIsacCodec);
1786 codecs.push_back(kPcmuCodec);
1787 codecs[0].id = 127;
1788 codecs[1].id = 96;
1789 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1790 webrtc::CodecInst gcodec;
1791 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1792 EXPECT_EQ(96, gcodec.pltype);
1793 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001794 EXPECT_TRUE(voe_.GetRED(channel_num));
1795 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796}
1797
1798// Test that we ignore RED if the parameters aren't named the way we expect.
1799TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1800 EXPECT_TRUE(SetupEngine());
1801 int channel_num = voe_.GetLastChannel();
1802 std::vector<cricket::AudioCodec> codecs;
1803 codecs.push_back(kRedCodec);
1804 codecs.push_back(kIsacCodec);
1805 codecs.push_back(kPcmuCodec);
1806 codecs[0].id = 127;
1807 codecs[0].params["ABC"] = "96/96";
1808 codecs[1].id = 96;
1809 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1810 webrtc::CodecInst gcodec;
1811 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1812 EXPECT_EQ(96, gcodec.pltype);
1813 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001814 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815}
1816
1817// Test that we ignore RED if it uses different primary/secondary encoding.
1818TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1819 EXPECT_TRUE(SetupEngine());
1820 int channel_num = voe_.GetLastChannel();
1821 std::vector<cricket::AudioCodec> codecs;
1822 codecs.push_back(kRedCodec);
1823 codecs.push_back(kIsacCodec);
1824 codecs.push_back(kPcmuCodec);
1825 codecs[0].id = 127;
1826 codecs[0].params[""] = "96/0";
1827 codecs[1].id = 96;
1828 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1829 webrtc::CodecInst gcodec;
1830 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1831 EXPECT_EQ(96, gcodec.pltype);
1832 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001833 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001834}
1835
1836// Test that we ignore RED if it uses more than 2 encodings.
1837TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1838 EXPECT_TRUE(SetupEngine());
1839 int channel_num = voe_.GetLastChannel();
1840 std::vector<cricket::AudioCodec> codecs;
1841 codecs.push_back(kRedCodec);
1842 codecs.push_back(kIsacCodec);
1843 codecs.push_back(kPcmuCodec);
1844 codecs[0].id = 127;
1845 codecs[0].params[""] = "96/96/96";
1846 codecs[1].id = 96;
1847 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1848 webrtc::CodecInst gcodec;
1849 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1850 EXPECT_EQ(96, gcodec.pltype);
1851 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001852 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001853}
1854
1855// Test that we ignore RED if it has bogus codec ids.
1856TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1857 EXPECT_TRUE(SetupEngine());
1858 int channel_num = voe_.GetLastChannel();
1859 std::vector<cricket::AudioCodec> codecs;
1860 codecs.push_back(kRedCodec);
1861 codecs.push_back(kIsacCodec);
1862 codecs.push_back(kPcmuCodec);
1863 codecs[0].id = 127;
1864 codecs[0].params[""] = "ABC/ABC";
1865 codecs[1].id = 96;
1866 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1867 webrtc::CodecInst gcodec;
1868 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1869 EXPECT_EQ(96, gcodec.pltype);
1870 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001871 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001872}
1873
1874// Test that we ignore RED if it refers to a codec that is not present.
1875TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1876 EXPECT_TRUE(SetupEngine());
1877 int channel_num = voe_.GetLastChannel();
1878 std::vector<cricket::AudioCodec> codecs;
1879 codecs.push_back(kRedCodec);
1880 codecs.push_back(kIsacCodec);
1881 codecs.push_back(kPcmuCodec);
1882 codecs[0].id = 127;
1883 codecs[0].params[""] = "97/97";
1884 codecs[1].id = 96;
1885 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1886 webrtc::CodecInst gcodec;
1887 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1888 EXPECT_EQ(96, gcodec.pltype);
1889 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001890 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001891}
1892
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001893// Test support for audio level header extension.
1894TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1895 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001896}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001897TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1898 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1899}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001900
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001901// Test support for absolute send time header extension.
1902TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1903 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1904}
1905TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1906 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001907}
1908
1909// Test that we can create a channel and start sending/playing out on it.
1910TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1911 EXPECT_TRUE(SetupEngine());
1912 int channel_num = voe_.GetLastChannel();
1913 std::vector<cricket::AudioCodec> codecs;
1914 codecs.push_back(kPcmuCodec);
1915 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1916 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1917 EXPECT_TRUE(voe_.GetSend(channel_num));
1918 EXPECT_TRUE(channel_->SetPlayout(true));
1919 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1920 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1921 EXPECT_FALSE(voe_.GetSend(channel_num));
1922 EXPECT_TRUE(channel_->SetPlayout(false));
1923 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1924}
1925
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001926// Test that we can add and remove send streams.
1927TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1928 SetupForMultiSendStream();
1929
1930 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1931
1932 // Set the global state for sending.
1933 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1934
1935 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1936 EXPECT_TRUE(channel_->AddSendStream(
1937 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1938
1939 // Verify that we are in a sending state for all the created streams.
1940 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1941 EXPECT_TRUE(voe_.GetSend(channel_num));
1942 }
1943
1944 // Remove the first send channel, which is the default channel. It will only
1945 // recycle the default channel but not delete it.
1946 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1947 // Stream should already be Removed from the send stream list.
1948 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1949 // But the default still exists.
1950 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1951
1952 // Delete the rest of send channel streams.
1953 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1954 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1955 // Stream should already be deleted.
1956 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1957 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1958 }
1959}
1960
1961// Test SetSendCodecs correctly configure the codecs in all send streams.
1962TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1963 SetupForMultiSendStream();
1964
1965 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1966 // Create send streams.
1967 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1968 EXPECT_TRUE(channel_->AddSendStream(
1969 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1970 }
1971
1972 std::vector<cricket::AudioCodec> codecs;
1973 // Set ISAC(16K) and CN(16K). VAD should be activated.
1974 codecs.push_back(kIsacCodec);
1975 codecs.push_back(kCn16000Codec);
1976 codecs[1].id = 97;
1977 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1978
1979 // Verify ISAC and VAD are corrected configured on all send channels.
1980 webrtc::CodecInst gcodec;
1981 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1982 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1983 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1984 EXPECT_STREQ("ISAC", gcodec.plname);
1985 EXPECT_TRUE(voe_.GetVAD(channel_num));
1986 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1987 }
1988
1989 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1990 codecs[0] = kPcmuCodec;
1991 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1992 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1993 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1994 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1995 EXPECT_STREQ("PCMU", gcodec.plname);
1996 EXPECT_FALSE(voe_.GetVAD(channel_num));
1997 }
1998}
1999
2000// Test we can SetSend on all send streams correctly.
2001TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2002 SetupForMultiSendStream();
2003
2004 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2005 // Create the send channels and they should be a SEND_NOTHING date.
2006 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2007 EXPECT_TRUE(channel_->AddSendStream(
2008 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2009 int channel_num = voe_.GetLastChannel();
2010 EXPECT_FALSE(voe_.GetSend(channel_num));
2011 }
2012
2013 // Set the global state for starting sending.
2014 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2015 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2016 // Verify that we are in a sending state for all the send streams.
2017 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2018 EXPECT_TRUE(voe_.GetSend(channel_num));
2019 }
2020
2021 // Set the global state for stopping sending.
2022 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2023 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
2024 // Verify that we are in a stop state for all the send streams.
2025 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2026 EXPECT_FALSE(voe_.GetSend(channel_num));
2027 }
2028}
2029
2030// Test we can set the correct statistics on all send streams.
2031TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2032 SetupForMultiSendStream();
2033
2034 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2035 // Create send streams.
2036 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2037 EXPECT_TRUE(channel_->AddSendStream(
2038 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2039 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002040 // Create a receive stream to check that none of the send streams end up in
2041 // the receive stream stats.
2042 EXPECT_TRUE(channel_->AddRecvStream(
2043 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002044 // We need send codec to be set to get all stats.
2045 std::vector<cricket::AudioCodec> codecs;
2046 codecs.push_back(kPcmuCodec);
2047 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002048 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049
2050 cricket::VoiceMediaInfo info;
2051 EXPECT_EQ(true, channel_->GetStats(&info));
2052 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
2053
2054 // Verify the statistic information is correct.
2055 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002056 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002057 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
2058 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
2059 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
2060 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
2061 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
2062 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
2063 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
2064 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002065 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002066 }
2067
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002068 EXPECT_EQ(0u, info.receivers.size());
2069 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2070 EXPECT_EQ(true, channel_->GetStats(&info));
2071
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002072 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002073 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2074 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2075 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2076 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2077 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002078 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2079 (1 << 14), info.receivers[0].expand_rate);
2080 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2081 (1 << 14), info.receivers[0].speech_expand_rate);
2082 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2083 (1 << 14), info.receivers[0].secondary_decoded_rate);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002084}
2085
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002086// Test that we can add and remove receive streams, and do proper send/playout.
2087// We can receive on multiple streams while sending one stream.
2088TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002089 EXPECT_TRUE(SetupEngine());
2090 int channel_num1 = voe_.GetLastChannel();
2091
2092 // Start playout on the default channel.
2093 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2094 EXPECT_TRUE(channel_->SetPlayout(true));
2095 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2096
2097 // Adding another stream should disable playout on the default channel.
2098 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2099 int channel_num2 = voe_.GetLastChannel();
2100 std::vector<cricket::AudioCodec> codecs;
2101 codecs.push_back(kPcmuCodec);
2102 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2103 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2104 EXPECT_TRUE(voe_.GetSend(channel_num1));
2105 EXPECT_FALSE(voe_.GetSend(channel_num2));
2106
2107 // Make sure only the new channel is played out.
2108 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2109 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2110
2111 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2112 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2113 int channel_num3 = voe_.GetLastChannel();
2114 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2115 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2116 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2117 EXPECT_FALSE(voe_.GetSend(channel_num3));
2118
2119 // Stop sending.
2120 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2121 EXPECT_FALSE(voe_.GetSend(channel_num1));
2122 EXPECT_FALSE(voe_.GetSend(channel_num2));
2123 EXPECT_FALSE(voe_.GetSend(channel_num3));
2124
2125 // Stop playout.
2126 EXPECT_TRUE(channel_->SetPlayout(false));
2127 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2128 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2129 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2130
2131 // Restart playout and make sure the default channel still is not played out.
2132 EXPECT_TRUE(channel_->SetPlayout(true));
2133 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2134 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2135 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2136
2137 // Now remove the new streams and verify that the default channel is
2138 // played out again.
2139 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2140 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2141
2142 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2143}
2144
2145// Test that we can set the devices to use.
2146TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2147 EXPECT_TRUE(SetupEngine());
2148 int channel_num = voe_.GetLastChannel();
2149 std::vector<cricket::AudioCodec> codecs;
2150 codecs.push_back(kPcmuCodec);
2151 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2152
2153 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2154 cricket::kFakeDefaultDeviceId);
2155 cricket::Device dev(cricket::kFakeDeviceName,
2156 cricket::kFakeDeviceId);
2157
2158 // Test SetDevices() while not sending or playing.
2159 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2160
2161 // Test SetDevices() while sending and playing.
2162 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2163 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2164 EXPECT_TRUE(channel_->SetPlayout(true));
2165 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2166 EXPECT_TRUE(voe_.GetSend(channel_num));
2167 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2168
2169 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2170
2171 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2172 EXPECT_TRUE(voe_.GetSend(channel_num));
2173 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2174
2175 // Test that failure to open newly selected devices does not prevent opening
2176 // ones after that.
2177 voe_.set_fail_start_recording_microphone(true);
2178 voe_.set_playout_fail_channel(channel_num);
2179 voe_.set_send_fail_channel(channel_num);
2180
2181 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2182
2183 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2184 EXPECT_FALSE(voe_.GetSend(channel_num));
2185 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2186
2187 voe_.set_fail_start_recording_microphone(false);
2188 voe_.set_playout_fail_channel(-1);
2189 voe_.set_send_fail_channel(-1);
2190
2191 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2192
2193 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2194 EXPECT_TRUE(voe_.GetSend(channel_num));
2195 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2196}
2197
2198// Test that we can set the devices to use even if we failed to
2199// open the initial ones.
2200TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2201 EXPECT_TRUE(SetupEngine());
2202 int channel_num = voe_.GetLastChannel();
2203 std::vector<cricket::AudioCodec> codecs;
2204 codecs.push_back(kPcmuCodec);
2205 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2206
2207 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2208 cricket::kFakeDefaultDeviceId);
2209 cricket::Device dev(cricket::kFakeDeviceName,
2210 cricket::kFakeDeviceId);
2211
2212 // Test that failure to open devices selected before starting
2213 // send/play does not prevent opening newly selected ones after that.
2214 voe_.set_fail_start_recording_microphone(true);
2215 voe_.set_playout_fail_channel(channel_num);
2216 voe_.set_send_fail_channel(channel_num);
2217
2218 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2219
2220 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2221 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2222 EXPECT_FALSE(channel_->SetPlayout(true));
2223 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2224 EXPECT_FALSE(voe_.GetSend(channel_num));
2225 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2226
2227 voe_.set_fail_start_recording_microphone(false);
2228 voe_.set_playout_fail_channel(-1);
2229 voe_.set_send_fail_channel(-1);
2230
2231 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2232
2233 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2234 EXPECT_TRUE(voe_.GetSend(channel_num));
2235 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2236}
2237
2238// Test that we can create a channel configured for multi-point conferences,
2239// and start sending/playing out on it.
2240TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2241 EXPECT_TRUE(SetupEngine());
2242 int channel_num = voe_.GetLastChannel();
2243 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2244 std::vector<cricket::AudioCodec> codecs;
2245 codecs.push_back(kPcmuCodec);
2246 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2247 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2248 EXPECT_TRUE(voe_.GetSend(channel_num));
2249}
2250
2251// Test that we can create a channel configured for Codian bridges,
2252// and start sending/playing out on it.
2253TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2254 EXPECT_TRUE(SetupEngine());
2255 int channel_num = voe_.GetLastChannel();
2256 webrtc::AgcConfig agc_config;
2257 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2258 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2259 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2260 std::vector<cricket::AudioCodec> codecs;
2261 codecs.push_back(kPcmuCodec);
2262 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2263 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2264 EXPECT_TRUE(voe_.GetSend(channel_num));
2265 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2266 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2267 EXPECT_TRUE(channel_->SetPlayout(true));
2268 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2269 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2270 EXPECT_FALSE(voe_.GetSend(channel_num));
2271 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2272 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2273 EXPECT_TRUE(channel_->SetPlayout(false));
2274 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2275}
2276
wu@webrtc.org97077a32013-10-25 21:18:33 +00002277TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2278 EXPECT_TRUE(SetupEngine());
2279 webrtc::AgcConfig agc_config;
2280 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2281 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2282
2283 cricket::AudioOptions options;
2284 options.tx_agc_target_dbov.Set(3);
2285 options.tx_agc_digital_compression_gain.Set(9);
2286 options.tx_agc_limiter.Set(true);
2287 options.auto_gain_control.Set(true);
2288 EXPECT_TRUE(engine_.SetOptions(options));
2289
2290 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2291 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2292 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2293 EXPECT_TRUE(agc_config.limiterEnable);
2294
2295 // Check interaction with adjust_agc_delta. Both should be respected, for
2296 // backwards compatibility.
2297 options.adjust_agc_delta.Set(-10);
2298 EXPECT_TRUE(engine_.SetOptions(options));
2299
2300 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2301 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2302}
2303
2304TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2305 EXPECT_TRUE(SetupEngine());
2306 int channel_num = voe_.GetLastChannel();
2307 cricket::AudioOptions options;
2308 options.rx_agc_target_dbov.Set(6);
2309 options.rx_agc_digital_compression_gain.Set(0);
2310 options.rx_agc_limiter.Set(true);
2311 options.rx_auto_gain_control.Set(true);
2312 EXPECT_TRUE(channel_->SetOptions(options));
2313
2314 webrtc::AgcConfig agc_config;
2315 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2316 channel_num, agc_config));
2317 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2318 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2319 EXPECT_TRUE(agc_config.limiterEnable);
2320}
2321
2322TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2323 EXPECT_TRUE(SetupEngine());
2324 cricket::AudioOptions options;
2325 options.recording_sample_rate.Set(48000u);
2326 options.playout_sample_rate.Set(44100u);
2327 EXPECT_TRUE(engine_.SetOptions(options));
2328
2329 unsigned int recording_sample_rate, playout_sample_rate;
2330 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2331 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2332 EXPECT_EQ(48000u, recording_sample_rate);
2333 EXPECT_EQ(44100u, playout_sample_rate);
2334}
2335
2336TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2337 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002338 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002339 EXPECT_EQ(
2340 // Info:
2341 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2342 // Warning:
2343 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2344 // Error:
2345 webrtc::kTraceError | webrtc::kTraceCritical,
2346 static_cast<int>(trace_wrapper_->filter_));
2347 // Now set it explicitly
2348 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002349 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2350 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002351 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2352 trace_wrapper_->filter_);
2353}
2354
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002355// Test that we can set the outgoing SSRC properly.
2356// SSRC is set in SetupEngine by calling AddSendStream.
2357TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2358 EXPECT_TRUE(SetupEngine());
2359 int channel_num = voe_.GetLastChannel();
2360 unsigned int send_ssrc;
2361 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2362 EXPECT_NE(0U, send_ssrc);
2363 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2364 EXPECT_EQ(kSsrc1, send_ssrc);
2365}
2366
2367TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2368 // Setup. We need send codec to be set to get all stats.
2369 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002370 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2371 // use a different SSRC.
2372 EXPECT_TRUE(channel_->AddRecvStream(
2373 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374 std::vector<cricket::AudioCodec> codecs;
2375 codecs.push_back(kPcmuCodec);
2376 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002377 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002378
2379 cricket::VoiceMediaInfo info;
2380 EXPECT_EQ(true, channel_->GetStats(&info));
2381 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002382 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002383 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2384 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2385 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2386 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2387 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2388 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2389 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2390 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002391 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002392 // TODO(sriniv): Add testing for more fields. These are not populated
2393 // in FakeWebrtcVoiceEngine yet.
2394 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2395 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2396 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2397 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2398 // EXPECT_EQ(cricket::kIntStatValue,
2399 // info.senders[0].echo_return_loss_enhancement);
2400
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002401 EXPECT_EQ(0u, info.receivers.size());
2402 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2403 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002404 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002405
2406 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2407 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2408 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2409 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2410 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002411 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2412 (1 << 14), info.receivers[0].expand_rate);
2413 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2414 (1 << 14), info.receivers[0].speech_expand_rate);
2415 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2416 (1 << 14), info.receivers[0].secondary_decoded_rate);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002417 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418}
2419
2420// Test that we can set the outgoing SSRC properly with multiple streams.
2421// SSRC is set in SetupEngine by calling AddSendStream.
2422TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2423 EXPECT_TRUE(SetupEngine());
2424 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2425 int channel_num1 = voe_.GetLastChannel();
2426 unsigned int send_ssrc;
2427 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2428 EXPECT_EQ(kSsrc1, send_ssrc);
2429
2430 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2431 int channel_num2 = voe_.GetLastChannel();
2432 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2433 EXPECT_EQ(kSsrc1, send_ssrc);
2434}
2435
2436// Test that the local SSRC is the same on sending and receiving channels if the
2437// receive channel is created before the send channel.
2438TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002439 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440 channel_ = engine_.CreateChannel();
2441 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2442
2443 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2444 int receive_channel_num = voe_.GetLastChannel();
2445 EXPECT_TRUE(channel_->AddSendStream(
2446 cricket::StreamParams::CreateLegacy(1234)));
2447 int send_channel_num = voe_.GetLastChannel();
2448
2449 unsigned int ssrc = 0;
2450 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2451 EXPECT_EQ(1234U, ssrc);
2452 ssrc = 0;
2453 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2454 EXPECT_EQ(1234U, ssrc);
2455}
2456
2457// Test that we can properly receive packets.
2458TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2459 EXPECT_TRUE(SetupEngine());
2460 int channel_num = voe_.GetLastChannel();
2461 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2462 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2463 sizeof(kPcmuFrame)));
2464}
2465
2466// Test that we can properly receive packets on multiple streams.
2467TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2468 EXPECT_TRUE(SetupEngine());
2469 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2470 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2471 int channel_num1 = voe_.GetLastChannel();
2472 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2473 int channel_num2 = voe_.GetLastChannel();
2474 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2475 int channel_num3 = voe_.GetLastChannel();
2476 // Create packets with the right SSRCs.
2477 char packets[4][sizeof(kPcmuFrame)];
2478 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2479 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002480 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 }
2482 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2483 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2484 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2485 DeliverPacket(packets[0], sizeof(packets[0]));
2486 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2487 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2488 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2489 DeliverPacket(packets[1], sizeof(packets[1]));
2490 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2491 sizeof(packets[1])));
2492 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2493 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2494 DeliverPacket(packets[2], sizeof(packets[2]));
2495 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2496 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2497 sizeof(packets[2])));
2498 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2499 DeliverPacket(packets[3], sizeof(packets[3]));
2500 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2501 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2502 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2503 sizeof(packets[3])));
2504 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2505 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2506 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2507}
2508
2509// Test that we properly handle failures to add a stream.
2510TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2511 EXPECT_TRUE(SetupEngine());
2512 voe_.set_fail_create_channel(true);
2513 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2514 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2515
2516 // In 1:1 call, we should not try to create a new channel.
2517 cricket::AudioOptions options_no_conference_;
2518 options_no_conference_.conference_mode.Set(false);
2519 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2520 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2521}
2522
2523// Test that AddRecvStream doesn't create new channel for 1:1 call.
2524TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2525 EXPECT_TRUE(SetupEngine());
2526 int channel_num = voe_.GetLastChannel();
2527 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2528 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2529}
2530
2531// Test that after adding a recv stream, we do not decode more codecs than
2532// those previously passed into SetRecvCodecs.
2533TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2534 EXPECT_TRUE(SetupEngine());
2535 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2536 std::vector<cricket::AudioCodec> codecs;
2537 codecs.push_back(kIsacCodec);
2538 codecs.push_back(kPcmuCodec);
2539 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2540 EXPECT_TRUE(channel_->AddRecvStream(
2541 cricket::StreamParams::CreateLegacy(kSsrc1)));
2542 int channel_num2 = voe_.GetLastChannel();
2543 webrtc::CodecInst gcodec;
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002544 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "opus");
2545 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002546 gcodec.channels = 2;
2547 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2548}
2549
2550// Test that we properly clean up any streams that were added, even if
2551// not explicitly removed.
2552TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2553 EXPECT_TRUE(SetupEngine());
2554 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2555 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2556 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2557 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2558 delete channel_;
2559 channel_ = NULL;
2560 EXPECT_EQ(0, voe_.GetNumChannels());
2561}
2562
wu@webrtc.org78187522013-10-07 23:32:02 +00002563TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2564 EXPECT_TRUE(SetupEngine());
2565 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2566}
2567
2568TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2569 EXPECT_TRUE(SetupEngine());
2570 // Stream 1 reuses default channel.
2571 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2572 // Manually delete default channel to simulate a failure.
2573 int default_channel = voe_.GetLastChannel();
2574 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2575 // Add recv stream 2 should fail because default channel is gone.
2576 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2577 int new_channel = voe_.GetLastChannel();
2578 EXPECT_NE(default_channel, new_channel);
2579 // The last created channel should have already been deleted.
2580 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2581}
2582
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002583// Test the InsertDtmf on default send stream as caller.
2584TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2585 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002586}
2587
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002588// Test the InsertDtmf on default send stream as callee
2589TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2590 TestInsertDtmf(0, false);
2591}
2592
2593// Test the InsertDtmf on specified send stream as caller.
2594TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2595 TestInsertDtmf(kSsrc1, true);
2596}
2597
2598// Test the InsertDtmf on specified send stream as callee.
2599TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2600 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002601}
2602
2603// Test that we can play a ringback tone properly in a single-stream call.
2604TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2605 EXPECT_TRUE(SetupEngine());
2606 int channel_num = voe_.GetLastChannel();
2607 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2608 // Check we fail if no ringback tone specified.
2609 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2610 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2611 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002612 EXPECT_TRUE(channel_->SetRingbackTone(
2613 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002614 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2615 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2616 // Check we can stop the tone manually.
2617 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2618 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2619 // Check we stop the tone if a packet arrives.
2620 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2621 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2622 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2623 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2624}
2625
2626// Test that we can play a ringback tone properly in a multi-stream call.
2627TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2628 EXPECT_TRUE(SetupEngine());
2629 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2630 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2631 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2632 int channel_num = voe_.GetLastChannel();
2633 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2634 // Check we fail if no ringback tone specified.
2635 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2636 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2637 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002638 EXPECT_TRUE(channel_->SetRingbackTone(
2639 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002640 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2641 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2642 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2643 // Check we can stop the tone manually.
2644 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2645 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2646 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2647 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2648 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2649 // Send a packet with SSRC 1; the tone should not stop.
2650 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2651 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2652 // Send a packet with SSRC 2; the tone should stop.
2653 char packet[sizeof(kPcmuFrame)];
2654 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002655 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002656 DeliverPacket(packet, sizeof(packet));
2657 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2658}
2659
2660// Tests creating soundclips, and make sure they come from the right engine.
2661TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002662 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002663 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002664 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002665 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002666 ASSERT_TRUE(soundclip_ != NULL);
2667 EXPECT_EQ(0, voe_.GetNumChannels());
2668 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2669 int channel_num = voe_sc_.GetLastChannel();
2670 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2671 delete soundclip_;
2672 soundclip_ = NULL;
2673 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002674 // Make sure the soundclip engine is uninitialized on shutdown, now that
2675 // we've initialized it by creating a soundclip.
2676 engine_.Terminate();
2677 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002678}
2679
2680// Tests playing out a fake sound.
2681TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2682 static const char kZeroes[16000] = {};
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002683 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002684 soundclip_ = engine_.CreateSoundclip();
2685 ASSERT_TRUE(soundclip_ != NULL);
2686 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2687}
2688
2689TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002690 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002691 cricket::WebRtcVoiceMediaChannel* media_channel;
2692 unsigned int ssrc = 0;
2693
2694 EXPECT_TRUE(SetupEngine());
2695 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2696 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2697
2698 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2699 listener.reset(new ChannelErrorListener(channel_));
2700
2701 // Test on WebRtc VoE channel.
2702 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2703 VE_SATURATION_WARNING);
2704 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2705 listener->error());
2706 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2707 EXPECT_EQ(ssrc, listener->ssrc());
2708
2709 listener->Reset();
2710 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2711 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2712 listener->error());
2713 EXPECT_EQ(0U, listener->ssrc());
2714
2715 // Add another stream and test on that.
2716 ++ssrc;
2717 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2718 ssrc)));
2719 listener->Reset();
2720 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2721 VE_SATURATION_WARNING);
2722 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2723 listener->error());
2724 EXPECT_EQ(ssrc, listener->ssrc());
2725
2726 // Testing a non-existing channel.
2727 listener->Reset();
2728 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2729 VE_SATURATION_WARNING);
2730 EXPECT_EQ(0, listener->error());
2731}
2732
2733TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2734 EXPECT_TRUE(SetupEngine());
2735 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2736 std::vector<cricket::AudioCodec> codecs;
2737 codecs.push_back(kPcmuCodec);
2738 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2739 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2740 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2741 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2742 EXPECT_TRUE(channel_->SetPlayout(true));
2743 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2744 EXPECT_TRUE(channel_->SetPlayout(false));
2745 EXPECT_FALSE(channel_->SetPlayout(true));
2746}
2747
2748// Test that the Registering/Unregistering with the
2749// webrtcvoiceengine works as expected
2750TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2751 EXPECT_TRUE(SetupEngine());
2752 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2753 EXPECT_TRUE(channel_->AddRecvStream(
2754 cricket::StreamParams::CreateLegacy(kSsrc2)));
2755 cricket::FakeMediaProcessor vp_1;
2756 cricket::FakeMediaProcessor vp_2;
2757
2758 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2759 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2760 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2761 voe_.TriggerProcessPacket(cricket::MPD_RX);
2762 voe_.TriggerProcessPacket(cricket::MPD_TX);
2763
2764 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2765 EXPECT_EQ(1, vp_1.voice_frame_count());
2766 EXPECT_EQ(1, vp_2.voice_frame_count());
2767
2768 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2769 &vp_2,
2770 cricket::MPD_RX));
2771 voe_.TriggerProcessPacket(cricket::MPD_RX);
2772 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2773 EXPECT_EQ(1, vp_2.voice_frame_count());
2774 EXPECT_EQ(2, vp_1.voice_frame_count());
2775
2776 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2777 &vp_1,
2778 cricket::MPD_RX));
2779 voe_.TriggerProcessPacket(cricket::MPD_RX);
2780 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2781 EXPECT_EQ(2, vp_1.voice_frame_count());
2782
2783 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2784 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2785 voe_.TriggerProcessPacket(cricket::MPD_RX);
2786 voe_.TriggerProcessPacket(cricket::MPD_TX);
2787 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2788 EXPECT_EQ(3, vp_1.voice_frame_count());
2789
2790 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2791 &vp_1,
2792 cricket::MPD_RX_AND_TX));
2793 voe_.TriggerProcessPacket(cricket::MPD_TX);
2794 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2795 EXPECT_EQ(3, vp_1.voice_frame_count());
2796 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2797 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2798 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2799
2800 // Test that we can register a processor on the receive channel on SSRC 0.
2801 // This tests the 1:1 case when the receive SSRC is unknown.
2802 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2803 voe_.TriggerProcessPacket(cricket::MPD_RX);
2804 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2805 EXPECT_EQ(4, vp_1.voice_frame_count());
2806 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2807 &vp_1,
2808 cricket::MPD_RX));
2809
2810 // The following tests test that FindChannelNumFromSsrc is doing
2811 // what we expect.
2812 // pick an invalid ssrc and make sure we can't register
2813 EXPECT_FALSE(engine_.RegisterProcessor(99,
2814 &vp_1,
2815 cricket::MPD_RX));
2816 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2817 EXPECT_TRUE(engine_.RegisterProcessor(1,
2818 &vp_1,
2819 cricket::MPD_RX));
2820 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2821 &vp_1,
2822 cricket::MPD_RX));
2823 EXPECT_FALSE(engine_.RegisterProcessor(1,
2824 &vp_1,
2825 cricket::MPD_TX));
2826 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2827}
2828
2829TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2830 EXPECT_TRUE(SetupEngine());
2831
2832 bool ec_enabled;
2833 webrtc::EcModes ec_mode;
2834 bool ec_metrics_enabled;
2835 webrtc::AecmModes aecm_mode;
2836 bool cng_enabled;
2837 bool agc_enabled;
2838 webrtc::AgcModes agc_mode;
2839 webrtc::AgcConfig agc_config;
2840 bool ns_enabled;
2841 webrtc::NsModes ns_mode;
2842 bool highpass_filter_enabled;
2843 bool stereo_swapping_enabled;
2844 bool typing_detection_enabled;
2845 voe_.GetEcStatus(ec_enabled, ec_mode);
2846 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2847 voe_.GetAecmMode(aecm_mode, cng_enabled);
2848 voe_.GetAgcStatus(agc_enabled, agc_mode);
2849 voe_.GetAgcConfig(agc_config);
2850 voe_.GetNsStatus(ns_enabled, ns_mode);
2851 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2852 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2853 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2854 EXPECT_TRUE(ec_enabled);
2855 EXPECT_TRUE(ec_metrics_enabled);
2856 EXPECT_FALSE(cng_enabled);
2857 EXPECT_TRUE(agc_enabled);
2858 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2859 EXPECT_TRUE(ns_enabled);
2860 EXPECT_TRUE(highpass_filter_enabled);
2861 EXPECT_FALSE(stereo_swapping_enabled);
2862 EXPECT_TRUE(typing_detection_enabled);
2863 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2864 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2865
2866 // Nothing set, so all ignored.
2867 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002868 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869 voe_.GetEcStatus(ec_enabled, ec_mode);
2870 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2871 voe_.GetAecmMode(aecm_mode, cng_enabled);
2872 voe_.GetAgcStatus(agc_enabled, agc_mode);
2873 voe_.GetAgcConfig(agc_config);
2874 voe_.GetNsStatus(ns_enabled, ns_mode);
2875 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2876 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2877 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2878 EXPECT_TRUE(ec_enabled);
2879 EXPECT_TRUE(ec_metrics_enabled);
2880 EXPECT_FALSE(cng_enabled);
2881 EXPECT_TRUE(agc_enabled);
2882 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2883 EXPECT_TRUE(ns_enabled);
2884 EXPECT_TRUE(highpass_filter_enabled);
2885 EXPECT_FALSE(stereo_swapping_enabled);
2886 EXPECT_TRUE(typing_detection_enabled);
2887 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2888 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2889
2890 // Turn echo cancellation off
2891 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002892 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002893 voe_.GetEcStatus(ec_enabled, ec_mode);
2894 EXPECT_FALSE(ec_enabled);
2895
2896 // Turn echo cancellation back on, with settings, and make sure
2897 // nothing else changed.
2898 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002899 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002900 voe_.GetEcStatus(ec_enabled, ec_mode);
2901 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2902 voe_.GetAecmMode(aecm_mode, cng_enabled);
2903 voe_.GetAgcStatus(agc_enabled, agc_mode);
2904 voe_.GetAgcConfig(agc_config);
2905 voe_.GetNsStatus(ns_enabled, ns_mode);
2906 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2907 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2908 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2909 EXPECT_TRUE(ec_enabled);
2910 EXPECT_TRUE(ec_metrics_enabled);
2911 EXPECT_TRUE(agc_enabled);
2912 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2913 EXPECT_TRUE(ns_enabled);
2914 EXPECT_TRUE(highpass_filter_enabled);
2915 EXPECT_FALSE(stereo_swapping_enabled);
2916 EXPECT_TRUE(typing_detection_enabled);
2917 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2918 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2919
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002920 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2921 // control.
2922 options.delay_agnostic_aec.Set(true);
2923 ASSERT_TRUE(engine_.SetOptions(options));
2924 voe_.GetEcStatus(ec_enabled, ec_mode);
2925 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2926 voe_.GetAecmMode(aecm_mode, cng_enabled);
2927 EXPECT_TRUE(ec_enabled);
2928 EXPECT_TRUE(ec_metrics_enabled);
2929 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2930
2931 // Turn off echo cancellation and delay agnostic aec.
2932 options.delay_agnostic_aec.Set(false);
2933 options.experimental_aec.Set(false);
2934 options.echo_cancellation.Set(false);
2935 ASSERT_TRUE(engine_.SetOptions(options));
2936 voe_.GetEcStatus(ec_enabled, ec_mode);
2937 EXPECT_FALSE(ec_enabled);
2938 // Turning delay agnostic aec back on should also turn on echo cancellation.
2939 options.delay_agnostic_aec.Set(true);
2940 ASSERT_TRUE(engine_.SetOptions(options));
2941 voe_.GetEcStatus(ec_enabled, ec_mode);
2942 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2943 EXPECT_TRUE(ec_enabled);
2944 EXPECT_TRUE(ec_metrics_enabled);
2945 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2946
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947 // Turn off AGC
2948 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002949 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002950 voe_.GetAgcStatus(agc_enabled, agc_mode);
2951 EXPECT_FALSE(agc_enabled);
2952
2953 // Turn AGC back on
2954 options.auto_gain_control.Set(true);
2955 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002956 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002957 voe_.GetAgcStatus(agc_enabled, agc_mode);
2958 EXPECT_TRUE(agc_enabled);
2959 voe_.GetAgcConfig(agc_config);
2960 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2961
2962 // Turn off other options (and stereo swapping on).
2963 options.noise_suppression.Set(false);
2964 options.highpass_filter.Set(false);
2965 options.typing_detection.Set(false);
2966 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002967 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002968 voe_.GetNsStatus(ns_enabled, ns_mode);
2969 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2970 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2971 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2972 EXPECT_FALSE(ns_enabled);
2973 EXPECT_FALSE(highpass_filter_enabled);
2974 EXPECT_FALSE(typing_detection_enabled);
2975 EXPECT_TRUE(stereo_swapping_enabled);
2976
2977 // Turn on "conference mode" to ensure it has no impact.
2978 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002979 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980 voe_.GetEcStatus(ec_enabled, ec_mode);
2981 voe_.GetNsStatus(ns_enabled, ns_mode);
2982 EXPECT_TRUE(ec_enabled);
2983 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2984 EXPECT_FALSE(ns_enabled);
2985 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2986}
2987
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002988TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002989 EXPECT_TRUE(SetupEngine());
2990
2991 bool ec_enabled;
2992 webrtc::EcModes ec_mode;
2993 bool ec_metrics_enabled;
2994 bool agc_enabled;
2995 webrtc::AgcModes agc_mode;
2996 bool ns_enabled;
2997 webrtc::NsModes ns_mode;
2998 bool highpass_filter_enabled;
2999 bool stereo_swapping_enabled;
3000 bool typing_detection_enabled;
3001
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003002 voe_.GetEcStatus(ec_enabled, ec_mode);
3003 voe_.GetEcMetricsStatus(ec_metrics_enabled);
3004 voe_.GetAgcStatus(agc_enabled, agc_mode);
3005 voe_.GetNsStatus(ns_enabled, ns_mode);
3006 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
3007 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3008 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3009 EXPECT_TRUE(ec_enabled);
3010 EXPECT_TRUE(agc_enabled);
3011 EXPECT_TRUE(ns_enabled);
3012 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003013 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003015}
3016
3017TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
3018 webrtc::AgcConfig set_config = {0};
3019 set_config.targetLeveldBOv = 3;
3020 set_config.digitalCompressionGaindB = 9;
3021 set_config.limiterEnable = true;
3022 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003023 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024
3025 webrtc::AgcConfig config = {0};
3026 EXPECT_EQ(0, voe_.GetAgcConfig(config));
3027 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
3028 EXPECT_EQ(set_config.digitalCompressionGaindB,
3029 config.digitalCompressionGaindB);
3030 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
3031}
3032
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003033TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
3034 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003035 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003036 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003037 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003038 engine_.CreateChannel());
3039
3040 // Have to add a stream to make SetSend work.
3041 cricket::StreamParams stream1;
3042 stream1.ssrcs.push_back(1);
3043 channel1->AddSendStream(stream1);
3044 cricket::StreamParams stream2;
3045 stream2.ssrcs.push_back(2);
3046 channel2->AddSendStream(stream2);
3047
3048 // AEC and AGC and NS
3049 cricket::AudioOptions options_all;
3050 options_all.echo_cancellation.Set(true);
3051 options_all.auto_gain_control.Set(true);
3052 options_all.noise_suppression.Set(true);
3053
3054 ASSERT_TRUE(channel1->SetOptions(options_all));
3055 cricket::AudioOptions expected_options = options_all;
3056 cricket::AudioOptions actual_options;
3057 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3058 EXPECT_EQ(expected_options, actual_options);
3059 ASSERT_TRUE(channel2->SetOptions(options_all));
3060 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3061 EXPECT_EQ(expected_options, actual_options);
3062
3063 // unset NS
3064 cricket::AudioOptions options_no_ns;
3065 options_no_ns.noise_suppression.Set(false);
3066 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
3067
3068 expected_options.echo_cancellation.Set(true);
3069 expected_options.auto_gain_control.Set(true);
3070 expected_options.noise_suppression.Set(false);
3071 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3072 EXPECT_EQ(expected_options, actual_options);
3073
3074 // unset AGC
3075 cricket::AudioOptions options_no_agc;
3076 options_no_agc.auto_gain_control.Set(false);
3077 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
3078
3079 expected_options.echo_cancellation.Set(true);
3080 expected_options.auto_gain_control.Set(false);
3081 expected_options.noise_suppression.Set(true);
3082 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3083 EXPECT_EQ(expected_options, actual_options);
3084
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003085 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003086 bool ec_enabled;
3087 webrtc::EcModes ec_mode;
3088 bool agc_enabled;
3089 webrtc::AgcModes agc_mode;
3090 bool ns_enabled;
3091 webrtc::NsModes ns_mode;
3092 voe_.GetEcStatus(ec_enabled, ec_mode);
3093 voe_.GetAgcStatus(agc_enabled, agc_mode);
3094 voe_.GetNsStatus(ns_enabled, ns_mode);
3095 EXPECT_TRUE(ec_enabled);
3096 EXPECT_TRUE(agc_enabled);
3097 EXPECT_TRUE(ns_enabled);
3098
3099 channel1->SetSend(cricket::SEND_MICROPHONE);
3100 voe_.GetEcStatus(ec_enabled, ec_mode);
3101 voe_.GetAgcStatus(agc_enabled, agc_mode);
3102 voe_.GetNsStatus(ns_enabled, ns_mode);
3103 EXPECT_TRUE(ec_enabled);
3104 EXPECT_TRUE(agc_enabled);
3105 EXPECT_FALSE(ns_enabled);
3106
3107 channel1->SetSend(cricket::SEND_NOTHING);
3108 voe_.GetEcStatus(ec_enabled, ec_mode);
3109 voe_.GetAgcStatus(agc_enabled, agc_mode);
3110 voe_.GetNsStatus(ns_enabled, ns_mode);
3111 EXPECT_TRUE(ec_enabled);
3112 EXPECT_TRUE(agc_enabled);
3113 EXPECT_TRUE(ns_enabled);
3114
3115 channel2->SetSend(cricket::SEND_MICROPHONE);
3116 voe_.GetEcStatus(ec_enabled, ec_mode);
3117 voe_.GetAgcStatus(agc_enabled, agc_mode);
3118 voe_.GetNsStatus(ns_enabled, ns_mode);
3119 EXPECT_TRUE(ec_enabled);
3120 EXPECT_FALSE(agc_enabled);
3121 EXPECT_TRUE(ns_enabled);
3122
3123 channel2->SetSend(cricket::SEND_NOTHING);
3124 voe_.GetEcStatus(ec_enabled, ec_mode);
3125 voe_.GetAgcStatus(agc_enabled, agc_mode);
3126 voe_.GetNsStatus(ns_enabled, ns_mode);
3127 EXPECT_TRUE(ec_enabled);
3128 EXPECT_TRUE(agc_enabled);
3129 EXPECT_TRUE(ns_enabled);
3130
3131 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003132 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003133 cricket::AudioOptions options_no_agc_nor_ns;
3134 options_no_agc_nor_ns.auto_gain_control.Set(false);
3135 options_no_agc_nor_ns.noise_suppression.Set(false);
3136 channel2->SetSend(cricket::SEND_MICROPHONE);
3137 channel2->SetOptions(options_no_agc_nor_ns);
3138
3139 expected_options.echo_cancellation.Set(true);
3140 expected_options.auto_gain_control.Set(false);
3141 expected_options.noise_suppression.Set(false);
3142 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3143 EXPECT_EQ(expected_options, actual_options);
3144 voe_.GetEcStatus(ec_enabled, ec_mode);
3145 voe_.GetAgcStatus(agc_enabled, agc_mode);
3146 voe_.GetNsStatus(ns_enabled, ns_mode);
3147 EXPECT_TRUE(ec_enabled);
3148 EXPECT_FALSE(agc_enabled);
3149 EXPECT_FALSE(ns_enabled);
3150}
3151
wu@webrtc.orgde305012013-10-31 15:40:38 +00003152// This test verifies DSCP settings are properly applied on voice media channel.
3153TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3154 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003155 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003156 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003157 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003158 new cricket::FakeNetworkInterface);
3159 channel->SetInterface(network_interface.get());
3160 cricket::AudioOptions options;
3161 options.dscp.Set(true);
3162 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003163 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003164 // Verify previous value is not modified if dscp option is not set.
3165 cricket::AudioOptions options1;
3166 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003167 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003168 options.dscp.Set(false);
3169 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003170 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003171}
3172
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00003173TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3174 cricket::WebRtcVoiceEngine engine;
3175 cricket::AudioOptions options = engine.GetOptions();
3176 // The default options should have at least a few things set. We purposefully
3177 // don't check the option values here, though.
3178 EXPECT_TRUE(options.echo_cancellation.IsSet());
3179 EXPECT_TRUE(options.auto_gain_control.IsSet());
3180 EXPECT_TRUE(options.noise_suppression.IsSet());
3181}
3182
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003183// Test that GetReceiveChannelNum returns the default channel for the first
3184// recv stream in 1-1 calls.
3185TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3186 EXPECT_TRUE(SetupEngine());
3187 cricket::WebRtcVoiceMediaChannel* media_channel =
3188 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3189 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3190 EXPECT_EQ(media_channel->voe_channel(),
3191 media_channel->GetReceiveChannelNum(0));
3192 cricket::StreamParams stream;
3193 stream.ssrcs.push_back(kSsrc2);
3194 EXPECT_TRUE(channel_->AddRecvStream(stream));
3195 EXPECT_EQ(media_channel->voe_channel(),
3196 media_channel->GetReceiveChannelNum(kSsrc2));
3197}
3198
3199// Test that GetReceiveChannelNum doesn't return the default channel for the
3200// first recv stream in conference calls.
3201TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3202 EXPECT_TRUE(SetupEngine());
3203 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3204 cricket::StreamParams stream;
3205 stream.ssrcs.push_back(kSsrc2);
3206 EXPECT_TRUE(channel_->AddRecvStream(stream));
3207 cricket::WebRtcVoiceMediaChannel* media_channel =
3208 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3209 EXPECT_LT(media_channel->voe_channel(),
3210 media_channel->GetReceiveChannelNum(kSsrc2));
3211}
3212
3213TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3214 EXPECT_TRUE(SetupEngine());
3215 double left, right;
3216 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
3217 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
3218 EXPECT_DOUBLE_EQ(1, left);
3219 EXPECT_DOUBLE_EQ(2, right);
3220
3221 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3222 cricket::StreamParams stream;
3223 stream.ssrcs.push_back(kSsrc2);
3224 EXPECT_TRUE(channel_->AddRecvStream(stream));
3225
3226 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
3227 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
3228 EXPECT_DOUBLE_EQ(2, left);
3229 EXPECT_DOUBLE_EQ(1, right);
3230}
3231
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003232// Tests for the actual WebRtc VoE library.
3233
3234// Tests that the library initializes and shuts down properly.
3235TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3236 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003237 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003238 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3239 EXPECT_TRUE(channel != NULL);
3240 delete channel;
3241 engine.Terminate();
3242
3243 // Reinit to catch regression where VoiceEngineObserver reference is lost
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003244 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003245 engine.Terminate();
3246}
3247
3248// Tests that the logging from the library is cleartext.
3249TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
3250 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003251 rtc::scoped_ptr<rtc::MemoryStream> stream(
3252 new rtc::MemoryStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003253 size_t size = 0;
3254 bool cleartext = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003255 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3256 engine.SetLogging(rtc::LS_VERBOSE, "");
3257 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003258 EXPECT_TRUE(stream->GetSize(&size));
3259 EXPECT_GT(size, 0U);
3260 engine.Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003261 rtc::LogMessage::RemoveLogToStream(stream.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003262 const char* buf = stream->GetBuffer();
3263 for (size_t i = 0; i < size && cleartext; ++i) {
3264 int ch = static_cast<int>(buf[i]);
3265 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
3266 << std::hex << ch;
3267 cleartext = (isprint(ch) || isspace(ch));
3268 }
3269 EXPECT_TRUE(cleartext);
3270}
3271
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003272// Tests that the library is configured with the codecs we want.
3273TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3274 cricket::WebRtcVoiceEngine engine;
3275 // Check codecs by name.
3276 EXPECT_TRUE(engine.FindCodec(
3277 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3278 EXPECT_TRUE(engine.FindCodec(
3279 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3280 EXPECT_TRUE(engine.FindCodec(
3281 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3282 // Check that name matching is case-insensitive.
3283 EXPECT_TRUE(engine.FindCodec(
3284 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3285 EXPECT_TRUE(engine.FindCodec(
3286 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3287 EXPECT_TRUE(engine.FindCodec(
3288 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3289 EXPECT_TRUE(engine.FindCodec(
3290 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3291 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003292 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003293 EXPECT_TRUE(engine.FindCodec(
3294 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003295 EXPECT_TRUE(engine.FindCodec(
3296 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3297 EXPECT_TRUE(engine.FindCodec(
3298 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3299 EXPECT_TRUE(engine.FindCodec(
3300 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3301 EXPECT_TRUE(engine.FindCodec(
3302 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3303 // Check codecs with an id by id.
3304 EXPECT_TRUE(engine.FindCodec(
3305 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3306 EXPECT_TRUE(engine.FindCodec(
3307 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3308 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003309 cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003310 EXPECT_TRUE(engine.FindCodec(
3311 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3312 // Check sample/bitrate matching.
3313 EXPECT_TRUE(engine.FindCodec(
3314 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3315 // Check that bad codecs fail.
3316 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3317 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3318 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3319 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3320 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003321 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3322 for (std::vector<cricket::AudioCodec>::const_iterator it =
3323 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3324 if (it->name == "CN" && it->clockrate == 16000) {
3325 EXPECT_EQ(105, it->id);
3326 } else if (it->name == "CN" && it->clockrate == 32000) {
3327 EXPECT_EQ(106, it->id);
3328 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3329 EXPECT_EQ(103, it->id);
3330 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3331 EXPECT_EQ(104, it->id);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003332 } else if (it->name == "G722" && it->clockrate == 8000) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003333 EXPECT_EQ(9, it->id);
3334 } else if (it->name == "telephone-event") {
3335 EXPECT_EQ(126, it->id);
3336 } else if (it->name == "red") {
3337 EXPECT_EQ(127, it->id);
3338 } else if (it->name == "opus") {
3339 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003340 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003341 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003342 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003343 EXPECT_EQ("60", it->params.find("maxptime")->second);
minyue@webrtc.org4ef22d12014-11-17 09:26:39 +00003344 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3345 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003346 }
3347 }
3348
3349 engine.Terminate();
3350}
3351
3352// Tests that VoE supports at least 32 channels
3353TEST(WebRtcVoiceEngineTest, Has32Channels) {
3354 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003355 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003356
3357 cricket::VoiceMediaChannel* channels[32];
3358 int num_channels = 0;
3359
3360 while (num_channels < ARRAY_SIZE(channels)) {
3361 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3362 if (!channel)
3363 break;
3364
3365 channels[num_channels++] = channel;
3366 }
3367
3368 int expected = ARRAY_SIZE(channels);
3369 EXPECT_EQ(expected, num_channels);
3370
3371 while (num_channels > 0) {
3372 delete channels[--num_channels];
3373 }
3374
3375 engine.Terminate();
3376}
3377
3378// Test that we set our preferred codecs properly.
3379TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3380 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003381 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003382 cricket::WebRtcVoiceMediaChannel channel(&engine);
3383 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3384}
3385
3386#ifdef WIN32
3387// Test our workarounds to WebRtc VoE' munging of the coinit count
3388TEST(WebRtcVoiceEngineTest, CoInitialize) {
3389 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3390
3391 // Initial refcount should be 0.
3392 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3393
3394 // Engine should start even with COM already inited.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003395 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003396 engine->Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003397 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003398 engine->Terminate();
3399
3400 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3401 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3402 // Decrement refcount to (hopefully) 0.
3403 CoUninitialize();
3404 CoUninitialize();
3405 delete engine;
3406
3407 // Ensure refcount is 0.
3408 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3409 CoUninitialize();
3410}
3411#endif
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003412
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003413TEST_F(WebRtcVoiceEngineTestFake, ChangeCombinedBweOption_Call) {
3414 // Test that changing the combined_audio_video_bwe option results in the
3415 // expected state changes on an associated Call.
3416 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3417 const uint32 kAudioSsrc1 = 223;
3418 const uint32 kAudioSsrc2 = 224;
3419
3420 EXPECT_TRUE(SetupEngine());
3421 cricket::WebRtcVoiceMediaChannel* media_channel =
3422 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3423 media_channel->SetCall(&call);
3424 EXPECT_TRUE(media_channel->AddRecvStream(
3425 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3426 EXPECT_TRUE(media_channel->AddRecvStream(
3427 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3428
3429 // Combined BWE should not be set up yet.
3430 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3431
3432 // Enable combined BWE option - now it should be set up.
3433 cricket::AudioOptions options;
3434 options.combined_audio_video_bwe.Set(true);
3435 EXPECT_TRUE(media_channel->SetOptions(options));
3436 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3437 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc1));
3438 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc2));
3439
3440 // Disable combined BWE option - should be disabled again.
3441 options.combined_audio_video_bwe.Set(false);
3442 EXPECT_TRUE(media_channel->SetOptions(options));
3443 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3444
3445 media_channel->SetCall(nullptr);
3446}
3447
3448TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBwe_Call) {
3449 // Test that calling SetCall() on the voice media channel results in the
3450 // expected state changes in Call.
3451 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3452 cricket::FakeCall call2(webrtc::Call::Config(nullptr));
3453 const uint32 kAudioSsrc1 = 223;
3454 const uint32 kAudioSsrc2 = 224;
3455
3456 EXPECT_TRUE(SetupEngine());
3457 cricket::WebRtcVoiceMediaChannel* media_channel =
3458 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3459 cricket::AudioOptions options;
3460 options.combined_audio_video_bwe.Set(true);
3461 EXPECT_TRUE(media_channel->SetOptions(options));
3462 EXPECT_TRUE(media_channel->AddRecvStream(
3463 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3464 EXPECT_TRUE(media_channel->AddRecvStream(
3465 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3466
3467 // Combined BWE should not be set up yet.
3468 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3469
3470 // Register - should be enabled.
3471 media_channel->SetCall(&call);
3472 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3473 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc1));
3474 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc2));
3475
3476 // Re-register - should now be enabled on new call.
3477 media_channel->SetCall(&call2);
3478 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3479 EXPECT_EQ(2, call2.GetAudioReceiveStreams().size());
3480 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc1));
3481 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc2));
3482
3483 // Unregister - should be disabled again.
3484 media_channel->SetCall(nullptr);
3485 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3486}
3487
3488TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams_Call) {
3489 // Test that adding receive streams after enabling combined bandwidth
3490 // estimation will correctly configure each channel.
3491 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3492
3493 EXPECT_TRUE(SetupEngine());
3494 cricket::WebRtcVoiceMediaChannel* media_channel =
3495 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3496 media_channel->SetCall(&call);
3497 cricket::AudioOptions options;
3498 options.combined_audio_video_bwe.Set(true);
3499 EXPECT_TRUE(media_channel->SetOptions(options));
3500
3501 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3502 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3503 EXPECT_TRUE(media_channel->AddRecvStream(
3504 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3505 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kSsrcs[i]));
3506 }
3507 EXPECT_EQ(ARRAY_SIZE(kSsrcs), call.GetAudioReceiveStreams().size());
3508
3509 media_channel->SetCall(nullptr);
3510 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3511}
3512
3513TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweExtensions_Call) {
3514 // Test that setting the header extensions results in the expected state
3515 // changes on an associated Call.
3516 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3517 std::vector<uint32> ssrcs;
3518 ssrcs.push_back(223);
3519 ssrcs.push_back(224);
3520
3521 EXPECT_TRUE(SetupEngine());
3522 cricket::WebRtcVoiceMediaChannel* media_channel =
3523 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3524 media_channel->SetCall(&call);
3525 cricket::AudioOptions options;
3526 options.combined_audio_video_bwe.Set(true);
3527 EXPECT_TRUE(media_channel->SetOptions(options));
3528 for (uint32 ssrc : ssrcs) {
3529 EXPECT_TRUE(media_channel->AddRecvStream(
3530 cricket::StreamParams::CreateLegacy(ssrc)));
3531 }
3532
3533 // Combined BWE should be set up, but with no configured extensions.
3534 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3535 for (uint32 ssrc : ssrcs) {
3536 const auto* s = call.GetAudioReceiveStream(ssrc);
3537 EXPECT_NE(nullptr, s);
3538 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3539 }
3540
3541 // Set up receive extensions.
3542 const auto& e_exts = engine_.rtp_header_extensions();
3543 channel_->SetRecvRtpHeaderExtensions(e_exts);
3544 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3545 for (uint32 ssrc : ssrcs) {
3546 const auto* s = call.GetAudioReceiveStream(ssrc);
3547 EXPECT_NE(nullptr, s);
3548 const auto& s_exts = s->GetConfig().rtp.extensions;
3549 EXPECT_EQ(e_exts.size(), s_exts.size());
3550 for (const auto& e_ext : e_exts) {
3551 for (const auto& s_ext : s_exts) {
3552 if (e_ext.id == s_ext.id) {
3553 EXPECT_EQ(e_ext.uri, s_ext.name);
3554 }
3555 }
3556 }
3557 }
3558
3559 // Disable receive extensions.
3560 std::vector<cricket::RtpHeaderExtension> extensions;
3561 channel_->SetRecvRtpHeaderExtensions(extensions);
3562 for (uint32 ssrc : ssrcs) {
3563 const auto* s = call.GetAudioReceiveStream(ssrc);
3564 EXPECT_NE(nullptr, s);
3565 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3566 }
3567
3568 media_channel->SetCall(nullptr);
3569}
3570
3571TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3572 // Test that packets are forwarded to the Call when configured accordingly.
3573 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3574 const uint32 kAudioSsrc = 1;
3575 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3576 static const unsigned char kRtcp[] = {
3577 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3578 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3581 };
3582 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3583
3584 EXPECT_TRUE(SetupEngine());
3585 cricket::WebRtcVoiceMediaChannel* media_channel =
3586 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3587 cricket::AudioOptions options;
3588 options.combined_audio_video_bwe.Set(true);
3589 EXPECT_TRUE(media_channel->SetOptions(options));
3590 EXPECT_TRUE(media_channel->AddRecvStream(
3591 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3592
3593 // Call not set on media channel, so no packets can be forwarded.
3594 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3595 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3596 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3597 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3598
3599 // Set Call, now there should be a receive stream which is forwarded packets.
3600 media_channel->SetCall(&call);
3601 EXPECT_EQ(1, call.GetAudioReceiveStreams().size());
3602 const cricket::FakeAudioReceiveStream* s =
3603 call.GetAudioReceiveStream(kAudioSsrc);
3604 EXPECT_EQ(0, s->received_packets());
3605 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3606 EXPECT_EQ(1, s->received_packets());
3607 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3608 EXPECT_EQ(2, s->received_packets());
3609
3610 media_channel->SetCall(nullptr);
3611}