blob: 7737f3413af83777774fead08f675bd430bb79b6 [file] [log] [blame]
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001/*
2 * libjingle
3 * Copyright 2008 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
28#ifdef WIN32
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000029#include "webrtc/base/win32.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030#include <objbase.h>
31#endif
32
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000033#include "webrtc/base/byteorder.h"
34#include "webrtc/base/gunit.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035#include "talk/media/base/constants.h"
36#include "talk/media/base/fakemediaengine.h"
37#include "talk/media/base/fakemediaprocessor.h"
wu@webrtc.orgde305012013-10-31 15:40:38 +000038#include "talk/media/base/fakenetworkinterface.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/media/base/fakertp.h"
Fredrik Solenberg4b60c732015-05-07 14:07:48 +020040#include "talk/media/webrtc/fakewebrtccall.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +000042#include "talk/media/webrtc/webrtcvie.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043#include "talk/media/webrtc/webrtcvoiceengine.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044#include "webrtc/p2p/base/fakesession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045#include "talk/session/media/channel.h"
46
47// Tests for the WebRtcVoiceEngine/VoiceChannel code.
48
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000049using cricket::kRtpAudioLevelHeaderExtension;
50using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
51
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
53static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +000055static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
56static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
58static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
59static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
60static const cricket::AudioCodec
61 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
62static const cricket::AudioCodec* const kAudioCodecs[] = {
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +000063 &kPcmuCodec, &kIsacCodec, &kOpusCodec, &kG722CodecVoE, &kRedCodec,
64 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065};
66const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
67static uint32 kSsrc1 = 0x99;
68static uint32 kSsrc2 = 0x98;
69
70class FakeVoEWrapper : public cricket::VoEWrapper {
71 public:
72 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
73 : cricket::VoEWrapper(engine, // processing
74 engine, // base
75 engine, // codec
76 engine, // dtmf
77 engine, // file
78 engine, // hw
79 engine, // media
80 engine, // neteq
81 engine, // network
82 engine, // rtp
83 engine, // sync
84 engine) { // volume
85 }
86};
87
wu@webrtc.org97077a32013-10-25 21:18:33 +000088class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 public:
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020090 int SetTraceFilter(const unsigned int filter) override {
wu@webrtc.org97077a32013-10-25 21:18:33 +000091 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092 return 0;
93 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020094 int SetTraceFile(const char* fileNameUTF8) override { return 0; }
95 int SetTraceCallback(webrtc::TraceCallback* callback) override { return 0; }
wu@webrtc.org97077a32013-10-25 21:18:33 +000096 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097};
98
99class WebRtcVoiceEngineTestFake : public testing::Test {
100 public:
101 class ChannelErrorListener : public sigslot::has_slots<> {
102 public:
103 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
104 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +0200105 DCHECK(channel != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000106 channel->SignalMediaError.connect(
107 this, &ChannelErrorListener::OnVoiceChannelError);
108 }
109 void OnVoiceChannelError(uint32 ssrc,
110 cricket::VoiceMediaChannel::Error error) {
111 ssrc_ = ssrc;
112 error_ = error;
113 }
114 void Reset() {
115 ssrc_ = 0;
116 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
117 }
118 uint32 ssrc() const {
119 return ssrc_;
120 }
121 cricket::VoiceMediaChannel::Error error() const {
122 return error_;
123 }
124
125 private:
126 uint32 ssrc_;
127 cricket::VoiceMediaChannel::Error error_;
128 };
129
130 WebRtcVoiceEngineTestFake()
131 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
132 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000133 trace_wrapper_(new FakeVoETraceWrapper()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134 engine_(new FakeVoEWrapper(&voe_),
135 new FakeVoEWrapper(&voe_sc_),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000136 trace_wrapper_),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 channel_(NULL), soundclip_(NULL) {
138 options_conference_.conference_mode.Set(true);
139 options_adjust_agc_.adjust_agc_delta.Set(-10);
140 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000141 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000142 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000143 return false;
144 }
145 channel_ = engine_.CreateChannel();
146 return (channel_ != NULL);
147 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000149 if (!SetupEngineWithoutStream()) {
150 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000152 return channel_->AddSendStream(
153 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000155 void SetupForMultiSendStream() {
156 EXPECT_TRUE(SetupEngine());
157 // Remove stream added in Setup, which is corresponding to default channel.
158 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000159 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000160 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
161 EXPECT_EQ(kSsrc1, default_send_ssrc);
162 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
163
164 // Verify the default channel still exists.
165 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
166 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 void DeliverPacket(const void* data, int len) {
Karl Wiberg94784372015-04-20 14:03:07 +0200168 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000169 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000170 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200171 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 delete soundclip_;
173 delete channel_;
174 engine_.Terminate();
175 }
176
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000177 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000178 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000179 channel_ = engine_.CreateChannel();
180 EXPECT_TRUE(channel_ != NULL);
181 if (caller) {
182 // if this is a caller, local description will be applied and add the
183 // send stream.
184 EXPECT_TRUE(channel_->AddSendStream(
185 cricket::StreamParams::CreateLegacy(kSsrc1)));
186 }
187 int channel_id = voe_.GetLastChannel();
188
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189 // Test we can only InsertDtmf when the other side supports telephone-event.
190 std::vector<cricket::AudioCodec> codecs;
191 codecs.push_back(kPcmuCodec);
192 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
193 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
194 EXPECT_FALSE(channel_->CanInsertDtmf());
195 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
196 codecs.push_back(kTelephoneEventCodec);
197 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
198 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000199
200 if (!caller) {
201 // There's no active send channel yet.
202 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
203 EXPECT_TRUE(channel_->AddSendStream(
204 cricket::StreamParams::CreateLegacy(kSsrc1)));
205 }
206
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 // Check we fail if the ssrc is invalid.
208 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
209
210 // Test send
211 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
212 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
213 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
214
215 // Test play
216 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
217 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
218 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
219
220 // Test send and play
221 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
222 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
223 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
224 cricket::DF_PLAY | cricket::DF_SEND));
225 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
226 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
227 }
228
229 // Test that send bandwidth is set correctly.
230 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000231 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
232 // |expected_result| is the expected result from SetMaxSendBandwidth().
233 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000235 int max_bitrate,
236 bool expected_result,
237 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 int channel_num = voe_.GetLastChannel();
239 std::vector<cricket::AudioCodec> codecs;
240
241 codecs.push_back(codec);
242 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
243
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000244 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000245 EXPECT_EQ(expected_result, result);
246
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000247 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
249
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000250 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 }
252
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000253 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
254 EXPECT_TRUE(SetupEngineWithoutStream());
255 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000256
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000257 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000258 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000259
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000260 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000261 // Ensure unknown extensions won't cause an error.
262 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000263 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000264 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000265 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000266
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000267 // Ensure extensions stay off with an empty list of headers.
268 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000269 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000270 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000271
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000272 // Ensure extension is set properly.
273 const int id = 1;
274 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000275 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000276 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000277
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000278 // Ensure extension is set properly on new channel.
279 // The first stream to occupy the default channel.
280 EXPECT_TRUE(channel_->AddSendStream(
281 cricket::StreamParams::CreateLegacy(123)));
282 EXPECT_TRUE(channel_->AddSendStream(
283 cricket::StreamParams::CreateLegacy(234)));
284 int new_channel_num = voe_.GetLastChannel();
285 EXPECT_NE(channel_num, new_channel_num);
286 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000287
288 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000289 extensions.clear();
290 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000291 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
292 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000293 }
294
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000295 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
296 EXPECT_TRUE(SetupEngineWithoutStream());
297 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000298
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000299 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000300 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000301
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000302 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000303 // Ensure unknown extensions won't cause an error.
304 extensions.push_back(cricket::RtpHeaderExtension(
305 "urn:ietf:params:unknownextention", 1));
306 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000307 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000308
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000309 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000310 extensions.clear();
311 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000312 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000313
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000314 // Ensure extension is set properly.
315 const int id = 2;
316 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000317 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000318 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000319
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000320 // Ensure extension is set properly on new channel.
321 // The first stream to occupy the default channel.
322 EXPECT_TRUE(channel_->AddRecvStream(
323 cricket::StreamParams::CreateLegacy(345)));
324 EXPECT_TRUE(channel_->AddRecvStream(
325 cricket::StreamParams::CreateLegacy(456)));
326 int new_channel_num = voe_.GetLastChannel();
327 EXPECT_NE(channel_num, new_channel_num);
328 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
329
330 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000331 extensions.clear();
332 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000333 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
334 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000335 }
336
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 protected:
338 cricket::FakeWebRtcVoiceEngine voe_;
339 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000340 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000341 cricket::WebRtcVoiceEngine engine_;
342 cricket::VoiceMediaChannel* channel_;
343 cricket::SoundclipMedia* soundclip_;
344
345 cricket::AudioOptions options_conference_;
346 cricket::AudioOptions options_adjust_agc_;
347};
348
349// Tests that our stub library "works".
350TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
351 EXPECT_FALSE(voe_.IsInited());
352 EXPECT_FALSE(voe_sc_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000353 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000355 // The soundclip engine is lazily initialized.
356 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357 engine_.Terminate();
358 EXPECT_FALSE(voe_.IsInited());
359 EXPECT_FALSE(voe_sc_.IsInited());
360}
361
362// Tests that we can create and destroy a channel.
363TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000364 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365 channel_ = engine_.CreateChannel();
366 EXPECT_TRUE(channel_ != NULL);
367}
368
369// Tests that we properly handle failures in CreateChannel.
370TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
371 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000372 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373 channel_ = engine_.CreateChannel();
374 EXPECT_TRUE(channel_ == NULL);
375}
376
377// Tests that the list of supported codecs is created properly and ordered
378// correctly
379TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
380 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
381 ASSERT_FALSE(codecs.empty());
382 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
383 EXPECT_EQ(48000, codecs[0].clockrate);
384 EXPECT_EQ(2, codecs[0].channels);
385 EXPECT_EQ(64000, codecs[0].bitrate);
386 int pref = codecs[0].preference;
387 for (size_t i = 1; i < codecs.size(); ++i) {
388 EXPECT_GT(pref, codecs[i].preference);
389 pref = codecs[i].preference;
390 }
391}
392
393// Tests that we can find codecs by name or id, and that we interpret the
394// clockrate and bitrate fields properly.
395TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
396 cricket::AudioCodec codec;
397 webrtc::CodecInst codec_inst;
398 // Find PCMU with explicit clockrate and bitrate.
399 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
400 // Find ISAC with explicit clockrate and 0 bitrate.
401 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
402 // Find telephone-event with explicit clockrate and 0 bitrate.
403 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
404 // Find ISAC with a different payload id.
405 codec = kIsacCodec;
406 codec.id = 127;
407 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
408 EXPECT_EQ(codec.id, codec_inst.pltype);
409 // Find PCMU with a 0 clockrate.
410 codec = kPcmuCodec;
411 codec.clockrate = 0;
412 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
413 EXPECT_EQ(codec.id, codec_inst.pltype);
414 EXPECT_EQ(8000, codec_inst.plfreq);
415 // Find PCMU with a 0 bitrate.
416 codec = kPcmuCodec;
417 codec.bitrate = 0;
418 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
419 EXPECT_EQ(codec.id, codec_inst.pltype);
420 EXPECT_EQ(64000, codec_inst.rate);
421 // Find ISAC with an explicit bitrate.
422 codec = kIsacCodec;
423 codec.bitrate = 32000;
424 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
425 EXPECT_EQ(codec.id, codec_inst.pltype);
426 EXPECT_EQ(32000, codec_inst.rate);
427}
428
429// Test that we set our inbound codecs properly, including changing PT.
430TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
431 EXPECT_TRUE(SetupEngine());
432 int channel_num = voe_.GetLastChannel();
433 std::vector<cricket::AudioCodec> codecs;
434 codecs.push_back(kIsacCodec);
435 codecs.push_back(kPcmuCodec);
436 codecs.push_back(kTelephoneEventCodec);
437 codecs[0].id = 106; // collide with existing telephone-event
438 codecs[2].id = 126;
439 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
440 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000441 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000442 gcodec.plfreq = 16000;
443 gcodec.channels = 1;
444 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
445 EXPECT_EQ(106, gcodec.pltype);
446 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000447 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000448 "telephone-event");
449 gcodec.plfreq = 8000;
450 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
451 EXPECT_EQ(126, gcodec.pltype);
452 EXPECT_STREQ("telephone-event", gcodec.plname);
453}
454
455// Test that we fail to set an unknown inbound codec.
456TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
457 EXPECT_TRUE(SetupEngine());
458 std::vector<cricket::AudioCodec> codecs;
459 codecs.push_back(kIsacCodec);
460 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
461 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
462}
463
464// Test that we fail if we have duplicate types in the inbound list.
465TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
466 EXPECT_TRUE(SetupEngine());
467 std::vector<cricket::AudioCodec> codecs;
468 codecs.push_back(kIsacCodec);
469 codecs.push_back(kCn16000Codec);
470 codecs[1].id = kIsacCodec.id;
471 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
472}
473
474// Test that we can decode OPUS without stereo parameters.
475TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
476 EXPECT_TRUE(SetupEngine());
477 EXPECT_TRUE(channel_->SetOptions(options_conference_));
478 std::vector<cricket::AudioCodec> codecs;
479 codecs.push_back(kIsacCodec);
480 codecs.push_back(kPcmuCodec);
481 codecs.push_back(kOpusCodec);
482 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
483 EXPECT_TRUE(channel_->AddRecvStream(
484 cricket::StreamParams::CreateLegacy(kSsrc1)));
485 int channel_num2 = voe_.GetLastChannel();
486 webrtc::CodecInst opus;
487 engine_.FindWebRtcCodec(kOpusCodec, &opus);
488 // Even without stereo parameters, recv codecs still specify channels = 2.
489 EXPECT_EQ(2, opus.channels);
490 EXPECT_EQ(111, opus.pltype);
491 EXPECT_STREQ("opus", opus.plname);
492 opus.pltype = 0;
493 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
494 EXPECT_EQ(111, opus.pltype);
495}
496
497// Test that we can decode OPUS with stereo = 0.
498TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
499 EXPECT_TRUE(SetupEngine());
500 EXPECT_TRUE(channel_->SetOptions(options_conference_));
501 std::vector<cricket::AudioCodec> codecs;
502 codecs.push_back(kIsacCodec);
503 codecs.push_back(kPcmuCodec);
504 codecs.push_back(kOpusCodec);
505 codecs[2].params["stereo"] = "0";
506 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
507 EXPECT_TRUE(channel_->AddRecvStream(
508 cricket::StreamParams::CreateLegacy(kSsrc1)));
509 int channel_num2 = voe_.GetLastChannel();
510 webrtc::CodecInst opus;
511 engine_.FindWebRtcCodec(kOpusCodec, &opus);
512 // Even when stereo is off, recv codecs still specify channels = 2.
513 EXPECT_EQ(2, opus.channels);
514 EXPECT_EQ(111, opus.pltype);
515 EXPECT_STREQ("opus", opus.plname);
516 opus.pltype = 0;
517 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
518 EXPECT_EQ(111, opus.pltype);
519}
520
521// Test that we can decode OPUS with stereo = 1.
522TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
523 EXPECT_TRUE(SetupEngine());
524 EXPECT_TRUE(channel_->SetOptions(options_conference_));
525 std::vector<cricket::AudioCodec> codecs;
526 codecs.push_back(kIsacCodec);
527 codecs.push_back(kPcmuCodec);
528 codecs.push_back(kOpusCodec);
529 codecs[2].params["stereo"] = "1";
530 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
531 EXPECT_TRUE(channel_->AddRecvStream(
532 cricket::StreamParams::CreateLegacy(kSsrc1)));
533 int channel_num2 = voe_.GetLastChannel();
534 webrtc::CodecInst opus;
535 engine_.FindWebRtcCodec(kOpusCodec, &opus);
536 EXPECT_EQ(2, opus.channels);
537 EXPECT_EQ(111, opus.pltype);
538 EXPECT_STREQ("opus", opus.plname);
539 opus.pltype = 0;
540 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
541 EXPECT_EQ(111, opus.pltype);
542}
543
544// Test that changes to recv codecs are applied to all streams.
545TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
546 EXPECT_TRUE(SetupEngine());
547 EXPECT_TRUE(channel_->SetOptions(options_conference_));
548 std::vector<cricket::AudioCodec> codecs;
549 codecs.push_back(kIsacCodec);
550 codecs.push_back(kPcmuCodec);
551 codecs.push_back(kTelephoneEventCodec);
552 codecs[0].id = 106; // collide with existing telephone-event
553 codecs[2].id = 126;
554 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
555 EXPECT_TRUE(channel_->AddRecvStream(
556 cricket::StreamParams::CreateLegacy(kSsrc1)));
557 int channel_num2 = voe_.GetLastChannel();
558 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000559 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 gcodec.plfreq = 16000;
561 gcodec.channels = 1;
562 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
563 EXPECT_EQ(106, gcodec.pltype);
564 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000565 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000566 "telephone-event");
567 gcodec.plfreq = 8000;
568 gcodec.channels = 1;
569 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
570 EXPECT_EQ(126, gcodec.pltype);
571 EXPECT_STREQ("telephone-event", gcodec.plname);
572}
573
574TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
575 EXPECT_TRUE(SetupEngine());
576 EXPECT_TRUE(channel_->SetOptions(options_conference_));
577 std::vector<cricket::AudioCodec> codecs;
578 codecs.push_back(kIsacCodec);
579 codecs[0].id = 106; // collide with existing telephone-event
580
581 EXPECT_TRUE(channel_->AddRecvStream(
582 cricket::StreamParams::CreateLegacy(kSsrc1)));
583 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
584
585 int channel_num2 = voe_.GetLastChannel();
586 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000587 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000588 gcodec.plfreq = 16000;
589 gcodec.channels = 1;
590 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
591 EXPECT_EQ(106, gcodec.pltype);
592 EXPECT_STREQ("ISAC", gcodec.plname);
593}
594
595// Test that we can apply the same set of codecs again while playing.
596TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
597 EXPECT_TRUE(SetupEngine());
598 int channel_num = voe_.GetLastChannel();
599 std::vector<cricket::AudioCodec> codecs;
600 codecs.push_back(kIsacCodec);
601 codecs.push_back(kCn16000Codec);
602 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
603 EXPECT_TRUE(channel_->SetPlayout(true));
604 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
605
606 // Changing the payload type of a codec should fail.
607 codecs[0].id = 127;
608 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
609 EXPECT_TRUE(voe_.GetPlayout(channel_num));
610}
611
612// Test that we can add a codec while playing.
613TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
614 EXPECT_TRUE(SetupEngine());
615 int channel_num = voe_.GetLastChannel();
616 std::vector<cricket::AudioCodec> codecs;
617 codecs.push_back(kIsacCodec);
618 codecs.push_back(kCn16000Codec);
619 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
620 EXPECT_TRUE(channel_->SetPlayout(true));
621
622 codecs.push_back(kOpusCodec);
623 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
624 EXPECT_TRUE(voe_.GetPlayout(channel_num));
625 webrtc::CodecInst gcodec;
626 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
627 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
628}
629
630TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
631 EXPECT_TRUE(SetupEngine());
632 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
633
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000634 // Test that when autobw is enabled, bitrate is kept as the default
635 // value. autobw is enabled for the following tests because the target
636 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000637
638 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000639 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000640
641 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000642 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000643
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000644 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000645 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646}
647
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000648TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 EXPECT_TRUE(SetupEngine());
650 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
651
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000652 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653
654 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000655 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
656 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000659 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
660 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000661}
662
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000663TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
664 EXPECT_TRUE(SetupEngine());
665 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
666
667 // Test that we can only set a maximum bitrate for a fixed-rate codec
668 // if it's bigger than the fixed rate.
669
670 // PCMU, fixed bitrate == 64000.
671 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
672 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
673 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
674 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
675 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
676 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
677 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
678}
679
680TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000681 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000682 channel_ = engine_.CreateChannel();
683 EXPECT_TRUE(channel_ != NULL);
684 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
685
686 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000687 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000688
689 EXPECT_TRUE(channel_->AddSendStream(
690 cricket::StreamParams::CreateLegacy(kSsrc1)));
691
692 int channel_num = voe_.GetLastChannel();
693 webrtc::CodecInst codec;
694 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
695 EXPECT_EQ(desired_bitrate, codec.rate);
696}
697
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698// Test that bitrate cannot be set for CBR codecs.
699// Bitrate is ignored if it is higher than the fixed bitrate.
700// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000701TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000702 EXPECT_TRUE(SetupEngine());
703 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
704
705 webrtc::CodecInst codec;
706 int channel_num = voe_.GetLastChannel();
707 std::vector<cricket::AudioCodec> codecs;
708
709 // PCMU, default bitrate == 64000.
710 codecs.push_back(kPcmuCodec);
711 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
712 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
713 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000714 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
716 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000717 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
719 EXPECT_EQ(64000, codec.rate);
720}
721
722// Test that we apply codecs properly.
723TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
724 EXPECT_TRUE(SetupEngine());
725 int channel_num = voe_.GetLastChannel();
726 std::vector<cricket::AudioCodec> codecs;
727 codecs.push_back(kIsacCodec);
728 codecs.push_back(kPcmuCodec);
729 codecs.push_back(kRedCodec);
730 codecs[0].id = 96;
731 codecs[0].bitrate = 48000;
732 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000733 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734 webrtc::CodecInst gcodec;
735 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
736 EXPECT_EQ(96, gcodec.pltype);
737 EXPECT_EQ(48000, gcodec.rate);
738 EXPECT_STREQ("ISAC", gcodec.plname);
739 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000740 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000741 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
742 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
743 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
744}
745
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000746// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
747// to apply.
748TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
749 EXPECT_TRUE(SetupEngine());
750 std::vector<cricket::AudioCodec> codecs;
751 codecs.push_back(kIsacCodec);
752 codecs.push_back(kPcmuCodec);
753 codecs.push_back(kRedCodec);
754 codecs[0].id = 96;
755 codecs[0].bitrate = 48000;
756 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
757 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
758 // Calling SetSendCodec again with same codec which is already set.
759 // In this case media channel shouldn't send codec to VoE.
760 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
761 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
762}
763
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +0000764// Verify that G722 is set with 16000 samples per second to WebRTC.
765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
766 EXPECT_TRUE(SetupEngine());
767 int channel_num = voe_.GetLastChannel();
768 std::vector<cricket::AudioCodec> codecs;
769 codecs.push_back(kG722CodecSdp);
770 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
771 webrtc::CodecInst gcodec;
772 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
773 EXPECT_STREQ("G722", gcodec.plname);
774 EXPECT_EQ(1, gcodec.channels);
775 EXPECT_EQ(16000, gcodec.plfreq);
776}
777
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000778// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000779TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
780 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781 std::vector<cricket::AudioCodec> codecs;
782 codecs.push_back(kOpusCodec);
783 codecs[0].bitrate = 0;
784 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000785 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786}
787
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000788// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000789TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
790 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791 std::vector<cricket::AudioCodec> codecs;
792 codecs.push_back(kOpusCodec);
793 codecs[0].bitrate = 0;
794 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000795 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796}
797
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000798// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000799TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
800 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801 std::vector<cricket::AudioCodec> codecs;
802 codecs.push_back(kOpusCodec);
803 codecs[0].bitrate = 0;
804 codecs[0].channels = 0;
805 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000806 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807}
808
809// Test that if channel is 1 for opus and there's no stereo, we fail.
810TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
811 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812 std::vector<cricket::AudioCodec> codecs;
813 codecs.push_back(kOpusCodec);
814 codecs[0].bitrate = 0;
815 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000816 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817}
818
819// Test that if channel is 1 for opus and stereo=0, we fail.
820TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
821 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 std::vector<cricket::AudioCodec> codecs;
823 codecs.push_back(kOpusCodec);
824 codecs[0].bitrate = 0;
825 codecs[0].channels = 1;
826 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000827 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828}
829
830// Test that if channel is 1 for opus and stereo=1, we fail.
831TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
832 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000833 std::vector<cricket::AudioCodec> codecs;
834 codecs.push_back(kOpusCodec);
835 codecs[0].bitrate = 0;
836 codecs[0].channels = 1;
837 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000838 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000839}
840
841// Test that with bitrate=0 and no stereo,
842// channels and bitrate are 1 and 32000.
843TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
844 EXPECT_TRUE(SetupEngine());
845 int channel_num = voe_.GetLastChannel();
846 std::vector<cricket::AudioCodec> codecs;
847 codecs.push_back(kOpusCodec);
848 codecs[0].bitrate = 0;
849 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
850 webrtc::CodecInst gcodec;
851 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
852 EXPECT_STREQ("opus", gcodec.plname);
853 EXPECT_EQ(1, gcodec.channels);
854 EXPECT_EQ(32000, gcodec.rate);
855}
856
857// Test that with bitrate=0 and stereo=0,
858// channels and bitrate are 1 and 32000.
859TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
860 EXPECT_TRUE(SetupEngine());
861 int channel_num = voe_.GetLastChannel();
862 std::vector<cricket::AudioCodec> codecs;
863 codecs.push_back(kOpusCodec);
864 codecs[0].bitrate = 0;
865 codecs[0].params["stereo"] = "0";
866 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
867 webrtc::CodecInst gcodec;
868 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
869 EXPECT_STREQ("opus", gcodec.plname);
870 EXPECT_EQ(1, gcodec.channels);
871 EXPECT_EQ(32000, gcodec.rate);
872}
873
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000874// Test that with bitrate=invalid and stereo=0,
875// channels and bitrate are 1 and 32000.
876TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
877 EXPECT_TRUE(SetupEngine());
878 int channel_num = voe_.GetLastChannel();
879 std::vector<cricket::AudioCodec> codecs;
880 codecs.push_back(kOpusCodec);
881 codecs[0].params["stereo"] = "0";
882 webrtc::CodecInst gcodec;
883
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000884 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000885 codecs[0].bitrate = 5999;
886 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
887 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
888 EXPECT_STREQ("opus", gcodec.plname);
889 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000890 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000891
892 codecs[0].bitrate = 510001;
893 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
894 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
895 EXPECT_STREQ("opus", gcodec.plname);
896 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000897 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000898}
899
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900// Test that with bitrate=0 and stereo=1,
901// channels and bitrate are 2 and 64000.
902TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
903 EXPECT_TRUE(SetupEngine());
904 int channel_num = voe_.GetLastChannel();
905 std::vector<cricket::AudioCodec> codecs;
906 codecs.push_back(kOpusCodec);
907 codecs[0].bitrate = 0;
908 codecs[0].params["stereo"] = "1";
909 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
910 webrtc::CodecInst gcodec;
911 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
912 EXPECT_STREQ("opus", gcodec.plname);
913 EXPECT_EQ(2, gcodec.channels);
914 EXPECT_EQ(64000, gcodec.rate);
915}
916
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000917// Test that with bitrate=invalid and stereo=1,
918// channels and bitrate are 2 and 64000.
919TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
920 EXPECT_TRUE(SetupEngine());
921 int channel_num = voe_.GetLastChannel();
922 std::vector<cricket::AudioCodec> codecs;
923 codecs.push_back(kOpusCodec);
924 codecs[0].params["stereo"] = "1";
925 webrtc::CodecInst gcodec;
926
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000927 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000928 codecs[0].bitrate = 5999;
929 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
930 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
931 EXPECT_STREQ("opus", gcodec.plname);
932 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000933 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000934
935 codecs[0].bitrate = 510001;
936 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
937 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
938 EXPECT_STREQ("opus", gcodec.plname);
939 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000940 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000941}
942
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000943// Test that with bitrate=N and stereo unset,
944// channels and bitrate are 1 and N.
945TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
946 EXPECT_TRUE(SetupEngine());
947 int channel_num = voe_.GetLastChannel();
948 std::vector<cricket::AudioCodec> codecs;
949 codecs.push_back(kOpusCodec);
950 codecs[0].bitrate = 96000;
951 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
952 webrtc::CodecInst gcodec;
953 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
954 EXPECT_EQ(111, gcodec.pltype);
955 EXPECT_EQ(96000, gcodec.rate);
956 EXPECT_STREQ("opus", gcodec.plname);
957 EXPECT_EQ(1, gcodec.channels);
958 EXPECT_EQ(48000, gcodec.plfreq);
959}
960
961// Test that with bitrate=N and stereo=0,
962// channels and bitrate are 1 and N.
963TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
964 EXPECT_TRUE(SetupEngine());
965 int channel_num = voe_.GetLastChannel();
966 std::vector<cricket::AudioCodec> codecs;
967 codecs.push_back(kOpusCodec);
968 codecs[0].bitrate = 30000;
969 codecs[0].params["stereo"] = "0";
970 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
971 webrtc::CodecInst gcodec;
972 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
973 EXPECT_EQ(1, gcodec.channels);
974 EXPECT_EQ(30000, gcodec.rate);
975 EXPECT_STREQ("opus", gcodec.plname);
976}
977
978// Test that with bitrate=N and without any parameters,
979// channels and bitrate are 1 and N.
980TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
981 EXPECT_TRUE(SetupEngine());
982 int channel_num = voe_.GetLastChannel();
983 std::vector<cricket::AudioCodec> codecs;
984 codecs.push_back(kOpusCodec);
985 codecs[0].bitrate = 30000;
986 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
987 webrtc::CodecInst gcodec;
988 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
989 EXPECT_EQ(1, gcodec.channels);
990 EXPECT_EQ(30000, gcodec.rate);
991 EXPECT_STREQ("opus", gcodec.plname);
992}
993
994// Test that with bitrate=N and stereo=1,
995// channels and bitrate are 2 and N.
996TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
997 EXPECT_TRUE(SetupEngine());
998 int channel_num = voe_.GetLastChannel();
999 std::vector<cricket::AudioCodec> codecs;
1000 codecs.push_back(kOpusCodec);
1001 codecs[0].bitrate = 30000;
1002 codecs[0].params["stereo"] = "1";
1003 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1004 webrtc::CodecInst gcodec;
1005 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1006 EXPECT_EQ(2, gcodec.channels);
1007 EXPECT_EQ(30000, gcodec.rate);
1008 EXPECT_STREQ("opus", gcodec.plname);
1009}
1010
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001011// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1012// Also test that the "maxaveragebitrate" can't be set to values outside the
1013// range of 6000 and 510000
1014TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1015 EXPECT_TRUE(SetupEngine());
1016 int channel_num = voe_.GetLastChannel();
1017 std::vector<cricket::AudioCodec> codecs;
1018 codecs.push_back(kOpusCodec);
1019 codecs[0].bitrate = 30000;
1020 webrtc::CodecInst gcodec;
1021
1022 // Ignore if less than 6000.
1023 codecs[0].params["maxaveragebitrate"] = "5999";
1024 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1025 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001026 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001027
1028 // Ignore if larger than 510000.
1029 codecs[0].params["maxaveragebitrate"] = "510001";
1030 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1031 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001032 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001033
1034 codecs[0].params["maxaveragebitrate"] = "200000";
1035 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1036 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1037 EXPECT_EQ(200000, gcodec.rate);
1038}
1039
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001040// Test that we can enable NACK with opus as caller.
1041TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001042 EXPECT_TRUE(SetupEngine());
1043 int channel_num = voe_.GetLastChannel();
1044 std::vector<cricket::AudioCodec> codecs;
1045 codecs.push_back(kOpusCodec);
1046 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1047 cricket::kParamValueEmpty));
1048 EXPECT_FALSE(voe_.GetNACK(channel_num));
1049 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1050 EXPECT_TRUE(voe_.GetNACK(channel_num));
1051}
1052
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001053// Test that we can enable NACK with opus as callee.
1054TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001055 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001056 channel_ = engine_.CreateChannel();
1057 EXPECT_TRUE(channel_ != NULL);
1058
1059 int channel_num = voe_.GetLastChannel();
1060 std::vector<cricket::AudioCodec> codecs;
1061 codecs.push_back(kOpusCodec);
1062 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1063 cricket::kParamValueEmpty));
1064 EXPECT_FALSE(voe_.GetNACK(channel_num));
1065 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1066 EXPECT_FALSE(voe_.GetNACK(channel_num));
1067
1068 EXPECT_TRUE(channel_->AddSendStream(
1069 cricket::StreamParams::CreateLegacy(kSsrc1)));
1070 EXPECT_TRUE(voe_.GetNACK(channel_num));
1071}
1072
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001073// Test that we can enable NACK on receive streams.
1074TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1075 EXPECT_TRUE(SetupEngine());
1076 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1077 int channel_num1 = voe_.GetLastChannel();
1078 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1079 int channel_num2 = voe_.GetLastChannel();
1080 std::vector<cricket::AudioCodec> codecs;
1081 codecs.push_back(kOpusCodec);
1082 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1083 cricket::kParamValueEmpty));
1084 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1085 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1086 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1087 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1088 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1089}
1090
1091// Test that we can disable NACK.
1092TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1093 EXPECT_TRUE(SetupEngine());
1094 int channel_num = voe_.GetLastChannel();
1095 std::vector<cricket::AudioCodec> codecs;
1096 codecs.push_back(kOpusCodec);
1097 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1098 cricket::kParamValueEmpty));
1099 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1100 EXPECT_TRUE(voe_.GetNACK(channel_num));
1101
1102 codecs.clear();
1103 codecs.push_back(kOpusCodec);
1104 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1105 EXPECT_FALSE(voe_.GetNACK(channel_num));
1106}
1107
1108// Test that we can disable NACK on receive streams.
1109TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1110 EXPECT_TRUE(SetupEngine());
1111 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1112 int channel_num1 = voe_.GetLastChannel();
1113 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1114 int channel_num2 = voe_.GetLastChannel();
1115 std::vector<cricket::AudioCodec> codecs;
1116 codecs.push_back(kOpusCodec);
1117 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1118 cricket::kParamValueEmpty));
1119 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1120 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1121 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1122
1123 codecs.clear();
1124 codecs.push_back(kOpusCodec);
1125 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1126 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1127 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1128}
1129
1130// Test that NACK is enabled on a new receive stream.
1131TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1132 EXPECT_TRUE(SetupEngine());
1133 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1134 int channel_num = voe_.GetLastChannel();
1135 std::vector<cricket::AudioCodec> codecs;
1136 codecs.push_back(kIsacCodec);
1137 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1138 cricket::kParamValueEmpty));
1139 codecs.push_back(kCn16000Codec);
1140 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1141 EXPECT_TRUE(voe_.GetNACK(channel_num));
1142
1143 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1144 channel_num = voe_.GetLastChannel();
1145 EXPECT_TRUE(voe_.GetNACK(channel_num));
1146 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1147 channel_num = voe_.GetLastChannel();
1148 EXPECT_TRUE(voe_.GetNACK(channel_num));
1149}
1150
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001151// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001152TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001153 EXPECT_TRUE(SetupEngine());
1154 int channel_num = voe_.GetLastChannel();
1155 std::vector<cricket::AudioCodec> codecs;
1156 codecs.push_back(kOpusCodec);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001157 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1158 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1159}
1160
1161// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001162TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001163 EXPECT_TRUE(SetupEngine());
1164 int channel_num = voe_.GetLastChannel();
1165 std::vector<cricket::AudioCodec> codecs;
1166 codecs.push_back(kOpusCodec);
1167 codecs[0].bitrate = 0;
1168 codecs[0].params["useinbandfec"] = "0";
1169 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1170 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1171 webrtc::CodecInst gcodec;
1172 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1173 EXPECT_STREQ("opus", gcodec.plname);
1174 EXPECT_EQ(1, gcodec.channels);
1175 EXPECT_EQ(32000, gcodec.rate);
1176}
1177
1178// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001179TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001180 EXPECT_TRUE(SetupEngine());
1181 int channel_num = voe_.GetLastChannel();
1182 std::vector<cricket::AudioCodec> codecs;
1183 codecs.push_back(kOpusCodec);
1184 codecs[0].bitrate = 0;
1185 codecs[0].params["useinbandfec"] = "1";
1186 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1187 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1188 webrtc::CodecInst gcodec;
1189 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1190 EXPECT_STREQ("opus", gcodec.plname);
1191 EXPECT_EQ(1, gcodec.channels);
1192 EXPECT_EQ(32000, gcodec.rate);
1193}
1194
1195// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001196TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001197 EXPECT_TRUE(SetupEngine());
1198 int channel_num = voe_.GetLastChannel();
1199 std::vector<cricket::AudioCodec> codecs;
1200 codecs.push_back(kOpusCodec);
1201 codecs[0].bitrate = 0;
1202 codecs[0].params["stereo"] = "1";
1203 codecs[0].params["useinbandfec"] = "1";
1204 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1205 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1206 webrtc::CodecInst gcodec;
1207 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1208 EXPECT_STREQ("opus", gcodec.plname);
1209 EXPECT_EQ(2, gcodec.channels);
1210 EXPECT_EQ(64000, gcodec.rate);
1211}
1212
1213// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001214TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001215 EXPECT_TRUE(SetupEngine());
1216 int channel_num = voe_.GetLastChannel();
1217 std::vector<cricket::AudioCodec> codecs;
1218 codecs.push_back(kIsacCodec);
1219 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1220 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1221}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001222
1223// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1224TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1225 EXPECT_TRUE(SetupEngine());
1226 int channel_num = voe_.GetLastChannel();
1227 std::vector<cricket::AudioCodec> codecs;
1228 codecs.push_back(kIsacCodec);
1229 codecs[0].params["useinbandfec"] = "1";
1230 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1231 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1232}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001233
1234// Test that Opus FEC status can be changed.
1235TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1236 EXPECT_TRUE(SetupEngine());
1237 int channel_num = voe_.GetLastChannel();
1238 std::vector<cricket::AudioCodec> codecs;
1239 codecs.push_back(kOpusCodec);
1240 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1241 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1242 codecs[0].params["useinbandfec"] = "1";
1243 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1244 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1245}
1246
1247// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1248TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1249 EXPECT_TRUE(SetupEngine());
1250 int channel_num = voe_.GetLastChannel();
1251 std::vector<cricket::AudioCodec> codecs;
1252 codecs.push_back(kOpusCodec);
1253 codecs[0].bitrate = 0;
1254 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1255 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1256 EXPECT_EQ(cricket::kOpusBandwidthNb,
1257 voe_.GetMaxEncodingBandwidth(channel_num));
1258 webrtc::CodecInst gcodec;
1259 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1260 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001261
1262 EXPECT_EQ(12000, gcodec.rate);
1263 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1264 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1265 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1266 EXPECT_EQ(24000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001267}
1268
1269// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1270TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1271 EXPECT_TRUE(SetupEngine());
1272 int channel_num = voe_.GetLastChannel();
1273 std::vector<cricket::AudioCodec> codecs;
1274 codecs.push_back(kOpusCodec);
1275 codecs[0].bitrate = 0;
1276 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1277 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1278 EXPECT_EQ(cricket::kOpusBandwidthMb,
1279 voe_.GetMaxEncodingBandwidth(channel_num));
1280 webrtc::CodecInst gcodec;
1281 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1282 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001283
1284 EXPECT_EQ(20000, gcodec.rate);
1285 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1286 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1287 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1288 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001289}
1290
1291// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1292TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1293 EXPECT_TRUE(SetupEngine());
1294 int channel_num = voe_.GetLastChannel();
1295 std::vector<cricket::AudioCodec> codecs;
1296 codecs.push_back(kOpusCodec);
1297 codecs[0].bitrate = 0;
1298 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1299 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1300 EXPECT_EQ(cricket::kOpusBandwidthWb,
1301 voe_.GetMaxEncodingBandwidth(channel_num));
1302 webrtc::CodecInst gcodec;
1303 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1304 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001305
1306 EXPECT_EQ(20000, gcodec.rate);
1307 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1308 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1309 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1310 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001311}
1312
1313// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1314TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1315 EXPECT_TRUE(SetupEngine());
1316 int channel_num = voe_.GetLastChannel();
1317 std::vector<cricket::AudioCodec> codecs;
1318 codecs.push_back(kOpusCodec);
1319 codecs[0].bitrate = 0;
1320 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1321 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1322 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1323 voe_.GetMaxEncodingBandwidth(channel_num));
1324 webrtc::CodecInst gcodec;
1325 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1326 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001327
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001328 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001329 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1330 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1331 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1332 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001333}
1334
1335// Test 24000 < maxplaybackrate triggers Opus full band mode.
1336TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1337 EXPECT_TRUE(SetupEngine());
1338 int channel_num = voe_.GetLastChannel();
1339 std::vector<cricket::AudioCodec> codecs;
1340 codecs.push_back(kOpusCodec);
1341 codecs[0].bitrate = 0;
1342 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1343 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1344 EXPECT_EQ(cricket::kOpusBandwidthFb,
1345 voe_.GetMaxEncodingBandwidth(channel_num));
1346 webrtc::CodecInst gcodec;
1347 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1348 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001349
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001350 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001351 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1352 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1353 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1354 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001355}
1356
1357// Test Opus that without maxplaybackrate, default playback rate is used.
1358TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1359 EXPECT_TRUE(SetupEngine());
1360 int channel_num = voe_.GetLastChannel();
1361 std::vector<cricket::AudioCodec> codecs;
1362 codecs.push_back(kOpusCodec);
1363 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1364 EXPECT_EQ(cricket::kOpusBandwidthFb,
1365 voe_.GetMaxEncodingBandwidth(channel_num));
1366}
1367
1368// Test the with non-Opus, maxplaybackrate has no effect.
1369TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1370 EXPECT_TRUE(SetupEngine());
1371 int channel_num = voe_.GetLastChannel();
1372 std::vector<cricket::AudioCodec> codecs;
1373 codecs.push_back(kIsacCodec);
1374 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1375 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1376 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1377}
1378
1379// Test maxplaybackrate can be set on two streams.
1380TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1381 EXPECT_TRUE(SetupEngine());
1382 int channel_num = voe_.GetLastChannel();
1383 std::vector<cricket::AudioCodec> codecs;
1384 codecs.push_back(kOpusCodec);
1385 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1386 // Default bandwidth is 24000.
1387 EXPECT_EQ(cricket::kOpusBandwidthFb,
1388 voe_.GetMaxEncodingBandwidth(channel_num));
1389
1390 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1391
1392 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1393 EXPECT_EQ(cricket::kOpusBandwidthNb,
1394 voe_.GetMaxEncodingBandwidth(channel_num));
1395
1396 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1397 channel_num = voe_.GetLastChannel();
1398 EXPECT_EQ(cricket::kOpusBandwidthNb,
1399 voe_.GetMaxEncodingBandwidth(channel_num));
1400}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001401
Minyue Li7100dcd2015-03-27 05:05:59 +01001402// Test that with usedtx=0, Opus DTX is off.
1403TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1404 EXPECT_TRUE(SetupEngine());
1405 int channel_num = voe_.GetLastChannel();
1406 std::vector<cricket::AudioCodec> codecs;
1407 codecs.push_back(kOpusCodec);
1408 codecs[0].params["usedtx"] = "0";
1409 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1410 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1411}
1412
1413// Test that with usedtx=1, Opus DTX is on.
1414TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1415 EXPECT_TRUE(SetupEngine());
1416 int channel_num = voe_.GetLastChannel();
1417 std::vector<cricket::AudioCodec> codecs;
1418 codecs.push_back(kOpusCodec);
1419 codecs[0].params["usedtx"] = "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 works with stereo Opus.
1426TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1427 EXPECT_TRUE(SetupEngine());
1428 int channel_num = voe_.GetLastChannel();
1429 std::vector<cricket::AudioCodec> codecs;
1430 codecs.push_back(kOpusCodec);
1431 codecs[0].params["usedtx"] = "1";
1432 codecs[0].params["stereo"] = "1";
1433 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1434 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1435 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1436}
1437
1438// Test that usedtx=1 does not work with non Opus.
1439TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1440 EXPECT_TRUE(SetupEngine());
1441 int channel_num = voe_.GetLastChannel();
1442 std::vector<cricket::AudioCodec> codecs;
1443 codecs.push_back(kIsacCodec);
1444 codecs[0].params["usedtx"] = "1";
1445 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1446 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1447}
1448
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001449// Test that we can switch back and forth between Opus and ISAC with CN.
1450TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451 EXPECT_TRUE(SetupEngine());
1452 int channel_num = voe_.GetLastChannel();
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001453 std::vector<cricket::AudioCodec> opus_codecs;
1454 opus_codecs.push_back(kOpusCodec);
1455 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001456 webrtc::CodecInst gcodec;
1457 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001458 EXPECT_EQ(111, gcodec.pltype);
1459 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460
1461 std::vector<cricket::AudioCodec> isac_codecs;
1462 isac_codecs.push_back(kIsacCodec);
1463 isac_codecs.push_back(kCn16000Codec);
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001464 isac_codecs.push_back(kOpusCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1466 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1467 EXPECT_EQ(103, gcodec.pltype);
1468 EXPECT_STREQ("ISAC", gcodec.plname);
1469
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001470 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001471 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001472 EXPECT_EQ(111, gcodec.pltype);
1473 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474}
1475
1476// Test that we handle various ways of specifying bitrate.
1477TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1478 EXPECT_TRUE(SetupEngine());
1479 int channel_num = voe_.GetLastChannel();
1480 std::vector<cricket::AudioCodec> codecs;
1481 codecs.push_back(kIsacCodec); // bitrate == 32000
1482 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1483 webrtc::CodecInst gcodec;
1484 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1485 EXPECT_EQ(103, gcodec.pltype);
1486 EXPECT_STREQ("ISAC", gcodec.plname);
1487 EXPECT_EQ(32000, gcodec.rate);
1488
1489 codecs[0].bitrate = 0; // bitrate == default
1490 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1491 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1492 EXPECT_EQ(103, gcodec.pltype);
1493 EXPECT_STREQ("ISAC", gcodec.plname);
1494 EXPECT_EQ(-1, gcodec.rate);
1495
1496 codecs[0].bitrate = 28000; // bitrate == 28000
1497 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1498 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1499 EXPECT_EQ(103, gcodec.pltype);
1500 EXPECT_STREQ("ISAC", gcodec.plname);
1501 EXPECT_EQ(28000, gcodec.rate);
1502
1503 codecs[0] = kPcmuCodec; // bitrate == 64000
1504 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1505 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1506 EXPECT_EQ(0, gcodec.pltype);
1507 EXPECT_STREQ("PCMU", gcodec.plname);
1508 EXPECT_EQ(64000, gcodec.rate);
1509
1510 codecs[0].bitrate = 0; // bitrate == default
1511 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1512 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1513 EXPECT_EQ(0, gcodec.pltype);
1514 EXPECT_STREQ("PCMU", gcodec.plname);
1515 EXPECT_EQ(64000, gcodec.rate);
1516
1517 codecs[0] = kOpusCodec;
1518 codecs[0].bitrate = 0; // bitrate == default
1519 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1520 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1521 EXPECT_EQ(111, gcodec.pltype);
1522 EXPECT_STREQ("opus", gcodec.plname);
1523 EXPECT_EQ(32000, gcodec.rate);
1524}
1525
Brave Yao5225dd82015-03-26 07:39:19 +08001526// Test that we could set packet size specified in kCodecParamPTime.
1527TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1528 EXPECT_TRUE(SetupEngine());
1529 int channel_num = voe_.GetLastChannel();
1530 std::vector<cricket::AudioCodec> codecs;
1531 codecs.push_back(kOpusCodec);
1532 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1533 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1534 webrtc::CodecInst gcodec;
1535 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1536 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1537
1538 codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Value below range.
1539 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1540 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1541 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1542
1543 codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Value beyond range.
1544 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1545 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1546 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1547
1548 codecs[0] = kIsacCodec; // Also try Isac, and with unsupported size.
1549 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1550 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1551 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1552 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1553
1554 codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1555 codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1556 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1557 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1558 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1559}
1560
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001561// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1563 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001564 std::vector<cricket::AudioCodec> codecs;
1565 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1566}
1567
1568// Test that we can set send codecs even with telephone-event codec as the first
1569// one on the list.
1570TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1571 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001572 int channel_num = voe_.GetLastChannel();
1573 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001574 codecs.push_back(kTelephoneEventCodec);
1575 codecs.push_back(kIsacCodec);
1576 codecs.push_back(kPcmuCodec);
1577 codecs[0].id = 98; // DTMF
1578 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1580 webrtc::CodecInst gcodec;
1581 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001582 EXPECT_EQ(96, gcodec.pltype);
1583 EXPECT_STREQ("ISAC", gcodec.plname);
1584 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1585}
1586
1587// Test that we can set send codecs even with CN codec as the first
1588// one on the list.
1589TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1590 EXPECT_TRUE(SetupEngine());
1591 int channel_num = voe_.GetLastChannel();
1592 std::vector<cricket::AudioCodec> codecs;
1593 codecs.push_back(kCn16000Codec);
1594 codecs.push_back(kIsacCodec);
1595 codecs.push_back(kPcmuCodec);
1596 codecs[0].id = 98; // wideband CN
1597 codecs[1].id = 96;
1598 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1599 webrtc::CodecInst gcodec;
1600 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1601 EXPECT_EQ(96, gcodec.pltype);
1602 EXPECT_STREQ("ISAC", gcodec.plname);
1603 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001604}
1605
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001606// Test that we set VAD and DTMF types correctly as caller.
1607TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001608 EXPECT_TRUE(SetupEngine());
1609 int channel_num = voe_.GetLastChannel();
1610 std::vector<cricket::AudioCodec> codecs;
1611 codecs.push_back(kIsacCodec);
1612 codecs.push_back(kPcmuCodec);
1613 // TODO(juberti): cn 32000
1614 codecs.push_back(kCn16000Codec);
1615 codecs.push_back(kCn8000Codec);
1616 codecs.push_back(kTelephoneEventCodec);
1617 codecs.push_back(kRedCodec);
1618 codecs[0].id = 96;
1619 codecs[2].id = 97; // wideband CN
1620 codecs[4].id = 98; // DTMF
1621 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1622 webrtc::CodecInst gcodec;
1623 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1624 EXPECT_EQ(96, gcodec.pltype);
1625 EXPECT_STREQ("ISAC", gcodec.plname);
1626 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001627 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001628 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1629 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1630 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1631}
1632
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001633// Test that we set VAD and DTMF types correctly as callee.
1634TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001635 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001636 channel_ = engine_.CreateChannel();
1637 EXPECT_TRUE(channel_ != NULL);
1638
1639 int channel_num = voe_.GetLastChannel();
1640 std::vector<cricket::AudioCodec> codecs;
1641 codecs.push_back(kIsacCodec);
1642 codecs.push_back(kPcmuCodec);
1643 // TODO(juberti): cn 32000
1644 codecs.push_back(kCn16000Codec);
1645 codecs.push_back(kCn8000Codec);
1646 codecs.push_back(kTelephoneEventCodec);
1647 codecs.push_back(kRedCodec);
1648 codecs[0].id = 96;
1649 codecs[2].id = 97; // wideband CN
1650 codecs[4].id = 98; // DTMF
1651 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1652 EXPECT_TRUE(channel_->AddSendStream(
1653 cricket::StreamParams::CreateLegacy(kSsrc1)));
1654
1655 webrtc::CodecInst gcodec;
1656 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1657 EXPECT_EQ(96, gcodec.pltype);
1658 EXPECT_STREQ("ISAC", gcodec.plname);
1659 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001660 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001661 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1662 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1663 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1664}
1665
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001666// Test that we only apply VAD if we have a CN codec that matches the
1667// send codec clockrate.
1668TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1669 EXPECT_TRUE(SetupEngine());
1670 int channel_num = voe_.GetLastChannel();
1671 std::vector<cricket::AudioCodec> codecs;
1672 // Set ISAC(16K) and CN(16K). VAD should be activated.
1673 codecs.push_back(kIsacCodec);
1674 codecs.push_back(kCn16000Codec);
1675 codecs[1].id = 97;
1676 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1677 webrtc::CodecInst gcodec;
1678 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1679 EXPECT_STREQ("ISAC", gcodec.plname);
1680 EXPECT_TRUE(voe_.GetVAD(channel_num));
1681 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1682 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1683 codecs[0] = kPcmuCodec;
1684 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1685 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1686 EXPECT_STREQ("PCMU", gcodec.plname);
1687 EXPECT_FALSE(voe_.GetVAD(channel_num));
1688 // Set PCMU(8K) and CN(8K). VAD should be activated.
1689 codecs[1] = kCn8000Codec;
1690 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1691 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1692 EXPECT_STREQ("PCMU", gcodec.plname);
1693 EXPECT_TRUE(voe_.GetVAD(channel_num));
1694 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
Brave Yao5225dd82015-03-26 07:39:19 +08001695 // Set ISAC(16K) and CN(8K). VAD should not be activated.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001696 codecs[0] = kIsacCodec;
1697 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1698 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1699 EXPECT_STREQ("ISAC", gcodec.plname);
1700 EXPECT_FALSE(voe_.GetVAD(channel_num));
1701}
1702
1703// Test that we perform case-insensitive matching of codec names.
1704TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1705 EXPECT_TRUE(SetupEngine());
1706 int channel_num = voe_.GetLastChannel();
1707 std::vector<cricket::AudioCodec> codecs;
1708 codecs.push_back(kIsacCodec);
1709 codecs.push_back(kPcmuCodec);
1710 codecs.push_back(kCn16000Codec);
1711 codecs.push_back(kCn8000Codec);
1712 codecs.push_back(kTelephoneEventCodec);
1713 codecs.push_back(kRedCodec);
1714 codecs[0].name = "iSaC";
1715 codecs[0].id = 96;
1716 codecs[2].id = 97; // wideband CN
1717 codecs[4].id = 98; // DTMF
1718 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1719 webrtc::CodecInst gcodec;
1720 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1721 EXPECT_EQ(96, gcodec.pltype);
1722 EXPECT_STREQ("ISAC", gcodec.plname);
1723 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001724 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001725 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1726 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1727 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1728}
1729
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001730// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001731TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001732 EXPECT_TRUE(SetupEngine());
1733 int channel_num = voe_.GetLastChannel();
1734 std::vector<cricket::AudioCodec> codecs;
1735 codecs.push_back(kRedCodec);
1736 codecs.push_back(kIsacCodec);
1737 codecs.push_back(kPcmuCodec);
1738 codecs[0].id = 127;
1739 codecs[0].params[""] = "96/96";
1740 codecs[1].id = 96;
1741 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1742 webrtc::CodecInst gcodec;
1743 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1744 EXPECT_EQ(96, gcodec.pltype);
1745 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001746 EXPECT_TRUE(voe_.GetRED(channel_num));
1747 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001748}
1749
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001750// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001751TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001752 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001753 channel_ = engine_.CreateChannel();
1754 EXPECT_TRUE(channel_ != NULL);
1755
1756 int channel_num = voe_.GetLastChannel();
1757 std::vector<cricket::AudioCodec> codecs;
1758 codecs.push_back(kRedCodec);
1759 codecs.push_back(kIsacCodec);
1760 codecs.push_back(kPcmuCodec);
1761 codecs[0].id = 127;
1762 codecs[0].params[""] = "96/96";
1763 codecs[1].id = 96;
1764 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1765 EXPECT_TRUE(channel_->AddSendStream(
1766 cricket::StreamParams::CreateLegacy(kSsrc1)));
1767 webrtc::CodecInst gcodec;
1768 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1769 EXPECT_EQ(96, gcodec.pltype);
1770 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001771 EXPECT_TRUE(voe_.GetRED(channel_num));
1772 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001773}
1774
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001775// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1777 EXPECT_TRUE(SetupEngine());
1778 int channel_num = voe_.GetLastChannel();
1779 std::vector<cricket::AudioCodec> codecs;
1780 codecs.push_back(kRedCodec);
1781 codecs.push_back(kIsacCodec);
1782 codecs.push_back(kPcmuCodec);
1783 codecs[0].id = 127;
1784 codecs[1].id = 96;
1785 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1786 webrtc::CodecInst gcodec;
1787 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1788 EXPECT_EQ(96, gcodec.pltype);
1789 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001790 EXPECT_TRUE(voe_.GetRED(channel_num));
1791 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001792}
1793
1794// Test that we ignore RED if the parameters aren't named the way we expect.
1795TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1796 EXPECT_TRUE(SetupEngine());
1797 int channel_num = voe_.GetLastChannel();
1798 std::vector<cricket::AudioCodec> codecs;
1799 codecs.push_back(kRedCodec);
1800 codecs.push_back(kIsacCodec);
1801 codecs.push_back(kPcmuCodec);
1802 codecs[0].id = 127;
1803 codecs[0].params["ABC"] = "96/96";
1804 codecs[1].id = 96;
1805 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1806 webrtc::CodecInst gcodec;
1807 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1808 EXPECT_EQ(96, gcodec.pltype);
1809 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001810 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811}
1812
1813// Test that we ignore RED if it uses different primary/secondary encoding.
1814TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1815 EXPECT_TRUE(SetupEngine());
1816 int channel_num = voe_.GetLastChannel();
1817 std::vector<cricket::AudioCodec> codecs;
1818 codecs.push_back(kRedCodec);
1819 codecs.push_back(kIsacCodec);
1820 codecs.push_back(kPcmuCodec);
1821 codecs[0].id = 127;
1822 codecs[0].params[""] = "96/0";
1823 codecs[1].id = 96;
1824 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1825 webrtc::CodecInst gcodec;
1826 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1827 EXPECT_EQ(96, gcodec.pltype);
1828 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001829 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001830}
1831
1832// Test that we ignore RED if it uses more than 2 encodings.
1833TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1834 EXPECT_TRUE(SetupEngine());
1835 int channel_num = voe_.GetLastChannel();
1836 std::vector<cricket::AudioCodec> codecs;
1837 codecs.push_back(kRedCodec);
1838 codecs.push_back(kIsacCodec);
1839 codecs.push_back(kPcmuCodec);
1840 codecs[0].id = 127;
1841 codecs[0].params[""] = "96/96/96";
1842 codecs[1].id = 96;
1843 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1844 webrtc::CodecInst gcodec;
1845 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1846 EXPECT_EQ(96, gcodec.pltype);
1847 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001848 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001849}
1850
1851// Test that we ignore RED if it has bogus codec ids.
1852TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1853 EXPECT_TRUE(SetupEngine());
1854 int channel_num = voe_.GetLastChannel();
1855 std::vector<cricket::AudioCodec> codecs;
1856 codecs.push_back(kRedCodec);
1857 codecs.push_back(kIsacCodec);
1858 codecs.push_back(kPcmuCodec);
1859 codecs[0].id = 127;
1860 codecs[0].params[""] = "ABC/ABC";
1861 codecs[1].id = 96;
1862 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1863 webrtc::CodecInst gcodec;
1864 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1865 EXPECT_EQ(96, gcodec.pltype);
1866 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001867 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001868}
1869
1870// Test that we ignore RED if it refers to a codec that is not present.
1871TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1872 EXPECT_TRUE(SetupEngine());
1873 int channel_num = voe_.GetLastChannel();
1874 std::vector<cricket::AudioCodec> codecs;
1875 codecs.push_back(kRedCodec);
1876 codecs.push_back(kIsacCodec);
1877 codecs.push_back(kPcmuCodec);
1878 codecs[0].id = 127;
1879 codecs[0].params[""] = "97/97";
1880 codecs[1].id = 96;
1881 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1882 webrtc::CodecInst gcodec;
1883 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1884 EXPECT_EQ(96, gcodec.pltype);
1885 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001886 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001887}
1888
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001889// Test support for audio level header extension.
1890TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1891 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001892}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001893TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1894 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1895}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001896
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001897// Test support for absolute send time header extension.
1898TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1899 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1900}
1901TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1902 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001903}
1904
1905// Test that we can create a channel and start sending/playing out on it.
1906TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1907 EXPECT_TRUE(SetupEngine());
1908 int channel_num = voe_.GetLastChannel();
1909 std::vector<cricket::AudioCodec> codecs;
1910 codecs.push_back(kPcmuCodec);
1911 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1912 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1913 EXPECT_TRUE(voe_.GetSend(channel_num));
1914 EXPECT_TRUE(channel_->SetPlayout(true));
1915 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1916 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1917 EXPECT_FALSE(voe_.GetSend(channel_num));
1918 EXPECT_TRUE(channel_->SetPlayout(false));
1919 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1920}
1921
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001922// Test that we can add and remove send streams.
1923TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1924 SetupForMultiSendStream();
1925
1926 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1927
1928 // Set the global state for sending.
1929 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1930
1931 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1932 EXPECT_TRUE(channel_->AddSendStream(
1933 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1934
1935 // Verify that we are in a sending state for all the created streams.
1936 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1937 EXPECT_TRUE(voe_.GetSend(channel_num));
1938 }
1939
1940 // Remove the first send channel, which is the default channel. It will only
1941 // recycle the default channel but not delete it.
1942 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1943 // Stream should already be Removed from the send stream list.
1944 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1945 // But the default still exists.
1946 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1947
1948 // Delete the rest of send channel streams.
1949 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1950 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1951 // Stream should already be deleted.
1952 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1953 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1954 }
1955}
1956
1957// Test SetSendCodecs correctly configure the codecs in all send streams.
1958TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1959 SetupForMultiSendStream();
1960
1961 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1962 // Create send streams.
1963 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1964 EXPECT_TRUE(channel_->AddSendStream(
1965 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1966 }
1967
1968 std::vector<cricket::AudioCodec> codecs;
1969 // Set ISAC(16K) and CN(16K). VAD should be activated.
1970 codecs.push_back(kIsacCodec);
1971 codecs.push_back(kCn16000Codec);
1972 codecs[1].id = 97;
1973 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1974
1975 // Verify ISAC and VAD are corrected configured on all send channels.
1976 webrtc::CodecInst gcodec;
1977 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1978 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1979 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1980 EXPECT_STREQ("ISAC", gcodec.plname);
1981 EXPECT_TRUE(voe_.GetVAD(channel_num));
1982 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1983 }
1984
1985 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1986 codecs[0] = kPcmuCodec;
1987 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1988 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1989 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1990 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1991 EXPECT_STREQ("PCMU", gcodec.plname);
1992 EXPECT_FALSE(voe_.GetVAD(channel_num));
1993 }
1994}
1995
1996// Test we can SetSend on all send streams correctly.
1997TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1998 SetupForMultiSendStream();
1999
2000 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2001 // Create the send channels and they should be a SEND_NOTHING date.
2002 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2003 EXPECT_TRUE(channel_->AddSendStream(
2004 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2005 int channel_num = voe_.GetLastChannel();
2006 EXPECT_FALSE(voe_.GetSend(channel_num));
2007 }
2008
2009 // Set the global state for starting sending.
2010 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2011 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2012 // Verify that we are in a sending state for all the send streams.
2013 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2014 EXPECT_TRUE(voe_.GetSend(channel_num));
2015 }
2016
2017 // Set the global state for stopping sending.
2018 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2019 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
2020 // Verify that we are in a stop state for all the send streams.
2021 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2022 EXPECT_FALSE(voe_.GetSend(channel_num));
2023 }
2024}
2025
2026// Test we can set the correct statistics on all send streams.
2027TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2028 SetupForMultiSendStream();
2029
2030 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2031 // Create send streams.
2032 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2033 EXPECT_TRUE(channel_->AddSendStream(
2034 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2035 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002036 // Create a receive stream to check that none of the send streams end up in
2037 // the receive stream stats.
2038 EXPECT_TRUE(channel_->AddRecvStream(
2039 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002040 // We need send codec to be set to get all stats.
2041 std::vector<cricket::AudioCodec> codecs;
2042 codecs.push_back(kPcmuCodec);
2043 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002044 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002045
2046 cricket::VoiceMediaInfo info;
2047 EXPECT_EQ(true, channel_->GetStats(&info));
2048 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
2049
2050 // Verify the statistic information is correct.
2051 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002052 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002053 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
2054 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
2055 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
2056 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
2057 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
2058 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
2059 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
2060 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002061 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002062 }
2063
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002064 EXPECT_EQ(0u, info.receivers.size());
2065 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2066 EXPECT_EQ(true, channel_->GetStats(&info));
2067
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002068 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002069 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2070 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2071 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2072 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2073 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002074 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2075 (1 << 14), info.receivers[0].expand_rate);
2076 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2077 (1 << 14), info.receivers[0].speech_expand_rate);
2078 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2079 (1 << 14), info.receivers[0].secondary_decoded_rate);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002080}
2081
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002082// Test that we can add and remove receive streams, and do proper send/playout.
2083// We can receive on multiple streams while sending one stream.
2084TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002085 EXPECT_TRUE(SetupEngine());
2086 int channel_num1 = voe_.GetLastChannel();
2087
2088 // Start playout on the default channel.
2089 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2090 EXPECT_TRUE(channel_->SetPlayout(true));
2091 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2092
2093 // Adding another stream should disable playout on the default channel.
2094 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2095 int channel_num2 = voe_.GetLastChannel();
2096 std::vector<cricket::AudioCodec> codecs;
2097 codecs.push_back(kPcmuCodec);
2098 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2099 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2100 EXPECT_TRUE(voe_.GetSend(channel_num1));
2101 EXPECT_FALSE(voe_.GetSend(channel_num2));
2102
2103 // Make sure only the new channel is played out.
2104 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2105 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2106
2107 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2108 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2109 int channel_num3 = voe_.GetLastChannel();
2110 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2111 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2112 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2113 EXPECT_FALSE(voe_.GetSend(channel_num3));
2114
2115 // Stop sending.
2116 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2117 EXPECT_FALSE(voe_.GetSend(channel_num1));
2118 EXPECT_FALSE(voe_.GetSend(channel_num2));
2119 EXPECT_FALSE(voe_.GetSend(channel_num3));
2120
2121 // Stop playout.
2122 EXPECT_TRUE(channel_->SetPlayout(false));
2123 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2124 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2125 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2126
2127 // Restart playout and make sure the default channel still is not played out.
2128 EXPECT_TRUE(channel_->SetPlayout(true));
2129 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2130 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2131 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2132
2133 // Now remove the new streams and verify that the default channel is
2134 // played out again.
2135 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2136 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2137
2138 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2139}
2140
2141// Test that we can set the devices to use.
2142TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2143 EXPECT_TRUE(SetupEngine());
2144 int channel_num = voe_.GetLastChannel();
2145 std::vector<cricket::AudioCodec> codecs;
2146 codecs.push_back(kPcmuCodec);
2147 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2148
2149 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2150 cricket::kFakeDefaultDeviceId);
2151 cricket::Device dev(cricket::kFakeDeviceName,
2152 cricket::kFakeDeviceId);
2153
2154 // Test SetDevices() while not sending or playing.
2155 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2156
2157 // Test SetDevices() while sending and playing.
2158 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2159 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2160 EXPECT_TRUE(channel_->SetPlayout(true));
2161 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2162 EXPECT_TRUE(voe_.GetSend(channel_num));
2163 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2164
2165 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2166
2167 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2168 EXPECT_TRUE(voe_.GetSend(channel_num));
2169 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2170
2171 // Test that failure to open newly selected devices does not prevent opening
2172 // ones after that.
2173 voe_.set_fail_start_recording_microphone(true);
2174 voe_.set_playout_fail_channel(channel_num);
2175 voe_.set_send_fail_channel(channel_num);
2176
2177 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2178
2179 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2180 EXPECT_FALSE(voe_.GetSend(channel_num));
2181 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2182
2183 voe_.set_fail_start_recording_microphone(false);
2184 voe_.set_playout_fail_channel(-1);
2185 voe_.set_send_fail_channel(-1);
2186
2187 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2188
2189 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2190 EXPECT_TRUE(voe_.GetSend(channel_num));
2191 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2192}
2193
2194// Test that we can set the devices to use even if we failed to
2195// open the initial ones.
2196TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2197 EXPECT_TRUE(SetupEngine());
2198 int channel_num = voe_.GetLastChannel();
2199 std::vector<cricket::AudioCodec> codecs;
2200 codecs.push_back(kPcmuCodec);
2201 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2202
2203 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2204 cricket::kFakeDefaultDeviceId);
2205 cricket::Device dev(cricket::kFakeDeviceName,
2206 cricket::kFakeDeviceId);
2207
2208 // Test that failure to open devices selected before starting
2209 // send/play does not prevent opening newly selected ones after that.
2210 voe_.set_fail_start_recording_microphone(true);
2211 voe_.set_playout_fail_channel(channel_num);
2212 voe_.set_send_fail_channel(channel_num);
2213
2214 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2215
2216 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2217 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2218 EXPECT_FALSE(channel_->SetPlayout(true));
2219 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2220 EXPECT_FALSE(voe_.GetSend(channel_num));
2221 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2222
2223 voe_.set_fail_start_recording_microphone(false);
2224 voe_.set_playout_fail_channel(-1);
2225 voe_.set_send_fail_channel(-1);
2226
2227 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2228
2229 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2230 EXPECT_TRUE(voe_.GetSend(channel_num));
2231 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2232}
2233
2234// Test that we can create a channel configured for multi-point conferences,
2235// and start sending/playing out on it.
2236TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2237 EXPECT_TRUE(SetupEngine());
2238 int channel_num = voe_.GetLastChannel();
2239 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2240 std::vector<cricket::AudioCodec> codecs;
2241 codecs.push_back(kPcmuCodec);
2242 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2243 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2244 EXPECT_TRUE(voe_.GetSend(channel_num));
2245}
2246
2247// Test that we can create a channel configured for Codian bridges,
2248// and start sending/playing out on it.
2249TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2250 EXPECT_TRUE(SetupEngine());
2251 int channel_num = voe_.GetLastChannel();
2252 webrtc::AgcConfig agc_config;
2253 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2254 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2255 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2256 std::vector<cricket::AudioCodec> codecs;
2257 codecs.push_back(kPcmuCodec);
2258 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2259 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2260 EXPECT_TRUE(voe_.GetSend(channel_num));
2261 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2262 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2263 EXPECT_TRUE(channel_->SetPlayout(true));
2264 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2265 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2266 EXPECT_FALSE(voe_.GetSend(channel_num));
2267 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2268 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2269 EXPECT_TRUE(channel_->SetPlayout(false));
2270 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2271}
2272
wu@webrtc.org97077a32013-10-25 21:18:33 +00002273TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2274 EXPECT_TRUE(SetupEngine());
2275 webrtc::AgcConfig agc_config;
2276 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2277 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2278
2279 cricket::AudioOptions options;
2280 options.tx_agc_target_dbov.Set(3);
2281 options.tx_agc_digital_compression_gain.Set(9);
2282 options.tx_agc_limiter.Set(true);
2283 options.auto_gain_control.Set(true);
2284 EXPECT_TRUE(engine_.SetOptions(options));
2285
2286 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2287 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2288 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2289 EXPECT_TRUE(agc_config.limiterEnable);
2290
2291 // Check interaction with adjust_agc_delta. Both should be respected, for
2292 // backwards compatibility.
2293 options.adjust_agc_delta.Set(-10);
2294 EXPECT_TRUE(engine_.SetOptions(options));
2295
2296 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2297 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2298}
2299
2300TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2301 EXPECT_TRUE(SetupEngine());
2302 int channel_num = voe_.GetLastChannel();
2303 cricket::AudioOptions options;
2304 options.rx_agc_target_dbov.Set(6);
2305 options.rx_agc_digital_compression_gain.Set(0);
2306 options.rx_agc_limiter.Set(true);
2307 options.rx_auto_gain_control.Set(true);
2308 EXPECT_TRUE(channel_->SetOptions(options));
2309
2310 webrtc::AgcConfig agc_config;
2311 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2312 channel_num, agc_config));
2313 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2314 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2315 EXPECT_TRUE(agc_config.limiterEnable);
2316}
2317
2318TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2319 EXPECT_TRUE(SetupEngine());
2320 cricket::AudioOptions options;
2321 options.recording_sample_rate.Set(48000u);
2322 options.playout_sample_rate.Set(44100u);
2323 EXPECT_TRUE(engine_.SetOptions(options));
2324
2325 unsigned int recording_sample_rate, playout_sample_rate;
2326 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2327 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2328 EXPECT_EQ(48000u, recording_sample_rate);
2329 EXPECT_EQ(44100u, playout_sample_rate);
2330}
2331
2332TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2333 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002334 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002335 EXPECT_EQ(
2336 // Info:
2337 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2338 // Warning:
2339 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2340 // Error:
2341 webrtc::kTraceError | webrtc::kTraceCritical,
2342 static_cast<int>(trace_wrapper_->filter_));
2343 // Now set it explicitly
2344 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002345 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2346 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002347 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2348 trace_wrapper_->filter_);
2349}
2350
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002351// Test that we can set the outgoing SSRC properly.
2352// SSRC is set in SetupEngine by calling AddSendStream.
2353TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2354 EXPECT_TRUE(SetupEngine());
2355 int channel_num = voe_.GetLastChannel();
2356 unsigned int send_ssrc;
2357 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2358 EXPECT_NE(0U, send_ssrc);
2359 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2360 EXPECT_EQ(kSsrc1, send_ssrc);
2361}
2362
2363TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2364 // Setup. We need send codec to be set to get all stats.
2365 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002366 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2367 // use a different SSRC.
2368 EXPECT_TRUE(channel_->AddRecvStream(
2369 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002370 std::vector<cricket::AudioCodec> codecs;
2371 codecs.push_back(kPcmuCodec);
2372 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002373 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374
2375 cricket::VoiceMediaInfo info;
2376 EXPECT_EQ(true, channel_->GetStats(&info));
2377 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002378 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002379 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2380 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2381 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2382 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2383 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2384 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2385 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2386 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002387 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002388 // TODO(sriniv): Add testing for more fields. These are not populated
2389 // in FakeWebrtcVoiceEngine yet.
2390 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2391 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2392 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2393 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2394 // EXPECT_EQ(cricket::kIntStatValue,
2395 // info.senders[0].echo_return_loss_enhancement);
2396
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002397 EXPECT_EQ(0u, info.receivers.size());
2398 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2399 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002400 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002401
2402 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2403 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2404 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2405 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2406 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002407 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2408 (1 << 14), info.receivers[0].expand_rate);
2409 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2410 (1 << 14), info.receivers[0].speech_expand_rate);
2411 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2412 (1 << 14), info.receivers[0].secondary_decoded_rate);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002413 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002414}
2415
2416// Test that we can set the outgoing SSRC properly with multiple streams.
2417// SSRC is set in SetupEngine by calling AddSendStream.
2418TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2419 EXPECT_TRUE(SetupEngine());
2420 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2421 int channel_num1 = voe_.GetLastChannel();
2422 unsigned int send_ssrc;
2423 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2424 EXPECT_EQ(kSsrc1, send_ssrc);
2425
2426 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2427 int channel_num2 = voe_.GetLastChannel();
2428 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2429 EXPECT_EQ(kSsrc1, send_ssrc);
2430}
2431
2432// Test that the local SSRC is the same on sending and receiving channels if the
2433// receive channel is created before the send channel.
2434TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002435 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002436 channel_ = engine_.CreateChannel();
2437 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2438
2439 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2440 int receive_channel_num = voe_.GetLastChannel();
2441 EXPECT_TRUE(channel_->AddSendStream(
2442 cricket::StreamParams::CreateLegacy(1234)));
2443 int send_channel_num = voe_.GetLastChannel();
2444
2445 unsigned int ssrc = 0;
2446 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2447 EXPECT_EQ(1234U, ssrc);
2448 ssrc = 0;
2449 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2450 EXPECT_EQ(1234U, ssrc);
2451}
2452
2453// Test that we can properly receive packets.
2454TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2455 EXPECT_TRUE(SetupEngine());
2456 int channel_num = voe_.GetLastChannel();
2457 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2458 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2459 sizeof(kPcmuFrame)));
2460}
2461
2462// Test that we can properly receive packets on multiple streams.
2463TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2464 EXPECT_TRUE(SetupEngine());
2465 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2466 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2467 int channel_num1 = voe_.GetLastChannel();
2468 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2469 int channel_num2 = voe_.GetLastChannel();
2470 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2471 int channel_num3 = voe_.GetLastChannel();
2472 // Create packets with the right SSRCs.
2473 char packets[4][sizeof(kPcmuFrame)];
2474 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2475 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002476 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002477 }
2478 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2479 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2480 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2481 DeliverPacket(packets[0], sizeof(packets[0]));
2482 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2483 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2484 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2485 DeliverPacket(packets[1], sizeof(packets[1]));
2486 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2487 sizeof(packets[1])));
2488 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2489 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2490 DeliverPacket(packets[2], sizeof(packets[2]));
2491 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2492 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2493 sizeof(packets[2])));
2494 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2495 DeliverPacket(packets[3], sizeof(packets[3]));
2496 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2497 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2498 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2499 sizeof(packets[3])));
2500 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2501 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2502 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2503}
2504
2505// Test that we properly handle failures to add a stream.
2506TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2507 EXPECT_TRUE(SetupEngine());
2508 voe_.set_fail_create_channel(true);
2509 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2510 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2511
2512 // In 1:1 call, we should not try to create a new channel.
2513 cricket::AudioOptions options_no_conference_;
2514 options_no_conference_.conference_mode.Set(false);
2515 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2516 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2517}
2518
2519// Test that AddRecvStream doesn't create new channel for 1:1 call.
2520TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2521 EXPECT_TRUE(SetupEngine());
2522 int channel_num = voe_.GetLastChannel();
2523 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2524 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2525}
2526
2527// Test that after adding a recv stream, we do not decode more codecs than
2528// those previously passed into SetRecvCodecs.
2529TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2530 EXPECT_TRUE(SetupEngine());
2531 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2532 std::vector<cricket::AudioCodec> codecs;
2533 codecs.push_back(kIsacCodec);
2534 codecs.push_back(kPcmuCodec);
2535 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2536 EXPECT_TRUE(channel_->AddRecvStream(
2537 cricket::StreamParams::CreateLegacy(kSsrc1)));
2538 int channel_num2 = voe_.GetLastChannel();
2539 webrtc::CodecInst gcodec;
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002540 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "opus");
2541 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002542 gcodec.channels = 2;
2543 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2544}
2545
2546// Test that we properly clean up any streams that were added, even if
2547// not explicitly removed.
2548TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2549 EXPECT_TRUE(SetupEngine());
2550 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2551 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2552 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2553 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2554 delete channel_;
2555 channel_ = NULL;
2556 EXPECT_EQ(0, voe_.GetNumChannels());
2557}
2558
wu@webrtc.org78187522013-10-07 23:32:02 +00002559TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2560 EXPECT_TRUE(SetupEngine());
2561 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2562}
2563
2564TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2565 EXPECT_TRUE(SetupEngine());
2566 // Stream 1 reuses default channel.
2567 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2568 // Manually delete default channel to simulate a failure.
2569 int default_channel = voe_.GetLastChannel();
2570 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2571 // Add recv stream 2 should fail because default channel is gone.
2572 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2573 int new_channel = voe_.GetLastChannel();
2574 EXPECT_NE(default_channel, new_channel);
2575 // The last created channel should have already been deleted.
2576 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2577}
2578
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002579// Test the InsertDtmf on default send stream as caller.
2580TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2581 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002582}
2583
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002584// Test the InsertDtmf on default send stream as callee
2585TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2586 TestInsertDtmf(0, false);
2587}
2588
2589// Test the InsertDtmf on specified send stream as caller.
2590TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2591 TestInsertDtmf(kSsrc1, true);
2592}
2593
2594// Test the InsertDtmf on specified send stream as callee.
2595TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2596 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002597}
2598
2599// Test that we can play a ringback tone properly in a single-stream call.
2600TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2601 EXPECT_TRUE(SetupEngine());
2602 int channel_num = voe_.GetLastChannel();
2603 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2604 // Check we fail if no ringback tone specified.
2605 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2606 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2607 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002608 EXPECT_TRUE(channel_->SetRingbackTone(
2609 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002610 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2611 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2612 // Check we can stop the tone manually.
2613 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2614 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2615 // Check we stop the tone if a packet arrives.
2616 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2617 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2618 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2619 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2620}
2621
2622// Test that we can play a ringback tone properly in a multi-stream call.
2623TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2624 EXPECT_TRUE(SetupEngine());
2625 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2626 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2627 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2628 int channel_num = voe_.GetLastChannel();
2629 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2630 // Check we fail if no ringback tone specified.
2631 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2632 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2633 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002634 EXPECT_TRUE(channel_->SetRingbackTone(
2635 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002636 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2637 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2638 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2639 // Check we can stop the tone manually.
2640 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2641 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2642 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2643 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2644 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2645 // Send a packet with SSRC 1; the tone should not stop.
2646 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2647 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2648 // Send a packet with SSRC 2; the tone should stop.
2649 char packet[sizeof(kPcmuFrame)];
2650 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002651 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002652 DeliverPacket(packet, sizeof(packet));
2653 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2654}
2655
2656// Tests creating soundclips, and make sure they come from the right engine.
2657TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002658 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002659 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002660 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002661 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002662 ASSERT_TRUE(soundclip_ != NULL);
2663 EXPECT_EQ(0, voe_.GetNumChannels());
2664 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2665 int channel_num = voe_sc_.GetLastChannel();
2666 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2667 delete soundclip_;
2668 soundclip_ = NULL;
2669 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002670 // Make sure the soundclip engine is uninitialized on shutdown, now that
2671 // we've initialized it by creating a soundclip.
2672 engine_.Terminate();
2673 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002674}
2675
2676// Tests playing out a fake sound.
2677TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2678 static const char kZeroes[16000] = {};
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002679 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002680 soundclip_ = engine_.CreateSoundclip();
2681 ASSERT_TRUE(soundclip_ != NULL);
2682 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2683}
2684
2685TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002686 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002687 cricket::WebRtcVoiceMediaChannel* media_channel;
2688 unsigned int ssrc = 0;
2689
2690 EXPECT_TRUE(SetupEngine());
2691 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2692 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2693
2694 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2695 listener.reset(new ChannelErrorListener(channel_));
2696
2697 // Test on WebRtc VoE channel.
2698 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2699 VE_SATURATION_WARNING);
2700 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2701 listener->error());
2702 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2703 EXPECT_EQ(ssrc, listener->ssrc());
2704
2705 listener->Reset();
2706 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2707 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2708 listener->error());
2709 EXPECT_EQ(0U, listener->ssrc());
2710
2711 // Add another stream and test on that.
2712 ++ssrc;
2713 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2714 ssrc)));
2715 listener->Reset();
2716 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2717 VE_SATURATION_WARNING);
2718 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2719 listener->error());
2720 EXPECT_EQ(ssrc, listener->ssrc());
2721
2722 // Testing a non-existing channel.
2723 listener->Reset();
2724 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2725 VE_SATURATION_WARNING);
2726 EXPECT_EQ(0, listener->error());
2727}
2728
2729TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2730 EXPECT_TRUE(SetupEngine());
2731 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2732 std::vector<cricket::AudioCodec> codecs;
2733 codecs.push_back(kPcmuCodec);
2734 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2735 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2736 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2737 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2738 EXPECT_TRUE(channel_->SetPlayout(true));
2739 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2740 EXPECT_TRUE(channel_->SetPlayout(false));
2741 EXPECT_FALSE(channel_->SetPlayout(true));
2742}
2743
2744// Test that the Registering/Unregistering with the
2745// webrtcvoiceengine works as expected
2746TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2747 EXPECT_TRUE(SetupEngine());
2748 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2749 EXPECT_TRUE(channel_->AddRecvStream(
2750 cricket::StreamParams::CreateLegacy(kSsrc2)));
2751 cricket::FakeMediaProcessor vp_1;
2752 cricket::FakeMediaProcessor vp_2;
2753
2754 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2755 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2756 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2757 voe_.TriggerProcessPacket(cricket::MPD_RX);
2758 voe_.TriggerProcessPacket(cricket::MPD_TX);
2759
2760 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2761 EXPECT_EQ(1, vp_1.voice_frame_count());
2762 EXPECT_EQ(1, vp_2.voice_frame_count());
2763
2764 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2765 &vp_2,
2766 cricket::MPD_RX));
2767 voe_.TriggerProcessPacket(cricket::MPD_RX);
2768 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2769 EXPECT_EQ(1, vp_2.voice_frame_count());
2770 EXPECT_EQ(2, vp_1.voice_frame_count());
2771
2772 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2773 &vp_1,
2774 cricket::MPD_RX));
2775 voe_.TriggerProcessPacket(cricket::MPD_RX);
2776 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2777 EXPECT_EQ(2, vp_1.voice_frame_count());
2778
2779 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2780 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2781 voe_.TriggerProcessPacket(cricket::MPD_RX);
2782 voe_.TriggerProcessPacket(cricket::MPD_TX);
2783 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2784 EXPECT_EQ(3, vp_1.voice_frame_count());
2785
2786 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2787 &vp_1,
2788 cricket::MPD_RX_AND_TX));
2789 voe_.TriggerProcessPacket(cricket::MPD_TX);
2790 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2791 EXPECT_EQ(3, vp_1.voice_frame_count());
2792 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2793 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2794 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2795
2796 // Test that we can register a processor on the receive channel on SSRC 0.
2797 // This tests the 1:1 case when the receive SSRC is unknown.
2798 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2799 voe_.TriggerProcessPacket(cricket::MPD_RX);
2800 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2801 EXPECT_EQ(4, vp_1.voice_frame_count());
2802 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2803 &vp_1,
2804 cricket::MPD_RX));
2805
2806 // The following tests test that FindChannelNumFromSsrc is doing
2807 // what we expect.
2808 // pick an invalid ssrc and make sure we can't register
2809 EXPECT_FALSE(engine_.RegisterProcessor(99,
2810 &vp_1,
2811 cricket::MPD_RX));
2812 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2813 EXPECT_TRUE(engine_.RegisterProcessor(1,
2814 &vp_1,
2815 cricket::MPD_RX));
2816 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2817 &vp_1,
2818 cricket::MPD_RX));
2819 EXPECT_FALSE(engine_.RegisterProcessor(1,
2820 &vp_1,
2821 cricket::MPD_TX));
2822 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2823}
2824
2825TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2826 EXPECT_TRUE(SetupEngine());
2827
2828 bool ec_enabled;
2829 webrtc::EcModes ec_mode;
2830 bool ec_metrics_enabled;
2831 webrtc::AecmModes aecm_mode;
2832 bool cng_enabled;
2833 bool agc_enabled;
2834 webrtc::AgcModes agc_mode;
2835 webrtc::AgcConfig agc_config;
2836 bool ns_enabled;
2837 webrtc::NsModes ns_mode;
2838 bool highpass_filter_enabled;
2839 bool stereo_swapping_enabled;
2840 bool typing_detection_enabled;
2841 voe_.GetEcStatus(ec_enabled, ec_mode);
2842 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2843 voe_.GetAecmMode(aecm_mode, cng_enabled);
2844 voe_.GetAgcStatus(agc_enabled, agc_mode);
2845 voe_.GetAgcConfig(agc_config);
2846 voe_.GetNsStatus(ns_enabled, ns_mode);
2847 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2848 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2849 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2850 EXPECT_TRUE(ec_enabled);
2851 EXPECT_TRUE(ec_metrics_enabled);
2852 EXPECT_FALSE(cng_enabled);
2853 EXPECT_TRUE(agc_enabled);
2854 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2855 EXPECT_TRUE(ns_enabled);
2856 EXPECT_TRUE(highpass_filter_enabled);
2857 EXPECT_FALSE(stereo_swapping_enabled);
2858 EXPECT_TRUE(typing_detection_enabled);
2859 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2860 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2861
2862 // Nothing set, so all ignored.
2863 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002864 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002865 voe_.GetEcStatus(ec_enabled, ec_mode);
2866 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2867 voe_.GetAecmMode(aecm_mode, cng_enabled);
2868 voe_.GetAgcStatus(agc_enabled, agc_mode);
2869 voe_.GetAgcConfig(agc_config);
2870 voe_.GetNsStatus(ns_enabled, ns_mode);
2871 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2872 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2873 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2874 EXPECT_TRUE(ec_enabled);
2875 EXPECT_TRUE(ec_metrics_enabled);
2876 EXPECT_FALSE(cng_enabled);
2877 EXPECT_TRUE(agc_enabled);
2878 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2879 EXPECT_TRUE(ns_enabled);
2880 EXPECT_TRUE(highpass_filter_enabled);
2881 EXPECT_FALSE(stereo_swapping_enabled);
2882 EXPECT_TRUE(typing_detection_enabled);
2883 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2884 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2885
2886 // Turn echo cancellation off
2887 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002888 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889 voe_.GetEcStatus(ec_enabled, ec_mode);
2890 EXPECT_FALSE(ec_enabled);
2891
2892 // Turn echo cancellation back on, with settings, and make sure
2893 // nothing else changed.
2894 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002895 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002896 voe_.GetEcStatus(ec_enabled, ec_mode);
2897 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2898 voe_.GetAecmMode(aecm_mode, cng_enabled);
2899 voe_.GetAgcStatus(agc_enabled, agc_mode);
2900 voe_.GetAgcConfig(agc_config);
2901 voe_.GetNsStatus(ns_enabled, ns_mode);
2902 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2903 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2904 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2905 EXPECT_TRUE(ec_enabled);
2906 EXPECT_TRUE(ec_metrics_enabled);
2907 EXPECT_TRUE(agc_enabled);
2908 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2909 EXPECT_TRUE(ns_enabled);
2910 EXPECT_TRUE(highpass_filter_enabled);
2911 EXPECT_FALSE(stereo_swapping_enabled);
2912 EXPECT_TRUE(typing_detection_enabled);
2913 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2914 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2915
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002916 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2917 // control.
2918 options.delay_agnostic_aec.Set(true);
2919 ASSERT_TRUE(engine_.SetOptions(options));
2920 voe_.GetEcStatus(ec_enabled, ec_mode);
2921 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2922 voe_.GetAecmMode(aecm_mode, cng_enabled);
2923 EXPECT_TRUE(ec_enabled);
2924 EXPECT_TRUE(ec_metrics_enabled);
2925 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2926
2927 // Turn off echo cancellation and delay agnostic aec.
2928 options.delay_agnostic_aec.Set(false);
2929 options.experimental_aec.Set(false);
2930 options.echo_cancellation.Set(false);
2931 ASSERT_TRUE(engine_.SetOptions(options));
2932 voe_.GetEcStatus(ec_enabled, ec_mode);
2933 EXPECT_FALSE(ec_enabled);
2934 // Turning delay agnostic aec back on should also turn on echo cancellation.
2935 options.delay_agnostic_aec.Set(true);
2936 ASSERT_TRUE(engine_.SetOptions(options));
2937 voe_.GetEcStatus(ec_enabled, ec_mode);
2938 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2939 EXPECT_TRUE(ec_enabled);
2940 EXPECT_TRUE(ec_metrics_enabled);
2941 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2942
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002943 // Turn off AGC
2944 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002945 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002946 voe_.GetAgcStatus(agc_enabled, agc_mode);
2947 EXPECT_FALSE(agc_enabled);
2948
2949 // Turn AGC back on
2950 options.auto_gain_control.Set(true);
2951 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002952 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002953 voe_.GetAgcStatus(agc_enabled, agc_mode);
2954 EXPECT_TRUE(agc_enabled);
2955 voe_.GetAgcConfig(agc_config);
2956 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2957
2958 // Turn off other options (and stereo swapping on).
2959 options.noise_suppression.Set(false);
2960 options.highpass_filter.Set(false);
2961 options.typing_detection.Set(false);
2962 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002963 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002964 voe_.GetNsStatus(ns_enabled, ns_mode);
2965 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2966 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2967 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2968 EXPECT_FALSE(ns_enabled);
2969 EXPECT_FALSE(highpass_filter_enabled);
2970 EXPECT_FALSE(typing_detection_enabled);
2971 EXPECT_TRUE(stereo_swapping_enabled);
2972
2973 // Turn on "conference mode" to ensure it has no impact.
2974 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002975 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002976 voe_.GetEcStatus(ec_enabled, ec_mode);
2977 voe_.GetNsStatus(ns_enabled, ns_mode);
2978 EXPECT_TRUE(ec_enabled);
2979 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2980 EXPECT_FALSE(ns_enabled);
2981 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2982}
2983
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002984TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002985 EXPECT_TRUE(SetupEngine());
2986
2987 bool ec_enabled;
2988 webrtc::EcModes ec_mode;
2989 bool ec_metrics_enabled;
2990 bool agc_enabled;
2991 webrtc::AgcModes agc_mode;
2992 bool ns_enabled;
2993 webrtc::NsModes ns_mode;
2994 bool highpass_filter_enabled;
2995 bool stereo_swapping_enabled;
2996 bool typing_detection_enabled;
2997
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 voe_.GetEcStatus(ec_enabled, ec_mode);
2999 voe_.GetEcMetricsStatus(ec_metrics_enabled);
3000 voe_.GetAgcStatus(agc_enabled, agc_mode);
3001 voe_.GetNsStatus(ns_enabled, ns_mode);
3002 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
3003 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
3004 voe_.GetTypingDetectionStatus(typing_detection_enabled);
3005 EXPECT_TRUE(ec_enabled);
3006 EXPECT_TRUE(agc_enabled);
3007 EXPECT_TRUE(ns_enabled);
3008 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003009 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003011}
3012
3013TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
3014 webrtc::AgcConfig set_config = {0};
3015 set_config.targetLeveldBOv = 3;
3016 set_config.digitalCompressionGaindB = 9;
3017 set_config.limiterEnable = true;
3018 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003019 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003020
3021 webrtc::AgcConfig config = {0};
3022 EXPECT_EQ(0, voe_.GetAgcConfig(config));
3023 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
3024 EXPECT_EQ(set_config.digitalCompressionGaindB,
3025 config.digitalCompressionGaindB);
3026 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
3027}
3028
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
3030 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003031 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003032 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003033 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003034 engine_.CreateChannel());
3035
3036 // Have to add a stream to make SetSend work.
3037 cricket::StreamParams stream1;
3038 stream1.ssrcs.push_back(1);
3039 channel1->AddSendStream(stream1);
3040 cricket::StreamParams stream2;
3041 stream2.ssrcs.push_back(2);
3042 channel2->AddSendStream(stream2);
3043
3044 // AEC and AGC and NS
3045 cricket::AudioOptions options_all;
3046 options_all.echo_cancellation.Set(true);
3047 options_all.auto_gain_control.Set(true);
3048 options_all.noise_suppression.Set(true);
3049
3050 ASSERT_TRUE(channel1->SetOptions(options_all));
3051 cricket::AudioOptions expected_options = options_all;
3052 cricket::AudioOptions actual_options;
3053 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3054 EXPECT_EQ(expected_options, actual_options);
3055 ASSERT_TRUE(channel2->SetOptions(options_all));
3056 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3057 EXPECT_EQ(expected_options, actual_options);
3058
3059 // unset NS
3060 cricket::AudioOptions options_no_ns;
3061 options_no_ns.noise_suppression.Set(false);
3062 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
3063
3064 expected_options.echo_cancellation.Set(true);
3065 expected_options.auto_gain_control.Set(true);
3066 expected_options.noise_suppression.Set(false);
3067 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3068 EXPECT_EQ(expected_options, actual_options);
3069
3070 // unset AGC
3071 cricket::AudioOptions options_no_agc;
3072 options_no_agc.auto_gain_control.Set(false);
3073 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
3074
3075 expected_options.echo_cancellation.Set(true);
3076 expected_options.auto_gain_control.Set(false);
3077 expected_options.noise_suppression.Set(true);
3078 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3079 EXPECT_EQ(expected_options, actual_options);
3080
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003081 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082 bool ec_enabled;
3083 webrtc::EcModes ec_mode;
3084 bool agc_enabled;
3085 webrtc::AgcModes agc_mode;
3086 bool ns_enabled;
3087 webrtc::NsModes ns_mode;
3088 voe_.GetEcStatus(ec_enabled, ec_mode);
3089 voe_.GetAgcStatus(agc_enabled, agc_mode);
3090 voe_.GetNsStatus(ns_enabled, ns_mode);
3091 EXPECT_TRUE(ec_enabled);
3092 EXPECT_TRUE(agc_enabled);
3093 EXPECT_TRUE(ns_enabled);
3094
3095 channel1->SetSend(cricket::SEND_MICROPHONE);
3096 voe_.GetEcStatus(ec_enabled, ec_mode);
3097 voe_.GetAgcStatus(agc_enabled, agc_mode);
3098 voe_.GetNsStatus(ns_enabled, ns_mode);
3099 EXPECT_TRUE(ec_enabled);
3100 EXPECT_TRUE(agc_enabled);
3101 EXPECT_FALSE(ns_enabled);
3102
3103 channel1->SetSend(cricket::SEND_NOTHING);
3104 voe_.GetEcStatus(ec_enabled, ec_mode);
3105 voe_.GetAgcStatus(agc_enabled, agc_mode);
3106 voe_.GetNsStatus(ns_enabled, ns_mode);
3107 EXPECT_TRUE(ec_enabled);
3108 EXPECT_TRUE(agc_enabled);
3109 EXPECT_TRUE(ns_enabled);
3110
3111 channel2->SetSend(cricket::SEND_MICROPHONE);
3112 voe_.GetEcStatus(ec_enabled, ec_mode);
3113 voe_.GetAgcStatus(agc_enabled, agc_mode);
3114 voe_.GetNsStatus(ns_enabled, ns_mode);
3115 EXPECT_TRUE(ec_enabled);
3116 EXPECT_FALSE(agc_enabled);
3117 EXPECT_TRUE(ns_enabled);
3118
3119 channel2->SetSend(cricket::SEND_NOTHING);
3120 voe_.GetEcStatus(ec_enabled, ec_mode);
3121 voe_.GetAgcStatus(agc_enabled, agc_mode);
3122 voe_.GetNsStatus(ns_enabled, ns_mode);
3123 EXPECT_TRUE(ec_enabled);
3124 EXPECT_TRUE(agc_enabled);
3125 EXPECT_TRUE(ns_enabled);
3126
3127 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003128 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003129 cricket::AudioOptions options_no_agc_nor_ns;
3130 options_no_agc_nor_ns.auto_gain_control.Set(false);
3131 options_no_agc_nor_ns.noise_suppression.Set(false);
3132 channel2->SetSend(cricket::SEND_MICROPHONE);
3133 channel2->SetOptions(options_no_agc_nor_ns);
3134
3135 expected_options.echo_cancellation.Set(true);
3136 expected_options.auto_gain_control.Set(false);
3137 expected_options.noise_suppression.Set(false);
3138 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3139 EXPECT_EQ(expected_options, actual_options);
3140 voe_.GetEcStatus(ec_enabled, ec_mode);
3141 voe_.GetAgcStatus(agc_enabled, agc_mode);
3142 voe_.GetNsStatus(ns_enabled, ns_mode);
3143 EXPECT_TRUE(ec_enabled);
3144 EXPECT_FALSE(agc_enabled);
3145 EXPECT_FALSE(ns_enabled);
3146}
3147
wu@webrtc.orgde305012013-10-31 15:40:38 +00003148// This test verifies DSCP settings are properly applied on voice media channel.
3149TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3150 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003151 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003152 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003153 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003154 new cricket::FakeNetworkInterface);
3155 channel->SetInterface(network_interface.get());
3156 cricket::AudioOptions options;
3157 options.dscp.Set(true);
3158 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003159 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003160 // Verify previous value is not modified if dscp option is not set.
3161 cricket::AudioOptions options1;
3162 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003163 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003164 options.dscp.Set(false);
3165 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003166 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003167}
3168
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00003169TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3170 cricket::WebRtcVoiceEngine engine;
3171 cricket::AudioOptions options = engine.GetOptions();
3172 // The default options should have at least a few things set. We purposefully
3173 // don't check the option values here, though.
3174 EXPECT_TRUE(options.echo_cancellation.IsSet());
3175 EXPECT_TRUE(options.auto_gain_control.IsSet());
3176 EXPECT_TRUE(options.noise_suppression.IsSet());
3177}
3178
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003179// Test that GetReceiveChannelNum returns the default channel for the first
3180// recv stream in 1-1 calls.
3181TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3182 EXPECT_TRUE(SetupEngine());
3183 cricket::WebRtcVoiceMediaChannel* media_channel =
3184 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3185 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3186 EXPECT_EQ(media_channel->voe_channel(),
3187 media_channel->GetReceiveChannelNum(0));
3188 cricket::StreamParams stream;
3189 stream.ssrcs.push_back(kSsrc2);
3190 EXPECT_TRUE(channel_->AddRecvStream(stream));
3191 EXPECT_EQ(media_channel->voe_channel(),
3192 media_channel->GetReceiveChannelNum(kSsrc2));
3193}
3194
3195// Test that GetReceiveChannelNum doesn't return the default channel for the
3196// first recv stream in conference calls.
3197TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3198 EXPECT_TRUE(SetupEngine());
3199 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3200 cricket::StreamParams stream;
3201 stream.ssrcs.push_back(kSsrc2);
3202 EXPECT_TRUE(channel_->AddRecvStream(stream));
3203 cricket::WebRtcVoiceMediaChannel* media_channel =
3204 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3205 EXPECT_LT(media_channel->voe_channel(),
3206 media_channel->GetReceiveChannelNum(kSsrc2));
3207}
3208
3209TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3210 EXPECT_TRUE(SetupEngine());
3211 double left, right;
3212 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
3213 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
3214 EXPECT_DOUBLE_EQ(1, left);
3215 EXPECT_DOUBLE_EQ(2, right);
3216
3217 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3218 cricket::StreamParams stream;
3219 stream.ssrcs.push_back(kSsrc2);
3220 EXPECT_TRUE(channel_->AddRecvStream(stream));
3221
3222 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
3223 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
3224 EXPECT_DOUBLE_EQ(2, left);
3225 EXPECT_DOUBLE_EQ(1, right);
3226}
3227
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003228// Tests for the actual WebRtc VoE library.
3229
3230// Tests that the library initializes and shuts down properly.
3231TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3232 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003233 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003234 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3235 EXPECT_TRUE(channel != NULL);
3236 delete channel;
3237 engine.Terminate();
3238
3239 // Reinit to catch regression where VoiceEngineObserver reference is lost
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003240 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003241 engine.Terminate();
3242}
3243
3244// Tests that the logging from the library is cleartext.
3245TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
3246 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003247 rtc::scoped_ptr<rtc::MemoryStream> stream(
3248 new rtc::MemoryStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003249 size_t size = 0;
3250 bool cleartext = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003251 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3252 engine.SetLogging(rtc::LS_VERBOSE, "");
3253 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003254 EXPECT_TRUE(stream->GetSize(&size));
3255 EXPECT_GT(size, 0U);
3256 engine.Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003257 rtc::LogMessage::RemoveLogToStream(stream.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003258 const char* buf = stream->GetBuffer();
3259 for (size_t i = 0; i < size && cleartext; ++i) {
3260 int ch = static_cast<int>(buf[i]);
3261 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
3262 << std::hex << ch;
3263 cleartext = (isprint(ch) || isspace(ch));
3264 }
3265 EXPECT_TRUE(cleartext);
3266}
3267
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003268// Tests that the library is configured with the codecs we want.
3269TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3270 cricket::WebRtcVoiceEngine engine;
3271 // Check codecs by name.
3272 EXPECT_TRUE(engine.FindCodec(
3273 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3274 EXPECT_TRUE(engine.FindCodec(
3275 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3276 EXPECT_TRUE(engine.FindCodec(
3277 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3278 // Check that name matching is case-insensitive.
3279 EXPECT_TRUE(engine.FindCodec(
3280 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3281 EXPECT_TRUE(engine.FindCodec(
3282 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3283 EXPECT_TRUE(engine.FindCodec(
3284 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3285 EXPECT_TRUE(engine.FindCodec(
3286 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3287 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003288 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003289 EXPECT_TRUE(engine.FindCodec(
3290 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003291 EXPECT_TRUE(engine.FindCodec(
3292 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3293 EXPECT_TRUE(engine.FindCodec(
3294 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3295 EXPECT_TRUE(engine.FindCodec(
3296 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3297 EXPECT_TRUE(engine.FindCodec(
3298 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3299 // Check codecs with an id by id.
3300 EXPECT_TRUE(engine.FindCodec(
3301 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3302 EXPECT_TRUE(engine.FindCodec(
3303 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3304 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003305 cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003306 EXPECT_TRUE(engine.FindCodec(
3307 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3308 // Check sample/bitrate matching.
3309 EXPECT_TRUE(engine.FindCodec(
3310 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3311 // Check that bad codecs fail.
3312 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3313 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3314 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3315 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3316 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003317 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3318 for (std::vector<cricket::AudioCodec>::const_iterator it =
3319 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3320 if (it->name == "CN" && it->clockrate == 16000) {
3321 EXPECT_EQ(105, it->id);
3322 } else if (it->name == "CN" && it->clockrate == 32000) {
3323 EXPECT_EQ(106, it->id);
3324 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3325 EXPECT_EQ(103, it->id);
3326 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3327 EXPECT_EQ(104, it->id);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003328 } else if (it->name == "G722" && it->clockrate == 8000) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003329 EXPECT_EQ(9, it->id);
3330 } else if (it->name == "telephone-event") {
3331 EXPECT_EQ(126, it->id);
3332 } else if (it->name == "red") {
3333 EXPECT_EQ(127, it->id);
3334 } else if (it->name == "opus") {
3335 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003336 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003337 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003338 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003339 EXPECT_EQ("60", it->params.find("maxptime")->second);
minyue@webrtc.org4ef22d12014-11-17 09:26:39 +00003340 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3341 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003342 }
3343 }
3344
3345 engine.Terminate();
3346}
3347
3348// Tests that VoE supports at least 32 channels
3349TEST(WebRtcVoiceEngineTest, Has32Channels) {
3350 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003351 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003352
3353 cricket::VoiceMediaChannel* channels[32];
3354 int num_channels = 0;
3355
3356 while (num_channels < ARRAY_SIZE(channels)) {
3357 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3358 if (!channel)
3359 break;
3360
3361 channels[num_channels++] = channel;
3362 }
3363
3364 int expected = ARRAY_SIZE(channels);
3365 EXPECT_EQ(expected, num_channels);
3366
3367 while (num_channels > 0) {
3368 delete channels[--num_channels];
3369 }
3370
3371 engine.Terminate();
3372}
3373
3374// Test that we set our preferred codecs properly.
3375TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3376 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003377 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003378 cricket::WebRtcVoiceMediaChannel channel(&engine);
3379 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3380}
3381
3382#ifdef WIN32
3383// Test our workarounds to WebRtc VoE' munging of the coinit count
3384TEST(WebRtcVoiceEngineTest, CoInitialize) {
3385 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3386
3387 // Initial refcount should be 0.
3388 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3389
3390 // Engine should start even with COM already inited.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003391 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003392 engine->Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003393 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003394 engine->Terminate();
3395
3396 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3397 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3398 // Decrement refcount to (hopefully) 0.
3399 CoUninitialize();
3400 CoUninitialize();
3401 delete engine;
3402
3403 // Ensure refcount is 0.
3404 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3405 CoUninitialize();
3406}
3407#endif
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003408
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003409TEST_F(WebRtcVoiceEngineTestFake, ChangeCombinedBweOption_Call) {
3410 // Test that changing the combined_audio_video_bwe option results in the
3411 // expected state changes on an associated Call.
3412 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3413 const uint32 kAudioSsrc1 = 223;
3414 const uint32 kAudioSsrc2 = 224;
3415
3416 EXPECT_TRUE(SetupEngine());
3417 cricket::WebRtcVoiceMediaChannel* media_channel =
3418 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3419 media_channel->SetCall(&call);
3420 EXPECT_TRUE(media_channel->AddRecvStream(
3421 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3422 EXPECT_TRUE(media_channel->AddRecvStream(
3423 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3424
3425 // Combined BWE should not be set up yet.
3426 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3427
3428 // Enable combined BWE option - now it should be set up.
3429 cricket::AudioOptions options;
3430 options.combined_audio_video_bwe.Set(true);
3431 EXPECT_TRUE(media_channel->SetOptions(options));
3432 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3433 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc1));
3434 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc2));
3435
3436 // Disable combined BWE option - should be disabled again.
3437 options.combined_audio_video_bwe.Set(false);
3438 EXPECT_TRUE(media_channel->SetOptions(options));
3439 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3440
3441 media_channel->SetCall(nullptr);
3442}
3443
3444TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBwe_Call) {
3445 // Test that calling SetCall() on the voice media channel results in the
3446 // expected state changes in Call.
3447 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3448 cricket::FakeCall call2(webrtc::Call::Config(nullptr));
3449 const uint32 kAudioSsrc1 = 223;
3450 const uint32 kAudioSsrc2 = 224;
3451
3452 EXPECT_TRUE(SetupEngine());
3453 cricket::WebRtcVoiceMediaChannel* media_channel =
3454 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3455 cricket::AudioOptions options;
3456 options.combined_audio_video_bwe.Set(true);
3457 EXPECT_TRUE(media_channel->SetOptions(options));
3458 EXPECT_TRUE(media_channel->AddRecvStream(
3459 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3460 EXPECT_TRUE(media_channel->AddRecvStream(
3461 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3462
3463 // Combined BWE should not be set up yet.
3464 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3465
3466 // Register - should be enabled.
3467 media_channel->SetCall(&call);
3468 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3469 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc1));
3470 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc2));
3471
3472 // Re-register - should now be enabled on new call.
3473 media_channel->SetCall(&call2);
3474 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3475 EXPECT_EQ(2, call2.GetAudioReceiveStreams().size());
3476 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc1));
3477 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc2));
3478
3479 // Unregister - should be disabled again.
3480 media_channel->SetCall(nullptr);
3481 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3482}
3483
3484TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams_Call) {
3485 // Test that adding receive streams after enabling combined bandwidth
3486 // estimation will correctly configure each channel.
3487 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3488
3489 EXPECT_TRUE(SetupEngine());
3490 cricket::WebRtcVoiceMediaChannel* media_channel =
3491 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3492 media_channel->SetCall(&call);
3493 cricket::AudioOptions options;
3494 options.combined_audio_video_bwe.Set(true);
3495 EXPECT_TRUE(media_channel->SetOptions(options));
3496
3497 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3498 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3499 EXPECT_TRUE(media_channel->AddRecvStream(
3500 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3501 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kSsrcs[i]));
3502 }
3503 EXPECT_EQ(ARRAY_SIZE(kSsrcs), call.GetAudioReceiveStreams().size());
3504
3505 media_channel->SetCall(nullptr);
3506 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3507}
3508
3509TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweExtensions_Call) {
3510 // Test that setting the header extensions results in the expected state
3511 // changes on an associated Call.
3512 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3513 std::vector<uint32> ssrcs;
3514 ssrcs.push_back(223);
3515 ssrcs.push_back(224);
3516
3517 EXPECT_TRUE(SetupEngine());
3518 cricket::WebRtcVoiceMediaChannel* media_channel =
3519 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3520 media_channel->SetCall(&call);
3521 cricket::AudioOptions options;
3522 options.combined_audio_video_bwe.Set(true);
3523 EXPECT_TRUE(media_channel->SetOptions(options));
3524 for (uint32 ssrc : ssrcs) {
3525 EXPECT_TRUE(media_channel->AddRecvStream(
3526 cricket::StreamParams::CreateLegacy(ssrc)));
3527 }
3528
3529 // Combined BWE should be set up, but with no configured extensions.
3530 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3531 for (uint32 ssrc : ssrcs) {
3532 const auto* s = call.GetAudioReceiveStream(ssrc);
3533 EXPECT_NE(nullptr, s);
3534 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3535 }
3536
3537 // Set up receive extensions.
3538 const auto& e_exts = engine_.rtp_header_extensions();
3539 channel_->SetRecvRtpHeaderExtensions(e_exts);
3540 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3541 for (uint32 ssrc : ssrcs) {
3542 const auto* s = call.GetAudioReceiveStream(ssrc);
3543 EXPECT_NE(nullptr, s);
3544 const auto& s_exts = s->GetConfig().rtp.extensions;
3545 EXPECT_EQ(e_exts.size(), s_exts.size());
3546 for (const auto& e_ext : e_exts) {
3547 for (const auto& s_ext : s_exts) {
3548 if (e_ext.id == s_ext.id) {
3549 EXPECT_EQ(e_ext.uri, s_ext.name);
3550 }
3551 }
3552 }
3553 }
3554
3555 // Disable receive extensions.
3556 std::vector<cricket::RtpHeaderExtension> extensions;
3557 channel_->SetRecvRtpHeaderExtensions(extensions);
3558 for (uint32 ssrc : ssrcs) {
3559 const auto* s = call.GetAudioReceiveStream(ssrc);
3560 EXPECT_NE(nullptr, s);
3561 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3562 }
3563
3564 media_channel->SetCall(nullptr);
3565}
3566
3567TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3568 // Test that packets are forwarded to the Call when configured accordingly.
3569 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3570 const uint32 kAudioSsrc = 1;
3571 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3572 static const unsigned char kRtcp[] = {
3573 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3574 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3577 };
3578 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3579
3580 EXPECT_TRUE(SetupEngine());
3581 cricket::WebRtcVoiceMediaChannel* media_channel =
3582 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3583 cricket::AudioOptions options;
3584 options.combined_audio_video_bwe.Set(true);
3585 EXPECT_TRUE(media_channel->SetOptions(options));
3586 EXPECT_TRUE(media_channel->AddRecvStream(
3587 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3588
3589 // Call not set on media channel, so no packets can be forwarded.
3590 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3591 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3592 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3593 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3594
3595 // Set Call, now there should be a receive stream which is forwarded packets.
3596 media_channel->SetCall(&call);
3597 EXPECT_EQ(1, call.GetAudioReceiveStreams().size());
3598 const cricket::FakeAudioReceiveStream* s =
3599 call.GetAudioReceiveStream(kAudioSsrc);
3600 EXPECT_EQ(0, s->received_packets());
3601 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3602 EXPECT_EQ(1, s->received_packets());
3603 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3604 EXPECT_EQ(2, s->received_packets());
3605
3606 media_channel->SetCall(nullptr);
3607}