blob: 5fcdf5b3d5182bb710ca6facaddfc31c09c8517e [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"
Fredrik Solenberg709ed672015-09-15 12:26:33 +020030#include "webrtc/call.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031#include "talk/media/base/constants.h"
32#include "talk/media/base/fakemediaengine.h"
33#include "talk/media/base/fakemediaprocessor.h"
wu@webrtc.orgde305012013-10-31 15:40:38 +000034#include "talk/media/base/fakenetworkinterface.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035#include "talk/media/base/fakertp.h"
Fredrik Solenberg4b60c732015-05-07 14:07:48 +020036#include "talk/media/webrtc/fakewebrtccall.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
38#include "talk/media/webrtc/webrtcvoiceengine.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039#include "webrtc/p2p/base/fakesession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040#include "talk/session/media/channel.h"
41
42// Tests for the WebRtcVoiceEngine/VoiceChannel code.
43
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000044using cricket::kRtpAudioLevelHeaderExtension;
45using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
46
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
48static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +000050static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
51static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
53static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
54static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
55static const cricket::AudioCodec
56 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
57static const cricket::AudioCodec* const kAudioCodecs[] = {
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +000058 &kPcmuCodec, &kIsacCodec, &kOpusCodec, &kG722CodecVoE, &kRedCodec,
59 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060};
61const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
62static uint32 kSsrc1 = 0x99;
63static uint32 kSsrc2 = 0x98;
64
65class FakeVoEWrapper : public cricket::VoEWrapper {
66 public:
67 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
68 : cricket::VoEWrapper(engine, // processing
69 engine, // base
70 engine, // codec
71 engine, // dtmf
72 engine, // file
73 engine, // hw
74 engine, // media
75 engine, // neteq
76 engine, // network
77 engine, // rtp
78 engine, // sync
79 engine) { // volume
80 }
81};
82
wu@webrtc.org97077a32013-10-25 21:18:33 +000083class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084 public:
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020085 int SetTraceFilter(const unsigned int filter) override {
wu@webrtc.org97077a32013-10-25 21:18:33 +000086 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 return 0;
88 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020089 int SetTraceFile(const char* fileNameUTF8) override { return 0; }
90 int SetTraceCallback(webrtc::TraceCallback* callback) override { return 0; }
wu@webrtc.org97077a32013-10-25 21:18:33 +000091 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092};
93
94class WebRtcVoiceEngineTestFake : public testing::Test {
95 public:
96 class ChannelErrorListener : public sigslot::has_slots<> {
97 public:
98 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
99 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
henrikg91d6ede2015-09-17 00:24:34 -0700100 RTC_DCHECK(channel != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101 channel->SignalMediaError.connect(
102 this, &ChannelErrorListener::OnVoiceChannelError);
103 }
104 void OnVoiceChannelError(uint32 ssrc,
105 cricket::VoiceMediaChannel::Error error) {
106 ssrc_ = ssrc;
107 error_ = error;
108 }
109 void Reset() {
110 ssrc_ = 0;
111 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
112 }
113 uint32 ssrc() const {
114 return ssrc_;
115 }
116 cricket::VoiceMediaChannel::Error error() const {
117 return error_;
118 }
119
120 private:
121 uint32 ssrc_;
122 cricket::VoiceMediaChannel::Error error_;
123 };
124
125 WebRtcVoiceEngineTestFake()
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200126 : call_(webrtc::Call::Config()),
127 voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000128 trace_wrapper_(new FakeVoETraceWrapper()),
Jelena Marusicc28a8962015-05-29 15:05:44 +0200129 engine_(new FakeVoEWrapper(&voe_), trace_wrapper_),
130 channel_(nullptr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131 options_conference_.conference_mode.Set(true);
132 options_adjust_agc_.adjust_agc_delta.Set(-10);
133 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000134 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000135 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000136 return false;
137 }
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200138 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200139 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000140 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000141 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000142 if (!SetupEngineWithoutStream()) {
143 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000144 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000145 return channel_->AddSendStream(
146 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000148 void SetupForMultiSendStream() {
149 EXPECT_TRUE(SetupEngine());
150 // Remove stream added in Setup, which is corresponding to default channel.
151 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000152 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000153 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
154 EXPECT_EQ(kSsrc1, default_send_ssrc);
155 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
156
157 // Verify the default channel still exists.
158 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
159 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 void DeliverPacket(const void* data, int len) {
Karl Wiberg94784372015-04-20 14:03:07 +0200161 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000162 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200164 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165 delete channel_;
166 engine_.Terminate();
167 }
168
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000169 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000170 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200171 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200172 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000173 if (caller) {
174 // if this is a caller, local description will be applied and add the
175 // send stream.
176 EXPECT_TRUE(channel_->AddSendStream(
177 cricket::StreamParams::CreateLegacy(kSsrc1)));
178 }
179 int channel_id = voe_.GetLastChannel();
180
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 // Test we can only InsertDtmf when the other side supports telephone-event.
182 std::vector<cricket::AudioCodec> codecs;
183 codecs.push_back(kPcmuCodec);
184 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
185 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
186 EXPECT_FALSE(channel_->CanInsertDtmf());
187 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
188 codecs.push_back(kTelephoneEventCodec);
189 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
190 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000191
192 if (!caller) {
193 // There's no active send channel yet.
194 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
195 EXPECT_TRUE(channel_->AddSendStream(
196 cricket::StreamParams::CreateLegacy(kSsrc1)));
197 }
198
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 // Check we fail if the ssrc is invalid.
200 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
201
202 // Test send
203 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
204 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
205 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
206
207 // Test play
208 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
209 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
210 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
211
212 // Test send and play
213 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
214 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
215 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
216 cricket::DF_PLAY | cricket::DF_SEND));
217 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
218 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
219 }
220
221 // Test that send bandwidth is set correctly.
222 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000223 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
224 // |expected_result| is the expected result from SetMaxSendBandwidth().
225 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000227 int max_bitrate,
228 bool expected_result,
229 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 int channel_num = voe_.GetLastChannel();
231 std::vector<cricket::AudioCodec> codecs;
232
233 codecs.push_back(codec);
234 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
235
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000236 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 EXPECT_EQ(expected_result, result);
238
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000239 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
241
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000242 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 }
244
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000245 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
246 EXPECT_TRUE(SetupEngineWithoutStream());
247 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000248
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000249 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000250 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000252 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000253 // Ensure unknown extensions won't cause an error.
254 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000255 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000256 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000257 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000259 // Ensure extensions stay off with an empty list of headers.
260 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000261 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000262 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000263
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000264 // Ensure extension is set properly.
265 const int id = 1;
266 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000267 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000268 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000269
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000270 // Ensure extension is set properly on new channel.
271 // The first stream to occupy the default channel.
272 EXPECT_TRUE(channel_->AddSendStream(
273 cricket::StreamParams::CreateLegacy(123)));
274 EXPECT_TRUE(channel_->AddSendStream(
275 cricket::StreamParams::CreateLegacy(234)));
276 int new_channel_num = voe_.GetLastChannel();
277 EXPECT_NE(channel_num, new_channel_num);
278 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000279
280 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000281 extensions.clear();
282 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000283 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
284 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000285 }
286
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000287 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
288 EXPECT_TRUE(SetupEngineWithoutStream());
289 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000290
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000291 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000292 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000293
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000294 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000295 // Ensure unknown extensions won't cause an error.
296 extensions.push_back(cricket::RtpHeaderExtension(
297 "urn:ietf:params:unknownextention", 1));
298 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000299 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000300
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000301 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000302 extensions.clear();
303 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000304 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000305
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000306 // Ensure extension is set properly.
307 const int id = 2;
308 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000309 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000310 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000311
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000312 // Ensure extension is set properly on new channel.
313 // The first stream to occupy the default channel.
314 EXPECT_TRUE(channel_->AddRecvStream(
315 cricket::StreamParams::CreateLegacy(345)));
316 EXPECT_TRUE(channel_->AddRecvStream(
317 cricket::StreamParams::CreateLegacy(456)));
318 int new_channel_num = voe_.GetLastChannel();
319 EXPECT_NE(channel_num, new_channel_num);
320 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
321
322 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000323 extensions.clear();
324 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000325 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
326 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000327 }
328
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000329 protected:
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200330 cricket::FakeCall call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331 cricket::FakeWebRtcVoiceEngine voe_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000332 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 cricket::WebRtcVoiceEngine engine_;
334 cricket::VoiceMediaChannel* channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335
336 cricket::AudioOptions options_conference_;
337 cricket::AudioOptions options_adjust_agc_;
338};
339
340// Tests that our stub library "works".
341TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
342 EXPECT_FALSE(voe_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000343 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344 EXPECT_TRUE(voe_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 engine_.Terminate();
346 EXPECT_FALSE(voe_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347}
348
349// Tests that we can create and destroy a channel.
350TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000351 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200352 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200353 EXPECT_TRUE(channel_ != nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354}
355
356// Tests that we properly handle failures in CreateChannel.
357TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
358 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000359 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200360 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200361 EXPECT_TRUE(channel_ == nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362}
363
364// Tests that the list of supported codecs is created properly and ordered
365// correctly
366TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
367 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
368 ASSERT_FALSE(codecs.empty());
369 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
370 EXPECT_EQ(48000, codecs[0].clockrate);
371 EXPECT_EQ(2, codecs[0].channels);
372 EXPECT_EQ(64000, codecs[0].bitrate);
373 int pref = codecs[0].preference;
374 for (size_t i = 1; i < codecs.size(); ++i) {
375 EXPECT_GT(pref, codecs[i].preference);
376 pref = codecs[i].preference;
377 }
378}
379
380// Tests that we can find codecs by name or id, and that we interpret the
381// clockrate and bitrate fields properly.
382TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
383 cricket::AudioCodec codec;
384 webrtc::CodecInst codec_inst;
385 // Find PCMU with explicit clockrate and bitrate.
386 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
387 // Find ISAC with explicit clockrate and 0 bitrate.
388 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
389 // Find telephone-event with explicit clockrate and 0 bitrate.
390 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
391 // Find ISAC with a different payload id.
392 codec = kIsacCodec;
393 codec.id = 127;
394 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
395 EXPECT_EQ(codec.id, codec_inst.pltype);
396 // Find PCMU with a 0 clockrate.
397 codec = kPcmuCodec;
398 codec.clockrate = 0;
399 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
400 EXPECT_EQ(codec.id, codec_inst.pltype);
401 EXPECT_EQ(8000, codec_inst.plfreq);
402 // Find PCMU with a 0 bitrate.
403 codec = kPcmuCodec;
404 codec.bitrate = 0;
405 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
406 EXPECT_EQ(codec.id, codec_inst.pltype);
407 EXPECT_EQ(64000, codec_inst.rate);
408 // Find ISAC with an explicit bitrate.
409 codec = kIsacCodec;
410 codec.bitrate = 32000;
411 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
412 EXPECT_EQ(codec.id, codec_inst.pltype);
413 EXPECT_EQ(32000, codec_inst.rate);
414}
415
416// Test that we set our inbound codecs properly, including changing PT.
417TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
418 EXPECT_TRUE(SetupEngine());
419 int channel_num = voe_.GetLastChannel();
420 std::vector<cricket::AudioCodec> codecs;
421 codecs.push_back(kIsacCodec);
422 codecs.push_back(kPcmuCodec);
423 codecs.push_back(kTelephoneEventCodec);
424 codecs[0].id = 106; // collide with existing telephone-event
425 codecs[2].id = 126;
426 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
427 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000428 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000429 gcodec.plfreq = 16000;
430 gcodec.channels = 1;
431 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
432 EXPECT_EQ(106, gcodec.pltype);
433 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000434 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000435 "telephone-event");
436 gcodec.plfreq = 8000;
437 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
438 EXPECT_EQ(126, gcodec.pltype);
439 EXPECT_STREQ("telephone-event", gcodec.plname);
440}
441
442// Test that we fail to set an unknown inbound codec.
443TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
444 EXPECT_TRUE(SetupEngine());
445 std::vector<cricket::AudioCodec> codecs;
446 codecs.push_back(kIsacCodec);
447 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
448 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
449}
450
451// Test that we fail if we have duplicate types in the inbound list.
452TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
453 EXPECT_TRUE(SetupEngine());
454 std::vector<cricket::AudioCodec> codecs;
455 codecs.push_back(kIsacCodec);
456 codecs.push_back(kCn16000Codec);
457 codecs[1].id = kIsacCodec.id;
458 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
459}
460
461// Test that we can decode OPUS without stereo parameters.
462TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
463 EXPECT_TRUE(SetupEngine());
464 EXPECT_TRUE(channel_->SetOptions(options_conference_));
465 std::vector<cricket::AudioCodec> codecs;
466 codecs.push_back(kIsacCodec);
467 codecs.push_back(kPcmuCodec);
468 codecs.push_back(kOpusCodec);
469 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
470 EXPECT_TRUE(channel_->AddRecvStream(
471 cricket::StreamParams::CreateLegacy(kSsrc1)));
472 int channel_num2 = voe_.GetLastChannel();
473 webrtc::CodecInst opus;
474 engine_.FindWebRtcCodec(kOpusCodec, &opus);
475 // Even without stereo parameters, recv codecs still specify channels = 2.
476 EXPECT_EQ(2, opus.channels);
477 EXPECT_EQ(111, opus.pltype);
478 EXPECT_STREQ("opus", opus.plname);
479 opus.pltype = 0;
480 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
481 EXPECT_EQ(111, opus.pltype);
482}
483
484// Test that we can decode OPUS with stereo = 0.
485TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
486 EXPECT_TRUE(SetupEngine());
487 EXPECT_TRUE(channel_->SetOptions(options_conference_));
488 std::vector<cricket::AudioCodec> codecs;
489 codecs.push_back(kIsacCodec);
490 codecs.push_back(kPcmuCodec);
491 codecs.push_back(kOpusCodec);
492 codecs[2].params["stereo"] = "0";
493 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
494 EXPECT_TRUE(channel_->AddRecvStream(
495 cricket::StreamParams::CreateLegacy(kSsrc1)));
496 int channel_num2 = voe_.GetLastChannel();
497 webrtc::CodecInst opus;
498 engine_.FindWebRtcCodec(kOpusCodec, &opus);
499 // Even when stereo is off, recv codecs still specify channels = 2.
500 EXPECT_EQ(2, opus.channels);
501 EXPECT_EQ(111, opus.pltype);
502 EXPECT_STREQ("opus", opus.plname);
503 opus.pltype = 0;
504 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
505 EXPECT_EQ(111, opus.pltype);
506}
507
508// Test that we can decode OPUS with stereo = 1.
509TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
510 EXPECT_TRUE(SetupEngine());
511 EXPECT_TRUE(channel_->SetOptions(options_conference_));
512 std::vector<cricket::AudioCodec> codecs;
513 codecs.push_back(kIsacCodec);
514 codecs.push_back(kPcmuCodec);
515 codecs.push_back(kOpusCodec);
516 codecs[2].params["stereo"] = "1";
517 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
518 EXPECT_TRUE(channel_->AddRecvStream(
519 cricket::StreamParams::CreateLegacy(kSsrc1)));
520 int channel_num2 = voe_.GetLastChannel();
521 webrtc::CodecInst opus;
522 engine_.FindWebRtcCodec(kOpusCodec, &opus);
523 EXPECT_EQ(2, opus.channels);
524 EXPECT_EQ(111, opus.pltype);
525 EXPECT_STREQ("opus", opus.plname);
526 opus.pltype = 0;
527 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
528 EXPECT_EQ(111, opus.pltype);
529}
530
531// Test that changes to recv codecs are applied to all streams.
532TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
533 EXPECT_TRUE(SetupEngine());
534 EXPECT_TRUE(channel_->SetOptions(options_conference_));
535 std::vector<cricket::AudioCodec> codecs;
536 codecs.push_back(kIsacCodec);
537 codecs.push_back(kPcmuCodec);
538 codecs.push_back(kTelephoneEventCodec);
539 codecs[0].id = 106; // collide with existing telephone-event
540 codecs[2].id = 126;
541 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
542 EXPECT_TRUE(channel_->AddRecvStream(
543 cricket::StreamParams::CreateLegacy(kSsrc1)));
544 int channel_num2 = voe_.GetLastChannel();
545 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000546 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547 gcodec.plfreq = 16000;
548 gcodec.channels = 1;
549 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
550 EXPECT_EQ(106, gcodec.pltype);
551 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000552 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000553 "telephone-event");
554 gcodec.plfreq = 8000;
555 gcodec.channels = 1;
556 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
557 EXPECT_EQ(126, gcodec.pltype);
558 EXPECT_STREQ("telephone-event", gcodec.plname);
559}
560
561TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
562 EXPECT_TRUE(SetupEngine());
563 EXPECT_TRUE(channel_->SetOptions(options_conference_));
564 std::vector<cricket::AudioCodec> codecs;
565 codecs.push_back(kIsacCodec);
566 codecs[0].id = 106; // collide with existing telephone-event
567
568 EXPECT_TRUE(channel_->AddRecvStream(
569 cricket::StreamParams::CreateLegacy(kSsrc1)));
570 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
571
572 int channel_num2 = voe_.GetLastChannel();
573 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000574 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 gcodec.plfreq = 16000;
576 gcodec.channels = 1;
577 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
578 EXPECT_EQ(106, gcodec.pltype);
579 EXPECT_STREQ("ISAC", gcodec.plname);
580}
581
582// Test that we can apply the same set of codecs again while playing.
583TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
584 EXPECT_TRUE(SetupEngine());
585 int channel_num = voe_.GetLastChannel();
586 std::vector<cricket::AudioCodec> codecs;
587 codecs.push_back(kIsacCodec);
588 codecs.push_back(kCn16000Codec);
589 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
590 EXPECT_TRUE(channel_->SetPlayout(true));
591 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
592
593 // Changing the payload type of a codec should fail.
594 codecs[0].id = 127;
595 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
596 EXPECT_TRUE(voe_.GetPlayout(channel_num));
597}
598
599// Test that we can add a codec while playing.
600TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
601 EXPECT_TRUE(SetupEngine());
602 int channel_num = voe_.GetLastChannel();
603 std::vector<cricket::AudioCodec> codecs;
604 codecs.push_back(kIsacCodec);
605 codecs.push_back(kCn16000Codec);
606 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
607 EXPECT_TRUE(channel_->SetPlayout(true));
608
609 codecs.push_back(kOpusCodec);
610 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
611 EXPECT_TRUE(voe_.GetPlayout(channel_num));
612 webrtc::CodecInst gcodec;
613 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
614 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
615}
616
617TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
618 EXPECT_TRUE(SetupEngine());
619 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
620
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000621 // Test that when autobw is enabled, bitrate is kept as the default
622 // value. autobw is enabled for the following tests because the target
623 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000624
625 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000626 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000627
628 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000629 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000630
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000631 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000632 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633}
634
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000635TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000636 EXPECT_TRUE(SetupEngine());
637 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
638
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000639 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000640
641 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000642 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
643 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000644
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000646 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
647 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648}
649
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000650TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
651 EXPECT_TRUE(SetupEngine());
652 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
653
654 // Test that we can only set a maximum bitrate for a fixed-rate codec
655 // if it's bigger than the fixed rate.
656
657 // PCMU, fixed bitrate == 64000.
658 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
659 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
660 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
661 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
662 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
663 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
664 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
665}
666
667TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000668 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200669 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +0200670 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000671 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
672
673 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000674 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000675
676 EXPECT_TRUE(channel_->AddSendStream(
677 cricket::StreamParams::CreateLegacy(kSsrc1)));
678
679 int channel_num = voe_.GetLastChannel();
680 webrtc::CodecInst codec;
681 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
682 EXPECT_EQ(desired_bitrate, codec.rate);
683}
684
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000685// Test that bitrate cannot be set for CBR codecs.
686// Bitrate is ignored if it is higher than the fixed bitrate.
687// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000688TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000689 EXPECT_TRUE(SetupEngine());
690 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
691
692 webrtc::CodecInst codec;
693 int channel_num = voe_.GetLastChannel();
694 std::vector<cricket::AudioCodec> codecs;
695
696 // PCMU, default bitrate == 64000.
697 codecs.push_back(kPcmuCodec);
698 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
699 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
700 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000701 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
703 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000704 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
706 EXPECT_EQ(64000, codec.rate);
707}
708
709// Test that we apply codecs properly.
710TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
711 EXPECT_TRUE(SetupEngine());
712 int channel_num = voe_.GetLastChannel();
713 std::vector<cricket::AudioCodec> codecs;
714 codecs.push_back(kIsacCodec);
715 codecs.push_back(kPcmuCodec);
716 codecs.push_back(kRedCodec);
717 codecs[0].id = 96;
718 codecs[0].bitrate = 48000;
719 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000720 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 webrtc::CodecInst gcodec;
722 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
723 EXPECT_EQ(96, gcodec.pltype);
724 EXPECT_EQ(48000, gcodec.rate);
725 EXPECT_STREQ("ISAC", gcodec.plname);
726 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000727 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000728 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
729 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
730 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
731}
732
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000733// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
734// to apply.
735TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
736 EXPECT_TRUE(SetupEngine());
737 std::vector<cricket::AudioCodec> codecs;
738 codecs.push_back(kIsacCodec);
739 codecs.push_back(kPcmuCodec);
740 codecs.push_back(kRedCodec);
741 codecs[0].id = 96;
742 codecs[0].bitrate = 48000;
743 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
744 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
745 // Calling SetSendCodec again with same codec which is already set.
746 // In this case media channel shouldn't send codec to VoE.
747 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
748 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
749}
750
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +0000751// Verify that G722 is set with 16000 samples per second to WebRTC.
752TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
753 EXPECT_TRUE(SetupEngine());
754 int channel_num = voe_.GetLastChannel();
755 std::vector<cricket::AudioCodec> codecs;
756 codecs.push_back(kG722CodecSdp);
757 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
758 webrtc::CodecInst gcodec;
759 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
760 EXPECT_STREQ("G722", gcodec.plname);
761 EXPECT_EQ(1, gcodec.channels);
762 EXPECT_EQ(16000, gcodec.plfreq);
763}
764
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000765// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
767 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768 std::vector<cricket::AudioCodec> codecs;
769 codecs.push_back(kOpusCodec);
770 codecs[0].bitrate = 0;
771 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000772 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773}
774
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000775// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
777 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000778 std::vector<cricket::AudioCodec> codecs;
779 codecs.push_back(kOpusCodec);
780 codecs[0].bitrate = 0;
781 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000782 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783}
784
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000785// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
787 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 std::vector<cricket::AudioCodec> codecs;
789 codecs.push_back(kOpusCodec);
790 codecs[0].bitrate = 0;
791 codecs[0].channels = 0;
792 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000793 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794}
795
796// Test that if channel is 1 for opus and there's no stereo, we fail.
797TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
798 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799 std::vector<cricket::AudioCodec> codecs;
800 codecs.push_back(kOpusCodec);
801 codecs[0].bitrate = 0;
802 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000803 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000804}
805
806// Test that if channel is 1 for opus and stereo=0, we fail.
807TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
808 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000809 std::vector<cricket::AudioCodec> codecs;
810 codecs.push_back(kOpusCodec);
811 codecs[0].bitrate = 0;
812 codecs[0].channels = 1;
813 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000814 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000815}
816
817// Test that if channel is 1 for opus and stereo=1, we fail.
818TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
819 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820 std::vector<cricket::AudioCodec> codecs;
821 codecs.push_back(kOpusCodec);
822 codecs[0].bitrate = 0;
823 codecs[0].channels = 1;
824 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000825 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826}
827
828// Test that with bitrate=0 and no stereo,
829// channels and bitrate are 1 and 32000.
830TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
831 EXPECT_TRUE(SetupEngine());
832 int channel_num = voe_.GetLastChannel();
833 std::vector<cricket::AudioCodec> codecs;
834 codecs.push_back(kOpusCodec);
835 codecs[0].bitrate = 0;
836 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
837 webrtc::CodecInst gcodec;
838 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
839 EXPECT_STREQ("opus", gcodec.plname);
840 EXPECT_EQ(1, gcodec.channels);
841 EXPECT_EQ(32000, gcodec.rate);
842}
843
844// Test that with bitrate=0 and stereo=0,
845// channels and bitrate are 1 and 32000.
846TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
847 EXPECT_TRUE(SetupEngine());
848 int channel_num = voe_.GetLastChannel();
849 std::vector<cricket::AudioCodec> codecs;
850 codecs.push_back(kOpusCodec);
851 codecs[0].bitrate = 0;
852 codecs[0].params["stereo"] = "0";
853 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
854 webrtc::CodecInst gcodec;
855 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
856 EXPECT_STREQ("opus", gcodec.plname);
857 EXPECT_EQ(1, gcodec.channels);
858 EXPECT_EQ(32000, gcodec.rate);
859}
860
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000861// Test that with bitrate=invalid and stereo=0,
862// channels and bitrate are 1 and 32000.
863TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
864 EXPECT_TRUE(SetupEngine());
865 int channel_num = voe_.GetLastChannel();
866 std::vector<cricket::AudioCodec> codecs;
867 codecs.push_back(kOpusCodec);
868 codecs[0].params["stereo"] = "0";
869 webrtc::CodecInst gcodec;
870
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000871 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000872 codecs[0].bitrate = 5999;
873 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
874 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
875 EXPECT_STREQ("opus", gcodec.plname);
876 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000877 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000878
879 codecs[0].bitrate = 510001;
880 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
881 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
882 EXPECT_STREQ("opus", gcodec.plname);
883 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000884 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000885}
886
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887// Test that with bitrate=0 and stereo=1,
888// channels and bitrate are 2 and 64000.
889TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
890 EXPECT_TRUE(SetupEngine());
891 int channel_num = voe_.GetLastChannel();
892 std::vector<cricket::AudioCodec> codecs;
893 codecs.push_back(kOpusCodec);
894 codecs[0].bitrate = 0;
895 codecs[0].params["stereo"] = "1";
896 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
897 webrtc::CodecInst gcodec;
898 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
899 EXPECT_STREQ("opus", gcodec.plname);
900 EXPECT_EQ(2, gcodec.channels);
901 EXPECT_EQ(64000, gcodec.rate);
902}
903
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000904// Test that with bitrate=invalid and stereo=1,
905// channels and bitrate are 2 and 64000.
906TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
907 EXPECT_TRUE(SetupEngine());
908 int channel_num = voe_.GetLastChannel();
909 std::vector<cricket::AudioCodec> codecs;
910 codecs.push_back(kOpusCodec);
911 codecs[0].params["stereo"] = "1";
912 webrtc::CodecInst gcodec;
913
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000914 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000915 codecs[0].bitrate = 5999;
916 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
917 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
918 EXPECT_STREQ("opus", gcodec.plname);
919 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000920 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000921
922 codecs[0].bitrate = 510001;
923 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
924 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
925 EXPECT_STREQ("opus", gcodec.plname);
926 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000927 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000928}
929
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930// Test that with bitrate=N and stereo unset,
931// channels and bitrate are 1 and N.
932TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
933 EXPECT_TRUE(SetupEngine());
934 int channel_num = voe_.GetLastChannel();
935 std::vector<cricket::AudioCodec> codecs;
936 codecs.push_back(kOpusCodec);
937 codecs[0].bitrate = 96000;
938 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
939 webrtc::CodecInst gcodec;
940 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
941 EXPECT_EQ(111, gcodec.pltype);
942 EXPECT_EQ(96000, gcodec.rate);
943 EXPECT_STREQ("opus", gcodec.plname);
944 EXPECT_EQ(1, gcodec.channels);
945 EXPECT_EQ(48000, gcodec.plfreq);
946}
947
948// Test that with bitrate=N and stereo=0,
949// channels and bitrate are 1 and N.
950TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
951 EXPECT_TRUE(SetupEngine());
952 int channel_num = voe_.GetLastChannel();
953 std::vector<cricket::AudioCodec> codecs;
954 codecs.push_back(kOpusCodec);
955 codecs[0].bitrate = 30000;
956 codecs[0].params["stereo"] = "0";
957 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
958 webrtc::CodecInst gcodec;
959 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
960 EXPECT_EQ(1, gcodec.channels);
961 EXPECT_EQ(30000, gcodec.rate);
962 EXPECT_STREQ("opus", gcodec.plname);
963}
964
965// Test that with bitrate=N and without any parameters,
966// channels and bitrate are 1 and N.
967TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
968 EXPECT_TRUE(SetupEngine());
969 int channel_num = voe_.GetLastChannel();
970 std::vector<cricket::AudioCodec> codecs;
971 codecs.push_back(kOpusCodec);
972 codecs[0].bitrate = 30000;
973 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
974 webrtc::CodecInst gcodec;
975 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
976 EXPECT_EQ(1, gcodec.channels);
977 EXPECT_EQ(30000, gcodec.rate);
978 EXPECT_STREQ("opus", gcodec.plname);
979}
980
981// Test that with bitrate=N and stereo=1,
982// channels and bitrate are 2 and N.
983TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
984 EXPECT_TRUE(SetupEngine());
985 int channel_num = voe_.GetLastChannel();
986 std::vector<cricket::AudioCodec> codecs;
987 codecs.push_back(kOpusCodec);
988 codecs[0].bitrate = 30000;
989 codecs[0].params["stereo"] = "1";
990 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
991 webrtc::CodecInst gcodec;
992 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
993 EXPECT_EQ(2, gcodec.channels);
994 EXPECT_EQ(30000, gcodec.rate);
995 EXPECT_STREQ("opus", gcodec.plname);
996}
997
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000998// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
999// Also test that the "maxaveragebitrate" can't be set to values outside the
1000// range of 6000 and 510000
1001TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1002 EXPECT_TRUE(SetupEngine());
1003 int channel_num = voe_.GetLastChannel();
1004 std::vector<cricket::AudioCodec> codecs;
1005 codecs.push_back(kOpusCodec);
1006 codecs[0].bitrate = 30000;
1007 webrtc::CodecInst gcodec;
1008
1009 // Ignore if less than 6000.
1010 codecs[0].params["maxaveragebitrate"] = "5999";
1011 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1012 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001013 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001014
1015 // Ignore if larger than 510000.
1016 codecs[0].params["maxaveragebitrate"] = "510001";
1017 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1018 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001019 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001020
1021 codecs[0].params["maxaveragebitrate"] = "200000";
1022 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1023 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1024 EXPECT_EQ(200000, gcodec.rate);
1025}
1026
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001027// Test that we can enable NACK with opus as caller.
1028TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001029 EXPECT_TRUE(SetupEngine());
1030 int channel_num = voe_.GetLastChannel();
1031 std::vector<cricket::AudioCodec> codecs;
1032 codecs.push_back(kOpusCodec);
1033 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1034 cricket::kParamValueEmpty));
1035 EXPECT_FALSE(voe_.GetNACK(channel_num));
1036 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1037 EXPECT_TRUE(voe_.GetNACK(channel_num));
1038}
1039
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001040// Test that we can enable NACK with opus as callee.
1041TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001042 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001043 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +02001044 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001045
1046 int channel_num = voe_.GetLastChannel();
1047 std::vector<cricket::AudioCodec> codecs;
1048 codecs.push_back(kOpusCodec);
1049 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1050 cricket::kParamValueEmpty));
1051 EXPECT_FALSE(voe_.GetNACK(channel_num));
1052 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1053 EXPECT_FALSE(voe_.GetNACK(channel_num));
1054
1055 EXPECT_TRUE(channel_->AddSendStream(
1056 cricket::StreamParams::CreateLegacy(kSsrc1)));
1057 EXPECT_TRUE(voe_.GetNACK(channel_num));
1058}
1059
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001060// Test that we can enable NACK on receive streams.
1061TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1062 EXPECT_TRUE(SetupEngine());
1063 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1064 int channel_num1 = voe_.GetLastChannel();
1065 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1066 int channel_num2 = voe_.GetLastChannel();
1067 std::vector<cricket::AudioCodec> codecs;
1068 codecs.push_back(kOpusCodec);
1069 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1070 cricket::kParamValueEmpty));
1071 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1072 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1073 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1074 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1075 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1076}
1077
1078// Test that we can disable NACK.
1079TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1080 EXPECT_TRUE(SetupEngine());
1081 int channel_num = voe_.GetLastChannel();
1082 std::vector<cricket::AudioCodec> codecs;
1083 codecs.push_back(kOpusCodec);
1084 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1085 cricket::kParamValueEmpty));
1086 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1087 EXPECT_TRUE(voe_.GetNACK(channel_num));
1088
1089 codecs.clear();
1090 codecs.push_back(kOpusCodec);
1091 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1092 EXPECT_FALSE(voe_.GetNACK(channel_num));
1093}
1094
1095// Test that we can disable NACK on receive streams.
1096TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1097 EXPECT_TRUE(SetupEngine());
1098 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1099 int channel_num1 = voe_.GetLastChannel();
1100 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1101 int channel_num2 = voe_.GetLastChannel();
1102 std::vector<cricket::AudioCodec> codecs;
1103 codecs.push_back(kOpusCodec);
1104 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1105 cricket::kParamValueEmpty));
1106 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1107 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1108 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1109
1110 codecs.clear();
1111 codecs.push_back(kOpusCodec);
1112 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1113 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1114 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1115}
1116
1117// Test that NACK is enabled on a new receive stream.
1118TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1119 EXPECT_TRUE(SetupEngine());
1120 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1121 int channel_num = voe_.GetLastChannel();
1122 std::vector<cricket::AudioCodec> codecs;
1123 codecs.push_back(kIsacCodec);
1124 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1125 cricket::kParamValueEmpty));
1126 codecs.push_back(kCn16000Codec);
1127 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1128 EXPECT_TRUE(voe_.GetNACK(channel_num));
1129
1130 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1131 channel_num = voe_.GetLastChannel();
1132 EXPECT_TRUE(voe_.GetNACK(channel_num));
1133 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1134 channel_num = voe_.GetLastChannel();
1135 EXPECT_TRUE(voe_.GetNACK(channel_num));
1136}
1137
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001138// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001139TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001140 EXPECT_TRUE(SetupEngine());
1141 int channel_num = voe_.GetLastChannel();
1142 std::vector<cricket::AudioCodec> codecs;
1143 codecs.push_back(kOpusCodec);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001144 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1145 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1146}
1147
1148// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001149TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001150 EXPECT_TRUE(SetupEngine());
1151 int channel_num = voe_.GetLastChannel();
1152 std::vector<cricket::AudioCodec> codecs;
1153 codecs.push_back(kOpusCodec);
1154 codecs[0].bitrate = 0;
1155 codecs[0].params["useinbandfec"] = "0";
1156 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1157 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1158 webrtc::CodecInst gcodec;
1159 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1160 EXPECT_STREQ("opus", gcodec.plname);
1161 EXPECT_EQ(1, gcodec.channels);
1162 EXPECT_EQ(32000, gcodec.rate);
1163}
1164
1165// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001166TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001167 EXPECT_TRUE(SetupEngine());
1168 int channel_num = voe_.GetLastChannel();
1169 std::vector<cricket::AudioCodec> codecs;
1170 codecs.push_back(kOpusCodec);
1171 codecs[0].bitrate = 0;
1172 codecs[0].params["useinbandfec"] = "1";
1173 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1174 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1175 webrtc::CodecInst gcodec;
1176 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1177 EXPECT_STREQ("opus", gcodec.plname);
1178 EXPECT_EQ(1, gcodec.channels);
1179 EXPECT_EQ(32000, gcodec.rate);
1180}
1181
1182// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001183TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001184 EXPECT_TRUE(SetupEngine());
1185 int channel_num = voe_.GetLastChannel();
1186 std::vector<cricket::AudioCodec> codecs;
1187 codecs.push_back(kOpusCodec);
1188 codecs[0].bitrate = 0;
1189 codecs[0].params["stereo"] = "1";
1190 codecs[0].params["useinbandfec"] = "1";
1191 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1192 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1193 webrtc::CodecInst gcodec;
1194 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1195 EXPECT_STREQ("opus", gcodec.plname);
1196 EXPECT_EQ(2, gcodec.channels);
1197 EXPECT_EQ(64000, gcodec.rate);
1198}
1199
1200// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001201TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001202 EXPECT_TRUE(SetupEngine());
1203 int channel_num = voe_.GetLastChannel();
1204 std::vector<cricket::AudioCodec> codecs;
1205 codecs.push_back(kIsacCodec);
1206 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1207 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1208}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001209
1210// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1211TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1212 EXPECT_TRUE(SetupEngine());
1213 int channel_num = voe_.GetLastChannel();
1214 std::vector<cricket::AudioCodec> codecs;
1215 codecs.push_back(kIsacCodec);
1216 codecs[0].params["useinbandfec"] = "1";
1217 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1218 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1219}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001220
1221// Test that Opus FEC status can be changed.
1222TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1223 EXPECT_TRUE(SetupEngine());
1224 int channel_num = voe_.GetLastChannel();
1225 std::vector<cricket::AudioCodec> codecs;
1226 codecs.push_back(kOpusCodec);
1227 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1228 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1229 codecs[0].params["useinbandfec"] = "1";
1230 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1231 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1232}
1233
1234// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1235TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1236 EXPECT_TRUE(SetupEngine());
1237 int channel_num = voe_.GetLastChannel();
1238 std::vector<cricket::AudioCodec> codecs;
1239 codecs.push_back(kOpusCodec);
1240 codecs[0].bitrate = 0;
1241 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1242 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1243 EXPECT_EQ(cricket::kOpusBandwidthNb,
1244 voe_.GetMaxEncodingBandwidth(channel_num));
1245 webrtc::CodecInst gcodec;
1246 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1247 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001248
1249 EXPECT_EQ(12000, gcodec.rate);
1250 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1251 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1252 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1253 EXPECT_EQ(24000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001254}
1255
1256// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1257TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1258 EXPECT_TRUE(SetupEngine());
1259 int channel_num = voe_.GetLastChannel();
1260 std::vector<cricket::AudioCodec> codecs;
1261 codecs.push_back(kOpusCodec);
1262 codecs[0].bitrate = 0;
1263 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1264 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1265 EXPECT_EQ(cricket::kOpusBandwidthMb,
1266 voe_.GetMaxEncodingBandwidth(channel_num));
1267 webrtc::CodecInst gcodec;
1268 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1269 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001270
1271 EXPECT_EQ(20000, gcodec.rate);
1272 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1273 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1274 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1275 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001276}
1277
1278// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1279TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1280 EXPECT_TRUE(SetupEngine());
1281 int channel_num = voe_.GetLastChannel();
1282 std::vector<cricket::AudioCodec> codecs;
1283 codecs.push_back(kOpusCodec);
1284 codecs[0].bitrate = 0;
1285 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1286 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1287 EXPECT_EQ(cricket::kOpusBandwidthWb,
1288 voe_.GetMaxEncodingBandwidth(channel_num));
1289 webrtc::CodecInst gcodec;
1290 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1291 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001292
1293 EXPECT_EQ(20000, gcodec.rate);
1294 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1295 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1296 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1297 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001298}
1299
1300// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1301TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1302 EXPECT_TRUE(SetupEngine());
1303 int channel_num = voe_.GetLastChannel();
1304 std::vector<cricket::AudioCodec> codecs;
1305 codecs.push_back(kOpusCodec);
1306 codecs[0].bitrate = 0;
1307 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1308 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1309 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1310 voe_.GetMaxEncodingBandwidth(channel_num));
1311 webrtc::CodecInst gcodec;
1312 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1313 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001314
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001315 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001316 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1317 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1318 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1319 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001320}
1321
1322// Test 24000 < maxplaybackrate triggers Opus full band mode.
1323TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1324 EXPECT_TRUE(SetupEngine());
1325 int channel_num = voe_.GetLastChannel();
1326 std::vector<cricket::AudioCodec> codecs;
1327 codecs.push_back(kOpusCodec);
1328 codecs[0].bitrate = 0;
1329 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1330 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1331 EXPECT_EQ(cricket::kOpusBandwidthFb,
1332 voe_.GetMaxEncodingBandwidth(channel_num));
1333 webrtc::CodecInst gcodec;
1334 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1335 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001336
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001337 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001338 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1339 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1340 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1341 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001342}
1343
1344// Test Opus that without maxplaybackrate, default playback rate is used.
1345TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1346 EXPECT_TRUE(SetupEngine());
1347 int channel_num = voe_.GetLastChannel();
1348 std::vector<cricket::AudioCodec> codecs;
1349 codecs.push_back(kOpusCodec);
1350 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1351 EXPECT_EQ(cricket::kOpusBandwidthFb,
1352 voe_.GetMaxEncodingBandwidth(channel_num));
1353}
1354
1355// Test the with non-Opus, maxplaybackrate has no effect.
1356TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1357 EXPECT_TRUE(SetupEngine());
1358 int channel_num = voe_.GetLastChannel();
1359 std::vector<cricket::AudioCodec> codecs;
1360 codecs.push_back(kIsacCodec);
1361 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1362 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1363 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1364}
1365
1366// Test maxplaybackrate can be set on two streams.
1367TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1368 EXPECT_TRUE(SetupEngine());
1369 int channel_num = voe_.GetLastChannel();
1370 std::vector<cricket::AudioCodec> codecs;
1371 codecs.push_back(kOpusCodec);
1372 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1373 // Default bandwidth is 24000.
1374 EXPECT_EQ(cricket::kOpusBandwidthFb,
1375 voe_.GetMaxEncodingBandwidth(channel_num));
1376
1377 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1378
1379 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1380 EXPECT_EQ(cricket::kOpusBandwidthNb,
1381 voe_.GetMaxEncodingBandwidth(channel_num));
1382
1383 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1384 channel_num = voe_.GetLastChannel();
1385 EXPECT_EQ(cricket::kOpusBandwidthNb,
1386 voe_.GetMaxEncodingBandwidth(channel_num));
1387}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001388
Minyue Li7100dcd2015-03-27 05:05:59 +01001389// Test that with usedtx=0, Opus DTX is off.
1390TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1391 EXPECT_TRUE(SetupEngine());
1392 int channel_num = voe_.GetLastChannel();
1393 std::vector<cricket::AudioCodec> codecs;
1394 codecs.push_back(kOpusCodec);
1395 codecs[0].params["usedtx"] = "0";
1396 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1397 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1398}
1399
1400// Test that with usedtx=1, Opus DTX is on.
1401TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1402 EXPECT_TRUE(SetupEngine());
1403 int channel_num = voe_.GetLastChannel();
1404 std::vector<cricket::AudioCodec> codecs;
1405 codecs.push_back(kOpusCodec);
1406 codecs[0].params["usedtx"] = "1";
1407 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1408 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1409 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1410}
1411
1412// Test that usedtx=1 works with stereo Opus.
1413TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1414 EXPECT_TRUE(SetupEngine());
1415 int channel_num = voe_.GetLastChannel();
1416 std::vector<cricket::AudioCodec> codecs;
1417 codecs.push_back(kOpusCodec);
1418 codecs[0].params["usedtx"] = "1";
1419 codecs[0].params["stereo"] = "1";
1420 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1421 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1422 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1423}
1424
1425// Test that usedtx=1 does not work with non Opus.
1426TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1427 EXPECT_TRUE(SetupEngine());
1428 int channel_num = voe_.GetLastChannel();
1429 std::vector<cricket::AudioCodec> codecs;
1430 codecs.push_back(kIsacCodec);
1431 codecs[0].params["usedtx"] = "1";
1432 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1433 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1434}
1435
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001436// Test that we can switch back and forth between Opus and ISAC with CN.
1437TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001438 EXPECT_TRUE(SetupEngine());
1439 int channel_num = voe_.GetLastChannel();
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001440 std::vector<cricket::AudioCodec> opus_codecs;
1441 opus_codecs.push_back(kOpusCodec);
1442 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443 webrtc::CodecInst gcodec;
1444 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001445 EXPECT_EQ(111, gcodec.pltype);
1446 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001447
1448 std::vector<cricket::AudioCodec> isac_codecs;
1449 isac_codecs.push_back(kIsacCodec);
1450 isac_codecs.push_back(kCn16000Codec);
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001451 isac_codecs.push_back(kOpusCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001452 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1453 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1454 EXPECT_EQ(103, gcodec.pltype);
1455 EXPECT_STREQ("ISAC", gcodec.plname);
1456
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001457 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001459 EXPECT_EQ(111, gcodec.pltype);
1460 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001461}
1462
1463// Test that we handle various ways of specifying bitrate.
1464TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1465 EXPECT_TRUE(SetupEngine());
1466 int channel_num = voe_.GetLastChannel();
1467 std::vector<cricket::AudioCodec> codecs;
1468 codecs.push_back(kIsacCodec); // bitrate == 32000
1469 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1470 webrtc::CodecInst gcodec;
1471 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1472 EXPECT_EQ(103, gcodec.pltype);
1473 EXPECT_STREQ("ISAC", gcodec.plname);
1474 EXPECT_EQ(32000, gcodec.rate);
1475
1476 codecs[0].bitrate = 0; // bitrate == default
1477 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1478 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1479 EXPECT_EQ(103, gcodec.pltype);
1480 EXPECT_STREQ("ISAC", gcodec.plname);
1481 EXPECT_EQ(-1, gcodec.rate);
1482
1483 codecs[0].bitrate = 28000; // bitrate == 28000
1484 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1485 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1486 EXPECT_EQ(103, gcodec.pltype);
1487 EXPECT_STREQ("ISAC", gcodec.plname);
1488 EXPECT_EQ(28000, gcodec.rate);
1489
1490 codecs[0] = kPcmuCodec; // bitrate == 64000
1491 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1492 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1493 EXPECT_EQ(0, gcodec.pltype);
1494 EXPECT_STREQ("PCMU", gcodec.plname);
1495 EXPECT_EQ(64000, gcodec.rate);
1496
1497 codecs[0].bitrate = 0; // bitrate == default
1498 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1499 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1500 EXPECT_EQ(0, gcodec.pltype);
1501 EXPECT_STREQ("PCMU", gcodec.plname);
1502 EXPECT_EQ(64000, gcodec.rate);
1503
1504 codecs[0] = kOpusCodec;
1505 codecs[0].bitrate = 0; // bitrate == default
1506 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1507 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1508 EXPECT_EQ(111, gcodec.pltype);
1509 EXPECT_STREQ("opus", gcodec.plname);
1510 EXPECT_EQ(32000, gcodec.rate);
1511}
1512
Brave Yao5225dd82015-03-26 07:39:19 +08001513// Test that we could set packet size specified in kCodecParamPTime.
1514TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1515 EXPECT_TRUE(SetupEngine());
1516 int channel_num = voe_.GetLastChannel();
1517 std::vector<cricket::AudioCodec> codecs;
1518 codecs.push_back(kOpusCodec);
1519 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1520 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1521 webrtc::CodecInst gcodec;
1522 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1523 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1524
1525 codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Value below range.
1526 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1527 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1528 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1529
1530 codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Value beyond range.
1531 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1532 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1533 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1534
1535 codecs[0] = kIsacCodec; // Also try Isac, and with unsupported size.
1536 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1537 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1538 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1539 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1540
1541 codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1542 codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1543 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1544 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1545 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1546}
1547
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001548// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001549TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1550 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001551 std::vector<cricket::AudioCodec> codecs;
1552 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1553}
1554
1555// Test that we can set send codecs even with telephone-event codec as the first
1556// one on the list.
1557TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1558 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559 int channel_num = voe_.GetLastChannel();
1560 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001561 codecs.push_back(kTelephoneEventCodec);
1562 codecs.push_back(kIsacCodec);
1563 codecs.push_back(kPcmuCodec);
1564 codecs[0].id = 98; // DTMF
1565 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1567 webrtc::CodecInst gcodec;
1568 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001569 EXPECT_EQ(96, gcodec.pltype);
1570 EXPECT_STREQ("ISAC", gcodec.plname);
1571 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1572}
1573
1574// Test that we can set send codecs even with CN codec as the first
1575// one on the list.
1576TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1577 EXPECT_TRUE(SetupEngine());
1578 int channel_num = voe_.GetLastChannel();
1579 std::vector<cricket::AudioCodec> codecs;
1580 codecs.push_back(kCn16000Codec);
1581 codecs.push_back(kIsacCodec);
1582 codecs.push_back(kPcmuCodec);
1583 codecs[0].id = 98; // wideband CN
1584 codecs[1].id = 96;
1585 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1586 webrtc::CodecInst gcodec;
1587 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1588 EXPECT_EQ(96, gcodec.pltype);
1589 EXPECT_STREQ("ISAC", gcodec.plname);
1590 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591}
1592
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001593// Test that we set VAD and DTMF types correctly as caller.
1594TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001595 EXPECT_TRUE(SetupEngine());
1596 int channel_num = voe_.GetLastChannel();
1597 std::vector<cricket::AudioCodec> codecs;
1598 codecs.push_back(kIsacCodec);
1599 codecs.push_back(kPcmuCodec);
1600 // TODO(juberti): cn 32000
1601 codecs.push_back(kCn16000Codec);
1602 codecs.push_back(kCn8000Codec);
1603 codecs.push_back(kTelephoneEventCodec);
1604 codecs.push_back(kRedCodec);
1605 codecs[0].id = 96;
1606 codecs[2].id = 97; // wideband CN
1607 codecs[4].id = 98; // DTMF
1608 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1609 webrtc::CodecInst gcodec;
1610 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1611 EXPECT_EQ(96, gcodec.pltype);
1612 EXPECT_STREQ("ISAC", gcodec.plname);
1613 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001614 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001615 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1616 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1617 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1618}
1619
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001620// Test that we set VAD and DTMF types correctly as callee.
1621TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001622 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001623 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +02001624 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001625
1626 int channel_num = voe_.GetLastChannel();
1627 std::vector<cricket::AudioCodec> codecs;
1628 codecs.push_back(kIsacCodec);
1629 codecs.push_back(kPcmuCodec);
1630 // TODO(juberti): cn 32000
1631 codecs.push_back(kCn16000Codec);
1632 codecs.push_back(kCn8000Codec);
1633 codecs.push_back(kTelephoneEventCodec);
1634 codecs.push_back(kRedCodec);
1635 codecs[0].id = 96;
1636 codecs[2].id = 97; // wideband CN
1637 codecs[4].id = 98; // DTMF
1638 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1639 EXPECT_TRUE(channel_->AddSendStream(
1640 cricket::StreamParams::CreateLegacy(kSsrc1)));
1641
1642 webrtc::CodecInst gcodec;
1643 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1644 EXPECT_EQ(96, gcodec.pltype);
1645 EXPECT_STREQ("ISAC", gcodec.plname);
1646 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001647 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001648 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1649 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1650 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1651}
1652
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001653// Test that we only apply VAD if we have a CN codec that matches the
1654// send codec clockrate.
1655TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1656 EXPECT_TRUE(SetupEngine());
1657 int channel_num = voe_.GetLastChannel();
1658 std::vector<cricket::AudioCodec> codecs;
1659 // Set ISAC(16K) and CN(16K). VAD should be activated.
1660 codecs.push_back(kIsacCodec);
1661 codecs.push_back(kCn16000Codec);
1662 codecs[1].id = 97;
1663 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1664 webrtc::CodecInst gcodec;
1665 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1666 EXPECT_STREQ("ISAC", gcodec.plname);
1667 EXPECT_TRUE(voe_.GetVAD(channel_num));
1668 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1669 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1670 codecs[0] = kPcmuCodec;
1671 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1672 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1673 EXPECT_STREQ("PCMU", gcodec.plname);
1674 EXPECT_FALSE(voe_.GetVAD(channel_num));
1675 // Set PCMU(8K) and CN(8K). VAD should be activated.
1676 codecs[1] = kCn8000Codec;
1677 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1678 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1679 EXPECT_STREQ("PCMU", gcodec.plname);
1680 EXPECT_TRUE(voe_.GetVAD(channel_num));
1681 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
Brave Yao5225dd82015-03-26 07:39:19 +08001682 // Set ISAC(16K) and CN(8K). VAD should not be activated.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001683 codecs[0] = kIsacCodec;
1684 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1685 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1686 EXPECT_STREQ("ISAC", gcodec.plname);
1687 EXPECT_FALSE(voe_.GetVAD(channel_num));
1688}
1689
1690// Test that we perform case-insensitive matching of codec names.
1691TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1692 EXPECT_TRUE(SetupEngine());
1693 int channel_num = voe_.GetLastChannel();
1694 std::vector<cricket::AudioCodec> codecs;
1695 codecs.push_back(kIsacCodec);
1696 codecs.push_back(kPcmuCodec);
1697 codecs.push_back(kCn16000Codec);
1698 codecs.push_back(kCn8000Codec);
1699 codecs.push_back(kTelephoneEventCodec);
1700 codecs.push_back(kRedCodec);
1701 codecs[0].name = "iSaC";
1702 codecs[0].id = 96;
1703 codecs[2].id = 97; // wideband CN
1704 codecs[4].id = 98; // DTMF
1705 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1706 webrtc::CodecInst gcodec;
1707 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1708 EXPECT_EQ(96, gcodec.pltype);
1709 EXPECT_STREQ("ISAC", gcodec.plname);
1710 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001711 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001712 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1713 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1714 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1715}
1716
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001717// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001718TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719 EXPECT_TRUE(SetupEngine());
1720 int channel_num = voe_.GetLastChannel();
1721 std::vector<cricket::AudioCodec> codecs;
1722 codecs.push_back(kRedCodec);
1723 codecs.push_back(kIsacCodec);
1724 codecs.push_back(kPcmuCodec);
1725 codecs[0].id = 127;
1726 codecs[0].params[""] = "96/96";
1727 codecs[1].id = 96;
1728 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1729 webrtc::CodecInst gcodec;
1730 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1731 EXPECT_EQ(96, gcodec.pltype);
1732 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001733 EXPECT_TRUE(voe_.GetRED(channel_num));
1734 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735}
1736
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001737// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001738TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001739 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001740 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
Jelena Marusicc28a8962015-05-29 15:05:44 +02001741 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001742
1743 int channel_num = voe_.GetLastChannel();
1744 std::vector<cricket::AudioCodec> codecs;
1745 codecs.push_back(kRedCodec);
1746 codecs.push_back(kIsacCodec);
1747 codecs.push_back(kPcmuCodec);
1748 codecs[0].id = 127;
1749 codecs[0].params[""] = "96/96";
1750 codecs[1].id = 96;
1751 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1752 EXPECT_TRUE(channel_->AddSendStream(
1753 cricket::StreamParams::CreateLegacy(kSsrc1)));
1754 webrtc::CodecInst gcodec;
1755 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1756 EXPECT_EQ(96, gcodec.pltype);
1757 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001758 EXPECT_TRUE(voe_.GetRED(channel_num));
1759 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001760}
1761
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001762// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1764 EXPECT_TRUE(SetupEngine());
1765 int channel_num = voe_.GetLastChannel();
1766 std::vector<cricket::AudioCodec> codecs;
1767 codecs.push_back(kRedCodec);
1768 codecs.push_back(kIsacCodec);
1769 codecs.push_back(kPcmuCodec);
1770 codecs[0].id = 127;
1771 codecs[1].id = 96;
1772 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1773 webrtc::CodecInst gcodec;
1774 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1775 EXPECT_EQ(96, gcodec.pltype);
1776 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001777 EXPECT_TRUE(voe_.GetRED(channel_num));
1778 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779}
1780
1781// Test that we ignore RED if the parameters aren't named the way we expect.
1782TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1783 EXPECT_TRUE(SetupEngine());
1784 int channel_num = voe_.GetLastChannel();
1785 std::vector<cricket::AudioCodec> codecs;
1786 codecs.push_back(kRedCodec);
1787 codecs.push_back(kIsacCodec);
1788 codecs.push_back(kPcmuCodec);
1789 codecs[0].id = 127;
1790 codecs[0].params["ABC"] = "96/96";
1791 codecs[1].id = 96;
1792 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1793 webrtc::CodecInst gcodec;
1794 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1795 EXPECT_EQ(96, gcodec.pltype);
1796 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001797 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001798}
1799
1800// Test that we ignore RED if it uses different primary/secondary encoding.
1801TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1802 EXPECT_TRUE(SetupEngine());
1803 int channel_num = voe_.GetLastChannel();
1804 std::vector<cricket::AudioCodec> codecs;
1805 codecs.push_back(kRedCodec);
1806 codecs.push_back(kIsacCodec);
1807 codecs.push_back(kPcmuCodec);
1808 codecs[0].id = 127;
1809 codecs[0].params[""] = "96/0";
1810 codecs[1].id = 96;
1811 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1812 webrtc::CodecInst gcodec;
1813 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1814 EXPECT_EQ(96, gcodec.pltype);
1815 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001816 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817}
1818
1819// Test that we ignore RED if it uses more than 2 encodings.
1820TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1821 EXPECT_TRUE(SetupEngine());
1822 int channel_num = voe_.GetLastChannel();
1823 std::vector<cricket::AudioCodec> codecs;
1824 codecs.push_back(kRedCodec);
1825 codecs.push_back(kIsacCodec);
1826 codecs.push_back(kPcmuCodec);
1827 codecs[0].id = 127;
1828 codecs[0].params[""] = "96/96/96";
1829 codecs[1].id = 96;
1830 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1831 webrtc::CodecInst gcodec;
1832 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1833 EXPECT_EQ(96, gcodec.pltype);
1834 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001835 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001836}
1837
1838// Test that we ignore RED if it has bogus codec ids.
1839TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1840 EXPECT_TRUE(SetupEngine());
1841 int channel_num = voe_.GetLastChannel();
1842 std::vector<cricket::AudioCodec> codecs;
1843 codecs.push_back(kRedCodec);
1844 codecs.push_back(kIsacCodec);
1845 codecs.push_back(kPcmuCodec);
1846 codecs[0].id = 127;
1847 codecs[0].params[""] = "ABC/ABC";
1848 codecs[1].id = 96;
1849 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1850 webrtc::CodecInst gcodec;
1851 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1852 EXPECT_EQ(96, gcodec.pltype);
1853 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001854 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001855}
1856
1857// Test that we ignore RED if it refers to a codec that is not present.
1858TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1859 EXPECT_TRUE(SetupEngine());
1860 int channel_num = voe_.GetLastChannel();
1861 std::vector<cricket::AudioCodec> codecs;
1862 codecs.push_back(kRedCodec);
1863 codecs.push_back(kIsacCodec);
1864 codecs.push_back(kPcmuCodec);
1865 codecs[0].id = 127;
1866 codecs[0].params[""] = "97/97";
1867 codecs[1].id = 96;
1868 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1869 webrtc::CodecInst gcodec;
1870 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1871 EXPECT_EQ(96, gcodec.pltype);
1872 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001873 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001874}
1875
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001876// Test support for audio level header extension.
1877TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1878 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001879}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001880TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1881 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1882}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001883
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001884// Test support for absolute send time header extension.
1885TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1886 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1887}
1888TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1889 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890}
1891
1892// Test that we can create a channel and start sending/playing out on it.
1893TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1894 EXPECT_TRUE(SetupEngine());
1895 int channel_num = voe_.GetLastChannel();
1896 std::vector<cricket::AudioCodec> codecs;
1897 codecs.push_back(kPcmuCodec);
1898 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1899 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1900 EXPECT_TRUE(voe_.GetSend(channel_num));
1901 EXPECT_TRUE(channel_->SetPlayout(true));
1902 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1903 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1904 EXPECT_FALSE(voe_.GetSend(channel_num));
1905 EXPECT_TRUE(channel_->SetPlayout(false));
1906 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1907}
1908
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001909// Test that we can add and remove send streams.
1910TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1911 SetupForMultiSendStream();
1912
1913 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1914
1915 // Set the global state for sending.
1916 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1917
1918 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1919 EXPECT_TRUE(channel_->AddSendStream(
1920 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1921
1922 // Verify that we are in a sending state for all the created streams.
1923 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1924 EXPECT_TRUE(voe_.GetSend(channel_num));
1925 }
1926
1927 // Remove the first send channel, which is the default channel. It will only
1928 // recycle the default channel but not delete it.
1929 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1930 // Stream should already be Removed from the send stream list.
1931 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1932 // But the default still exists.
1933 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1934
1935 // Delete the rest of send channel streams.
1936 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1937 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1938 // Stream should already be deleted.
1939 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1940 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1941 }
1942}
1943
1944// Test SetSendCodecs correctly configure the codecs in all send streams.
1945TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1946 SetupForMultiSendStream();
1947
1948 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1949 // Create send streams.
1950 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1951 EXPECT_TRUE(channel_->AddSendStream(
1952 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1953 }
1954
1955 std::vector<cricket::AudioCodec> codecs;
1956 // Set ISAC(16K) and CN(16K). VAD should be activated.
1957 codecs.push_back(kIsacCodec);
1958 codecs.push_back(kCn16000Codec);
1959 codecs[1].id = 97;
1960 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1961
1962 // Verify ISAC and VAD are corrected configured on all send channels.
1963 webrtc::CodecInst gcodec;
1964 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1965 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1966 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1967 EXPECT_STREQ("ISAC", gcodec.plname);
1968 EXPECT_TRUE(voe_.GetVAD(channel_num));
1969 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1970 }
1971
1972 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1973 codecs[0] = kPcmuCodec;
1974 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1975 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1976 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1977 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1978 EXPECT_STREQ("PCMU", gcodec.plname);
1979 EXPECT_FALSE(voe_.GetVAD(channel_num));
1980 }
1981}
1982
1983// Test we can SetSend on all send streams correctly.
1984TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1985 SetupForMultiSendStream();
1986
1987 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1988 // Create the send channels and they should be a SEND_NOTHING date.
1989 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1990 EXPECT_TRUE(channel_->AddSendStream(
1991 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1992 int channel_num = voe_.GetLastChannel();
1993 EXPECT_FALSE(voe_.GetSend(channel_num));
1994 }
1995
1996 // Set the global state for starting sending.
1997 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1998 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1999 // Verify that we are in a sending state for all the send streams.
2000 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2001 EXPECT_TRUE(voe_.GetSend(channel_num));
2002 }
2003
2004 // Set the global state for stopping sending.
2005 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2006 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
2007 // Verify that we are in a stop state for all the send streams.
2008 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2009 EXPECT_FALSE(voe_.GetSend(channel_num));
2010 }
2011}
2012
2013// Test we can set the correct statistics on all send streams.
2014TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2015 SetupForMultiSendStream();
2016
2017 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2018 // Create send streams.
2019 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2020 EXPECT_TRUE(channel_->AddSendStream(
2021 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2022 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002023 // Create a receive stream to check that none of the send streams end up in
2024 // the receive stream stats.
2025 EXPECT_TRUE(channel_->AddRecvStream(
2026 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002027 // We need send codec to be set to get all stats.
2028 std::vector<cricket::AudioCodec> codecs;
2029 codecs.push_back(kPcmuCodec);
2030 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002031 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002032
2033 cricket::VoiceMediaInfo info;
2034 EXPECT_EQ(true, channel_->GetStats(&info));
2035 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
2036
2037 // Verify the statistic information is correct.
2038 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002039 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
2041 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
2042 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
2043 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
2044 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
2045 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
2046 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
2047 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002048 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002049 }
2050
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002051 EXPECT_EQ(0u, info.receivers.size());
2052 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2053 EXPECT_EQ(true, channel_->GetStats(&info));
2054
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002055 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002056 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2057 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2058 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2059 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2060 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002061 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2062 (1 << 14), info.receivers[0].expand_rate);
2063 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2064 (1 << 14), info.receivers[0].speech_expand_rate);
2065 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2066 (1 << 14), info.receivers[0].secondary_decoded_rate);
Henrik Lundin8e6fd462015-06-02 09:24:52 +02002067 EXPECT_EQ(
2068 static_cast<float>(cricket::kNetStats.currentAccelerateRate) / (1 << 14),
2069 info.receivers[0].accelerate_rate);
2070 EXPECT_EQ(
2071 static_cast<float>(cricket::kNetStats.currentPreemptiveRate) / (1 << 14),
2072 info.receivers[0].preemptive_expand_rate);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002073}
2074
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075// Test that we can add and remove receive streams, and do proper send/playout.
2076// We can receive on multiple streams while sending one stream.
2077TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002078 EXPECT_TRUE(SetupEngine());
2079 int channel_num1 = voe_.GetLastChannel();
2080
2081 // Start playout on the default channel.
2082 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2083 EXPECT_TRUE(channel_->SetPlayout(true));
2084 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2085
2086 // Adding another stream should disable playout on the default channel.
2087 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2088 int channel_num2 = voe_.GetLastChannel();
2089 std::vector<cricket::AudioCodec> codecs;
2090 codecs.push_back(kPcmuCodec);
2091 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2092 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2093 EXPECT_TRUE(voe_.GetSend(channel_num1));
2094 EXPECT_FALSE(voe_.GetSend(channel_num2));
2095
2096 // Make sure only the new channel is played out.
2097 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2098 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2099
2100 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2101 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2102 int channel_num3 = voe_.GetLastChannel();
2103 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2104 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2105 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2106 EXPECT_FALSE(voe_.GetSend(channel_num3));
2107
2108 // Stop sending.
2109 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2110 EXPECT_FALSE(voe_.GetSend(channel_num1));
2111 EXPECT_FALSE(voe_.GetSend(channel_num2));
2112 EXPECT_FALSE(voe_.GetSend(channel_num3));
2113
2114 // Stop playout.
2115 EXPECT_TRUE(channel_->SetPlayout(false));
2116 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2117 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2118 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2119
2120 // Restart playout and make sure the default channel still is not played out.
2121 EXPECT_TRUE(channel_->SetPlayout(true));
2122 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2123 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2124 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2125
2126 // Now remove the new streams and verify that the default channel is
2127 // played out again.
2128 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2129 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2130
2131 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2132}
2133
2134// Test that we can set the devices to use.
2135TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2136 EXPECT_TRUE(SetupEngine());
2137 int channel_num = voe_.GetLastChannel();
2138 std::vector<cricket::AudioCodec> codecs;
2139 codecs.push_back(kPcmuCodec);
2140 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2141
2142 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2143 cricket::kFakeDefaultDeviceId);
2144 cricket::Device dev(cricket::kFakeDeviceName,
2145 cricket::kFakeDeviceId);
2146
2147 // Test SetDevices() while not sending or playing.
2148 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2149
2150 // Test SetDevices() while sending and playing.
2151 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2152 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2153 EXPECT_TRUE(channel_->SetPlayout(true));
2154 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2155 EXPECT_TRUE(voe_.GetSend(channel_num));
2156 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2157
2158 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2159
2160 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2161 EXPECT_TRUE(voe_.GetSend(channel_num));
2162 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2163
2164 // Test that failure to open newly selected devices does not prevent opening
2165 // ones after that.
2166 voe_.set_fail_start_recording_microphone(true);
2167 voe_.set_playout_fail_channel(channel_num);
2168 voe_.set_send_fail_channel(channel_num);
2169
2170 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2171
2172 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2173 EXPECT_FALSE(voe_.GetSend(channel_num));
2174 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2175
2176 voe_.set_fail_start_recording_microphone(false);
2177 voe_.set_playout_fail_channel(-1);
2178 voe_.set_send_fail_channel(-1);
2179
2180 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2181
2182 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2183 EXPECT_TRUE(voe_.GetSend(channel_num));
2184 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2185}
2186
2187// Test that we can set the devices to use even if we failed to
2188// open the initial ones.
2189TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2190 EXPECT_TRUE(SetupEngine());
2191 int channel_num = voe_.GetLastChannel();
2192 std::vector<cricket::AudioCodec> codecs;
2193 codecs.push_back(kPcmuCodec);
2194 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2195
2196 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2197 cricket::kFakeDefaultDeviceId);
2198 cricket::Device dev(cricket::kFakeDeviceName,
2199 cricket::kFakeDeviceId);
2200
2201 // Test that failure to open devices selected before starting
2202 // send/play does not prevent opening newly selected ones after that.
2203 voe_.set_fail_start_recording_microphone(true);
2204 voe_.set_playout_fail_channel(channel_num);
2205 voe_.set_send_fail_channel(channel_num);
2206
2207 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2208
2209 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2210 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2211 EXPECT_FALSE(channel_->SetPlayout(true));
2212 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2213 EXPECT_FALSE(voe_.GetSend(channel_num));
2214 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2215
2216 voe_.set_fail_start_recording_microphone(false);
2217 voe_.set_playout_fail_channel(-1);
2218 voe_.set_send_fail_channel(-1);
2219
2220 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2221
2222 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2223 EXPECT_TRUE(voe_.GetSend(channel_num));
2224 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2225}
2226
2227// Test that we can create a channel configured for multi-point conferences,
2228// and start sending/playing out on it.
2229TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2230 EXPECT_TRUE(SetupEngine());
2231 int channel_num = voe_.GetLastChannel();
2232 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2233 std::vector<cricket::AudioCodec> codecs;
2234 codecs.push_back(kPcmuCodec);
2235 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2236 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2237 EXPECT_TRUE(voe_.GetSend(channel_num));
2238}
2239
2240// Test that we can create a channel configured for Codian bridges,
2241// and start sending/playing out on it.
2242TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2243 EXPECT_TRUE(SetupEngine());
2244 int channel_num = voe_.GetLastChannel();
2245 webrtc::AgcConfig agc_config;
2246 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2247 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2248 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2249 std::vector<cricket::AudioCodec> codecs;
2250 codecs.push_back(kPcmuCodec);
2251 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2252 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2253 EXPECT_TRUE(voe_.GetSend(channel_num));
2254 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2255 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2256 EXPECT_TRUE(channel_->SetPlayout(true));
2257 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2258 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2259 EXPECT_FALSE(voe_.GetSend(channel_num));
2260 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2261 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2262 EXPECT_TRUE(channel_->SetPlayout(false));
2263 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2264}
2265
wu@webrtc.org97077a32013-10-25 21:18:33 +00002266TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2267 EXPECT_TRUE(SetupEngine());
2268 webrtc::AgcConfig agc_config;
2269 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2270 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2271
2272 cricket::AudioOptions options;
2273 options.tx_agc_target_dbov.Set(3);
2274 options.tx_agc_digital_compression_gain.Set(9);
2275 options.tx_agc_limiter.Set(true);
2276 options.auto_gain_control.Set(true);
2277 EXPECT_TRUE(engine_.SetOptions(options));
2278
2279 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2280 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2281 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2282 EXPECT_TRUE(agc_config.limiterEnable);
2283
2284 // Check interaction with adjust_agc_delta. Both should be respected, for
2285 // backwards compatibility.
2286 options.adjust_agc_delta.Set(-10);
2287 EXPECT_TRUE(engine_.SetOptions(options));
2288
2289 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2290 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2291}
2292
2293TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2294 EXPECT_TRUE(SetupEngine());
2295 int channel_num = voe_.GetLastChannel();
2296 cricket::AudioOptions options;
2297 options.rx_agc_target_dbov.Set(6);
2298 options.rx_agc_digital_compression_gain.Set(0);
2299 options.rx_agc_limiter.Set(true);
2300 options.rx_auto_gain_control.Set(true);
2301 EXPECT_TRUE(channel_->SetOptions(options));
2302
2303 webrtc::AgcConfig agc_config;
2304 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2305 channel_num, agc_config));
2306 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2307 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2308 EXPECT_TRUE(agc_config.limiterEnable);
2309}
2310
2311TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2312 EXPECT_TRUE(SetupEngine());
2313 cricket::AudioOptions options;
2314 options.recording_sample_rate.Set(48000u);
2315 options.playout_sample_rate.Set(44100u);
2316 EXPECT_TRUE(engine_.SetOptions(options));
2317
2318 unsigned int recording_sample_rate, playout_sample_rate;
2319 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2320 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2321 EXPECT_EQ(48000u, recording_sample_rate);
2322 EXPECT_EQ(44100u, playout_sample_rate);
2323}
2324
2325TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2326 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002327 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002328 EXPECT_EQ(
2329 // Info:
2330 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2331 // Warning:
2332 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2333 // Error:
2334 webrtc::kTraceError | webrtc::kTraceCritical,
2335 static_cast<int>(trace_wrapper_->filter_));
2336 // Now set it explicitly
2337 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002338 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2339 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002340 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2341 trace_wrapper_->filter_);
2342}
2343
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002344// Test that we can set the outgoing SSRC properly.
2345// SSRC is set in SetupEngine by calling AddSendStream.
2346TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2347 EXPECT_TRUE(SetupEngine());
2348 int channel_num = voe_.GetLastChannel();
2349 unsigned int send_ssrc;
2350 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2351 EXPECT_NE(0U, send_ssrc);
2352 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2353 EXPECT_EQ(kSsrc1, send_ssrc);
2354}
2355
2356TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2357 // Setup. We need send codec to be set to get all stats.
2358 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002359 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2360 // use a different SSRC.
2361 EXPECT_TRUE(channel_->AddRecvStream(
2362 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363 std::vector<cricket::AudioCodec> codecs;
2364 codecs.push_back(kPcmuCodec);
2365 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002366 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002367
2368 cricket::VoiceMediaInfo info;
2369 EXPECT_EQ(true, channel_->GetStats(&info));
2370 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002371 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002372 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2373 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2374 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2375 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2376 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2377 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2378 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2379 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002380 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002381 // TODO(sriniv): Add testing for more fields. These are not populated
2382 // in FakeWebrtcVoiceEngine yet.
2383 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2384 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2385 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2386 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2387 // EXPECT_EQ(cricket::kIntStatValue,
2388 // info.senders[0].echo_return_loss_enhancement);
2389
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002390 EXPECT_EQ(0u, info.receivers.size());
2391 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2392 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002393 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002394
2395 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2396 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2397 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2398 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2399 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002400 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2401 (1 << 14), info.receivers[0].expand_rate);
2402 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2403 (1 << 14), info.receivers[0].speech_expand_rate);
2404 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2405 (1 << 14), info.receivers[0].secondary_decoded_rate);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002406 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002407}
2408
2409// Test that we can set the outgoing SSRC properly with multiple streams.
2410// SSRC is set in SetupEngine by calling AddSendStream.
2411TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2412 EXPECT_TRUE(SetupEngine());
2413 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2414 int channel_num1 = voe_.GetLastChannel();
2415 unsigned int send_ssrc;
2416 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2417 EXPECT_EQ(kSsrc1, send_ssrc);
2418
2419 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2420 int channel_num2 = voe_.GetLastChannel();
2421 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2422 EXPECT_EQ(kSsrc1, send_ssrc);
2423}
2424
2425// Test that the local SSRC is the same on sending and receiving channels if the
2426// receive channel is created before the send channel.
2427TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002428 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002429 channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002430 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2431
2432 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2433 int receive_channel_num = voe_.GetLastChannel();
2434 EXPECT_TRUE(channel_->AddSendStream(
2435 cricket::StreamParams::CreateLegacy(1234)));
2436 int send_channel_num = voe_.GetLastChannel();
2437
2438 unsigned int ssrc = 0;
2439 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2440 EXPECT_EQ(1234U, ssrc);
2441 ssrc = 0;
2442 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2443 EXPECT_EQ(1234U, ssrc);
2444}
2445
2446// Test that we can properly receive packets.
2447TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2448 EXPECT_TRUE(SetupEngine());
2449 int channel_num = voe_.GetLastChannel();
2450 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2451 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2452 sizeof(kPcmuFrame)));
2453}
2454
2455// Test that we can properly receive packets on multiple streams.
2456TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2457 EXPECT_TRUE(SetupEngine());
2458 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2459 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2460 int channel_num1 = voe_.GetLastChannel();
2461 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2462 int channel_num2 = voe_.GetLastChannel();
2463 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2464 int channel_num3 = voe_.GetLastChannel();
2465 // Create packets with the right SSRCs.
2466 char packets[4][sizeof(kPcmuFrame)];
2467 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2468 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002469 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002470 }
2471 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2472 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2473 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2474 DeliverPacket(packets[0], sizeof(packets[0]));
2475 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2476 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2477 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2478 DeliverPacket(packets[1], sizeof(packets[1]));
2479 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2480 sizeof(packets[1])));
2481 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2482 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2483 DeliverPacket(packets[2], sizeof(packets[2]));
2484 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2485 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2486 sizeof(packets[2])));
2487 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2488 DeliverPacket(packets[3], sizeof(packets[3]));
2489 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2490 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2491 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2492 sizeof(packets[3])));
2493 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2494 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2495 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2496}
2497
2498// Test that we properly handle failures to add a stream.
2499TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2500 EXPECT_TRUE(SetupEngine());
2501 voe_.set_fail_create_channel(true);
2502 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2503 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2504
2505 // In 1:1 call, we should not try to create a new channel.
2506 cricket::AudioOptions options_no_conference_;
2507 options_no_conference_.conference_mode.Set(false);
2508 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2509 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2510}
2511
2512// Test that AddRecvStream doesn't create new channel for 1:1 call.
2513TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2514 EXPECT_TRUE(SetupEngine());
2515 int channel_num = voe_.GetLastChannel();
2516 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2517 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2518}
2519
2520// Test that after adding a recv stream, we do not decode more codecs than
2521// those previously passed into SetRecvCodecs.
2522TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2523 EXPECT_TRUE(SetupEngine());
2524 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2525 std::vector<cricket::AudioCodec> codecs;
2526 codecs.push_back(kIsacCodec);
2527 codecs.push_back(kPcmuCodec);
2528 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2529 EXPECT_TRUE(channel_->AddRecvStream(
2530 cricket::StreamParams::CreateLegacy(kSsrc1)));
2531 int channel_num2 = voe_.GetLastChannel();
2532 webrtc::CodecInst gcodec;
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002533 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "opus");
2534 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002535 gcodec.channels = 2;
2536 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2537}
2538
2539// Test that we properly clean up any streams that were added, even if
2540// not explicitly removed.
2541TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2542 EXPECT_TRUE(SetupEngine());
2543 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2544 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2545 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2546 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2547 delete channel_;
2548 channel_ = NULL;
2549 EXPECT_EQ(0, voe_.GetNumChannels());
2550}
2551
wu@webrtc.org78187522013-10-07 23:32:02 +00002552TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2553 EXPECT_TRUE(SetupEngine());
2554 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2555}
2556
2557TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2558 EXPECT_TRUE(SetupEngine());
2559 // Stream 1 reuses default channel.
2560 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2561 // Manually delete default channel to simulate a failure.
2562 int default_channel = voe_.GetLastChannel();
2563 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2564 // Add recv stream 2 should fail because default channel is gone.
2565 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2566 int new_channel = voe_.GetLastChannel();
2567 EXPECT_NE(default_channel, new_channel);
2568 // The last created channel should have already been deleted.
2569 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2570}
2571
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002572// Test the InsertDtmf on default send stream as caller.
2573TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2574 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002575}
2576
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002577// Test the InsertDtmf on default send stream as callee
2578TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2579 TestInsertDtmf(0, false);
2580}
2581
2582// Test the InsertDtmf on specified send stream as caller.
2583TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2584 TestInsertDtmf(kSsrc1, true);
2585}
2586
2587// Test the InsertDtmf on specified send stream as callee.
2588TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2589 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002590}
2591
2592// Test that we can play a ringback tone properly in a single-stream call.
2593TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2594 EXPECT_TRUE(SetupEngine());
2595 int channel_num = voe_.GetLastChannel();
2596 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2597 // Check we fail if no ringback tone specified.
2598 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2599 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2600 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002601 EXPECT_TRUE(channel_->SetRingbackTone(
2602 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002603 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2604 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2605 // Check we can stop the tone manually.
2606 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2607 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2608 // Check we stop the tone if a packet arrives.
2609 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2610 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2611 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2612 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2613}
2614
2615// Test that we can play a ringback tone properly in a multi-stream call.
2616TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2617 EXPECT_TRUE(SetupEngine());
2618 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2619 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2620 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2621 int channel_num = voe_.GetLastChannel();
2622 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2623 // Check we fail if no ringback tone specified.
2624 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2625 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2626 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002627 EXPECT_TRUE(channel_->SetRingbackTone(
2628 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002629 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2630 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2631 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2632 // Check we can stop the tone manually.
2633 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2634 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2635 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2636 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2637 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2638 // Send a packet with SSRC 1; the tone should not stop.
2639 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2640 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2641 // Send a packet with SSRC 2; the tone should stop.
2642 char packet[sizeof(kPcmuFrame)];
2643 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002644 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002645 DeliverPacket(packet, sizeof(packet));
2646 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2647}
2648
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002649TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002650 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651 cricket::WebRtcVoiceMediaChannel* media_channel;
2652 unsigned int ssrc = 0;
2653
2654 EXPECT_TRUE(SetupEngine());
2655 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2656 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2657
2658 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2659 listener.reset(new ChannelErrorListener(channel_));
2660
2661 // Test on WebRtc VoE channel.
2662 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2663 VE_SATURATION_WARNING);
2664 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2665 listener->error());
2666 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2667 EXPECT_EQ(ssrc, listener->ssrc());
2668
2669 listener->Reset();
2670 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2671 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2672 listener->error());
2673 EXPECT_EQ(0U, listener->ssrc());
2674
2675 // Add another stream and test on that.
2676 ++ssrc;
2677 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2678 ssrc)));
2679 listener->Reset();
2680 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2681 VE_SATURATION_WARNING);
2682 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2683 listener->error());
2684 EXPECT_EQ(ssrc, listener->ssrc());
2685
2686 // Testing a non-existing channel.
2687 listener->Reset();
2688 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2689 VE_SATURATION_WARNING);
2690 EXPECT_EQ(0, listener->error());
2691}
2692
2693TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2694 EXPECT_TRUE(SetupEngine());
2695 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2696 std::vector<cricket::AudioCodec> codecs;
2697 codecs.push_back(kPcmuCodec);
2698 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2699 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2700 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2701 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2702 EXPECT_TRUE(channel_->SetPlayout(true));
2703 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2704 EXPECT_TRUE(channel_->SetPlayout(false));
2705 EXPECT_FALSE(channel_->SetPlayout(true));
2706}
2707
2708// Test that the Registering/Unregistering with the
2709// webrtcvoiceengine works as expected
2710TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2711 EXPECT_TRUE(SetupEngine());
2712 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2713 EXPECT_TRUE(channel_->AddRecvStream(
2714 cricket::StreamParams::CreateLegacy(kSsrc2)));
2715 cricket::FakeMediaProcessor vp_1;
2716 cricket::FakeMediaProcessor vp_2;
2717
2718 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2719 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2720 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2721 voe_.TriggerProcessPacket(cricket::MPD_RX);
2722 voe_.TriggerProcessPacket(cricket::MPD_TX);
2723
2724 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2725 EXPECT_EQ(1, vp_1.voice_frame_count());
2726 EXPECT_EQ(1, vp_2.voice_frame_count());
2727
2728 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2729 &vp_2,
2730 cricket::MPD_RX));
2731 voe_.TriggerProcessPacket(cricket::MPD_RX);
2732 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2733 EXPECT_EQ(1, vp_2.voice_frame_count());
2734 EXPECT_EQ(2, vp_1.voice_frame_count());
2735
2736 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2737 &vp_1,
2738 cricket::MPD_RX));
2739 voe_.TriggerProcessPacket(cricket::MPD_RX);
2740 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2741 EXPECT_EQ(2, vp_1.voice_frame_count());
2742
2743 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2744 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2745 voe_.TriggerProcessPacket(cricket::MPD_RX);
2746 voe_.TriggerProcessPacket(cricket::MPD_TX);
2747 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2748 EXPECT_EQ(3, vp_1.voice_frame_count());
2749
2750 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2751 &vp_1,
2752 cricket::MPD_RX_AND_TX));
2753 voe_.TriggerProcessPacket(cricket::MPD_TX);
2754 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2755 EXPECT_EQ(3, vp_1.voice_frame_count());
2756 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2757 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2758 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2759
2760 // Test that we can register a processor on the receive channel on SSRC 0.
2761 // This tests the 1:1 case when the receive SSRC is unknown.
2762 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2763 voe_.TriggerProcessPacket(cricket::MPD_RX);
2764 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2765 EXPECT_EQ(4, vp_1.voice_frame_count());
2766 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2767 &vp_1,
2768 cricket::MPD_RX));
2769
2770 // The following tests test that FindChannelNumFromSsrc is doing
2771 // what we expect.
2772 // pick an invalid ssrc and make sure we can't register
2773 EXPECT_FALSE(engine_.RegisterProcessor(99,
2774 &vp_1,
2775 cricket::MPD_RX));
2776 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2777 EXPECT_TRUE(engine_.RegisterProcessor(1,
2778 &vp_1,
2779 cricket::MPD_RX));
2780 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2781 &vp_1,
2782 cricket::MPD_RX));
2783 EXPECT_FALSE(engine_.RegisterProcessor(1,
2784 &vp_1,
2785 cricket::MPD_TX));
2786 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2787}
2788
2789TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2790 EXPECT_TRUE(SetupEngine());
2791
2792 bool ec_enabled;
2793 webrtc::EcModes ec_mode;
2794 bool ec_metrics_enabled;
2795 webrtc::AecmModes aecm_mode;
2796 bool cng_enabled;
2797 bool agc_enabled;
2798 webrtc::AgcModes agc_mode;
2799 webrtc::AgcConfig agc_config;
2800 bool ns_enabled;
2801 webrtc::NsModes ns_mode;
2802 bool highpass_filter_enabled;
2803 bool stereo_swapping_enabled;
2804 bool typing_detection_enabled;
2805 voe_.GetEcStatus(ec_enabled, ec_mode);
2806 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2807 voe_.GetAecmMode(aecm_mode, cng_enabled);
2808 voe_.GetAgcStatus(agc_enabled, agc_mode);
2809 voe_.GetAgcConfig(agc_config);
2810 voe_.GetNsStatus(ns_enabled, ns_mode);
2811 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2812 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2813 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2814 EXPECT_TRUE(ec_enabled);
2815 EXPECT_TRUE(ec_metrics_enabled);
2816 EXPECT_FALSE(cng_enabled);
2817 EXPECT_TRUE(agc_enabled);
2818 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2819 EXPECT_TRUE(ns_enabled);
2820 EXPECT_TRUE(highpass_filter_enabled);
2821 EXPECT_FALSE(stereo_swapping_enabled);
2822 EXPECT_TRUE(typing_detection_enabled);
2823 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2824 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2825
2826 // Nothing set, so all ignored.
2827 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002828 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002829 voe_.GetEcStatus(ec_enabled, ec_mode);
2830 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2831 voe_.GetAecmMode(aecm_mode, cng_enabled);
2832 voe_.GetAgcStatus(agc_enabled, agc_mode);
2833 voe_.GetAgcConfig(agc_config);
2834 voe_.GetNsStatus(ns_enabled, ns_mode);
2835 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2836 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2837 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2838 EXPECT_TRUE(ec_enabled);
2839 EXPECT_TRUE(ec_metrics_enabled);
2840 EXPECT_FALSE(cng_enabled);
2841 EXPECT_TRUE(agc_enabled);
2842 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2843 EXPECT_TRUE(ns_enabled);
2844 EXPECT_TRUE(highpass_filter_enabled);
2845 EXPECT_FALSE(stereo_swapping_enabled);
2846 EXPECT_TRUE(typing_detection_enabled);
2847 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2848 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
Henrik Lundin64dad832015-05-11 12:44:23 +02002849 EXPECT_EQ(50, voe_.GetNetEqCapacity()); // From GetDefaultEngineOptions().
Henrik Lundin5263b3c2015-06-01 10:29:41 +02002850 EXPECT_FALSE(
2851 voe_.GetNetEqFastAccelerate()); // From GetDefaultEngineOptions().
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852
2853 // Turn echo cancellation off
2854 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002855 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002856 voe_.GetEcStatus(ec_enabled, ec_mode);
2857 EXPECT_FALSE(ec_enabled);
2858
2859 // Turn echo cancellation back on, with settings, and make sure
2860 // nothing else changed.
2861 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002862 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002863 voe_.GetEcStatus(ec_enabled, ec_mode);
2864 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2865 voe_.GetAecmMode(aecm_mode, cng_enabled);
2866 voe_.GetAgcStatus(agc_enabled, agc_mode);
2867 voe_.GetAgcConfig(agc_config);
2868 voe_.GetNsStatus(ns_enabled, ns_mode);
2869 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2870 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2871 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2872 EXPECT_TRUE(ec_enabled);
2873 EXPECT_TRUE(ec_metrics_enabled);
2874 EXPECT_TRUE(agc_enabled);
2875 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2876 EXPECT_TRUE(ns_enabled);
2877 EXPECT_TRUE(highpass_filter_enabled);
2878 EXPECT_FALSE(stereo_swapping_enabled);
2879 EXPECT_TRUE(typing_detection_enabled);
2880 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2881 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2882
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002883 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2884 // control.
2885 options.delay_agnostic_aec.Set(true);
2886 ASSERT_TRUE(engine_.SetOptions(options));
2887 voe_.GetEcStatus(ec_enabled, ec_mode);
2888 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2889 voe_.GetAecmMode(aecm_mode, cng_enabled);
2890 EXPECT_TRUE(ec_enabled);
2891 EXPECT_TRUE(ec_metrics_enabled);
2892 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2893
2894 // Turn off echo cancellation and delay agnostic aec.
2895 options.delay_agnostic_aec.Set(false);
Henrik Lundin441f6342015-06-09 16:03:13 +02002896 options.extended_filter_aec.Set(false);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002897 options.echo_cancellation.Set(false);
2898 ASSERT_TRUE(engine_.SetOptions(options));
2899 voe_.GetEcStatus(ec_enabled, ec_mode);
2900 EXPECT_FALSE(ec_enabled);
2901 // Turning delay agnostic aec back on should also turn on echo cancellation.
2902 options.delay_agnostic_aec.Set(true);
2903 ASSERT_TRUE(engine_.SetOptions(options));
2904 voe_.GetEcStatus(ec_enabled, ec_mode);
2905 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2906 EXPECT_TRUE(ec_enabled);
2907 EXPECT_TRUE(ec_metrics_enabled);
2908 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2909
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002910 // Turn off AGC
2911 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002912 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002913 voe_.GetAgcStatus(agc_enabled, agc_mode);
2914 EXPECT_FALSE(agc_enabled);
2915
2916 // Turn AGC back on
2917 options.auto_gain_control.Set(true);
2918 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002919 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002920 voe_.GetAgcStatus(agc_enabled, agc_mode);
2921 EXPECT_TRUE(agc_enabled);
2922 voe_.GetAgcConfig(agc_config);
2923 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2924
2925 // Turn off other options (and stereo swapping on).
2926 options.noise_suppression.Set(false);
2927 options.highpass_filter.Set(false);
2928 options.typing_detection.Set(false);
2929 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002930 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002931 voe_.GetNsStatus(ns_enabled, ns_mode);
2932 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2933 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2934 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2935 EXPECT_FALSE(ns_enabled);
2936 EXPECT_FALSE(highpass_filter_enabled);
2937 EXPECT_FALSE(typing_detection_enabled);
2938 EXPECT_TRUE(stereo_swapping_enabled);
2939
2940 // Turn on "conference mode" to ensure it has no impact.
2941 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002942 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002943 voe_.GetEcStatus(ec_enabled, ec_mode);
2944 voe_.GetNsStatus(ns_enabled, ns_mode);
2945 EXPECT_TRUE(ec_enabled);
2946 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2947 EXPECT_FALSE(ns_enabled);
2948 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2949}
2950
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002951TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002952 EXPECT_TRUE(SetupEngine());
2953
2954 bool ec_enabled;
2955 webrtc::EcModes ec_mode;
2956 bool ec_metrics_enabled;
2957 bool agc_enabled;
2958 webrtc::AgcModes agc_mode;
2959 bool ns_enabled;
2960 webrtc::NsModes ns_mode;
2961 bool highpass_filter_enabled;
2962 bool stereo_swapping_enabled;
2963 bool typing_detection_enabled;
2964
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002965 voe_.GetEcStatus(ec_enabled, ec_mode);
2966 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2967 voe_.GetAgcStatus(agc_enabled, agc_mode);
2968 voe_.GetNsStatus(ns_enabled, ns_mode);
2969 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2970 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2971 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2972 EXPECT_TRUE(ec_enabled);
2973 EXPECT_TRUE(agc_enabled);
2974 EXPECT_TRUE(ns_enabled);
2975 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002976 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002977 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978}
2979
2980TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2981 webrtc::AgcConfig set_config = {0};
2982 set_config.targetLeveldBOv = 3;
2983 set_config.digitalCompressionGaindB = 9;
2984 set_config.limiterEnable = true;
2985 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002986 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002987
2988 webrtc::AgcConfig config = {0};
2989 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2990 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2991 EXPECT_EQ(set_config.digitalCompressionGaindB,
2992 config.digitalCompressionGaindB);
2993 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2994}
2995
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002996TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2997 EXPECT_TRUE(SetupEngine());
solenberg66f43392015-09-09 01:36:22 -07002998 rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
2999 static_cast<cricket::WebRtcVoiceMediaChannel*>(
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003000 engine_.CreateChannel(&call_, cricket::AudioOptions())));
solenberg66f43392015-09-09 01:36:22 -07003001 rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
3002 static_cast<cricket::WebRtcVoiceMediaChannel*>(
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003003 engine_.CreateChannel(&call_, cricket::AudioOptions())));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003004
3005 // Have to add a stream to make SetSend work.
3006 cricket::StreamParams stream1;
3007 stream1.ssrcs.push_back(1);
3008 channel1->AddSendStream(stream1);
3009 cricket::StreamParams stream2;
3010 stream2.ssrcs.push_back(2);
3011 channel2->AddSendStream(stream2);
3012
3013 // AEC and AGC and NS
3014 cricket::AudioOptions options_all;
3015 options_all.echo_cancellation.Set(true);
3016 options_all.auto_gain_control.Set(true);
3017 options_all.noise_suppression.Set(true);
3018
3019 ASSERT_TRUE(channel1->SetOptions(options_all));
3020 cricket::AudioOptions expected_options = options_all;
solenberg66f43392015-09-09 01:36:22 -07003021 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003022 ASSERT_TRUE(channel2->SetOptions(options_all));
solenberg66f43392015-09-09 01:36:22 -07003023 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024
3025 // unset NS
3026 cricket::AudioOptions options_no_ns;
3027 options_no_ns.noise_suppression.Set(false);
3028 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
3029
3030 expected_options.echo_cancellation.Set(true);
3031 expected_options.auto_gain_control.Set(true);
3032 expected_options.noise_suppression.Set(false);
solenberg66f43392015-09-09 01:36:22 -07003033 EXPECT_EQ(expected_options, channel1->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003034
3035 // unset AGC
3036 cricket::AudioOptions options_no_agc;
3037 options_no_agc.auto_gain_control.Set(false);
3038 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
3039
3040 expected_options.echo_cancellation.Set(true);
3041 expected_options.auto_gain_control.Set(false);
3042 expected_options.noise_suppression.Set(true);
solenberg66f43392015-09-09 01:36:22 -07003043 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003044
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);
solenberg66f43392015-09-09 01:36:22 -07003102 EXPECT_EQ(expected_options, channel2->options());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003103 voe_.GetEcStatus(ec_enabled, ec_mode);
3104 voe_.GetAgcStatus(agc_enabled, agc_mode);
3105 voe_.GetNsStatus(ns_enabled, ns_mode);
3106 EXPECT_TRUE(ec_enabled);
3107 EXPECT_FALSE(agc_enabled);
3108 EXPECT_FALSE(ns_enabled);
3109}
3110
wu@webrtc.orgde305012013-10-31 15:40:38 +00003111// This test verifies DSCP settings are properly applied on voice media channel.
3112TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3113 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003114 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003115 engine_.CreateChannel(&call_, cricket::AudioOptions()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003116 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003117 new cricket::FakeNetworkInterface);
3118 channel->SetInterface(network_interface.get());
3119 cricket::AudioOptions options;
3120 options.dscp.Set(true);
3121 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003122 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003123 // Verify previous value is not modified if dscp option is not set.
3124 cricket::AudioOptions options1;
3125 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003126 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003127 options.dscp.Set(false);
3128 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003129 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003130}
3131
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003132// Test that GetReceiveChannelNum returns the default channel for the first
3133// recv stream in 1-1 calls.
3134TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3135 EXPECT_TRUE(SetupEngine());
3136 cricket::WebRtcVoiceMediaChannel* media_channel =
3137 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3138 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3139 EXPECT_EQ(media_channel->voe_channel(),
3140 media_channel->GetReceiveChannelNum(0));
3141 cricket::StreamParams stream;
3142 stream.ssrcs.push_back(kSsrc2);
3143 EXPECT_TRUE(channel_->AddRecvStream(stream));
3144 EXPECT_EQ(media_channel->voe_channel(),
3145 media_channel->GetReceiveChannelNum(kSsrc2));
3146}
3147
3148// Test that GetReceiveChannelNum doesn't return the default channel for the
3149// first recv stream in conference calls.
3150TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3151 EXPECT_TRUE(SetupEngine());
3152 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3153 cricket::StreamParams stream;
3154 stream.ssrcs.push_back(kSsrc2);
3155 EXPECT_TRUE(channel_->AddRecvStream(stream));
3156 cricket::WebRtcVoiceMediaChannel* media_channel =
3157 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3158 EXPECT_LT(media_channel->voe_channel(),
3159 media_channel->GetReceiveChannelNum(kSsrc2));
3160}
3161
3162TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3163 EXPECT_TRUE(SetupEngine());
solenbergbb741b32015-09-07 03:56:38 -07003164 float scale, left, right;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003165 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
solenbergbb741b32015-09-07 03:56:38 -07003166 int channel_id = voe_.GetLastChannel();
3167 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
3168 EXPECT_EQ(0, voe_.GetOutputVolumePan(channel_id, left, right));
3169 EXPECT_DOUBLE_EQ(1, left * scale);
3170 EXPECT_DOUBLE_EQ(2, right * scale);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003171
3172 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3173 cricket::StreamParams stream;
3174 stream.ssrcs.push_back(kSsrc2);
3175 EXPECT_TRUE(channel_->AddRecvStream(stream));
3176
3177 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
solenbergbb741b32015-09-07 03:56:38 -07003178 channel_id = voe_.GetLastChannel();
3179 EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
3180 EXPECT_EQ(0, voe_.GetOutputVolumePan(channel_id, left, right));
3181 EXPECT_DOUBLE_EQ(2, left * scale);
3182 EXPECT_DOUBLE_EQ(1, right * scale);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003183}
3184
pbos8fc7fa72015-07-15 08:02:58 -07003185TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
pbos8fc7fa72015-07-15 08:02:58 -07003186 const uint32 kAudioSsrc = 123;
3187 const std::string kSyncLabel = "AvSyncLabel";
3188
3189 EXPECT_TRUE(SetupEngine());
pbos8fc7fa72015-07-15 08:02:58 -07003190 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3191 sp.sync_label = kSyncLabel;
3192 // Creating two channels to make sure that sync label is set properly for both
3193 // the default voice channel and following ones.
3194 EXPECT_TRUE(channel_->AddRecvStream(sp));
3195 sp.ssrcs[0] += 1;
3196 EXPECT_TRUE(channel_->AddRecvStream(sp));
3197
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003198 ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07003199 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003200 call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003201 << "SyncGroup should be set based on sync_label";
3202 EXPECT_EQ(kSyncLabel,
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003203 call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
pbos8fc7fa72015-07-15 08:02:58 -07003204 << "SyncGroup should be set based on sync_label";
pbos8fc7fa72015-07-15 08:02:58 -07003205}
3206
pbos6bb1b6e2015-07-24 07:10:18 -07003207TEST_F(WebRtcVoiceEngineTestFake, CanChangeCombinedBweOption) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003208 // Test that changing the combined_audio_video_bwe option results in the
3209 // expected state changes on an associated Call.
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003210 std::vector<uint32> ssrcs;
3211 ssrcs.push_back(223);
3212 ssrcs.push_back(224);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003213
3214 EXPECT_TRUE(SetupEngine());
3215 cricket::WebRtcVoiceMediaChannel* media_channel =
3216 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003217 for (uint32 ssrc : ssrcs) {
3218 EXPECT_TRUE(media_channel->AddRecvStream(
3219 cricket::StreamParams::CreateLegacy(ssrc)));
3220 }
3221 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003222
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003223 // Combined BWE should be disabled.
3224 for (uint32 ssrc : ssrcs) {
3225 const auto* s = call_.GetAudioReceiveStream(ssrc);
3226 EXPECT_NE(nullptr, s);
3227 EXPECT_EQ(false, s->GetConfig().combined_audio_video_bwe);
3228 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003229
3230 // Enable combined BWE option - now it should be set up.
3231 cricket::AudioOptions options;
3232 options.combined_audio_video_bwe.Set(true);
3233 EXPECT_TRUE(media_channel->SetOptions(options));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003234 for (uint32 ssrc : ssrcs) {
3235 const auto* s = call_.GetAudioReceiveStream(ssrc);
3236 EXPECT_NE(nullptr, s);
3237 EXPECT_EQ(true, s->GetConfig().combined_audio_video_bwe);
3238 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003239
3240 // Disable combined BWE option - should be disabled again.
3241 options.combined_audio_video_bwe.Set(false);
3242 EXPECT_TRUE(media_channel->SetOptions(options));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003243 for (uint32 ssrc : ssrcs) {
3244 const auto* s = call_.GetAudioReceiveStream(ssrc);
3245 EXPECT_NE(nullptr, s);
3246 EXPECT_EQ(false, s->GetConfig().combined_audio_video_bwe);
3247 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003248
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003249 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003250}
3251
pbos6bb1b6e2015-07-24 07:10:18 -07003252TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003253 // Test that adding receive streams after enabling combined bandwidth
3254 // estimation will correctly configure each channel.
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003255 EXPECT_TRUE(SetupEngine());
3256 cricket::WebRtcVoiceMediaChannel* media_channel =
3257 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003258 cricket::AudioOptions options;
3259 options.combined_audio_video_bwe.Set(true);
3260 EXPECT_TRUE(media_channel->SetOptions(options));
3261
3262 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3263 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3264 EXPECT_TRUE(media_channel->AddRecvStream(
3265 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003266 EXPECT_NE(nullptr, call_.GetAudioReceiveStream(kSsrcs[i]));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003267 }
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003268 EXPECT_EQ(ARRAY_SIZE(kSsrcs), call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003269}
3270
pbos6bb1b6e2015-07-24 07:10:18 -07003271TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003272 // Test that setting the header extensions results in the expected state
3273 // changes on an associated Call.
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003274 std::vector<uint32> ssrcs;
3275 ssrcs.push_back(223);
3276 ssrcs.push_back(224);
3277
3278 EXPECT_TRUE(SetupEngine());
3279 cricket::WebRtcVoiceMediaChannel* media_channel =
3280 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003281 cricket::AudioOptions options;
3282 options.combined_audio_video_bwe.Set(true);
3283 EXPECT_TRUE(media_channel->SetOptions(options));
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003284 for (uint32 ssrc : ssrcs) {
3285 EXPECT_TRUE(media_channel->AddRecvStream(
3286 cricket::StreamParams::CreateLegacy(ssrc)));
3287 }
3288
3289 // Combined BWE should be set up, but with no configured extensions.
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003290 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003291 for (uint32 ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003292 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003293 EXPECT_NE(nullptr, s);
3294 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3295 }
3296
3297 // Set up receive extensions.
3298 const auto& e_exts = engine_.rtp_header_extensions();
3299 channel_->SetRecvRtpHeaderExtensions(e_exts);
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003300 EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003301 for (uint32 ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003302 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003303 EXPECT_NE(nullptr, s);
3304 const auto& s_exts = s->GetConfig().rtp.extensions;
3305 EXPECT_EQ(e_exts.size(), s_exts.size());
3306 for (const auto& e_ext : e_exts) {
3307 for (const auto& s_ext : s_exts) {
3308 if (e_ext.id == s_ext.id) {
3309 EXPECT_EQ(e_ext.uri, s_ext.name);
3310 }
3311 }
3312 }
3313 }
3314
3315 // Disable receive extensions.
3316 std::vector<cricket::RtpHeaderExtension> extensions;
3317 channel_->SetRecvRtpHeaderExtensions(extensions);
3318 for (uint32 ssrc : ssrcs) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003319 const auto* s = call_.GetAudioReceiveStream(ssrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003320 EXPECT_NE(nullptr, s);
3321 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3322 }
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003323}
3324
3325TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3326 // Test that packets are forwarded to the Call when configured accordingly.
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003327 const uint32 kAudioSsrc = 1;
3328 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3329 static const unsigned char kRtcp[] = {
3330 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3331 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3334 };
3335 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3336
3337 EXPECT_TRUE(SetupEngine());
3338 cricket::WebRtcVoiceMediaChannel* media_channel =
3339 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3340 cricket::AudioOptions options;
3341 options.combined_audio_video_bwe.Set(true);
3342 EXPECT_TRUE(media_channel->SetOptions(options));
3343 EXPECT_TRUE(media_channel->AddRecvStream(
3344 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3345
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003346 EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003347 const cricket::FakeAudioReceiveStream* s =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003348 call_.GetAudioReceiveStream(kAudioSsrc);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003349 EXPECT_EQ(0, s->received_packets());
3350 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3351 EXPECT_EQ(1, s->received_packets());
3352 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3353 EXPECT_EQ(2, s->received_packets());
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003354}
Minyue2013aec2015-05-13 14:14:42 +02003355
3356// Associate channel should not set on 1:1 call, since the receive channel also
3357// sends RTCP SR.
3358TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelUnset1On1) {
3359 EXPECT_TRUE(SetupEngine());
3360 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3361 int recv_ch = voe_.GetLastChannel();
3362 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3363}
3364
3365// This test is an extension of AssociateChannelUnset1On1. We create two receive
3366// channels. The second should be associated with the default channel, since it
3367// does not send RTCP SR.
3368TEST_F(WebRtcVoiceEngineTestFake, AssociateDefaultChannelOnSecondRecvChannel) {
3369 EXPECT_TRUE(SetupEngine());
3370 cricket::WebRtcVoiceMediaChannel* media_channel =
3371 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3372 int default_channel = media_channel->voe_channel();
3373 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3374 int recv_ch_1 = voe_.GetLastChannel();
3375 EXPECT_EQ(recv_ch_1, default_channel);
3376 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
3377 int recv_ch_2 = voe_.GetLastChannel();
3378 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_1), -1);
3379 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_2), default_channel);
3380 // Add send stream, the association remains.
3381 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
3382 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_1), -1);
3383 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_2), default_channel);
3384}
3385
3386// In conference mode, all receive channels should be associated with the
3387// default channel, since they do not send RTCP SR.
3388TEST_F(WebRtcVoiceEngineTestFake, AssociateDefaultChannelOnConference) {
3389 EXPECT_TRUE(SetupEngine());
3390 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3391 cricket::WebRtcVoiceMediaChannel* media_channel =
3392 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3393 int default_channel = media_channel->voe_channel();
3394 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3395 int recv_ch = voe_.GetLastChannel();
3396 EXPECT_NE(recv_ch, default_channel);
3397 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3398 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3399 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3400}
3401
3402TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
3403 EXPECT_TRUE(SetupEngine());
3404 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3405
3406 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3407 int recv_ch = voe_.GetLastChannel();
3408
3409 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3410 int send_ch = voe_.GetLastChannel();
3411
3412 // Manually associate |recv_ch| to |send_ch|. This test is to verify a
3413 // deleting logic, i.e., deleting |send_ch| will reset the associate send
3414 // channel of |recv_ch|.This is not a common case, since, normally, only the
3415 // default channel can be associated. However, the default is not deletable.
3416 // So we force the |recv_ch| to associate with a non-default channel.
3417 EXPECT_EQ(0, voe_.AssociateSendChannel(recv_ch, send_ch));
3418 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), send_ch);
3419
3420 EXPECT_TRUE(channel_->RemoveSendStream(2));
3421 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3422}
stefan658910c2015-09-03 05:48:32 -07003423
3424// Tests for the actual WebRtc VoE library.
3425
3426TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3427 cricket::WebRtcVoiceEngine engine;
3428 cricket::AudioOptions options = engine.GetOptions();
3429 // The default options should have at least a few things set. We purposefully
3430 // don't check the option values here, though.
3431 EXPECT_TRUE(options.echo_cancellation.IsSet());
3432 EXPECT_TRUE(options.auto_gain_control.IsSet());
3433 EXPECT_TRUE(options.noise_suppression.IsSet());
3434}
3435
3436// Tests that the library initializes and shuts down properly.
3437TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3438 cricket::WebRtcVoiceEngine engine;
3439 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003440 rtc::scoped_ptr<webrtc::Call> call(
3441 webrtc::Call::Create(webrtc::Call::Config()));
stefan658910c2015-09-03 05:48:32 -07003442 cricket::VoiceMediaChannel* channel =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003443 engine.CreateChannel(call.get(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003444 EXPECT_TRUE(channel != nullptr);
3445 delete channel;
3446 engine.Terminate();
3447
3448 // Reinit to catch regression where VoiceEngineObserver reference is lost
3449 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3450 engine.Terminate();
3451}
3452
3453// Tests that the library is configured with the codecs we want.
3454TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3455 cricket::WebRtcVoiceEngine engine;
3456 // Check codecs by name.
3457 EXPECT_TRUE(engine.FindCodec(
3458 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3459 EXPECT_TRUE(engine.FindCodec(
3460 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3461 EXPECT_TRUE(engine.FindCodec(
3462 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3463 // Check that name matching is case-insensitive.
3464 EXPECT_TRUE(engine.FindCodec(
3465 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3466 EXPECT_TRUE(engine.FindCodec(
3467 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3468 EXPECT_TRUE(engine.FindCodec(
3469 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3470 EXPECT_TRUE(engine.FindCodec(
3471 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3472 EXPECT_TRUE(engine.FindCodec(
3473 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0)));
3474 EXPECT_TRUE(engine.FindCodec(
3475 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
3476 EXPECT_TRUE(engine.FindCodec(
3477 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3478 EXPECT_TRUE(engine.FindCodec(
3479 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3480 EXPECT_TRUE(engine.FindCodec(
3481 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3482 EXPECT_TRUE(engine.FindCodec(
3483 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3484 // Check codecs with an id by id.
3485 EXPECT_TRUE(engine.FindCodec(
3486 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3487 EXPECT_TRUE(engine.FindCodec(
3488 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3489 EXPECT_TRUE(engine.FindCodec(
3490 cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722
3491 EXPECT_TRUE(engine.FindCodec(
3492 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3493 // Check sample/bitrate matching.
3494 EXPECT_TRUE(engine.FindCodec(
3495 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3496 // Check that bad codecs fail.
3497 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3498 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3499 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3500 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3501 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
3502 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3503 for (std::vector<cricket::AudioCodec>::const_iterator it =
3504 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3505 if (it->name == "CN" && it->clockrate == 16000) {
3506 EXPECT_EQ(105, it->id);
3507 } else if (it->name == "CN" && it->clockrate == 32000) {
3508 EXPECT_EQ(106, it->id);
3509 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3510 EXPECT_EQ(103, it->id);
3511 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3512 EXPECT_EQ(104, it->id);
3513 } else if (it->name == "G722" && it->clockrate == 8000) {
3514 EXPECT_EQ(9, it->id);
3515 } else if (it->name == "telephone-event") {
3516 EXPECT_EQ(126, it->id);
3517 } else if (it->name == "red") {
3518 EXPECT_EQ(127, it->id);
3519 } else if (it->name == "opus") {
3520 EXPECT_EQ(111, it->id);
3521 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3522 EXPECT_EQ("10", it->params.find("minptime")->second);
3523 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3524 EXPECT_EQ("60", it->params.find("maxptime")->second);
3525 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3526 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
3527 }
3528 }
3529
3530 engine.Terminate();
3531}
3532
3533// Tests that VoE supports at least 32 channels
3534TEST(WebRtcVoiceEngineTest, Has32Channels) {
3535 cricket::WebRtcVoiceEngine engine;
3536 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003537 rtc::scoped_ptr<webrtc::Call> call(
3538 webrtc::Call::Create(webrtc::Call::Config()));
stefan658910c2015-09-03 05:48:32 -07003539
3540 cricket::VoiceMediaChannel* channels[32];
3541 int num_channels = 0;
stefan658910c2015-09-03 05:48:32 -07003542 while (num_channels < ARRAY_SIZE(channels)) {
3543 cricket::VoiceMediaChannel* channel =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003544 engine.CreateChannel(call.get(), cricket::AudioOptions());
stefan658910c2015-09-03 05:48:32 -07003545 if (!channel)
3546 break;
stefan658910c2015-09-03 05:48:32 -07003547 channels[num_channels++] = channel;
3548 }
3549
3550 int expected = ARRAY_SIZE(channels);
3551 EXPECT_EQ(expected, num_channels);
3552
3553 while (num_channels > 0) {
3554 delete channels[--num_channels];
3555 }
3556
3557 engine.Terminate();
3558}
3559
3560// Test that we set our preferred codecs properly.
3561TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3562 cricket::WebRtcVoiceEngine engine;
3563 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003564 rtc::scoped_ptr<webrtc::Call> call(
3565 webrtc::Call::Create(webrtc::Call::Config()));
3566 cricket::WebRtcVoiceMediaChannel channel(&engine, call.get());
stefan658910c2015-09-03 05:48:32 -07003567 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3568}