blob: 601d45fa18af5cce8c991c53a0a288dbef3243a5 [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
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000028#include "webrtc/base/byteorder.h"
29#include "webrtc/base/gunit.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030#include "talk/media/base/constants.h"
31#include "talk/media/base/fakemediaengine.h"
32#include "talk/media/base/fakemediaprocessor.h"
wu@webrtc.orgde305012013-10-31 15:40:38 +000033#include "talk/media/base/fakenetworkinterface.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/media/base/fakertp.h"
Fredrik Solenberg4b60c732015-05-07 14:07:48 +020035#include "talk/media/webrtc/fakewebrtccall.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
37#include "talk/media/webrtc/webrtcvoiceengine.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000038#include "webrtc/p2p/base/fakesession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/session/media/channel.h"
40
41// Tests for the WebRtcVoiceEngine/VoiceChannel code.
42
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000043using cricket::kRtpAudioLevelHeaderExtension;
44using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
45
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
47static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +000049static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
50static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
52static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
53static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
54static const cricket::AudioCodec
55 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
56static const cricket::AudioCodec* const kAudioCodecs[] = {
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +000057 &kPcmuCodec, &kIsacCodec, &kOpusCodec, &kG722CodecVoE, &kRedCodec,
58 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059};
60const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
61static uint32 kSsrc1 = 0x99;
62static uint32 kSsrc2 = 0x98;
63
64class FakeVoEWrapper : public cricket::VoEWrapper {
65 public:
66 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
67 : cricket::VoEWrapper(engine, // processing
68 engine, // base
69 engine, // codec
70 engine, // dtmf
71 engine, // file
72 engine, // hw
73 engine, // media
74 engine, // neteq
75 engine, // network
76 engine, // rtp
77 engine, // sync
78 engine) { // volume
79 }
80};
81
wu@webrtc.org97077a32013-10-25 21:18:33 +000082class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083 public:
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020084 int SetTraceFilter(const unsigned int filter) override {
wu@webrtc.org97077a32013-10-25 21:18:33 +000085 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 return 0;
87 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020088 int SetTraceFile(const char* fileNameUTF8) override { return 0; }
89 int SetTraceCallback(webrtc::TraceCallback* callback) override { return 0; }
wu@webrtc.org97077a32013-10-25 21:18:33 +000090 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091};
92
93class WebRtcVoiceEngineTestFake : public testing::Test {
94 public:
95 class ChannelErrorListener : public sigslot::has_slots<> {
96 public:
97 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
98 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +020099 DCHECK(channel != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100 channel->SignalMediaError.connect(
101 this, &ChannelErrorListener::OnVoiceChannelError);
102 }
103 void OnVoiceChannelError(uint32 ssrc,
104 cricket::VoiceMediaChannel::Error error) {
105 ssrc_ = ssrc;
106 error_ = error;
107 }
108 void Reset() {
109 ssrc_ = 0;
110 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
111 }
112 uint32 ssrc() const {
113 return ssrc_;
114 }
115 cricket::VoiceMediaChannel::Error error() const {
116 return error_;
117 }
118
119 private:
120 uint32 ssrc_;
121 cricket::VoiceMediaChannel::Error error_;
122 };
123
124 WebRtcVoiceEngineTestFake()
125 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000126 trace_wrapper_(new FakeVoETraceWrapper()),
Jelena Marusicc28a8962015-05-29 15:05:44 +0200127 engine_(new FakeVoEWrapper(&voe_), trace_wrapper_),
128 channel_(nullptr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 options_conference_.conference_mode.Set(true);
130 options_adjust_agc_.adjust_agc_delta.Set(-10);
131 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000132 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000133 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000134 return false;
135 }
Jelena Marusicc28a8962015-05-29 15:05:44 +0200136 channel_ = engine_.CreateChannel(cricket::AudioOptions());
137 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000138 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000140 if (!SetupEngineWithoutStream()) {
141 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000143 return channel_->AddSendStream(
144 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000146 void SetupForMultiSendStream() {
147 EXPECT_TRUE(SetupEngine());
148 // Remove stream added in Setup, which is corresponding to default channel.
149 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000150 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000151 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
152 EXPECT_EQ(kSsrc1, default_send_ssrc);
153 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
154
155 // Verify the default channel still exists.
156 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
157 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158 void DeliverPacket(const void* data, int len) {
Karl Wiberg94784372015-04-20 14:03:07 +0200159 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000160 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200162 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163 delete channel_;
164 engine_.Terminate();
165 }
166
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000167 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000168 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200169 channel_ = engine_.CreateChannel(cricket::AudioOptions());
170 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000171 if (caller) {
172 // if this is a caller, local description will be applied and add the
173 // send stream.
174 EXPECT_TRUE(channel_->AddSendStream(
175 cricket::StreamParams::CreateLegacy(kSsrc1)));
176 }
177 int channel_id = voe_.GetLastChannel();
178
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000179 // Test we can only InsertDtmf when the other side supports telephone-event.
180 std::vector<cricket::AudioCodec> codecs;
181 codecs.push_back(kPcmuCodec);
182 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
183 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
184 EXPECT_FALSE(channel_->CanInsertDtmf());
185 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
186 codecs.push_back(kTelephoneEventCodec);
187 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
188 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000189
190 if (!caller) {
191 // There's no active send channel yet.
192 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
193 EXPECT_TRUE(channel_->AddSendStream(
194 cricket::StreamParams::CreateLegacy(kSsrc1)));
195 }
196
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197 // Check we fail if the ssrc is invalid.
198 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
199
200 // Test send
201 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
202 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
203 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
204
205 // Test play
206 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
207 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
208 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
209
210 // Test send and play
211 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
212 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
213 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
214 cricket::DF_PLAY | cricket::DF_SEND));
215 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
216 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
217 }
218
219 // Test that send bandwidth is set correctly.
220 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000221 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
222 // |expected_result| is the expected result from SetMaxSendBandwidth().
223 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000225 int max_bitrate,
226 bool expected_result,
227 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 int channel_num = voe_.GetLastChannel();
229 std::vector<cricket::AudioCodec> codecs;
230
231 codecs.push_back(codec);
232 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
233
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000234 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 EXPECT_EQ(expected_result, result);
236
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000237 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
239
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000240 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 }
242
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000243 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
244 EXPECT_TRUE(SetupEngineWithoutStream());
245 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000246
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000247 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000248 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000249
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000250 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251 // Ensure unknown extensions won't cause an error.
252 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000253 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000254 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000255 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000256
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000257 // Ensure extensions stay off with an empty list of headers.
258 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000259 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000260 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000261
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000262 // Ensure extension is set properly.
263 const int id = 1;
264 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000265 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000266 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000267
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000268 // Ensure extension is set properly on new channel.
269 // The first stream to occupy the default channel.
270 EXPECT_TRUE(channel_->AddSendStream(
271 cricket::StreamParams::CreateLegacy(123)));
272 EXPECT_TRUE(channel_->AddSendStream(
273 cricket::StreamParams::CreateLegacy(234)));
274 int new_channel_num = voe_.GetLastChannel();
275 EXPECT_NE(channel_num, new_channel_num);
276 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000277
278 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000279 extensions.clear();
280 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000281 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
282 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000283 }
284
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000285 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
286 EXPECT_TRUE(SetupEngineWithoutStream());
287 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000288
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000289 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000290 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000291
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000292 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000293 // Ensure unknown extensions won't cause an error.
294 extensions.push_back(cricket::RtpHeaderExtension(
295 "urn:ietf:params:unknownextention", 1));
296 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000297 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000298
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000299 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000300 extensions.clear();
301 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000302 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000303
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000304 // Ensure extension is set properly.
305 const int id = 2;
306 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000307 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000308 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000309
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000310 // Ensure extension is set properly on new channel.
311 // The first stream to occupy the default channel.
312 EXPECT_TRUE(channel_->AddRecvStream(
313 cricket::StreamParams::CreateLegacy(345)));
314 EXPECT_TRUE(channel_->AddRecvStream(
315 cricket::StreamParams::CreateLegacy(456)));
316 int new_channel_num = voe_.GetLastChannel();
317 EXPECT_NE(channel_num, new_channel_num);
318 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
319
320 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000321 extensions.clear();
322 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000323 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
324 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000325 }
326
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 protected:
328 cricket::FakeWebRtcVoiceEngine voe_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000329 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 cricket::WebRtcVoiceEngine engine_;
331 cricket::VoiceMediaChannel* channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332
333 cricket::AudioOptions options_conference_;
334 cricket::AudioOptions options_adjust_agc_;
335};
336
337// Tests that our stub library "works".
338TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
339 EXPECT_FALSE(voe_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000340 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 EXPECT_TRUE(voe_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 engine_.Terminate();
343 EXPECT_FALSE(voe_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344}
345
346// Tests that we can create and destroy a channel.
347TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000348 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200349 channel_ = engine_.CreateChannel(cricket::AudioOptions());
350 EXPECT_TRUE(channel_ != nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351}
352
353// Tests that we properly handle failures in CreateChannel.
354TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
355 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000356 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200357 channel_ = engine_.CreateChannel(cricket::AudioOptions());
358 EXPECT_TRUE(channel_ == nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359}
360
361// Tests that the list of supported codecs is created properly and ordered
362// correctly
363TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
364 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
365 ASSERT_FALSE(codecs.empty());
366 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
367 EXPECT_EQ(48000, codecs[0].clockrate);
368 EXPECT_EQ(2, codecs[0].channels);
369 EXPECT_EQ(64000, codecs[0].bitrate);
370 int pref = codecs[0].preference;
371 for (size_t i = 1; i < codecs.size(); ++i) {
372 EXPECT_GT(pref, codecs[i].preference);
373 pref = codecs[i].preference;
374 }
375}
376
377// Tests that we can find codecs by name or id, and that we interpret the
378// clockrate and bitrate fields properly.
379TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
380 cricket::AudioCodec codec;
381 webrtc::CodecInst codec_inst;
382 // Find PCMU with explicit clockrate and bitrate.
383 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
384 // Find ISAC with explicit clockrate and 0 bitrate.
385 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
386 // Find telephone-event with explicit clockrate and 0 bitrate.
387 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
388 // Find ISAC with a different payload id.
389 codec = kIsacCodec;
390 codec.id = 127;
391 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
392 EXPECT_EQ(codec.id, codec_inst.pltype);
393 // Find PCMU with a 0 clockrate.
394 codec = kPcmuCodec;
395 codec.clockrate = 0;
396 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
397 EXPECT_EQ(codec.id, codec_inst.pltype);
398 EXPECT_EQ(8000, codec_inst.plfreq);
399 // Find PCMU with a 0 bitrate.
400 codec = kPcmuCodec;
401 codec.bitrate = 0;
402 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
403 EXPECT_EQ(codec.id, codec_inst.pltype);
404 EXPECT_EQ(64000, codec_inst.rate);
405 // Find ISAC with an explicit bitrate.
406 codec = kIsacCodec;
407 codec.bitrate = 32000;
408 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
409 EXPECT_EQ(codec.id, codec_inst.pltype);
410 EXPECT_EQ(32000, codec_inst.rate);
411}
412
413// Test that we set our inbound codecs properly, including changing PT.
414TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
415 EXPECT_TRUE(SetupEngine());
416 int channel_num = voe_.GetLastChannel();
417 std::vector<cricket::AudioCodec> codecs;
418 codecs.push_back(kIsacCodec);
419 codecs.push_back(kPcmuCodec);
420 codecs.push_back(kTelephoneEventCodec);
421 codecs[0].id = 106; // collide with existing telephone-event
422 codecs[2].id = 126;
423 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
424 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000425 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 gcodec.plfreq = 16000;
427 gcodec.channels = 1;
428 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
429 EXPECT_EQ(106, gcodec.pltype);
430 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000431 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000432 "telephone-event");
433 gcodec.plfreq = 8000;
434 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
435 EXPECT_EQ(126, gcodec.pltype);
436 EXPECT_STREQ("telephone-event", gcodec.plname);
437}
438
439// Test that we fail to set an unknown inbound codec.
440TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
441 EXPECT_TRUE(SetupEngine());
442 std::vector<cricket::AudioCodec> codecs;
443 codecs.push_back(kIsacCodec);
444 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
445 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
446}
447
448// Test that we fail if we have duplicate types in the inbound list.
449TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
450 EXPECT_TRUE(SetupEngine());
451 std::vector<cricket::AudioCodec> codecs;
452 codecs.push_back(kIsacCodec);
453 codecs.push_back(kCn16000Codec);
454 codecs[1].id = kIsacCodec.id;
455 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
456}
457
458// Test that we can decode OPUS without stereo parameters.
459TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
460 EXPECT_TRUE(SetupEngine());
461 EXPECT_TRUE(channel_->SetOptions(options_conference_));
462 std::vector<cricket::AudioCodec> codecs;
463 codecs.push_back(kIsacCodec);
464 codecs.push_back(kPcmuCodec);
465 codecs.push_back(kOpusCodec);
466 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
467 EXPECT_TRUE(channel_->AddRecvStream(
468 cricket::StreamParams::CreateLegacy(kSsrc1)));
469 int channel_num2 = voe_.GetLastChannel();
470 webrtc::CodecInst opus;
471 engine_.FindWebRtcCodec(kOpusCodec, &opus);
472 // Even without stereo parameters, recv codecs still specify channels = 2.
473 EXPECT_EQ(2, opus.channels);
474 EXPECT_EQ(111, opus.pltype);
475 EXPECT_STREQ("opus", opus.plname);
476 opus.pltype = 0;
477 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
478 EXPECT_EQ(111, opus.pltype);
479}
480
481// Test that we can decode OPUS with stereo = 0.
482TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
483 EXPECT_TRUE(SetupEngine());
484 EXPECT_TRUE(channel_->SetOptions(options_conference_));
485 std::vector<cricket::AudioCodec> codecs;
486 codecs.push_back(kIsacCodec);
487 codecs.push_back(kPcmuCodec);
488 codecs.push_back(kOpusCodec);
489 codecs[2].params["stereo"] = "0";
490 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
491 EXPECT_TRUE(channel_->AddRecvStream(
492 cricket::StreamParams::CreateLegacy(kSsrc1)));
493 int channel_num2 = voe_.GetLastChannel();
494 webrtc::CodecInst opus;
495 engine_.FindWebRtcCodec(kOpusCodec, &opus);
496 // Even when stereo is off, recv codecs still specify channels = 2.
497 EXPECT_EQ(2, opus.channels);
498 EXPECT_EQ(111, opus.pltype);
499 EXPECT_STREQ("opus", opus.plname);
500 opus.pltype = 0;
501 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
502 EXPECT_EQ(111, opus.pltype);
503}
504
505// Test that we can decode OPUS with stereo = 1.
506TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
507 EXPECT_TRUE(SetupEngine());
508 EXPECT_TRUE(channel_->SetOptions(options_conference_));
509 std::vector<cricket::AudioCodec> codecs;
510 codecs.push_back(kIsacCodec);
511 codecs.push_back(kPcmuCodec);
512 codecs.push_back(kOpusCodec);
513 codecs[2].params["stereo"] = "1";
514 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
515 EXPECT_TRUE(channel_->AddRecvStream(
516 cricket::StreamParams::CreateLegacy(kSsrc1)));
517 int channel_num2 = voe_.GetLastChannel();
518 webrtc::CodecInst opus;
519 engine_.FindWebRtcCodec(kOpusCodec, &opus);
520 EXPECT_EQ(2, opus.channels);
521 EXPECT_EQ(111, opus.pltype);
522 EXPECT_STREQ("opus", opus.plname);
523 opus.pltype = 0;
524 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
525 EXPECT_EQ(111, opus.pltype);
526}
527
528// Test that changes to recv codecs are applied to all streams.
529TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
530 EXPECT_TRUE(SetupEngine());
531 EXPECT_TRUE(channel_->SetOptions(options_conference_));
532 std::vector<cricket::AudioCodec> codecs;
533 codecs.push_back(kIsacCodec);
534 codecs.push_back(kPcmuCodec);
535 codecs.push_back(kTelephoneEventCodec);
536 codecs[0].id = 106; // collide with existing telephone-event
537 codecs[2].id = 126;
538 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
539 EXPECT_TRUE(channel_->AddRecvStream(
540 cricket::StreamParams::CreateLegacy(kSsrc1)));
541 int channel_num2 = voe_.GetLastChannel();
542 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000543 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000544 gcodec.plfreq = 16000;
545 gcodec.channels = 1;
546 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
547 EXPECT_EQ(106, gcodec.pltype);
548 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000549 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550 "telephone-event");
551 gcodec.plfreq = 8000;
552 gcodec.channels = 1;
553 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
554 EXPECT_EQ(126, gcodec.pltype);
555 EXPECT_STREQ("telephone-event", gcodec.plname);
556}
557
558TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
559 EXPECT_TRUE(SetupEngine());
560 EXPECT_TRUE(channel_->SetOptions(options_conference_));
561 std::vector<cricket::AudioCodec> codecs;
562 codecs.push_back(kIsacCodec);
563 codecs[0].id = 106; // collide with existing telephone-event
564
565 EXPECT_TRUE(channel_->AddRecvStream(
566 cricket::StreamParams::CreateLegacy(kSsrc1)));
567 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
568
569 int channel_num2 = voe_.GetLastChannel();
570 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000571 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572 gcodec.plfreq = 16000;
573 gcodec.channels = 1;
574 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
575 EXPECT_EQ(106, gcodec.pltype);
576 EXPECT_STREQ("ISAC", gcodec.plname);
577}
578
579// Test that we can apply the same set of codecs again while playing.
580TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
581 EXPECT_TRUE(SetupEngine());
582 int channel_num = voe_.GetLastChannel();
583 std::vector<cricket::AudioCodec> codecs;
584 codecs.push_back(kIsacCodec);
585 codecs.push_back(kCn16000Codec);
586 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
587 EXPECT_TRUE(channel_->SetPlayout(true));
588 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
589
590 // Changing the payload type of a codec should fail.
591 codecs[0].id = 127;
592 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
593 EXPECT_TRUE(voe_.GetPlayout(channel_num));
594}
595
596// Test that we can add a codec while playing.
597TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
598 EXPECT_TRUE(SetupEngine());
599 int channel_num = voe_.GetLastChannel();
600 std::vector<cricket::AudioCodec> codecs;
601 codecs.push_back(kIsacCodec);
602 codecs.push_back(kCn16000Codec);
603 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
604 EXPECT_TRUE(channel_->SetPlayout(true));
605
606 codecs.push_back(kOpusCodec);
607 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
608 EXPECT_TRUE(voe_.GetPlayout(channel_num));
609 webrtc::CodecInst gcodec;
610 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
611 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
612}
613
614TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
615 EXPECT_TRUE(SetupEngine());
616 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
617
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000618 // Test that when autobw is enabled, bitrate is kept as the default
619 // value. autobw is enabled for the following tests because the target
620 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000621
622 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000623 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000624
625 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000626 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000627
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000628 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000629 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000630}
631
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000632TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633 EXPECT_TRUE(SetupEngine());
634 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
635
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000636 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000637
638 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000639 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
640 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000641
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000643 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
644 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645}
646
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000647TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
648 EXPECT_TRUE(SetupEngine());
649 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
650
651 // Test that we can only set a maximum bitrate for a fixed-rate codec
652 // if it's bigger than the fixed rate.
653
654 // PCMU, fixed bitrate == 64000.
655 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
656 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
657 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
658 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
659 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
660 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
661 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
662}
663
664TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000665 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200666 channel_ = engine_.CreateChannel(cricket::AudioOptions());
667 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000668 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
669
670 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000671 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000672
673 EXPECT_TRUE(channel_->AddSendStream(
674 cricket::StreamParams::CreateLegacy(kSsrc1)));
675
676 int channel_num = voe_.GetLastChannel();
677 webrtc::CodecInst codec;
678 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
679 EXPECT_EQ(desired_bitrate, codec.rate);
680}
681
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000682// Test that bitrate cannot be set for CBR codecs.
683// Bitrate is ignored if it is higher than the fixed bitrate.
684// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000685TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686 EXPECT_TRUE(SetupEngine());
687 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
688
689 webrtc::CodecInst codec;
690 int channel_num = voe_.GetLastChannel();
691 std::vector<cricket::AudioCodec> codecs;
692
693 // PCMU, default bitrate == 64000.
694 codecs.push_back(kPcmuCodec);
695 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
696 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
697 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000698 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
700 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000701 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
703 EXPECT_EQ(64000, codec.rate);
704}
705
706// Test that we apply codecs properly.
707TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
708 EXPECT_TRUE(SetupEngine());
709 int channel_num = voe_.GetLastChannel();
710 std::vector<cricket::AudioCodec> codecs;
711 codecs.push_back(kIsacCodec);
712 codecs.push_back(kPcmuCodec);
713 codecs.push_back(kRedCodec);
714 codecs[0].id = 96;
715 codecs[0].bitrate = 48000;
716 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000717 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 webrtc::CodecInst gcodec;
719 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
720 EXPECT_EQ(96, gcodec.pltype);
721 EXPECT_EQ(48000, gcodec.rate);
722 EXPECT_STREQ("ISAC", gcodec.plname);
723 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000724 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
726 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
727 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
728}
729
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000730// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
731// to apply.
732TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
733 EXPECT_TRUE(SetupEngine());
734 std::vector<cricket::AudioCodec> codecs;
735 codecs.push_back(kIsacCodec);
736 codecs.push_back(kPcmuCodec);
737 codecs.push_back(kRedCodec);
738 codecs[0].id = 96;
739 codecs[0].bitrate = 48000;
740 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
741 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
742 // Calling SetSendCodec again with same codec which is already set.
743 // In this case media channel shouldn't send codec to VoE.
744 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
745 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
746}
747
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +0000748// Verify that G722 is set with 16000 samples per second to WebRTC.
749TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
750 EXPECT_TRUE(SetupEngine());
751 int channel_num = voe_.GetLastChannel();
752 std::vector<cricket::AudioCodec> codecs;
753 codecs.push_back(kG722CodecSdp);
754 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
755 webrtc::CodecInst gcodec;
756 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
757 EXPECT_STREQ("G722", gcodec.plname);
758 EXPECT_EQ(1, gcodec.channels);
759 EXPECT_EQ(16000, gcodec.plfreq);
760}
761
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000762// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
764 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765 std::vector<cricket::AudioCodec> codecs;
766 codecs.push_back(kOpusCodec);
767 codecs[0].bitrate = 0;
768 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000769 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770}
771
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000772// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
774 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775 std::vector<cricket::AudioCodec> codecs;
776 codecs.push_back(kOpusCodec);
777 codecs[0].bitrate = 0;
778 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000779 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780}
781
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000782// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
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].channels = 0;
789 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000790 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791}
792
793// Test that if channel is 1 for opus and there's no stereo, we fail.
794TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
795 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 std::vector<cricket::AudioCodec> codecs;
797 codecs.push_back(kOpusCodec);
798 codecs[0].bitrate = 0;
799 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000800 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801}
802
803// Test that if channel is 1 for opus and stereo=0, we fail.
804TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
805 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806 std::vector<cricket::AudioCodec> codecs;
807 codecs.push_back(kOpusCodec);
808 codecs[0].bitrate = 0;
809 codecs[0].channels = 1;
810 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000811 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812}
813
814// Test that if channel is 1 for opus and stereo=1, we fail.
815TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
816 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817 std::vector<cricket::AudioCodec> codecs;
818 codecs.push_back(kOpusCodec);
819 codecs[0].bitrate = 0;
820 codecs[0].channels = 1;
821 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000822 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that with bitrate=0 and no stereo,
826// channels and bitrate are 1 and 32000.
827TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
828 EXPECT_TRUE(SetupEngine());
829 int channel_num = voe_.GetLastChannel();
830 std::vector<cricket::AudioCodec> codecs;
831 codecs.push_back(kOpusCodec);
832 codecs[0].bitrate = 0;
833 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
834 webrtc::CodecInst gcodec;
835 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
836 EXPECT_STREQ("opus", gcodec.plname);
837 EXPECT_EQ(1, gcodec.channels);
838 EXPECT_EQ(32000, gcodec.rate);
839}
840
841// Test that with bitrate=0 and stereo=0,
842// channels and bitrate are 1 and 32000.
843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
844 EXPECT_TRUE(SetupEngine());
845 int channel_num = voe_.GetLastChannel();
846 std::vector<cricket::AudioCodec> codecs;
847 codecs.push_back(kOpusCodec);
848 codecs[0].bitrate = 0;
849 codecs[0].params["stereo"] = "0";
850 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
851 webrtc::CodecInst gcodec;
852 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
853 EXPECT_STREQ("opus", gcodec.plname);
854 EXPECT_EQ(1, gcodec.channels);
855 EXPECT_EQ(32000, gcodec.rate);
856}
857
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000858// Test that with bitrate=invalid and stereo=0,
859// channels and bitrate are 1 and 32000.
860TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
861 EXPECT_TRUE(SetupEngine());
862 int channel_num = voe_.GetLastChannel();
863 std::vector<cricket::AudioCodec> codecs;
864 codecs.push_back(kOpusCodec);
865 codecs[0].params["stereo"] = "0";
866 webrtc::CodecInst gcodec;
867
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000868 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000869 codecs[0].bitrate = 5999;
870 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
871 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
872 EXPECT_STREQ("opus", gcodec.plname);
873 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000874 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000875
876 codecs[0].bitrate = 510001;
877 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
878 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
879 EXPECT_STREQ("opus", gcodec.plname);
880 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000881 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000882}
883
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884// Test that with bitrate=0 and stereo=1,
885// channels and bitrate are 2 and 64000.
886TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
887 EXPECT_TRUE(SetupEngine());
888 int channel_num = voe_.GetLastChannel();
889 std::vector<cricket::AudioCodec> codecs;
890 codecs.push_back(kOpusCodec);
891 codecs[0].bitrate = 0;
892 codecs[0].params["stereo"] = "1";
893 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
894 webrtc::CodecInst gcodec;
895 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
896 EXPECT_STREQ("opus", gcodec.plname);
897 EXPECT_EQ(2, gcodec.channels);
898 EXPECT_EQ(64000, gcodec.rate);
899}
900
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000901// Test that with bitrate=invalid and stereo=1,
902// channels and bitrate are 2 and 64000.
903TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
904 EXPECT_TRUE(SetupEngine());
905 int channel_num = voe_.GetLastChannel();
906 std::vector<cricket::AudioCodec> codecs;
907 codecs.push_back(kOpusCodec);
908 codecs[0].params["stereo"] = "1";
909 webrtc::CodecInst gcodec;
910
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000911 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000912 codecs[0].bitrate = 5999;
913 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
914 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
915 EXPECT_STREQ("opus", gcodec.plname);
916 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000917 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000918
919 codecs[0].bitrate = 510001;
920 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
921 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
922 EXPECT_STREQ("opus", gcodec.plname);
923 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000924 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000925}
926
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000927// Test that with bitrate=N and stereo unset,
928// channels and bitrate are 1 and N.
929TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
930 EXPECT_TRUE(SetupEngine());
931 int channel_num = voe_.GetLastChannel();
932 std::vector<cricket::AudioCodec> codecs;
933 codecs.push_back(kOpusCodec);
934 codecs[0].bitrate = 96000;
935 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
936 webrtc::CodecInst gcodec;
937 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
938 EXPECT_EQ(111, gcodec.pltype);
939 EXPECT_EQ(96000, gcodec.rate);
940 EXPECT_STREQ("opus", gcodec.plname);
941 EXPECT_EQ(1, gcodec.channels);
942 EXPECT_EQ(48000, gcodec.plfreq);
943}
944
945// Test that with bitrate=N and stereo=0,
946// channels and bitrate are 1 and N.
947TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
948 EXPECT_TRUE(SetupEngine());
949 int channel_num = voe_.GetLastChannel();
950 std::vector<cricket::AudioCodec> codecs;
951 codecs.push_back(kOpusCodec);
952 codecs[0].bitrate = 30000;
953 codecs[0].params["stereo"] = "0";
954 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
955 webrtc::CodecInst gcodec;
956 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
957 EXPECT_EQ(1, gcodec.channels);
958 EXPECT_EQ(30000, gcodec.rate);
959 EXPECT_STREQ("opus", gcodec.plname);
960}
961
962// Test that with bitrate=N and without any parameters,
963// channels and bitrate are 1 and N.
964TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
965 EXPECT_TRUE(SetupEngine());
966 int channel_num = voe_.GetLastChannel();
967 std::vector<cricket::AudioCodec> codecs;
968 codecs.push_back(kOpusCodec);
969 codecs[0].bitrate = 30000;
970 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
971 webrtc::CodecInst gcodec;
972 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
973 EXPECT_EQ(1, gcodec.channels);
974 EXPECT_EQ(30000, gcodec.rate);
975 EXPECT_STREQ("opus", gcodec.plname);
976}
977
978// Test that with bitrate=N and stereo=1,
979// channels and bitrate are 2 and N.
980TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
981 EXPECT_TRUE(SetupEngine());
982 int channel_num = voe_.GetLastChannel();
983 std::vector<cricket::AudioCodec> codecs;
984 codecs.push_back(kOpusCodec);
985 codecs[0].bitrate = 30000;
986 codecs[0].params["stereo"] = "1";
987 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
988 webrtc::CodecInst gcodec;
989 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
990 EXPECT_EQ(2, gcodec.channels);
991 EXPECT_EQ(30000, gcodec.rate);
992 EXPECT_STREQ("opus", gcodec.plname);
993}
994
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000995// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
996// Also test that the "maxaveragebitrate" can't be set to values outside the
997// range of 6000 and 510000
998TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
999 EXPECT_TRUE(SetupEngine());
1000 int channel_num = voe_.GetLastChannel();
1001 std::vector<cricket::AudioCodec> codecs;
1002 codecs.push_back(kOpusCodec);
1003 codecs[0].bitrate = 30000;
1004 webrtc::CodecInst gcodec;
1005
1006 // Ignore if less than 6000.
1007 codecs[0].params["maxaveragebitrate"] = "5999";
1008 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1009 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001010 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001011
1012 // Ignore if larger than 510000.
1013 codecs[0].params["maxaveragebitrate"] = "510001";
1014 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1015 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001016 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001017
1018 codecs[0].params["maxaveragebitrate"] = "200000";
1019 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1020 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1021 EXPECT_EQ(200000, gcodec.rate);
1022}
1023
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001024// Test that we can enable NACK with opus as caller.
1025TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001026 EXPECT_TRUE(SetupEngine());
1027 int channel_num = voe_.GetLastChannel();
1028 std::vector<cricket::AudioCodec> codecs;
1029 codecs.push_back(kOpusCodec);
1030 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1031 cricket::kParamValueEmpty));
1032 EXPECT_FALSE(voe_.GetNACK(channel_num));
1033 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1034 EXPECT_TRUE(voe_.GetNACK(channel_num));
1035}
1036
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001037// Test that we can enable NACK with opus as callee.
1038TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001039 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02001040 channel_ = engine_.CreateChannel(cricket::AudioOptions());
1041 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001042
1043 int channel_num = voe_.GetLastChannel();
1044 std::vector<cricket::AudioCodec> codecs;
1045 codecs.push_back(kOpusCodec);
1046 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1047 cricket::kParamValueEmpty));
1048 EXPECT_FALSE(voe_.GetNACK(channel_num));
1049 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1050 EXPECT_FALSE(voe_.GetNACK(channel_num));
1051
1052 EXPECT_TRUE(channel_->AddSendStream(
1053 cricket::StreamParams::CreateLegacy(kSsrc1)));
1054 EXPECT_TRUE(voe_.GetNACK(channel_num));
1055}
1056
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057// Test that we can enable NACK on receive streams.
1058TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1059 EXPECT_TRUE(SetupEngine());
1060 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1061 int channel_num1 = voe_.GetLastChannel();
1062 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1063 int channel_num2 = 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_num1));
1069 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1070 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1071 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1072 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1073}
1074
1075// Test that we can disable NACK.
1076TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1077 EXPECT_TRUE(SetupEngine());
1078 int channel_num = voe_.GetLastChannel();
1079 std::vector<cricket::AudioCodec> codecs;
1080 codecs.push_back(kOpusCodec);
1081 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1082 cricket::kParamValueEmpty));
1083 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1084 EXPECT_TRUE(voe_.GetNACK(channel_num));
1085
1086 codecs.clear();
1087 codecs.push_back(kOpusCodec);
1088 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1089 EXPECT_FALSE(voe_.GetNACK(channel_num));
1090}
1091
1092// Test that we can disable NACK on receive streams.
1093TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1094 EXPECT_TRUE(SetupEngine());
1095 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1096 int channel_num1 = voe_.GetLastChannel();
1097 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1098 int channel_num2 = 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_num1));
1105 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1106
1107 codecs.clear();
1108 codecs.push_back(kOpusCodec);
1109 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1110 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1111 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1112}
1113
1114// Test that NACK is enabled on a new receive stream.
1115TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1116 EXPECT_TRUE(SetupEngine());
1117 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1118 int channel_num = voe_.GetLastChannel();
1119 std::vector<cricket::AudioCodec> codecs;
1120 codecs.push_back(kIsacCodec);
1121 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1122 cricket::kParamValueEmpty));
1123 codecs.push_back(kCn16000Codec);
1124 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1125 EXPECT_TRUE(voe_.GetNACK(channel_num));
1126
1127 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1128 channel_num = voe_.GetLastChannel();
1129 EXPECT_TRUE(voe_.GetNACK(channel_num));
1130 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1131 channel_num = voe_.GetLastChannel();
1132 EXPECT_TRUE(voe_.GetNACK(channel_num));
1133}
1134
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001135// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001136TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001137 EXPECT_TRUE(SetupEngine());
1138 int channel_num = voe_.GetLastChannel();
1139 std::vector<cricket::AudioCodec> codecs;
1140 codecs.push_back(kOpusCodec);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001141 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1142 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1143}
1144
1145// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001146TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001147 EXPECT_TRUE(SetupEngine());
1148 int channel_num = voe_.GetLastChannel();
1149 std::vector<cricket::AudioCodec> codecs;
1150 codecs.push_back(kOpusCodec);
1151 codecs[0].bitrate = 0;
1152 codecs[0].params["useinbandfec"] = "0";
1153 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1154 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1155 webrtc::CodecInst gcodec;
1156 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1157 EXPECT_STREQ("opus", gcodec.plname);
1158 EXPECT_EQ(1, gcodec.channels);
1159 EXPECT_EQ(32000, gcodec.rate);
1160}
1161
1162// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001163TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001164 EXPECT_TRUE(SetupEngine());
1165 int channel_num = voe_.GetLastChannel();
1166 std::vector<cricket::AudioCodec> codecs;
1167 codecs.push_back(kOpusCodec);
1168 codecs[0].bitrate = 0;
1169 codecs[0].params["useinbandfec"] = "1";
1170 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1171 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1172 webrtc::CodecInst gcodec;
1173 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1174 EXPECT_STREQ("opus", gcodec.plname);
1175 EXPECT_EQ(1, gcodec.channels);
1176 EXPECT_EQ(32000, gcodec.rate);
1177}
1178
1179// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001180TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001181 EXPECT_TRUE(SetupEngine());
1182 int channel_num = voe_.GetLastChannel();
1183 std::vector<cricket::AudioCodec> codecs;
1184 codecs.push_back(kOpusCodec);
1185 codecs[0].bitrate = 0;
1186 codecs[0].params["stereo"] = "1";
1187 codecs[0].params["useinbandfec"] = "1";
1188 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1189 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1190 webrtc::CodecInst gcodec;
1191 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1192 EXPECT_STREQ("opus", gcodec.plname);
1193 EXPECT_EQ(2, gcodec.channels);
1194 EXPECT_EQ(64000, gcodec.rate);
1195}
1196
1197// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001198TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001199 EXPECT_TRUE(SetupEngine());
1200 int channel_num = voe_.GetLastChannel();
1201 std::vector<cricket::AudioCodec> codecs;
1202 codecs.push_back(kIsacCodec);
1203 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1204 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1205}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001206
1207// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1208TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1209 EXPECT_TRUE(SetupEngine());
1210 int channel_num = voe_.GetLastChannel();
1211 std::vector<cricket::AudioCodec> codecs;
1212 codecs.push_back(kIsacCodec);
1213 codecs[0].params["useinbandfec"] = "1";
1214 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1215 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1216}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001217
1218// Test that Opus FEC status can be changed.
1219TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1220 EXPECT_TRUE(SetupEngine());
1221 int channel_num = voe_.GetLastChannel();
1222 std::vector<cricket::AudioCodec> codecs;
1223 codecs.push_back(kOpusCodec);
1224 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1225 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1226 codecs[0].params["useinbandfec"] = "1";
1227 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1228 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1229}
1230
1231// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1232TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1233 EXPECT_TRUE(SetupEngine());
1234 int channel_num = voe_.GetLastChannel();
1235 std::vector<cricket::AudioCodec> codecs;
1236 codecs.push_back(kOpusCodec);
1237 codecs[0].bitrate = 0;
1238 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1239 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1240 EXPECT_EQ(cricket::kOpusBandwidthNb,
1241 voe_.GetMaxEncodingBandwidth(channel_num));
1242 webrtc::CodecInst gcodec;
1243 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1244 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001245
1246 EXPECT_EQ(12000, gcodec.rate);
1247 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1248 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1249 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1250 EXPECT_EQ(24000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001251}
1252
1253// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1254TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1255 EXPECT_TRUE(SetupEngine());
1256 int channel_num = voe_.GetLastChannel();
1257 std::vector<cricket::AudioCodec> codecs;
1258 codecs.push_back(kOpusCodec);
1259 codecs[0].bitrate = 0;
1260 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1261 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1262 EXPECT_EQ(cricket::kOpusBandwidthMb,
1263 voe_.GetMaxEncodingBandwidth(channel_num));
1264 webrtc::CodecInst gcodec;
1265 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1266 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001267
1268 EXPECT_EQ(20000, gcodec.rate);
1269 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1270 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1271 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1272 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001273}
1274
1275// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1276TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1277 EXPECT_TRUE(SetupEngine());
1278 int channel_num = voe_.GetLastChannel();
1279 std::vector<cricket::AudioCodec> codecs;
1280 codecs.push_back(kOpusCodec);
1281 codecs[0].bitrate = 0;
1282 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1283 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1284 EXPECT_EQ(cricket::kOpusBandwidthWb,
1285 voe_.GetMaxEncodingBandwidth(channel_num));
1286 webrtc::CodecInst gcodec;
1287 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1288 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001289
1290 EXPECT_EQ(20000, gcodec.rate);
1291 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1292 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1293 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1294 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001295}
1296
1297// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1298TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1299 EXPECT_TRUE(SetupEngine());
1300 int channel_num = voe_.GetLastChannel();
1301 std::vector<cricket::AudioCodec> codecs;
1302 codecs.push_back(kOpusCodec);
1303 codecs[0].bitrate = 0;
1304 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1305 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1306 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1307 voe_.GetMaxEncodingBandwidth(channel_num));
1308 webrtc::CodecInst gcodec;
1309 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1310 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001311
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001312 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001313 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1314 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1315 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1316 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001317}
1318
1319// Test 24000 < maxplaybackrate triggers Opus full band mode.
1320TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1321 EXPECT_TRUE(SetupEngine());
1322 int channel_num = voe_.GetLastChannel();
1323 std::vector<cricket::AudioCodec> codecs;
1324 codecs.push_back(kOpusCodec);
1325 codecs[0].bitrate = 0;
1326 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1327 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1328 EXPECT_EQ(cricket::kOpusBandwidthFb,
1329 voe_.GetMaxEncodingBandwidth(channel_num));
1330 webrtc::CodecInst gcodec;
1331 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1332 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001333
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001334 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001335 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1336 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1337 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1338 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001339}
1340
1341// Test Opus that without maxplaybackrate, default playback rate is used.
1342TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1343 EXPECT_TRUE(SetupEngine());
1344 int channel_num = voe_.GetLastChannel();
1345 std::vector<cricket::AudioCodec> codecs;
1346 codecs.push_back(kOpusCodec);
1347 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1348 EXPECT_EQ(cricket::kOpusBandwidthFb,
1349 voe_.GetMaxEncodingBandwidth(channel_num));
1350}
1351
1352// Test the with non-Opus, maxplaybackrate has no effect.
1353TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1354 EXPECT_TRUE(SetupEngine());
1355 int channel_num = voe_.GetLastChannel();
1356 std::vector<cricket::AudioCodec> codecs;
1357 codecs.push_back(kIsacCodec);
1358 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1359 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1360 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1361}
1362
1363// Test maxplaybackrate can be set on two streams.
1364TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1365 EXPECT_TRUE(SetupEngine());
1366 int channel_num = voe_.GetLastChannel();
1367 std::vector<cricket::AudioCodec> codecs;
1368 codecs.push_back(kOpusCodec);
1369 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1370 // Default bandwidth is 24000.
1371 EXPECT_EQ(cricket::kOpusBandwidthFb,
1372 voe_.GetMaxEncodingBandwidth(channel_num));
1373
1374 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1375
1376 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1377 EXPECT_EQ(cricket::kOpusBandwidthNb,
1378 voe_.GetMaxEncodingBandwidth(channel_num));
1379
1380 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1381 channel_num = voe_.GetLastChannel();
1382 EXPECT_EQ(cricket::kOpusBandwidthNb,
1383 voe_.GetMaxEncodingBandwidth(channel_num));
1384}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001385
Minyue Li7100dcd2015-03-27 05:05:59 +01001386// Test that with usedtx=0, Opus DTX is off.
1387TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1388 EXPECT_TRUE(SetupEngine());
1389 int channel_num = voe_.GetLastChannel();
1390 std::vector<cricket::AudioCodec> codecs;
1391 codecs.push_back(kOpusCodec);
1392 codecs[0].params["usedtx"] = "0";
1393 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1394 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1395}
1396
1397// Test that with usedtx=1, Opus DTX is on.
1398TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1399 EXPECT_TRUE(SetupEngine());
1400 int channel_num = voe_.GetLastChannel();
1401 std::vector<cricket::AudioCodec> codecs;
1402 codecs.push_back(kOpusCodec);
1403 codecs[0].params["usedtx"] = "1";
1404 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1405 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1406 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1407}
1408
1409// Test that usedtx=1 works with stereo Opus.
1410TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1411 EXPECT_TRUE(SetupEngine());
1412 int channel_num = voe_.GetLastChannel();
1413 std::vector<cricket::AudioCodec> codecs;
1414 codecs.push_back(kOpusCodec);
1415 codecs[0].params["usedtx"] = "1";
1416 codecs[0].params["stereo"] = "1";
1417 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1418 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1419 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1420}
1421
1422// Test that usedtx=1 does not work with non Opus.
1423TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1424 EXPECT_TRUE(SetupEngine());
1425 int channel_num = voe_.GetLastChannel();
1426 std::vector<cricket::AudioCodec> codecs;
1427 codecs.push_back(kIsacCodec);
1428 codecs[0].params["usedtx"] = "1";
1429 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1430 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1431}
1432
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001433// Test that we can switch back and forth between Opus and ISAC with CN.
1434TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001435 EXPECT_TRUE(SetupEngine());
1436 int channel_num = voe_.GetLastChannel();
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001437 std::vector<cricket::AudioCodec> opus_codecs;
1438 opus_codecs.push_back(kOpusCodec);
1439 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440 webrtc::CodecInst gcodec;
1441 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001442 EXPECT_EQ(111, gcodec.pltype);
1443 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001444
1445 std::vector<cricket::AudioCodec> isac_codecs;
1446 isac_codecs.push_back(kIsacCodec);
1447 isac_codecs.push_back(kCn16000Codec);
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001448 isac_codecs.push_back(kOpusCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1450 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1451 EXPECT_EQ(103, gcodec.pltype);
1452 EXPECT_STREQ("ISAC", gcodec.plname);
1453
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001454 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001456 EXPECT_EQ(111, gcodec.pltype);
1457 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458}
1459
1460// Test that we handle various ways of specifying bitrate.
1461TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1462 EXPECT_TRUE(SetupEngine());
1463 int channel_num = voe_.GetLastChannel();
1464 std::vector<cricket::AudioCodec> codecs;
1465 codecs.push_back(kIsacCodec); // bitrate == 32000
1466 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1467 webrtc::CodecInst gcodec;
1468 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1469 EXPECT_EQ(103, gcodec.pltype);
1470 EXPECT_STREQ("ISAC", gcodec.plname);
1471 EXPECT_EQ(32000, gcodec.rate);
1472
1473 codecs[0].bitrate = 0; // bitrate == default
1474 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1475 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1476 EXPECT_EQ(103, gcodec.pltype);
1477 EXPECT_STREQ("ISAC", gcodec.plname);
1478 EXPECT_EQ(-1, gcodec.rate);
1479
1480 codecs[0].bitrate = 28000; // bitrate == 28000
1481 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1482 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1483 EXPECT_EQ(103, gcodec.pltype);
1484 EXPECT_STREQ("ISAC", gcodec.plname);
1485 EXPECT_EQ(28000, gcodec.rate);
1486
1487 codecs[0] = kPcmuCodec; // bitrate == 64000
1488 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1489 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1490 EXPECT_EQ(0, gcodec.pltype);
1491 EXPECT_STREQ("PCMU", gcodec.plname);
1492 EXPECT_EQ(64000, gcodec.rate);
1493
1494 codecs[0].bitrate = 0; // bitrate == default
1495 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1496 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1497 EXPECT_EQ(0, gcodec.pltype);
1498 EXPECT_STREQ("PCMU", gcodec.plname);
1499 EXPECT_EQ(64000, gcodec.rate);
1500
1501 codecs[0] = kOpusCodec;
1502 codecs[0].bitrate = 0; // bitrate == default
1503 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1504 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1505 EXPECT_EQ(111, gcodec.pltype);
1506 EXPECT_STREQ("opus", gcodec.plname);
1507 EXPECT_EQ(32000, gcodec.rate);
1508}
1509
Brave Yao5225dd82015-03-26 07:39:19 +08001510// Test that we could set packet size specified in kCodecParamPTime.
1511TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1512 EXPECT_TRUE(SetupEngine());
1513 int channel_num = voe_.GetLastChannel();
1514 std::vector<cricket::AudioCodec> codecs;
1515 codecs.push_back(kOpusCodec);
1516 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1517 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1518 webrtc::CodecInst gcodec;
1519 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1520 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1521
1522 codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Value below range.
1523 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1524 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1525 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1526
1527 codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Value beyond range.
1528 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1529 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1530 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1531
1532 codecs[0] = kIsacCodec; // Also try Isac, and with unsupported size.
1533 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1534 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1535 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1536 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1537
1538 codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1539 codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1540 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1541 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1542 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1543}
1544
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001545// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001546TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1547 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001548 std::vector<cricket::AudioCodec> codecs;
1549 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1550}
1551
1552// Test that we can set send codecs even with telephone-event codec as the first
1553// one on the list.
1554TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1555 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001556 int channel_num = voe_.GetLastChannel();
1557 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001558 codecs.push_back(kTelephoneEventCodec);
1559 codecs.push_back(kIsacCodec);
1560 codecs.push_back(kPcmuCodec);
1561 codecs[0].id = 98; // DTMF
1562 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001563 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1564 webrtc::CodecInst gcodec;
1565 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001566 EXPECT_EQ(96, gcodec.pltype);
1567 EXPECT_STREQ("ISAC", gcodec.plname);
1568 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1569}
1570
1571// Test that we can set send codecs even with CN codec as the first
1572// one on the list.
1573TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1574 EXPECT_TRUE(SetupEngine());
1575 int channel_num = voe_.GetLastChannel();
1576 std::vector<cricket::AudioCodec> codecs;
1577 codecs.push_back(kCn16000Codec);
1578 codecs.push_back(kIsacCodec);
1579 codecs.push_back(kPcmuCodec);
1580 codecs[0].id = 98; // wideband CN
1581 codecs[1].id = 96;
1582 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1583 webrtc::CodecInst gcodec;
1584 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1585 EXPECT_EQ(96, gcodec.pltype);
1586 EXPECT_STREQ("ISAC", gcodec.plname);
1587 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588}
1589
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001590// Test that we set VAD and DTMF types correctly as caller.
1591TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592 EXPECT_TRUE(SetupEngine());
1593 int channel_num = voe_.GetLastChannel();
1594 std::vector<cricket::AudioCodec> codecs;
1595 codecs.push_back(kIsacCodec);
1596 codecs.push_back(kPcmuCodec);
1597 // TODO(juberti): cn 32000
1598 codecs.push_back(kCn16000Codec);
1599 codecs.push_back(kCn8000Codec);
1600 codecs.push_back(kTelephoneEventCodec);
1601 codecs.push_back(kRedCodec);
1602 codecs[0].id = 96;
1603 codecs[2].id = 97; // wideband CN
1604 codecs[4].id = 98; // DTMF
1605 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1606 webrtc::CodecInst gcodec;
1607 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1608 EXPECT_EQ(96, gcodec.pltype);
1609 EXPECT_STREQ("ISAC", gcodec.plname);
1610 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001611 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1613 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1614 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1615}
1616
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001617// Test that we set VAD and DTMF types correctly as callee.
1618TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001619 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02001620 channel_ = engine_.CreateChannel(cricket::AudioOptions());
1621 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001622
1623 int channel_num = voe_.GetLastChannel();
1624 std::vector<cricket::AudioCodec> codecs;
1625 codecs.push_back(kIsacCodec);
1626 codecs.push_back(kPcmuCodec);
1627 // TODO(juberti): cn 32000
1628 codecs.push_back(kCn16000Codec);
1629 codecs.push_back(kCn8000Codec);
1630 codecs.push_back(kTelephoneEventCodec);
1631 codecs.push_back(kRedCodec);
1632 codecs[0].id = 96;
1633 codecs[2].id = 97; // wideband CN
1634 codecs[4].id = 98; // DTMF
1635 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1636 EXPECT_TRUE(channel_->AddSendStream(
1637 cricket::StreamParams::CreateLegacy(kSsrc1)));
1638
1639 webrtc::CodecInst gcodec;
1640 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1641 EXPECT_EQ(96, gcodec.pltype);
1642 EXPECT_STREQ("ISAC", gcodec.plname);
1643 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001644 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001645 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1646 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1647 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1648}
1649
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001650// Test that we only apply VAD if we have a CN codec that matches the
1651// send codec clockrate.
1652TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1653 EXPECT_TRUE(SetupEngine());
1654 int channel_num = voe_.GetLastChannel();
1655 std::vector<cricket::AudioCodec> codecs;
1656 // Set ISAC(16K) and CN(16K). VAD should be activated.
1657 codecs.push_back(kIsacCodec);
1658 codecs.push_back(kCn16000Codec);
1659 codecs[1].id = 97;
1660 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1661 webrtc::CodecInst gcodec;
1662 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1663 EXPECT_STREQ("ISAC", gcodec.plname);
1664 EXPECT_TRUE(voe_.GetVAD(channel_num));
1665 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1666 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1667 codecs[0] = kPcmuCodec;
1668 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1669 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1670 EXPECT_STREQ("PCMU", gcodec.plname);
1671 EXPECT_FALSE(voe_.GetVAD(channel_num));
1672 // Set PCMU(8K) and CN(8K). VAD should be activated.
1673 codecs[1] = kCn8000Codec;
1674 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1675 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1676 EXPECT_STREQ("PCMU", gcodec.plname);
1677 EXPECT_TRUE(voe_.GetVAD(channel_num));
1678 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
Brave Yao5225dd82015-03-26 07:39:19 +08001679 // Set ISAC(16K) and CN(8K). VAD should not be activated.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001680 codecs[0] = kIsacCodec;
1681 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1682 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1683 EXPECT_STREQ("ISAC", gcodec.plname);
1684 EXPECT_FALSE(voe_.GetVAD(channel_num));
1685}
1686
1687// Test that we perform case-insensitive matching of codec names.
1688TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1689 EXPECT_TRUE(SetupEngine());
1690 int channel_num = voe_.GetLastChannel();
1691 std::vector<cricket::AudioCodec> codecs;
1692 codecs.push_back(kIsacCodec);
1693 codecs.push_back(kPcmuCodec);
1694 codecs.push_back(kCn16000Codec);
1695 codecs.push_back(kCn8000Codec);
1696 codecs.push_back(kTelephoneEventCodec);
1697 codecs.push_back(kRedCodec);
1698 codecs[0].name = "iSaC";
1699 codecs[0].id = 96;
1700 codecs[2].id = 97; // wideband CN
1701 codecs[4].id = 98; // DTMF
1702 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1703 webrtc::CodecInst gcodec;
1704 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1705 EXPECT_EQ(96, gcodec.pltype);
1706 EXPECT_STREQ("ISAC", gcodec.plname);
1707 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001708 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001709 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1710 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1711 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1712}
1713
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001714// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001715TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716 EXPECT_TRUE(SetupEngine());
1717 int channel_num = voe_.GetLastChannel();
1718 std::vector<cricket::AudioCodec> codecs;
1719 codecs.push_back(kRedCodec);
1720 codecs.push_back(kIsacCodec);
1721 codecs.push_back(kPcmuCodec);
1722 codecs[0].id = 127;
1723 codecs[0].params[""] = "96/96";
1724 codecs[1].id = 96;
1725 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1726 webrtc::CodecInst gcodec;
1727 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1728 EXPECT_EQ(96, gcodec.pltype);
1729 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001730 EXPECT_TRUE(voe_.GetRED(channel_num));
1731 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732}
1733
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001734// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001735TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001736 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02001737 channel_ = engine_.CreateChannel(cricket::AudioOptions());
1738 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001739
1740 int channel_num = voe_.GetLastChannel();
1741 std::vector<cricket::AudioCodec> codecs;
1742 codecs.push_back(kRedCodec);
1743 codecs.push_back(kIsacCodec);
1744 codecs.push_back(kPcmuCodec);
1745 codecs[0].id = 127;
1746 codecs[0].params[""] = "96/96";
1747 codecs[1].id = 96;
1748 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1749 EXPECT_TRUE(channel_->AddSendStream(
1750 cricket::StreamParams::CreateLegacy(kSsrc1)));
1751 webrtc::CodecInst gcodec;
1752 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1753 EXPECT_EQ(96, gcodec.pltype);
1754 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001755 EXPECT_TRUE(voe_.GetRED(channel_num));
1756 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001757}
1758
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001759// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001760TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1761 EXPECT_TRUE(SetupEngine());
1762 int channel_num = voe_.GetLastChannel();
1763 std::vector<cricket::AudioCodec> codecs;
1764 codecs.push_back(kRedCodec);
1765 codecs.push_back(kIsacCodec);
1766 codecs.push_back(kPcmuCodec);
1767 codecs[0].id = 127;
1768 codecs[1].id = 96;
1769 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1770 webrtc::CodecInst gcodec;
1771 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1772 EXPECT_EQ(96, gcodec.pltype);
1773 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001774 EXPECT_TRUE(voe_.GetRED(channel_num));
1775 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776}
1777
1778// Test that we ignore RED if the parameters aren't named the way we expect.
1779TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1780 EXPECT_TRUE(SetupEngine());
1781 int channel_num = voe_.GetLastChannel();
1782 std::vector<cricket::AudioCodec> codecs;
1783 codecs.push_back(kRedCodec);
1784 codecs.push_back(kIsacCodec);
1785 codecs.push_back(kPcmuCodec);
1786 codecs[0].id = 127;
1787 codecs[0].params["ABC"] = "96/96";
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_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001795}
1796
1797// Test that we ignore RED if it uses different primary/secondary encoding.
1798TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1799 EXPECT_TRUE(SetupEngine());
1800 int channel_num = voe_.GetLastChannel();
1801 std::vector<cricket::AudioCodec> codecs;
1802 codecs.push_back(kRedCodec);
1803 codecs.push_back(kIsacCodec);
1804 codecs.push_back(kPcmuCodec);
1805 codecs[0].id = 127;
1806 codecs[0].params[""] = "96/0";
1807 codecs[1].id = 96;
1808 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1809 webrtc::CodecInst gcodec;
1810 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1811 EXPECT_EQ(96, gcodec.pltype);
1812 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001813 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001814}
1815
1816// Test that we ignore RED if it uses more than 2 encodings.
1817TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1818 EXPECT_TRUE(SetupEngine());
1819 int channel_num = voe_.GetLastChannel();
1820 std::vector<cricket::AudioCodec> codecs;
1821 codecs.push_back(kRedCodec);
1822 codecs.push_back(kIsacCodec);
1823 codecs.push_back(kPcmuCodec);
1824 codecs[0].id = 127;
1825 codecs[0].params[""] = "96/96/96";
1826 codecs[1].id = 96;
1827 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1828 webrtc::CodecInst gcodec;
1829 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1830 EXPECT_EQ(96, gcodec.pltype);
1831 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001832 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001833}
1834
1835// Test that we ignore RED if it has bogus codec ids.
1836TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1837 EXPECT_TRUE(SetupEngine());
1838 int channel_num = voe_.GetLastChannel();
1839 std::vector<cricket::AudioCodec> codecs;
1840 codecs.push_back(kRedCodec);
1841 codecs.push_back(kIsacCodec);
1842 codecs.push_back(kPcmuCodec);
1843 codecs[0].id = 127;
1844 codecs[0].params[""] = "ABC/ABC";
1845 codecs[1].id = 96;
1846 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1847 webrtc::CodecInst gcodec;
1848 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1849 EXPECT_EQ(96, gcodec.pltype);
1850 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001851 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001852}
1853
1854// Test that we ignore RED if it refers to a codec that is not present.
1855TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1856 EXPECT_TRUE(SetupEngine());
1857 int channel_num = voe_.GetLastChannel();
1858 std::vector<cricket::AudioCodec> codecs;
1859 codecs.push_back(kRedCodec);
1860 codecs.push_back(kIsacCodec);
1861 codecs.push_back(kPcmuCodec);
1862 codecs[0].id = 127;
1863 codecs[0].params[""] = "97/97";
1864 codecs[1].id = 96;
1865 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1866 webrtc::CodecInst gcodec;
1867 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1868 EXPECT_EQ(96, gcodec.pltype);
1869 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001870 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001871}
1872
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001873// Test support for audio level header extension.
1874TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1875 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001876}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001877TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1878 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1879}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001880
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001881// Test support for absolute send time header extension.
1882TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1883 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1884}
1885TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1886 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001887}
1888
1889// Test that we can create a channel and start sending/playing out on it.
1890TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1891 EXPECT_TRUE(SetupEngine());
1892 int channel_num = voe_.GetLastChannel();
1893 std::vector<cricket::AudioCodec> codecs;
1894 codecs.push_back(kPcmuCodec);
1895 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1896 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1897 EXPECT_TRUE(voe_.GetSend(channel_num));
1898 EXPECT_TRUE(channel_->SetPlayout(true));
1899 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1900 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1901 EXPECT_FALSE(voe_.GetSend(channel_num));
1902 EXPECT_TRUE(channel_->SetPlayout(false));
1903 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1904}
1905
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001906// Test that we can add and remove send streams.
1907TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1908 SetupForMultiSendStream();
1909
1910 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1911
1912 // Set the global state for sending.
1913 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1914
1915 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1916 EXPECT_TRUE(channel_->AddSendStream(
1917 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1918
1919 // Verify that we are in a sending state for all the created streams.
1920 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1921 EXPECT_TRUE(voe_.GetSend(channel_num));
1922 }
1923
1924 // Remove the first send channel, which is the default channel. It will only
1925 // recycle the default channel but not delete it.
1926 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1927 // Stream should already be Removed from the send stream list.
1928 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1929 // But the default still exists.
1930 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1931
1932 // Delete the rest of send channel streams.
1933 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1934 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1935 // Stream should already be deleted.
1936 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1937 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1938 }
1939}
1940
1941// Test SetSendCodecs correctly configure the codecs in all send streams.
1942TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1943 SetupForMultiSendStream();
1944
1945 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1946 // Create send streams.
1947 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1948 EXPECT_TRUE(channel_->AddSendStream(
1949 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1950 }
1951
1952 std::vector<cricket::AudioCodec> codecs;
1953 // Set ISAC(16K) and CN(16K). VAD should be activated.
1954 codecs.push_back(kIsacCodec);
1955 codecs.push_back(kCn16000Codec);
1956 codecs[1].id = 97;
1957 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1958
1959 // Verify ISAC and VAD are corrected configured on all send channels.
1960 webrtc::CodecInst gcodec;
1961 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1962 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1963 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1964 EXPECT_STREQ("ISAC", gcodec.plname);
1965 EXPECT_TRUE(voe_.GetVAD(channel_num));
1966 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1967 }
1968
1969 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1970 codecs[0] = kPcmuCodec;
1971 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1972 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1973 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1974 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1975 EXPECT_STREQ("PCMU", gcodec.plname);
1976 EXPECT_FALSE(voe_.GetVAD(channel_num));
1977 }
1978}
1979
1980// Test we can SetSend on all send streams correctly.
1981TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1982 SetupForMultiSendStream();
1983
1984 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1985 // Create the send channels and they should be a SEND_NOTHING date.
1986 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1987 EXPECT_TRUE(channel_->AddSendStream(
1988 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1989 int channel_num = voe_.GetLastChannel();
1990 EXPECT_FALSE(voe_.GetSend(channel_num));
1991 }
1992
1993 // Set the global state for starting sending.
1994 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1995 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1996 // Verify that we are in a sending state for all the send streams.
1997 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1998 EXPECT_TRUE(voe_.GetSend(channel_num));
1999 }
2000
2001 // Set the global state for stopping sending.
2002 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2003 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
2004 // Verify that we are in a stop state for all the send streams.
2005 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2006 EXPECT_FALSE(voe_.GetSend(channel_num));
2007 }
2008}
2009
2010// Test we can set the correct statistics on all send streams.
2011TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2012 SetupForMultiSendStream();
2013
2014 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2015 // Create send streams.
2016 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2017 EXPECT_TRUE(channel_->AddSendStream(
2018 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2019 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002020 // Create a receive stream to check that none of the send streams end up in
2021 // the receive stream stats.
2022 EXPECT_TRUE(channel_->AddRecvStream(
2023 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002024 // We need send codec to be set to get all stats.
2025 std::vector<cricket::AudioCodec> codecs;
2026 codecs.push_back(kPcmuCodec);
2027 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002028 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029
2030 cricket::VoiceMediaInfo info;
2031 EXPECT_EQ(true, channel_->GetStats(&info));
2032 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
2033
2034 // Verify the statistic information is correct.
2035 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002036 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002037 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
2038 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
2039 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
2040 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
2041 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
2042 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
2043 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
2044 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002045 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002046 }
2047
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002048 EXPECT_EQ(0u, info.receivers.size());
2049 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2050 EXPECT_EQ(true, channel_->GetStats(&info));
2051
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002052 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002053 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2054 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2055 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2056 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2057 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002058 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2059 (1 << 14), info.receivers[0].expand_rate);
2060 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2061 (1 << 14), info.receivers[0].speech_expand_rate);
2062 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2063 (1 << 14), info.receivers[0].secondary_decoded_rate);
Henrik Lundin8e6fd462015-06-02 09:24:52 +02002064 EXPECT_EQ(
2065 static_cast<float>(cricket::kNetStats.currentAccelerateRate) / (1 << 14),
2066 info.receivers[0].accelerate_rate);
2067 EXPECT_EQ(
2068 static_cast<float>(cricket::kNetStats.currentPreemptiveRate) / (1 << 14),
2069 info.receivers[0].preemptive_expand_rate);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002070}
2071
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002072// Test that we can add and remove receive streams, and do proper send/playout.
2073// We can receive on multiple streams while sending one stream.
2074TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002075 EXPECT_TRUE(SetupEngine());
2076 int channel_num1 = voe_.GetLastChannel();
2077
2078 // Start playout on the default channel.
2079 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2080 EXPECT_TRUE(channel_->SetPlayout(true));
2081 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2082
2083 // Adding another stream should disable playout on the default channel.
2084 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2085 int channel_num2 = voe_.GetLastChannel();
2086 std::vector<cricket::AudioCodec> codecs;
2087 codecs.push_back(kPcmuCodec);
2088 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2089 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2090 EXPECT_TRUE(voe_.GetSend(channel_num1));
2091 EXPECT_FALSE(voe_.GetSend(channel_num2));
2092
2093 // Make sure only the new channel is played out.
2094 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2095 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2096
2097 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2098 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2099 int channel_num3 = voe_.GetLastChannel();
2100 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2101 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2102 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2103 EXPECT_FALSE(voe_.GetSend(channel_num3));
2104
2105 // Stop sending.
2106 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2107 EXPECT_FALSE(voe_.GetSend(channel_num1));
2108 EXPECT_FALSE(voe_.GetSend(channel_num2));
2109 EXPECT_FALSE(voe_.GetSend(channel_num3));
2110
2111 // Stop playout.
2112 EXPECT_TRUE(channel_->SetPlayout(false));
2113 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2114 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2115 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2116
2117 // Restart playout and make sure the default channel still is not played out.
2118 EXPECT_TRUE(channel_->SetPlayout(true));
2119 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2120 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2121 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2122
2123 // Now remove the new streams and verify that the default channel is
2124 // played out again.
2125 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2126 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2127
2128 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2129}
2130
2131// Test that we can set the devices to use.
2132TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2133 EXPECT_TRUE(SetupEngine());
2134 int channel_num = voe_.GetLastChannel();
2135 std::vector<cricket::AudioCodec> codecs;
2136 codecs.push_back(kPcmuCodec);
2137 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2138
2139 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2140 cricket::kFakeDefaultDeviceId);
2141 cricket::Device dev(cricket::kFakeDeviceName,
2142 cricket::kFakeDeviceId);
2143
2144 // Test SetDevices() while not sending or playing.
2145 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2146
2147 // Test SetDevices() while sending and playing.
2148 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2149 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2150 EXPECT_TRUE(channel_->SetPlayout(true));
2151 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2152 EXPECT_TRUE(voe_.GetSend(channel_num));
2153 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2154
2155 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2156
2157 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2158 EXPECT_TRUE(voe_.GetSend(channel_num));
2159 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2160
2161 // Test that failure to open newly selected devices does not prevent opening
2162 // ones after that.
2163 voe_.set_fail_start_recording_microphone(true);
2164 voe_.set_playout_fail_channel(channel_num);
2165 voe_.set_send_fail_channel(channel_num);
2166
2167 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2168
2169 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2170 EXPECT_FALSE(voe_.GetSend(channel_num));
2171 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2172
2173 voe_.set_fail_start_recording_microphone(false);
2174 voe_.set_playout_fail_channel(-1);
2175 voe_.set_send_fail_channel(-1);
2176
2177 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2178
2179 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2180 EXPECT_TRUE(voe_.GetSend(channel_num));
2181 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2182}
2183
2184// Test that we can set the devices to use even if we failed to
2185// open the initial ones.
2186TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2187 EXPECT_TRUE(SetupEngine());
2188 int channel_num = voe_.GetLastChannel();
2189 std::vector<cricket::AudioCodec> codecs;
2190 codecs.push_back(kPcmuCodec);
2191 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2192
2193 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2194 cricket::kFakeDefaultDeviceId);
2195 cricket::Device dev(cricket::kFakeDeviceName,
2196 cricket::kFakeDeviceId);
2197
2198 // Test that failure to open devices selected before starting
2199 // send/play does not prevent opening newly selected ones after that.
2200 voe_.set_fail_start_recording_microphone(true);
2201 voe_.set_playout_fail_channel(channel_num);
2202 voe_.set_send_fail_channel(channel_num);
2203
2204 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2205
2206 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2207 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2208 EXPECT_FALSE(channel_->SetPlayout(true));
2209 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2210 EXPECT_FALSE(voe_.GetSend(channel_num));
2211 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2212
2213 voe_.set_fail_start_recording_microphone(false);
2214 voe_.set_playout_fail_channel(-1);
2215 voe_.set_send_fail_channel(-1);
2216
2217 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2218
2219 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2220 EXPECT_TRUE(voe_.GetSend(channel_num));
2221 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2222}
2223
2224// Test that we can create a channel configured for multi-point conferences,
2225// and start sending/playing out on it.
2226TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2227 EXPECT_TRUE(SetupEngine());
2228 int channel_num = voe_.GetLastChannel();
2229 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2230 std::vector<cricket::AudioCodec> codecs;
2231 codecs.push_back(kPcmuCodec);
2232 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2233 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2234 EXPECT_TRUE(voe_.GetSend(channel_num));
2235}
2236
2237// Test that we can create a channel configured for Codian bridges,
2238// and start sending/playing out on it.
2239TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2240 EXPECT_TRUE(SetupEngine());
2241 int channel_num = voe_.GetLastChannel();
2242 webrtc::AgcConfig agc_config;
2243 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2244 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2245 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2246 std::vector<cricket::AudioCodec> codecs;
2247 codecs.push_back(kPcmuCodec);
2248 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2249 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2250 EXPECT_TRUE(voe_.GetSend(channel_num));
2251 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2252 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2253 EXPECT_TRUE(channel_->SetPlayout(true));
2254 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2255 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2256 EXPECT_FALSE(voe_.GetSend(channel_num));
2257 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2258 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2259 EXPECT_TRUE(channel_->SetPlayout(false));
2260 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2261}
2262
wu@webrtc.org97077a32013-10-25 21:18:33 +00002263TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2264 EXPECT_TRUE(SetupEngine());
2265 webrtc::AgcConfig agc_config;
2266 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2267 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2268
2269 cricket::AudioOptions options;
2270 options.tx_agc_target_dbov.Set(3);
2271 options.tx_agc_digital_compression_gain.Set(9);
2272 options.tx_agc_limiter.Set(true);
2273 options.auto_gain_control.Set(true);
2274 EXPECT_TRUE(engine_.SetOptions(options));
2275
2276 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2277 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2278 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2279 EXPECT_TRUE(agc_config.limiterEnable);
2280
2281 // Check interaction with adjust_agc_delta. Both should be respected, for
2282 // backwards compatibility.
2283 options.adjust_agc_delta.Set(-10);
2284 EXPECT_TRUE(engine_.SetOptions(options));
2285
2286 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2287 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2288}
2289
2290TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2291 EXPECT_TRUE(SetupEngine());
2292 int channel_num = voe_.GetLastChannel();
2293 cricket::AudioOptions options;
2294 options.rx_agc_target_dbov.Set(6);
2295 options.rx_agc_digital_compression_gain.Set(0);
2296 options.rx_agc_limiter.Set(true);
2297 options.rx_auto_gain_control.Set(true);
2298 EXPECT_TRUE(channel_->SetOptions(options));
2299
2300 webrtc::AgcConfig agc_config;
2301 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2302 channel_num, agc_config));
2303 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2304 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2305 EXPECT_TRUE(agc_config.limiterEnable);
2306}
2307
2308TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2309 EXPECT_TRUE(SetupEngine());
2310 cricket::AudioOptions options;
2311 options.recording_sample_rate.Set(48000u);
2312 options.playout_sample_rate.Set(44100u);
2313 EXPECT_TRUE(engine_.SetOptions(options));
2314
2315 unsigned int recording_sample_rate, playout_sample_rate;
2316 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2317 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2318 EXPECT_EQ(48000u, recording_sample_rate);
2319 EXPECT_EQ(44100u, playout_sample_rate);
2320}
2321
2322TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2323 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002324 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002325 EXPECT_EQ(
2326 // Info:
2327 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2328 // Warning:
2329 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2330 // Error:
2331 webrtc::kTraceError | webrtc::kTraceCritical,
2332 static_cast<int>(trace_wrapper_->filter_));
2333 // Now set it explicitly
2334 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002335 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2336 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002337 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2338 trace_wrapper_->filter_);
2339}
2340
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002341// Test that we can set the outgoing SSRC properly.
2342// SSRC is set in SetupEngine by calling AddSendStream.
2343TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2344 EXPECT_TRUE(SetupEngine());
2345 int channel_num = voe_.GetLastChannel();
2346 unsigned int send_ssrc;
2347 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2348 EXPECT_NE(0U, send_ssrc);
2349 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2350 EXPECT_EQ(kSsrc1, send_ssrc);
2351}
2352
2353TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2354 // Setup. We need send codec to be set to get all stats.
2355 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002356 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2357 // use a different SSRC.
2358 EXPECT_TRUE(channel_->AddRecvStream(
2359 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002360 std::vector<cricket::AudioCodec> codecs;
2361 codecs.push_back(kPcmuCodec);
2362 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002363 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002364
2365 cricket::VoiceMediaInfo info;
2366 EXPECT_EQ(true, channel_->GetStats(&info));
2367 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002368 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2370 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2371 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2372 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2373 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2374 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2375 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2376 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002377 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002378 // TODO(sriniv): Add testing for more fields. These are not populated
2379 // in FakeWebrtcVoiceEngine yet.
2380 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2381 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2382 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2383 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2384 // EXPECT_EQ(cricket::kIntStatValue,
2385 // info.senders[0].echo_return_loss_enhancement);
2386
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002387 EXPECT_EQ(0u, info.receivers.size());
2388 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2389 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002390 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002391
2392 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2393 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2394 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2395 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2396 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002397 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2398 (1 << 14), info.receivers[0].expand_rate);
2399 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2400 (1 << 14), info.receivers[0].speech_expand_rate);
2401 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2402 (1 << 14), info.receivers[0].secondary_decoded_rate);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002403 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002404}
2405
2406// Test that we can set the outgoing SSRC properly with multiple streams.
2407// SSRC is set in SetupEngine by calling AddSendStream.
2408TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2409 EXPECT_TRUE(SetupEngine());
2410 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2411 int channel_num1 = voe_.GetLastChannel();
2412 unsigned int send_ssrc;
2413 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2414 EXPECT_EQ(kSsrc1, send_ssrc);
2415
2416 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2417 int channel_num2 = voe_.GetLastChannel();
2418 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2419 EXPECT_EQ(kSsrc1, send_ssrc);
2420}
2421
2422// Test that the local SSRC is the same on sending and receiving channels if the
2423// receive channel is created before the send channel.
2424TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002425 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02002426 channel_ = engine_.CreateChannel(cricket::AudioOptions());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2428
2429 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2430 int receive_channel_num = voe_.GetLastChannel();
2431 EXPECT_TRUE(channel_->AddSendStream(
2432 cricket::StreamParams::CreateLegacy(1234)));
2433 int send_channel_num = voe_.GetLastChannel();
2434
2435 unsigned int ssrc = 0;
2436 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2437 EXPECT_EQ(1234U, ssrc);
2438 ssrc = 0;
2439 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2440 EXPECT_EQ(1234U, ssrc);
2441}
2442
2443// Test that we can properly receive packets.
2444TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2445 EXPECT_TRUE(SetupEngine());
2446 int channel_num = voe_.GetLastChannel();
2447 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2448 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2449 sizeof(kPcmuFrame)));
2450}
2451
2452// Test that we can properly receive packets on multiple streams.
2453TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2454 EXPECT_TRUE(SetupEngine());
2455 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2456 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2457 int channel_num1 = voe_.GetLastChannel();
2458 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2459 int channel_num2 = voe_.GetLastChannel();
2460 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2461 int channel_num3 = voe_.GetLastChannel();
2462 // Create packets with the right SSRCs.
2463 char packets[4][sizeof(kPcmuFrame)];
2464 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2465 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002466 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002467 }
2468 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2469 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2470 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2471 DeliverPacket(packets[0], sizeof(packets[0]));
2472 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2473 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2474 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2475 DeliverPacket(packets[1], sizeof(packets[1]));
2476 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2477 sizeof(packets[1])));
2478 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2479 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2480 DeliverPacket(packets[2], sizeof(packets[2]));
2481 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2482 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2483 sizeof(packets[2])));
2484 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2485 DeliverPacket(packets[3], sizeof(packets[3]));
2486 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2487 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2488 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2489 sizeof(packets[3])));
2490 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2491 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2492 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2493}
2494
2495// Test that we properly handle failures to add a stream.
2496TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2497 EXPECT_TRUE(SetupEngine());
2498 voe_.set_fail_create_channel(true);
2499 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2500 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2501
2502 // In 1:1 call, we should not try to create a new channel.
2503 cricket::AudioOptions options_no_conference_;
2504 options_no_conference_.conference_mode.Set(false);
2505 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2506 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2507}
2508
2509// Test that AddRecvStream doesn't create new channel for 1:1 call.
2510TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2511 EXPECT_TRUE(SetupEngine());
2512 int channel_num = voe_.GetLastChannel();
2513 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2514 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2515}
2516
2517// Test that after adding a recv stream, we do not decode more codecs than
2518// those previously passed into SetRecvCodecs.
2519TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2520 EXPECT_TRUE(SetupEngine());
2521 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2522 std::vector<cricket::AudioCodec> codecs;
2523 codecs.push_back(kIsacCodec);
2524 codecs.push_back(kPcmuCodec);
2525 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2526 EXPECT_TRUE(channel_->AddRecvStream(
2527 cricket::StreamParams::CreateLegacy(kSsrc1)));
2528 int channel_num2 = voe_.GetLastChannel();
2529 webrtc::CodecInst gcodec;
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002530 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "opus");
2531 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002532 gcodec.channels = 2;
2533 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2534}
2535
2536// Test that we properly clean up any streams that were added, even if
2537// not explicitly removed.
2538TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2539 EXPECT_TRUE(SetupEngine());
2540 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2541 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2542 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2543 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2544 delete channel_;
2545 channel_ = NULL;
2546 EXPECT_EQ(0, voe_.GetNumChannels());
2547}
2548
wu@webrtc.org78187522013-10-07 23:32:02 +00002549TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2550 EXPECT_TRUE(SetupEngine());
2551 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2552}
2553
2554TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2555 EXPECT_TRUE(SetupEngine());
2556 // Stream 1 reuses default channel.
2557 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2558 // Manually delete default channel to simulate a failure.
2559 int default_channel = voe_.GetLastChannel();
2560 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2561 // Add recv stream 2 should fail because default channel is gone.
2562 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2563 int new_channel = voe_.GetLastChannel();
2564 EXPECT_NE(default_channel, new_channel);
2565 // The last created channel should have already been deleted.
2566 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2567}
2568
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002569// Test the InsertDtmf on default send stream as caller.
2570TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2571 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002572}
2573
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002574// Test the InsertDtmf on default send stream as callee
2575TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2576 TestInsertDtmf(0, false);
2577}
2578
2579// Test the InsertDtmf on specified send stream as caller.
2580TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2581 TestInsertDtmf(kSsrc1, true);
2582}
2583
2584// Test the InsertDtmf on specified send stream as callee.
2585TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2586 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002587}
2588
2589// Test that we can play a ringback tone properly in a single-stream call.
2590TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2591 EXPECT_TRUE(SetupEngine());
2592 int channel_num = voe_.GetLastChannel();
2593 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2594 // Check we fail if no ringback tone specified.
2595 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2596 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2597 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002598 EXPECT_TRUE(channel_->SetRingbackTone(
2599 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002600 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2601 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2602 // Check we can stop the tone manually.
2603 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2604 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2605 // Check we stop the tone if a packet arrives.
2606 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2607 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2608 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2609 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2610}
2611
2612// Test that we can play a ringback tone properly in a multi-stream call.
2613TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2614 EXPECT_TRUE(SetupEngine());
2615 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2616 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2617 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2618 int channel_num = voe_.GetLastChannel();
2619 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2620 // Check we fail if no ringback tone specified.
2621 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2622 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2623 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002624 EXPECT_TRUE(channel_->SetRingbackTone(
2625 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002626 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2627 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2628 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2629 // Check we can stop the tone manually.
2630 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2631 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2632 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2633 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2634 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2635 // Send a packet with SSRC 1; the tone should not stop.
2636 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2637 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2638 // Send a packet with SSRC 2; the tone should stop.
2639 char packet[sizeof(kPcmuFrame)];
2640 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002641 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002642 DeliverPacket(packet, sizeof(packet));
2643 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2644}
2645
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002646TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002647 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002648 cricket::WebRtcVoiceMediaChannel* media_channel;
2649 unsigned int ssrc = 0;
2650
2651 EXPECT_TRUE(SetupEngine());
2652 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2653 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2654
2655 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2656 listener.reset(new ChannelErrorListener(channel_));
2657
2658 // Test on WebRtc VoE channel.
2659 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2660 VE_SATURATION_WARNING);
2661 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2662 listener->error());
2663 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2664 EXPECT_EQ(ssrc, listener->ssrc());
2665
2666 listener->Reset();
2667 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2668 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2669 listener->error());
2670 EXPECT_EQ(0U, listener->ssrc());
2671
2672 // Add another stream and test on that.
2673 ++ssrc;
2674 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2675 ssrc)));
2676 listener->Reset();
2677 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2678 VE_SATURATION_WARNING);
2679 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2680 listener->error());
2681 EXPECT_EQ(ssrc, listener->ssrc());
2682
2683 // Testing a non-existing channel.
2684 listener->Reset();
2685 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2686 VE_SATURATION_WARNING);
2687 EXPECT_EQ(0, listener->error());
2688}
2689
2690TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2691 EXPECT_TRUE(SetupEngine());
2692 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2693 std::vector<cricket::AudioCodec> codecs;
2694 codecs.push_back(kPcmuCodec);
2695 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2696 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2697 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2698 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2699 EXPECT_TRUE(channel_->SetPlayout(true));
2700 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2701 EXPECT_TRUE(channel_->SetPlayout(false));
2702 EXPECT_FALSE(channel_->SetPlayout(true));
2703}
2704
2705// Test that the Registering/Unregistering with the
2706// webrtcvoiceengine works as expected
2707TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2708 EXPECT_TRUE(SetupEngine());
2709 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2710 EXPECT_TRUE(channel_->AddRecvStream(
2711 cricket::StreamParams::CreateLegacy(kSsrc2)));
2712 cricket::FakeMediaProcessor vp_1;
2713 cricket::FakeMediaProcessor vp_2;
2714
2715 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2716 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2717 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2718 voe_.TriggerProcessPacket(cricket::MPD_RX);
2719 voe_.TriggerProcessPacket(cricket::MPD_TX);
2720
2721 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2722 EXPECT_EQ(1, vp_1.voice_frame_count());
2723 EXPECT_EQ(1, vp_2.voice_frame_count());
2724
2725 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2726 &vp_2,
2727 cricket::MPD_RX));
2728 voe_.TriggerProcessPacket(cricket::MPD_RX);
2729 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2730 EXPECT_EQ(1, vp_2.voice_frame_count());
2731 EXPECT_EQ(2, vp_1.voice_frame_count());
2732
2733 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2734 &vp_1,
2735 cricket::MPD_RX));
2736 voe_.TriggerProcessPacket(cricket::MPD_RX);
2737 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2738 EXPECT_EQ(2, vp_1.voice_frame_count());
2739
2740 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2741 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2742 voe_.TriggerProcessPacket(cricket::MPD_RX);
2743 voe_.TriggerProcessPacket(cricket::MPD_TX);
2744 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2745 EXPECT_EQ(3, vp_1.voice_frame_count());
2746
2747 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2748 &vp_1,
2749 cricket::MPD_RX_AND_TX));
2750 voe_.TriggerProcessPacket(cricket::MPD_TX);
2751 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2752 EXPECT_EQ(3, vp_1.voice_frame_count());
2753 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2754 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2755 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2756
2757 // Test that we can register a processor on the receive channel on SSRC 0.
2758 // This tests the 1:1 case when the receive SSRC is unknown.
2759 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2760 voe_.TriggerProcessPacket(cricket::MPD_RX);
2761 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2762 EXPECT_EQ(4, vp_1.voice_frame_count());
2763 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2764 &vp_1,
2765 cricket::MPD_RX));
2766
2767 // The following tests test that FindChannelNumFromSsrc is doing
2768 // what we expect.
2769 // pick an invalid ssrc and make sure we can't register
2770 EXPECT_FALSE(engine_.RegisterProcessor(99,
2771 &vp_1,
2772 cricket::MPD_RX));
2773 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2774 EXPECT_TRUE(engine_.RegisterProcessor(1,
2775 &vp_1,
2776 cricket::MPD_RX));
2777 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2778 &vp_1,
2779 cricket::MPD_RX));
2780 EXPECT_FALSE(engine_.RegisterProcessor(1,
2781 &vp_1,
2782 cricket::MPD_TX));
2783 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2784}
2785
2786TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2787 EXPECT_TRUE(SetupEngine());
2788
2789 bool ec_enabled;
2790 webrtc::EcModes ec_mode;
2791 bool ec_metrics_enabled;
2792 webrtc::AecmModes aecm_mode;
2793 bool cng_enabled;
2794 bool agc_enabled;
2795 webrtc::AgcModes agc_mode;
2796 webrtc::AgcConfig agc_config;
2797 bool ns_enabled;
2798 webrtc::NsModes ns_mode;
2799 bool highpass_filter_enabled;
2800 bool stereo_swapping_enabled;
2801 bool typing_detection_enabled;
2802 voe_.GetEcStatus(ec_enabled, ec_mode);
2803 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2804 voe_.GetAecmMode(aecm_mode, cng_enabled);
2805 voe_.GetAgcStatus(agc_enabled, agc_mode);
2806 voe_.GetAgcConfig(agc_config);
2807 voe_.GetNsStatus(ns_enabled, ns_mode);
2808 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2809 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2810 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2811 EXPECT_TRUE(ec_enabled);
2812 EXPECT_TRUE(ec_metrics_enabled);
2813 EXPECT_FALSE(cng_enabled);
2814 EXPECT_TRUE(agc_enabled);
2815 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2816 EXPECT_TRUE(ns_enabled);
2817 EXPECT_TRUE(highpass_filter_enabled);
2818 EXPECT_FALSE(stereo_swapping_enabled);
2819 EXPECT_TRUE(typing_detection_enabled);
2820 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2821 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2822
2823 // Nothing set, so all ignored.
2824 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002825 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002826 voe_.GetEcStatus(ec_enabled, ec_mode);
2827 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2828 voe_.GetAecmMode(aecm_mode, cng_enabled);
2829 voe_.GetAgcStatus(agc_enabled, agc_mode);
2830 voe_.GetAgcConfig(agc_config);
2831 voe_.GetNsStatus(ns_enabled, ns_mode);
2832 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2833 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2834 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2835 EXPECT_TRUE(ec_enabled);
2836 EXPECT_TRUE(ec_metrics_enabled);
2837 EXPECT_FALSE(cng_enabled);
2838 EXPECT_TRUE(agc_enabled);
2839 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2840 EXPECT_TRUE(ns_enabled);
2841 EXPECT_TRUE(highpass_filter_enabled);
2842 EXPECT_FALSE(stereo_swapping_enabled);
2843 EXPECT_TRUE(typing_detection_enabled);
2844 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2845 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
Henrik Lundin64dad832015-05-11 12:44:23 +02002846 EXPECT_EQ(50, voe_.GetNetEqCapacity()); // From GetDefaultEngineOptions().
Henrik Lundin5263b3c2015-06-01 10:29:41 +02002847 EXPECT_FALSE(
2848 voe_.GetNetEqFastAccelerate()); // From GetDefaultEngineOptions().
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002849
2850 // Turn echo cancellation off
2851 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002852 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002853 voe_.GetEcStatus(ec_enabled, ec_mode);
2854 EXPECT_FALSE(ec_enabled);
2855
2856 // Turn echo cancellation back on, with settings, and make sure
2857 // nothing else changed.
2858 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002859 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002860 voe_.GetEcStatus(ec_enabled, ec_mode);
2861 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2862 voe_.GetAecmMode(aecm_mode, cng_enabled);
2863 voe_.GetAgcStatus(agc_enabled, agc_mode);
2864 voe_.GetAgcConfig(agc_config);
2865 voe_.GetNsStatus(ns_enabled, ns_mode);
2866 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2867 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2868 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2869 EXPECT_TRUE(ec_enabled);
2870 EXPECT_TRUE(ec_metrics_enabled);
2871 EXPECT_TRUE(agc_enabled);
2872 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2873 EXPECT_TRUE(ns_enabled);
2874 EXPECT_TRUE(highpass_filter_enabled);
2875 EXPECT_FALSE(stereo_swapping_enabled);
2876 EXPECT_TRUE(typing_detection_enabled);
2877 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2878 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2879
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002880 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2881 // control.
2882 options.delay_agnostic_aec.Set(true);
2883 ASSERT_TRUE(engine_.SetOptions(options));
2884 voe_.GetEcStatus(ec_enabled, ec_mode);
2885 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2886 voe_.GetAecmMode(aecm_mode, cng_enabled);
2887 EXPECT_TRUE(ec_enabled);
2888 EXPECT_TRUE(ec_metrics_enabled);
2889 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2890
2891 // Turn off echo cancellation and delay agnostic aec.
2892 options.delay_agnostic_aec.Set(false);
Henrik Lundin441f6342015-06-09 16:03:13 +02002893 options.extended_filter_aec.Set(false);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002894 options.echo_cancellation.Set(false);
2895 ASSERT_TRUE(engine_.SetOptions(options));
2896 voe_.GetEcStatus(ec_enabled, ec_mode);
2897 EXPECT_FALSE(ec_enabled);
2898 // Turning delay agnostic aec back on should also turn on echo cancellation.
2899 options.delay_agnostic_aec.Set(true);
2900 ASSERT_TRUE(engine_.SetOptions(options));
2901 voe_.GetEcStatus(ec_enabled, ec_mode);
2902 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2903 EXPECT_TRUE(ec_enabled);
2904 EXPECT_TRUE(ec_metrics_enabled);
2905 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2906
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907 // Turn off AGC
2908 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002909 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910 voe_.GetAgcStatus(agc_enabled, agc_mode);
2911 EXPECT_FALSE(agc_enabled);
2912
2913 // Turn AGC back on
2914 options.auto_gain_control.Set(true);
2915 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002916 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002917 voe_.GetAgcStatus(agc_enabled, agc_mode);
2918 EXPECT_TRUE(agc_enabled);
2919 voe_.GetAgcConfig(agc_config);
2920 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2921
2922 // Turn off other options (and stereo swapping on).
2923 options.noise_suppression.Set(false);
2924 options.highpass_filter.Set(false);
2925 options.typing_detection.Set(false);
2926 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002927 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002928 voe_.GetNsStatus(ns_enabled, ns_mode);
2929 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2930 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2931 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2932 EXPECT_FALSE(ns_enabled);
2933 EXPECT_FALSE(highpass_filter_enabled);
2934 EXPECT_FALSE(typing_detection_enabled);
2935 EXPECT_TRUE(stereo_swapping_enabled);
2936
2937 // Turn on "conference mode" to ensure it has no impact.
2938 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002939 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002940 voe_.GetEcStatus(ec_enabled, ec_mode);
2941 voe_.GetNsStatus(ns_enabled, ns_mode);
2942 EXPECT_TRUE(ec_enabled);
2943 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2944 EXPECT_FALSE(ns_enabled);
2945 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2946}
2947
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002948TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002949 EXPECT_TRUE(SetupEngine());
2950
2951 bool ec_enabled;
2952 webrtc::EcModes ec_mode;
2953 bool ec_metrics_enabled;
2954 bool agc_enabled;
2955 webrtc::AgcModes agc_mode;
2956 bool ns_enabled;
2957 webrtc::NsModes ns_mode;
2958 bool highpass_filter_enabled;
2959 bool stereo_swapping_enabled;
2960 bool typing_detection_enabled;
2961
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002962 voe_.GetEcStatus(ec_enabled, ec_mode);
2963 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2964 voe_.GetAgcStatus(agc_enabled, agc_mode);
2965 voe_.GetNsStatus(ns_enabled, ns_mode);
2966 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2967 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2968 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2969 EXPECT_TRUE(ec_enabled);
2970 EXPECT_TRUE(agc_enabled);
2971 EXPECT_TRUE(ns_enabled);
2972 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002973 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002974 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002975}
2976
2977TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2978 webrtc::AgcConfig set_config = {0};
2979 set_config.targetLeveldBOv = 3;
2980 set_config.digitalCompressionGaindB = 9;
2981 set_config.limiterEnable = true;
2982 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002983 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002984
2985 webrtc::AgcConfig config = {0};
2986 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2987 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2988 EXPECT_EQ(set_config.digitalCompressionGaindB,
2989 config.digitalCompressionGaindB);
2990 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2991}
2992
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002993TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2994 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002995 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
Jelena Marusicc28a8962015-05-29 15:05:44 +02002996 engine_.CreateChannel(cricket::AudioOptions()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002997 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
Jelena Marusicc28a8962015-05-29 15:05:44 +02002998 engine_.CreateChannel(cricket::AudioOptions()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
3000 // Have to add a stream to make SetSend work.
3001 cricket::StreamParams stream1;
3002 stream1.ssrcs.push_back(1);
3003 channel1->AddSendStream(stream1);
3004 cricket::StreamParams stream2;
3005 stream2.ssrcs.push_back(2);
3006 channel2->AddSendStream(stream2);
3007
3008 // AEC and AGC and NS
3009 cricket::AudioOptions options_all;
3010 options_all.echo_cancellation.Set(true);
3011 options_all.auto_gain_control.Set(true);
3012 options_all.noise_suppression.Set(true);
3013
3014 ASSERT_TRUE(channel1->SetOptions(options_all));
3015 cricket::AudioOptions expected_options = options_all;
3016 cricket::AudioOptions actual_options;
3017 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3018 EXPECT_EQ(expected_options, actual_options);
3019 ASSERT_TRUE(channel2->SetOptions(options_all));
3020 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3021 EXPECT_EQ(expected_options, actual_options);
3022
3023 // unset NS
3024 cricket::AudioOptions options_no_ns;
3025 options_no_ns.noise_suppression.Set(false);
3026 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
3027
3028 expected_options.echo_cancellation.Set(true);
3029 expected_options.auto_gain_control.Set(true);
3030 expected_options.noise_suppression.Set(false);
3031 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3032 EXPECT_EQ(expected_options, actual_options);
3033
3034 // unset AGC
3035 cricket::AudioOptions options_no_agc;
3036 options_no_agc.auto_gain_control.Set(false);
3037 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
3038
3039 expected_options.echo_cancellation.Set(true);
3040 expected_options.auto_gain_control.Set(false);
3041 expected_options.noise_suppression.Set(true);
3042 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3043 EXPECT_EQ(expected_options, actual_options);
3044
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003045 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046 bool ec_enabled;
3047 webrtc::EcModes ec_mode;
3048 bool agc_enabled;
3049 webrtc::AgcModes agc_mode;
3050 bool ns_enabled;
3051 webrtc::NsModes ns_mode;
3052 voe_.GetEcStatus(ec_enabled, ec_mode);
3053 voe_.GetAgcStatus(agc_enabled, agc_mode);
3054 voe_.GetNsStatus(ns_enabled, ns_mode);
3055 EXPECT_TRUE(ec_enabled);
3056 EXPECT_TRUE(agc_enabled);
3057 EXPECT_TRUE(ns_enabled);
3058
3059 channel1->SetSend(cricket::SEND_MICROPHONE);
3060 voe_.GetEcStatus(ec_enabled, ec_mode);
3061 voe_.GetAgcStatus(agc_enabled, agc_mode);
3062 voe_.GetNsStatus(ns_enabled, ns_mode);
3063 EXPECT_TRUE(ec_enabled);
3064 EXPECT_TRUE(agc_enabled);
3065 EXPECT_FALSE(ns_enabled);
3066
3067 channel1->SetSend(cricket::SEND_NOTHING);
3068 voe_.GetEcStatus(ec_enabled, ec_mode);
3069 voe_.GetAgcStatus(agc_enabled, agc_mode);
3070 voe_.GetNsStatus(ns_enabled, ns_mode);
3071 EXPECT_TRUE(ec_enabled);
3072 EXPECT_TRUE(agc_enabled);
3073 EXPECT_TRUE(ns_enabled);
3074
3075 channel2->SetSend(cricket::SEND_MICROPHONE);
3076 voe_.GetEcStatus(ec_enabled, ec_mode);
3077 voe_.GetAgcStatus(agc_enabled, agc_mode);
3078 voe_.GetNsStatus(ns_enabled, ns_mode);
3079 EXPECT_TRUE(ec_enabled);
3080 EXPECT_FALSE(agc_enabled);
3081 EXPECT_TRUE(ns_enabled);
3082
3083 channel2->SetSend(cricket::SEND_NOTHING);
3084 voe_.GetEcStatus(ec_enabled, ec_mode);
3085 voe_.GetAgcStatus(agc_enabled, agc_mode);
3086 voe_.GetNsStatus(ns_enabled, ns_mode);
3087 EXPECT_TRUE(ec_enabled);
3088 EXPECT_TRUE(agc_enabled);
3089 EXPECT_TRUE(ns_enabled);
3090
3091 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003092 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003093 cricket::AudioOptions options_no_agc_nor_ns;
3094 options_no_agc_nor_ns.auto_gain_control.Set(false);
3095 options_no_agc_nor_ns.noise_suppression.Set(false);
3096 channel2->SetSend(cricket::SEND_MICROPHONE);
3097 channel2->SetOptions(options_no_agc_nor_ns);
3098
3099 expected_options.echo_cancellation.Set(true);
3100 expected_options.auto_gain_control.Set(false);
3101 expected_options.noise_suppression.Set(false);
3102 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3103 EXPECT_EQ(expected_options, actual_options);
3104 voe_.GetEcStatus(ec_enabled, ec_mode);
3105 voe_.GetAgcStatus(agc_enabled, agc_mode);
3106 voe_.GetNsStatus(ns_enabled, ns_mode);
3107 EXPECT_TRUE(ec_enabled);
3108 EXPECT_FALSE(agc_enabled);
3109 EXPECT_FALSE(ns_enabled);
3110}
3111
wu@webrtc.orgde305012013-10-31 15:40:38 +00003112// This test verifies DSCP settings are properly applied on voice media channel.
3113TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3114 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003115 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
Jelena Marusicc28a8962015-05-29 15:05:44 +02003116 engine_.CreateChannel(cricket::AudioOptions()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003117 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003118 new cricket::FakeNetworkInterface);
3119 channel->SetInterface(network_interface.get());
3120 cricket::AudioOptions options;
3121 options.dscp.Set(true);
3122 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003123 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003124 // Verify previous value is not modified if dscp option is not set.
3125 cricket::AudioOptions options1;
3126 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003127 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003128 options.dscp.Set(false);
3129 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003130 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003131}
3132
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003133// Test that GetReceiveChannelNum returns the default channel for the first
3134// recv stream in 1-1 calls.
3135TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3136 EXPECT_TRUE(SetupEngine());
3137 cricket::WebRtcVoiceMediaChannel* media_channel =
3138 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3139 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3140 EXPECT_EQ(media_channel->voe_channel(),
3141 media_channel->GetReceiveChannelNum(0));
3142 cricket::StreamParams stream;
3143 stream.ssrcs.push_back(kSsrc2);
3144 EXPECT_TRUE(channel_->AddRecvStream(stream));
3145 EXPECT_EQ(media_channel->voe_channel(),
3146 media_channel->GetReceiveChannelNum(kSsrc2));
3147}
3148
3149// Test that GetReceiveChannelNum doesn't return the default channel for the
3150// first recv stream in conference calls.
3151TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3152 EXPECT_TRUE(SetupEngine());
3153 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3154 cricket::StreamParams stream;
3155 stream.ssrcs.push_back(kSsrc2);
3156 EXPECT_TRUE(channel_->AddRecvStream(stream));
3157 cricket::WebRtcVoiceMediaChannel* media_channel =
3158 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3159 EXPECT_LT(media_channel->voe_channel(),
3160 media_channel->GetReceiveChannelNum(kSsrc2));
3161}
3162
3163TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3164 EXPECT_TRUE(SetupEngine());
solenbergbb741b32015-09-07 03:56:38 -07003165 float scale, left, right;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003166 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
solenbergbb741b32015-09-07 03:56:38 -07003167 int channel_id = voe_.GetLastChannel();
3168 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
3169 EXPECT_EQ(0, voe_.GetOutputVolumePan(channel_id, left, right));
3170 EXPECT_DOUBLE_EQ(1, left * scale);
3171 EXPECT_DOUBLE_EQ(2, right * scale);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003172
3173 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3174 cricket::StreamParams stream;
3175 stream.ssrcs.push_back(kSsrc2);
3176 EXPECT_TRUE(channel_->AddRecvStream(stream));
3177
3178 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
solenbergbb741b32015-09-07 03:56:38 -07003179 channel_id = voe_.GetLastChannel();
3180 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
3181 EXPECT_EQ(0, voe_.GetOutputVolumePan(channel_id, left, right));
3182 EXPECT_DOUBLE_EQ(2, left * scale);
3183 EXPECT_DOUBLE_EQ(1, right * scale);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003184}
3185
pbos8fc7fa72015-07-15 08:02:58 -07003186TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
solenberg4fbae2b2015-08-28 04:07:10 -07003187 cricket::FakeCall call((webrtc::Call::Config()));
pbos8fc7fa72015-07-15 08:02:58 -07003188 const uint32 kAudioSsrc = 123;
3189 const std::string kSyncLabel = "AvSyncLabel";
3190
3191 EXPECT_TRUE(SetupEngine());
3192 cricket::WebRtcVoiceMediaChannel* media_channel =
3193 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3194 media_channel->SetCall(&call);
3195 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3196 sp.sync_label = kSyncLabel;
3197 // Creating two channels to make sure that sync label is set properly for both
3198 // the default voice channel and following ones.
3199 EXPECT_TRUE(channel_->AddRecvStream(sp));
3200 sp.ssrcs[0] += 1;
3201 EXPECT_TRUE(channel_->AddRecvStream(sp));
3202
3203 ASSERT_EQ(2, call.GetAudioReceiveStreams().size());
3204 EXPECT_EQ(kSyncLabel,
3205 call.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
3206 << "SyncGroup should be set based on sync_label";
3207 EXPECT_EQ(kSyncLabel,
3208 call.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
3209 << "SyncGroup should be set based on sync_label";
3210
3211 media_channel->SetCall(nullptr);
3212}
3213
pbos6bb1b6e2015-07-24 07:10:18 -07003214TEST_F(WebRtcVoiceEngineTestFake, CanChangeCombinedBweOption) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003215 // Test that changing the combined_audio_video_bwe option results in the
3216 // expected state changes on an associated Call.
solenberg4fbae2b2015-08-28 04:07:10 -07003217 cricket::FakeCall call((webrtc::Call::Config()));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003218 const uint32 kAudioSsrc1 = 223;
3219 const uint32 kAudioSsrc2 = 224;
3220
3221 EXPECT_TRUE(SetupEngine());
3222 cricket::WebRtcVoiceMediaChannel* media_channel =
3223 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
pbos8fc7fa72015-07-15 08:02:58 -07003224 const auto& rtp_extensions = engine_.rtp_header_extensions();
3225 media_channel->SetRecvRtpHeaderExtensions(rtp_extensions);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003226 media_channel->SetCall(&call);
3227 EXPECT_TRUE(media_channel->AddRecvStream(
3228 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3229 EXPECT_TRUE(media_channel->AddRecvStream(
3230 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3231
pbos6bb1b6e2015-07-24 07:10:18 -07003232 // Combined BWE should not be set up yet.
pbos8fc7fa72015-07-15 08:02:58 -07003233 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
pbos6bb1b6e2015-07-24 07:10:18 -07003234 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc1)
3235 ->GetConfig()
3236 .combined_audio_video_bwe);
3237 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc2)
3238 ->GetConfig()
3239 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003240
3241 // Enable combined BWE option - now it should be set up.
3242 cricket::AudioOptions options;
3243 options.combined_audio_video_bwe.Set(true);
3244 EXPECT_TRUE(media_channel->SetOptions(options));
3245 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
pbos6bb1b6e2015-07-24 07:10:18 -07003246 EXPECT_TRUE(call.GetAudioReceiveStream(kAudioSsrc1)
3247 ->GetConfig()
3248 .combined_audio_video_bwe);
3249 EXPECT_TRUE(call.GetAudioReceiveStream(kAudioSsrc2)
3250 ->GetConfig()
3251 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003252
3253 // Disable combined BWE option - should be disabled again.
3254 options.combined_audio_video_bwe.Set(false);
3255 EXPECT_TRUE(media_channel->SetOptions(options));
pbos8fc7fa72015-07-15 08:02:58 -07003256 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
pbos6bb1b6e2015-07-24 07:10:18 -07003257 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc1)
3258 ->GetConfig()
3259 .combined_audio_video_bwe);
3260 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc2)
3261 ->GetConfig()
3262 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003263
3264 media_channel->SetCall(nullptr);
3265}
3266
pbos6bb1b6e2015-07-24 07:10:18 -07003267TEST_F(WebRtcVoiceEngineTestFake, SetCallConfiguresAudioReceiveChannels) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003268 // Test that calling SetCall() on the voice media channel results in the
3269 // expected state changes in Call.
solenberg4fbae2b2015-08-28 04:07:10 -07003270 cricket::FakeCall call((webrtc::Call::Config()));
3271 cricket::FakeCall call2((webrtc::Call::Config()));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 const uint32 kAudioSsrc1 = 223;
3273 const uint32 kAudioSsrc2 = 224;
3274
3275 EXPECT_TRUE(SetupEngine());
3276 cricket::WebRtcVoiceMediaChannel* media_channel =
3277 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003278 EXPECT_TRUE(media_channel->AddRecvStream(
3279 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3280 EXPECT_TRUE(media_channel->AddRecvStream(
3281 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3282
3283 // Combined BWE should not be set up yet.
3284 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3285
3286 // Register - should be enabled.
3287 media_channel->SetCall(&call);
3288 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3289 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc1));
3290 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc2));
3291
3292 // Re-register - should now be enabled on new call.
3293 media_channel->SetCall(&call2);
3294 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3295 EXPECT_EQ(2, call2.GetAudioReceiveStreams().size());
3296 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc1));
3297 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc2));
3298
3299 // Unregister - should be disabled again.
3300 media_channel->SetCall(nullptr);
3301 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3302}
3303
pbos6bb1b6e2015-07-24 07:10:18 -07003304TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003305 // Test that adding receive streams after enabling combined bandwidth
3306 // estimation will correctly configure each channel.
solenberg4fbae2b2015-08-28 04:07:10 -07003307 cricket::FakeCall call((webrtc::Call::Config()));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003308
3309 EXPECT_TRUE(SetupEngine());
3310 cricket::WebRtcVoiceMediaChannel* media_channel =
3311 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3312 media_channel->SetCall(&call);
3313 cricket::AudioOptions options;
3314 options.combined_audio_video_bwe.Set(true);
3315 EXPECT_TRUE(media_channel->SetOptions(options));
3316
3317 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3318 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3319 EXPECT_TRUE(media_channel->AddRecvStream(
3320 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3321 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kSsrcs[i]));
pbos6bb1b6e2015-07-24 07:10:18 -07003322 EXPECT_TRUE(call.GetAudioReceiveStream(kSsrcs[i])
3323 ->GetConfig()
3324 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003325 }
3326 EXPECT_EQ(ARRAY_SIZE(kSsrcs), call.GetAudioReceiveStreams().size());
3327
3328 media_channel->SetCall(nullptr);
3329 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3330}
3331
pbos6bb1b6e2015-07-24 07:10:18 -07003332TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003333 // Test that setting the header extensions results in the expected state
3334 // changes on an associated Call.
solenberg4fbae2b2015-08-28 04:07:10 -07003335 cricket::FakeCall call((webrtc::Call::Config()));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003336 std::vector<uint32> ssrcs;
3337 ssrcs.push_back(223);
3338 ssrcs.push_back(224);
3339
3340 EXPECT_TRUE(SetupEngine());
3341 cricket::WebRtcVoiceMediaChannel* media_channel =
3342 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3343 media_channel->SetCall(&call);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003344 for (uint32 ssrc : ssrcs) {
3345 EXPECT_TRUE(media_channel->AddRecvStream(
3346 cricket::StreamParams::CreateLegacy(ssrc)));
3347 }
3348
3349 // Combined BWE should be set up, but with no configured extensions.
3350 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3351 for (uint32 ssrc : ssrcs) {
3352 const auto* s = call.GetAudioReceiveStream(ssrc);
3353 EXPECT_NE(nullptr, s);
3354 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3355 }
3356
3357 // Set up receive extensions.
3358 const auto& e_exts = engine_.rtp_header_extensions();
3359 channel_->SetRecvRtpHeaderExtensions(e_exts);
3360 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3361 for (uint32 ssrc : ssrcs) {
3362 const auto* s = call.GetAudioReceiveStream(ssrc);
3363 EXPECT_NE(nullptr, s);
3364 const auto& s_exts = s->GetConfig().rtp.extensions;
3365 EXPECT_EQ(e_exts.size(), s_exts.size());
3366 for (const auto& e_ext : e_exts) {
3367 for (const auto& s_ext : s_exts) {
3368 if (e_ext.id == s_ext.id) {
3369 EXPECT_EQ(e_ext.uri, s_ext.name);
3370 }
3371 }
3372 }
3373 }
3374
3375 // Disable receive extensions.
3376 std::vector<cricket::RtpHeaderExtension> extensions;
3377 channel_->SetRecvRtpHeaderExtensions(extensions);
3378 for (uint32 ssrc : ssrcs) {
3379 const auto* s = call.GetAudioReceiveStream(ssrc);
3380 EXPECT_NE(nullptr, s);
3381 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3382 }
3383
3384 media_channel->SetCall(nullptr);
3385}
3386
3387TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3388 // Test that packets are forwarded to the Call when configured accordingly.
solenberg4fbae2b2015-08-28 04:07:10 -07003389 cricket::FakeCall call((webrtc::Call::Config()));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003390 const uint32 kAudioSsrc = 1;
3391 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3392 static const unsigned char kRtcp[] = {
3393 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3394 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3397 };
3398 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3399
3400 EXPECT_TRUE(SetupEngine());
3401 cricket::WebRtcVoiceMediaChannel* media_channel =
3402 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3403 cricket::AudioOptions options;
3404 options.combined_audio_video_bwe.Set(true);
3405 EXPECT_TRUE(media_channel->SetOptions(options));
3406 EXPECT_TRUE(media_channel->AddRecvStream(
3407 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3408
3409 // Call not set on media channel, so no packets can be forwarded.
3410 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3411 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3412 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3413 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3414
3415 // Set Call, now there should be a receive stream which is forwarded packets.
3416 media_channel->SetCall(&call);
3417 EXPECT_EQ(1, call.GetAudioReceiveStreams().size());
3418 const cricket::FakeAudioReceiveStream* s =
3419 call.GetAudioReceiveStream(kAudioSsrc);
3420 EXPECT_EQ(0, s->received_packets());
3421 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3422 EXPECT_EQ(1, s->received_packets());
3423 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3424 EXPECT_EQ(2, s->received_packets());
3425
3426 media_channel->SetCall(nullptr);
3427}
Minyue2013aec2015-05-13 14:14:42 +02003428
3429// Associate channel should not set on 1:1 call, since the receive channel also
3430// sends RTCP SR.
3431TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelUnset1On1) {
3432 EXPECT_TRUE(SetupEngine());
3433 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3434 int recv_ch = voe_.GetLastChannel();
3435 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3436}
3437
3438// This test is an extension of AssociateChannelUnset1On1. We create two receive
3439// channels. The second should be associated with the default channel, since it
3440// does not send RTCP SR.
3441TEST_F(WebRtcVoiceEngineTestFake, AssociateDefaultChannelOnSecondRecvChannel) {
3442 EXPECT_TRUE(SetupEngine());
3443 cricket::WebRtcVoiceMediaChannel* media_channel =
3444 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3445 int default_channel = media_channel->voe_channel();
3446 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3447 int recv_ch_1 = voe_.GetLastChannel();
3448 EXPECT_EQ(recv_ch_1, default_channel);
3449 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
3450 int recv_ch_2 = voe_.GetLastChannel();
3451 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_1), -1);
3452 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_2), default_channel);
3453 // Add send stream, the association remains.
3454 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
3455 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_1), -1);
3456 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_2), default_channel);
3457}
3458
3459// In conference mode, all receive channels should be associated with the
3460// default channel, since they do not send RTCP SR.
3461TEST_F(WebRtcVoiceEngineTestFake, AssociateDefaultChannelOnConference) {
3462 EXPECT_TRUE(SetupEngine());
3463 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3464 cricket::WebRtcVoiceMediaChannel* media_channel =
3465 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3466 int default_channel = media_channel->voe_channel();
3467 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3468 int recv_ch = voe_.GetLastChannel();
3469 EXPECT_NE(recv_ch, default_channel);
3470 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3471 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3472 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3473}
3474
3475TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
3476 EXPECT_TRUE(SetupEngine());
3477 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3478
3479 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3480 int recv_ch = voe_.GetLastChannel();
3481
3482 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3483 int send_ch = voe_.GetLastChannel();
3484
3485 // Manually associate |recv_ch| to |send_ch|. This test is to verify a
3486 // deleting logic, i.e., deleting |send_ch| will reset the associate send
3487 // channel of |recv_ch|.This is not a common case, since, normally, only the
3488 // default channel can be associated. However, the default is not deletable.
3489 // So we force the |recv_ch| to associate with a non-default channel.
3490 EXPECT_EQ(0, voe_.AssociateSendChannel(recv_ch, send_ch));
3491 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), send_ch);
3492
3493 EXPECT_TRUE(channel_->RemoveSendStream(2));
3494 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3495}
stefan658910c2015-09-03 05:48:32 -07003496
3497// Tests for the actual WebRtc VoE library.
3498
3499TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3500 cricket::WebRtcVoiceEngine engine;
3501 cricket::AudioOptions options = engine.GetOptions();
3502 // The default options should have at least a few things set. We purposefully
3503 // don't check the option values here, though.
3504 EXPECT_TRUE(options.echo_cancellation.IsSet());
3505 EXPECT_TRUE(options.auto_gain_control.IsSet());
3506 EXPECT_TRUE(options.noise_suppression.IsSet());
3507}
3508
3509// Tests that the library initializes and shuts down properly.
3510TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3511 cricket::WebRtcVoiceEngine engine;
3512 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3513 cricket::VoiceMediaChannel* channel =
3514 engine.CreateChannel(cricket::AudioOptions());
3515 EXPECT_TRUE(channel != nullptr);
3516 delete channel;
3517 engine.Terminate();
3518
3519 // Reinit to catch regression where VoiceEngineObserver reference is lost
3520 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3521 engine.Terminate();
3522}
3523
3524// Tests that the library is configured with the codecs we want.
3525TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3526 cricket::WebRtcVoiceEngine engine;
3527 // Check codecs by name.
3528 EXPECT_TRUE(engine.FindCodec(
3529 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3530 EXPECT_TRUE(engine.FindCodec(
3531 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3532 EXPECT_TRUE(engine.FindCodec(
3533 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3534 // Check that name matching is case-insensitive.
3535 EXPECT_TRUE(engine.FindCodec(
3536 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3537 EXPECT_TRUE(engine.FindCodec(
3538 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3539 EXPECT_TRUE(engine.FindCodec(
3540 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3541 EXPECT_TRUE(engine.FindCodec(
3542 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3543 EXPECT_TRUE(engine.FindCodec(
3544 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0)));
3545 EXPECT_TRUE(engine.FindCodec(
3546 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
3547 EXPECT_TRUE(engine.FindCodec(
3548 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3549 EXPECT_TRUE(engine.FindCodec(
3550 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3551 EXPECT_TRUE(engine.FindCodec(
3552 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3553 EXPECT_TRUE(engine.FindCodec(
3554 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3555 // Check codecs with an id by id.
3556 EXPECT_TRUE(engine.FindCodec(
3557 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3558 EXPECT_TRUE(engine.FindCodec(
3559 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3560 EXPECT_TRUE(engine.FindCodec(
3561 cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722
3562 EXPECT_TRUE(engine.FindCodec(
3563 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3564 // Check sample/bitrate matching.
3565 EXPECT_TRUE(engine.FindCodec(
3566 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3567 // Check that bad codecs fail.
3568 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3569 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3570 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3571 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3572 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
3573 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3574 for (std::vector<cricket::AudioCodec>::const_iterator it =
3575 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3576 if (it->name == "CN" && it->clockrate == 16000) {
3577 EXPECT_EQ(105, it->id);
3578 } else if (it->name == "CN" && it->clockrate == 32000) {
3579 EXPECT_EQ(106, it->id);
3580 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3581 EXPECT_EQ(103, it->id);
3582 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3583 EXPECT_EQ(104, it->id);
3584 } else if (it->name == "G722" && it->clockrate == 8000) {
3585 EXPECT_EQ(9, it->id);
3586 } else if (it->name == "telephone-event") {
3587 EXPECT_EQ(126, it->id);
3588 } else if (it->name == "red") {
3589 EXPECT_EQ(127, it->id);
3590 } else if (it->name == "opus") {
3591 EXPECT_EQ(111, it->id);
3592 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3593 EXPECT_EQ("10", it->params.find("minptime")->second);
3594 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3595 EXPECT_EQ("60", it->params.find("maxptime")->second);
3596 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3597 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
3598 }
3599 }
3600
3601 engine.Terminate();
3602}
3603
3604// Tests that VoE supports at least 32 channels
3605TEST(WebRtcVoiceEngineTest, Has32Channels) {
3606 cricket::WebRtcVoiceEngine engine;
3607 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3608
3609 cricket::VoiceMediaChannel* channels[32];
3610 int num_channels = 0;
3611
3612 while (num_channels < ARRAY_SIZE(channels)) {
3613 cricket::VoiceMediaChannel* channel =
3614 engine.CreateChannel(cricket::AudioOptions());
3615 if (!channel)
3616 break;
3617
3618 channels[num_channels++] = channel;
3619 }
3620
3621 int expected = ARRAY_SIZE(channels);
3622 EXPECT_EQ(expected, num_channels);
3623
3624 while (num_channels > 0) {
3625 delete channels[--num_channels];
3626 }
3627
3628 engine.Terminate();
3629}
3630
3631// Test that we set our preferred codecs properly.
3632TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3633 cricket::WebRtcVoiceEngine engine;
3634 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3635 cricket::WebRtcVoiceMediaChannel channel(&engine);
3636 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3637}