blob: c559e39f8392af12a4b7a275ad15c011a5da53b5 [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"
42#include "talk/media/webrtc/webrtcvoiceengine.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000043#include "webrtc/p2p/base/fakesession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044#include "talk/session/media/channel.h"
45
46// Tests for the WebRtcVoiceEngine/VoiceChannel code.
47
buildbot@webrtc.org150835e2014-05-06 15:54:38 +000048using cricket::kRtpAudioLevelHeaderExtension;
49using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
50
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
52static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +000054static const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
55static const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
57static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
58static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
59static const cricket::AudioCodec
60 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
61static const cricket::AudioCodec* const kAudioCodecs[] = {
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +000062 &kPcmuCodec, &kIsacCodec, &kOpusCodec, &kG722CodecVoE, &kRedCodec,
63 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064};
65const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
66static uint32 kSsrc1 = 0x99;
67static uint32 kSsrc2 = 0x98;
68
69class FakeVoEWrapper : public cricket::VoEWrapper {
70 public:
71 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
72 : cricket::VoEWrapper(engine, // processing
73 engine, // base
74 engine, // codec
75 engine, // dtmf
76 engine, // file
77 engine, // hw
78 engine, // media
79 engine, // neteq
80 engine, // network
81 engine, // rtp
82 engine, // sync
83 engine) { // volume
84 }
85};
86
wu@webrtc.org97077a32013-10-25 21:18:33 +000087class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088 public:
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020089 int SetTraceFilter(const unsigned int filter) override {
wu@webrtc.org97077a32013-10-25 21:18:33 +000090 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091 return 0;
92 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +020093 int SetTraceFile(const char* fileNameUTF8) override { return 0; }
94 int SetTraceCallback(webrtc::TraceCallback* callback) override { return 0; }
wu@webrtc.org97077a32013-10-25 21:18:33 +000095 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096};
97
98class WebRtcVoiceEngineTestFake : public testing::Test {
99 public:
100 class ChannelErrorListener : public sigslot::has_slots<> {
101 public:
102 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
103 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +0200104 DCHECK(channel != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000105 channel->SignalMediaError.connect(
106 this, &ChannelErrorListener::OnVoiceChannelError);
107 }
108 void OnVoiceChannelError(uint32 ssrc,
109 cricket::VoiceMediaChannel::Error error) {
110 ssrc_ = ssrc;
111 error_ = error;
112 }
113 void Reset() {
114 ssrc_ = 0;
115 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
116 }
117 uint32 ssrc() const {
118 return ssrc_;
119 }
120 cricket::VoiceMediaChannel::Error error() const {
121 return error_;
122 }
123
124 private:
125 uint32 ssrc_;
126 cricket::VoiceMediaChannel::Error error_;
127 };
128
129 WebRtcVoiceEngineTestFake()
130 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000131 trace_wrapper_(new FakeVoETraceWrapper()),
Jelena Marusicc28a8962015-05-29 15:05:44 +0200132 engine_(new FakeVoEWrapper(&voe_), trace_wrapper_),
133 channel_(nullptr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134 options_conference_.conference_mode.Set(true);
135 options_adjust_agc_.adjust_agc_delta.Set(-10);
136 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000137 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000138 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000139 return false;
140 }
Jelena Marusicc28a8962015-05-29 15:05:44 +0200141 channel_ = engine_.CreateChannel(cricket::AudioOptions());
142 return (channel_ != nullptr);
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000143 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000144 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000145 if (!SetupEngineWithoutStream()) {
146 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000148 return channel_->AddSendStream(
149 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000151 void SetupForMultiSendStream() {
152 EXPECT_TRUE(SetupEngine());
153 // Remove stream added in Setup, which is corresponding to default channel.
154 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000155 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000156 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
157 EXPECT_EQ(kSsrc1, default_send_ssrc);
158 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
159
160 // Verify the default channel still exists.
161 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
162 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163 void DeliverPacket(const void* data, int len) {
Karl Wiberg94784372015-04-20 14:03:07 +0200164 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000165 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 }
Fredrik Solenbergaaf8ff22015-05-07 16:05:53 +0200167 void TearDown() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168 delete channel_;
169 engine_.Terminate();
170 }
171
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000172 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000173 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200174 channel_ = engine_.CreateChannel(cricket::AudioOptions());
175 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000176 if (caller) {
177 // if this is a caller, local description will be applied and add the
178 // send stream.
179 EXPECT_TRUE(channel_->AddSendStream(
180 cricket::StreamParams::CreateLegacy(kSsrc1)));
181 }
182 int channel_id = voe_.GetLastChannel();
183
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000184 // Test we can only InsertDtmf when the other side supports telephone-event.
185 std::vector<cricket::AudioCodec> codecs;
186 codecs.push_back(kPcmuCodec);
187 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
188 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
189 EXPECT_FALSE(channel_->CanInsertDtmf());
190 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
191 codecs.push_back(kTelephoneEventCodec);
192 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
193 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000194
195 if (!caller) {
196 // There's no active send channel yet.
197 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
198 EXPECT_TRUE(channel_->AddSendStream(
199 cricket::StreamParams::CreateLegacy(kSsrc1)));
200 }
201
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 // Check we fail if the ssrc is invalid.
203 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
204
205 // Test send
206 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
207 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
208 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
209
210 // Test play
211 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
212 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
213 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
214
215 // Test send and play
216 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
217 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
218 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
219 cricket::DF_PLAY | cricket::DF_SEND));
220 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
221 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
222 }
223
224 // Test that send bandwidth is set correctly.
225 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000226 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
227 // |expected_result| is the expected result from SetMaxSendBandwidth().
228 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000230 int max_bitrate,
231 bool expected_result,
232 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 int channel_num = voe_.GetLastChannel();
234 std::vector<cricket::AudioCodec> codecs;
235
236 codecs.push_back(codec);
237 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
238
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000239 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 EXPECT_EQ(expected_result, result);
241
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000242 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
244
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000245 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 }
247
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000248 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
249 EXPECT_TRUE(SetupEngineWithoutStream());
250 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000251
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000252 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000253 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000254
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000255 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000256 // Ensure unknown extensions won't cause an error.
257 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000258 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000259 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000260 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000261
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000262 // Ensure extensions stay off with an empty list of headers.
263 extensions.clear();
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
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000267 // Ensure extension is set properly.
268 const int id = 1;
269 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000270 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000271 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000272
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000273 // Ensure extension is set properly on new channel.
274 // The first stream to occupy the default channel.
275 EXPECT_TRUE(channel_->AddSendStream(
276 cricket::StreamParams::CreateLegacy(123)));
277 EXPECT_TRUE(channel_->AddSendStream(
278 cricket::StreamParams::CreateLegacy(234)));
279 int new_channel_num = voe_.GetLastChannel();
280 EXPECT_NE(channel_num, new_channel_num);
281 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000282
283 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000284 extensions.clear();
285 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000286 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
287 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000288 }
289
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000290 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
291 EXPECT_TRUE(SetupEngineWithoutStream());
292 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000293
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000294 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000295 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000296
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000297 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000298 // Ensure unknown extensions won't cause an error.
299 extensions.push_back(cricket::RtpHeaderExtension(
300 "urn:ietf:params:unknownextention", 1));
301 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000302 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000303
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000304 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000305 extensions.clear();
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 extension is set properly.
310 const int id = 2;
311 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000312 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000313 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000314
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000315 // Ensure extension is set properly on new channel.
316 // The first stream to occupy the default channel.
317 EXPECT_TRUE(channel_->AddRecvStream(
318 cricket::StreamParams::CreateLegacy(345)));
319 EXPECT_TRUE(channel_->AddRecvStream(
320 cricket::StreamParams::CreateLegacy(456)));
321 int new_channel_num = voe_.GetLastChannel();
322 EXPECT_NE(channel_num, new_channel_num);
323 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
324
325 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000326 extensions.clear();
327 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000328 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
329 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000330 }
331
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 protected:
333 cricket::FakeWebRtcVoiceEngine voe_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000334 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 cricket::WebRtcVoiceEngine engine_;
336 cricket::VoiceMediaChannel* channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337
338 cricket::AudioOptions options_conference_;
339 cricket::AudioOptions options_adjust_agc_;
340};
341
342// Tests that our stub library "works".
343TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
344 EXPECT_FALSE(voe_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000345 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346 EXPECT_TRUE(voe_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 engine_.Terminate();
348 EXPECT_FALSE(voe_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349}
350
351// Tests that we can create and destroy a channel.
352TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000353 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200354 channel_ = engine_.CreateChannel(cricket::AudioOptions());
355 EXPECT_TRUE(channel_ != nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356}
357
358// Tests that we properly handle failures in CreateChannel.
359TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
360 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000361 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200362 channel_ = engine_.CreateChannel(cricket::AudioOptions());
363 EXPECT_TRUE(channel_ == nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364}
365
366// Tests that the list of supported codecs is created properly and ordered
367// correctly
368TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
369 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
370 ASSERT_FALSE(codecs.empty());
371 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
372 EXPECT_EQ(48000, codecs[0].clockrate);
373 EXPECT_EQ(2, codecs[0].channels);
374 EXPECT_EQ(64000, codecs[0].bitrate);
375 int pref = codecs[0].preference;
376 for (size_t i = 1; i < codecs.size(); ++i) {
377 EXPECT_GT(pref, codecs[i].preference);
378 pref = codecs[i].preference;
379 }
380}
381
382// Tests that we can find codecs by name or id, and that we interpret the
383// clockrate and bitrate fields properly.
384TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
385 cricket::AudioCodec codec;
386 webrtc::CodecInst codec_inst;
387 // Find PCMU with explicit clockrate and bitrate.
388 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
389 // Find ISAC with explicit clockrate and 0 bitrate.
390 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
391 // Find telephone-event with explicit clockrate and 0 bitrate.
392 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
393 // Find ISAC with a different payload id.
394 codec = kIsacCodec;
395 codec.id = 127;
396 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
397 EXPECT_EQ(codec.id, codec_inst.pltype);
398 // Find PCMU with a 0 clockrate.
399 codec = kPcmuCodec;
400 codec.clockrate = 0;
401 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
402 EXPECT_EQ(codec.id, codec_inst.pltype);
403 EXPECT_EQ(8000, codec_inst.plfreq);
404 // Find PCMU with a 0 bitrate.
405 codec = kPcmuCodec;
406 codec.bitrate = 0;
407 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
408 EXPECT_EQ(codec.id, codec_inst.pltype);
409 EXPECT_EQ(64000, codec_inst.rate);
410 // Find ISAC with an explicit bitrate.
411 codec = kIsacCodec;
412 codec.bitrate = 32000;
413 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
414 EXPECT_EQ(codec.id, codec_inst.pltype);
415 EXPECT_EQ(32000, codec_inst.rate);
416}
417
418// Test that we set our inbound codecs properly, including changing PT.
419TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
420 EXPECT_TRUE(SetupEngine());
421 int channel_num = voe_.GetLastChannel();
422 std::vector<cricket::AudioCodec> codecs;
423 codecs.push_back(kIsacCodec);
424 codecs.push_back(kPcmuCodec);
425 codecs.push_back(kTelephoneEventCodec);
426 codecs[0].id = 106; // collide with existing telephone-event
427 codecs[2].id = 126;
428 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
429 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000430 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000431 gcodec.plfreq = 16000;
432 gcodec.channels = 1;
433 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
434 EXPECT_EQ(106, gcodec.pltype);
435 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000436 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437 "telephone-event");
438 gcodec.plfreq = 8000;
439 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
440 EXPECT_EQ(126, gcodec.pltype);
441 EXPECT_STREQ("telephone-event", gcodec.plname);
442}
443
444// Test that we fail to set an unknown inbound codec.
445TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
446 EXPECT_TRUE(SetupEngine());
447 std::vector<cricket::AudioCodec> codecs;
448 codecs.push_back(kIsacCodec);
449 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
450 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
451}
452
453// Test that we fail if we have duplicate types in the inbound list.
454TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
455 EXPECT_TRUE(SetupEngine());
456 std::vector<cricket::AudioCodec> codecs;
457 codecs.push_back(kIsacCodec);
458 codecs.push_back(kCn16000Codec);
459 codecs[1].id = kIsacCodec.id;
460 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
461}
462
463// Test that we can decode OPUS without stereo parameters.
464TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
465 EXPECT_TRUE(SetupEngine());
466 EXPECT_TRUE(channel_->SetOptions(options_conference_));
467 std::vector<cricket::AudioCodec> codecs;
468 codecs.push_back(kIsacCodec);
469 codecs.push_back(kPcmuCodec);
470 codecs.push_back(kOpusCodec);
471 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
472 EXPECT_TRUE(channel_->AddRecvStream(
473 cricket::StreamParams::CreateLegacy(kSsrc1)));
474 int channel_num2 = voe_.GetLastChannel();
475 webrtc::CodecInst opus;
476 engine_.FindWebRtcCodec(kOpusCodec, &opus);
477 // Even without stereo parameters, recv codecs still specify channels = 2.
478 EXPECT_EQ(2, opus.channels);
479 EXPECT_EQ(111, opus.pltype);
480 EXPECT_STREQ("opus", opus.plname);
481 opus.pltype = 0;
482 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
483 EXPECT_EQ(111, opus.pltype);
484}
485
486// Test that we can decode OPUS with stereo = 0.
487TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
488 EXPECT_TRUE(SetupEngine());
489 EXPECT_TRUE(channel_->SetOptions(options_conference_));
490 std::vector<cricket::AudioCodec> codecs;
491 codecs.push_back(kIsacCodec);
492 codecs.push_back(kPcmuCodec);
493 codecs.push_back(kOpusCodec);
494 codecs[2].params["stereo"] = "0";
495 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
496 EXPECT_TRUE(channel_->AddRecvStream(
497 cricket::StreamParams::CreateLegacy(kSsrc1)));
498 int channel_num2 = voe_.GetLastChannel();
499 webrtc::CodecInst opus;
500 engine_.FindWebRtcCodec(kOpusCodec, &opus);
501 // Even when stereo is off, recv codecs still specify channels = 2.
502 EXPECT_EQ(2, opus.channels);
503 EXPECT_EQ(111, opus.pltype);
504 EXPECT_STREQ("opus", opus.plname);
505 opus.pltype = 0;
506 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
507 EXPECT_EQ(111, opus.pltype);
508}
509
510// Test that we can decode OPUS with stereo = 1.
511TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
512 EXPECT_TRUE(SetupEngine());
513 EXPECT_TRUE(channel_->SetOptions(options_conference_));
514 std::vector<cricket::AudioCodec> codecs;
515 codecs.push_back(kIsacCodec);
516 codecs.push_back(kPcmuCodec);
517 codecs.push_back(kOpusCodec);
518 codecs[2].params["stereo"] = "1";
519 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
520 EXPECT_TRUE(channel_->AddRecvStream(
521 cricket::StreamParams::CreateLegacy(kSsrc1)));
522 int channel_num2 = voe_.GetLastChannel();
523 webrtc::CodecInst opus;
524 engine_.FindWebRtcCodec(kOpusCodec, &opus);
525 EXPECT_EQ(2, opus.channels);
526 EXPECT_EQ(111, opus.pltype);
527 EXPECT_STREQ("opus", opus.plname);
528 opus.pltype = 0;
529 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
530 EXPECT_EQ(111, opus.pltype);
531}
532
533// Test that changes to recv codecs are applied to all streams.
534TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
535 EXPECT_TRUE(SetupEngine());
536 EXPECT_TRUE(channel_->SetOptions(options_conference_));
537 std::vector<cricket::AudioCodec> codecs;
538 codecs.push_back(kIsacCodec);
539 codecs.push_back(kPcmuCodec);
540 codecs.push_back(kTelephoneEventCodec);
541 codecs[0].id = 106; // collide with existing telephone-event
542 codecs[2].id = 126;
543 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
544 EXPECT_TRUE(channel_->AddRecvStream(
545 cricket::StreamParams::CreateLegacy(kSsrc1)));
546 int channel_num2 = voe_.GetLastChannel();
547 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000548 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000549 gcodec.plfreq = 16000;
550 gcodec.channels = 1;
551 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
552 EXPECT_EQ(106, gcodec.pltype);
553 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000554 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 "telephone-event");
556 gcodec.plfreq = 8000;
557 gcodec.channels = 1;
558 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
559 EXPECT_EQ(126, gcodec.pltype);
560 EXPECT_STREQ("telephone-event", gcodec.plname);
561}
562
563TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
564 EXPECT_TRUE(SetupEngine());
565 EXPECT_TRUE(channel_->SetOptions(options_conference_));
566 std::vector<cricket::AudioCodec> codecs;
567 codecs.push_back(kIsacCodec);
568 codecs[0].id = 106; // collide with existing telephone-event
569
570 EXPECT_TRUE(channel_->AddRecvStream(
571 cricket::StreamParams::CreateLegacy(kSsrc1)));
572 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
573
574 int channel_num2 = voe_.GetLastChannel();
575 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000576 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 gcodec.plfreq = 16000;
578 gcodec.channels = 1;
579 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
580 EXPECT_EQ(106, gcodec.pltype);
581 EXPECT_STREQ("ISAC", gcodec.plname);
582}
583
584// Test that we can apply the same set of codecs again while playing.
585TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
586 EXPECT_TRUE(SetupEngine());
587 int channel_num = voe_.GetLastChannel();
588 std::vector<cricket::AudioCodec> codecs;
589 codecs.push_back(kIsacCodec);
590 codecs.push_back(kCn16000Codec);
591 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
592 EXPECT_TRUE(channel_->SetPlayout(true));
593 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
594
595 // Changing the payload type of a codec should fail.
596 codecs[0].id = 127;
597 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
598 EXPECT_TRUE(voe_.GetPlayout(channel_num));
599}
600
601// Test that we can add a codec while playing.
602TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
603 EXPECT_TRUE(SetupEngine());
604 int channel_num = voe_.GetLastChannel();
605 std::vector<cricket::AudioCodec> codecs;
606 codecs.push_back(kIsacCodec);
607 codecs.push_back(kCn16000Codec);
608 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
609 EXPECT_TRUE(channel_->SetPlayout(true));
610
611 codecs.push_back(kOpusCodec);
612 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
613 EXPECT_TRUE(voe_.GetPlayout(channel_num));
614 webrtc::CodecInst gcodec;
615 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
616 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
617}
618
619TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
620 EXPECT_TRUE(SetupEngine());
621 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
622
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000623 // Test that when autobw is enabled, bitrate is kept as the default
624 // value. autobw is enabled for the following tests because the target
625 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000626
627 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000628 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629
630 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000631 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000634 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635}
636
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000637TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000638 EXPECT_TRUE(SetupEngine());
639 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
640
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000641 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642
643 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000644 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
645 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000647 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000648 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
649 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650}
651
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000652TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
653 EXPECT_TRUE(SetupEngine());
654 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
655
656 // Test that we can only set a maximum bitrate for a fixed-rate codec
657 // if it's bigger than the fixed rate.
658
659 // PCMU, fixed bitrate == 64000.
660 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
661 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
662 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
663 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
664 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
665 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
666 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
667}
668
669TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000670 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +0200671 channel_ = engine_.CreateChannel(cricket::AudioOptions());
672 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000673 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
674
675 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000676 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000677
678 EXPECT_TRUE(channel_->AddSendStream(
679 cricket::StreamParams::CreateLegacy(kSsrc1)));
680
681 int channel_num = voe_.GetLastChannel();
682 webrtc::CodecInst codec;
683 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
684 EXPECT_EQ(desired_bitrate, codec.rate);
685}
686
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000687// Test that bitrate cannot be set for CBR codecs.
688// Bitrate is ignored if it is higher than the fixed bitrate.
689// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000690TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691 EXPECT_TRUE(SetupEngine());
692 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
693
694 webrtc::CodecInst codec;
695 int channel_num = voe_.GetLastChannel();
696 std::vector<cricket::AudioCodec> codecs;
697
698 // PCMU, default bitrate == 64000.
699 codecs.push_back(kPcmuCodec);
700 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
701 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
702 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000703 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
705 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000706 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
708 EXPECT_EQ(64000, codec.rate);
709}
710
711// Test that we apply codecs properly.
712TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
713 EXPECT_TRUE(SetupEngine());
714 int channel_num = voe_.GetLastChannel();
715 std::vector<cricket::AudioCodec> codecs;
716 codecs.push_back(kIsacCodec);
717 codecs.push_back(kPcmuCodec);
718 codecs.push_back(kRedCodec);
719 codecs[0].id = 96;
720 codecs[0].bitrate = 48000;
721 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000722 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723 webrtc::CodecInst gcodec;
724 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
725 EXPECT_EQ(96, gcodec.pltype);
726 EXPECT_EQ(48000, gcodec.rate);
727 EXPECT_STREQ("ISAC", gcodec.plname);
728 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000729 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
731 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
732 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
733}
734
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000735// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
736// to apply.
737TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
738 EXPECT_TRUE(SetupEngine());
739 std::vector<cricket::AudioCodec> codecs;
740 codecs.push_back(kIsacCodec);
741 codecs.push_back(kPcmuCodec);
742 codecs.push_back(kRedCodec);
743 codecs[0].id = 96;
744 codecs[0].bitrate = 48000;
745 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
746 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
747 // Calling SetSendCodec again with same codec which is already set.
748 // In this case media channel shouldn't send codec to VoE.
749 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
750 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
751}
752
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +0000753// Verify that G722 is set with 16000 samples per second to WebRTC.
754TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
755 EXPECT_TRUE(SetupEngine());
756 int channel_num = voe_.GetLastChannel();
757 std::vector<cricket::AudioCodec> codecs;
758 codecs.push_back(kG722CodecSdp);
759 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
760 webrtc::CodecInst gcodec;
761 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
762 EXPECT_STREQ("G722", gcodec.plname);
763 EXPECT_EQ(1, gcodec.channels);
764 EXPECT_EQ(16000, gcodec.plfreq);
765}
766
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000767// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
769 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000770 std::vector<cricket::AudioCodec> codecs;
771 codecs.push_back(kOpusCodec);
772 codecs[0].bitrate = 0;
773 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000774 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775}
776
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000777// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000778TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
779 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000780 std::vector<cricket::AudioCodec> codecs;
781 codecs.push_back(kOpusCodec);
782 codecs[0].bitrate = 0;
783 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000784 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785}
786
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000787// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
789 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 std::vector<cricket::AudioCodec> codecs;
791 codecs.push_back(kOpusCodec);
792 codecs[0].bitrate = 0;
793 codecs[0].channels = 0;
794 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000795 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796}
797
798// Test that if channel is 1 for opus and there's no stereo, we fail.
799TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
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 = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000805 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000806}
807
808// Test that if channel is 1 for opus and stereo=0, we fail.
809TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
810 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000811 std::vector<cricket::AudioCodec> codecs;
812 codecs.push_back(kOpusCodec);
813 codecs[0].bitrate = 0;
814 codecs[0].channels = 1;
815 codecs[0].params["stereo"] = "0";
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=1, we fail.
820TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
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"] = "1";
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 with bitrate=0 and no stereo,
831// channels and bitrate are 1 and 32000.
832TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
833 EXPECT_TRUE(SetupEngine());
834 int channel_num = voe_.GetLastChannel();
835 std::vector<cricket::AudioCodec> codecs;
836 codecs.push_back(kOpusCodec);
837 codecs[0].bitrate = 0;
838 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
839 webrtc::CodecInst gcodec;
840 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
841 EXPECT_STREQ("opus", gcodec.plname);
842 EXPECT_EQ(1, gcodec.channels);
843 EXPECT_EQ(32000, gcodec.rate);
844}
845
846// Test that with bitrate=0 and stereo=0,
847// channels and bitrate are 1 and 32000.
848TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
849 EXPECT_TRUE(SetupEngine());
850 int channel_num = voe_.GetLastChannel();
851 std::vector<cricket::AudioCodec> codecs;
852 codecs.push_back(kOpusCodec);
853 codecs[0].bitrate = 0;
854 codecs[0].params["stereo"] = "0";
855 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
856 webrtc::CodecInst gcodec;
857 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
858 EXPECT_STREQ("opus", gcodec.plname);
859 EXPECT_EQ(1, gcodec.channels);
860 EXPECT_EQ(32000, gcodec.rate);
861}
862
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000863// Test that with bitrate=invalid and stereo=0,
864// channels and bitrate are 1 and 32000.
865TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
866 EXPECT_TRUE(SetupEngine());
867 int channel_num = voe_.GetLastChannel();
868 std::vector<cricket::AudioCodec> codecs;
869 codecs.push_back(kOpusCodec);
870 codecs[0].params["stereo"] = "0";
871 webrtc::CodecInst gcodec;
872
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000873 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000874 codecs[0].bitrate = 5999;
875 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
876 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
877 EXPECT_STREQ("opus", gcodec.plname);
878 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000879 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000880
881 codecs[0].bitrate = 510001;
882 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
883 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
884 EXPECT_STREQ("opus", gcodec.plname);
885 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000886 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000887}
888
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000889// Test that with bitrate=0 and stereo=1,
890// channels and bitrate are 2 and 64000.
891TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
892 EXPECT_TRUE(SetupEngine());
893 int channel_num = voe_.GetLastChannel();
894 std::vector<cricket::AudioCodec> codecs;
895 codecs.push_back(kOpusCodec);
896 codecs[0].bitrate = 0;
897 codecs[0].params["stereo"] = "1";
898 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
899 webrtc::CodecInst gcodec;
900 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
901 EXPECT_STREQ("opus", gcodec.plname);
902 EXPECT_EQ(2, gcodec.channels);
903 EXPECT_EQ(64000, gcodec.rate);
904}
905
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000906// Test that with bitrate=invalid and stereo=1,
907// channels and bitrate are 2 and 64000.
908TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
909 EXPECT_TRUE(SetupEngine());
910 int channel_num = voe_.GetLastChannel();
911 std::vector<cricket::AudioCodec> codecs;
912 codecs.push_back(kOpusCodec);
913 codecs[0].params["stereo"] = "1";
914 webrtc::CodecInst gcodec;
915
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000916 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000917 codecs[0].bitrate = 5999;
918 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
919 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
920 EXPECT_STREQ("opus", gcodec.plname);
921 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000922 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000923
924 codecs[0].bitrate = 510001;
925 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
926 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
927 EXPECT_STREQ("opus", gcodec.plname);
928 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000929 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000930}
931
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000932// Test that with bitrate=N and stereo unset,
933// channels and bitrate are 1 and N.
934TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
935 EXPECT_TRUE(SetupEngine());
936 int channel_num = voe_.GetLastChannel();
937 std::vector<cricket::AudioCodec> codecs;
938 codecs.push_back(kOpusCodec);
939 codecs[0].bitrate = 96000;
940 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
941 webrtc::CodecInst gcodec;
942 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
943 EXPECT_EQ(111, gcodec.pltype);
944 EXPECT_EQ(96000, gcodec.rate);
945 EXPECT_STREQ("opus", gcodec.plname);
946 EXPECT_EQ(1, gcodec.channels);
947 EXPECT_EQ(48000, gcodec.plfreq);
948}
949
950// Test that with bitrate=N and stereo=0,
951// channels and bitrate are 1 and N.
952TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
953 EXPECT_TRUE(SetupEngine());
954 int channel_num = voe_.GetLastChannel();
955 std::vector<cricket::AudioCodec> codecs;
956 codecs.push_back(kOpusCodec);
957 codecs[0].bitrate = 30000;
958 codecs[0].params["stereo"] = "0";
959 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
960 webrtc::CodecInst gcodec;
961 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
962 EXPECT_EQ(1, gcodec.channels);
963 EXPECT_EQ(30000, gcodec.rate);
964 EXPECT_STREQ("opus", gcodec.plname);
965}
966
967// Test that with bitrate=N and without any parameters,
968// channels and bitrate are 1 and N.
969TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
970 EXPECT_TRUE(SetupEngine());
971 int channel_num = voe_.GetLastChannel();
972 std::vector<cricket::AudioCodec> codecs;
973 codecs.push_back(kOpusCodec);
974 codecs[0].bitrate = 30000;
975 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
976 webrtc::CodecInst gcodec;
977 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
978 EXPECT_EQ(1, gcodec.channels);
979 EXPECT_EQ(30000, gcodec.rate);
980 EXPECT_STREQ("opus", gcodec.plname);
981}
982
983// Test that with bitrate=N and stereo=1,
984// channels and bitrate are 2 and N.
985TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
986 EXPECT_TRUE(SetupEngine());
987 int channel_num = voe_.GetLastChannel();
988 std::vector<cricket::AudioCodec> codecs;
989 codecs.push_back(kOpusCodec);
990 codecs[0].bitrate = 30000;
991 codecs[0].params["stereo"] = "1";
992 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
993 webrtc::CodecInst gcodec;
994 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
995 EXPECT_EQ(2, gcodec.channels);
996 EXPECT_EQ(30000, gcodec.rate);
997 EXPECT_STREQ("opus", gcodec.plname);
998}
999
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001000// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1001// Also test that the "maxaveragebitrate" can't be set to values outside the
1002// range of 6000 and 510000
1003TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1004 EXPECT_TRUE(SetupEngine());
1005 int channel_num = voe_.GetLastChannel();
1006 std::vector<cricket::AudioCodec> codecs;
1007 codecs.push_back(kOpusCodec);
1008 codecs[0].bitrate = 30000;
1009 webrtc::CodecInst gcodec;
1010
1011 // Ignore if less than 6000.
1012 codecs[0].params["maxaveragebitrate"] = "5999";
1013 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1014 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001015 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001016
1017 // Ignore if larger than 510000.
1018 codecs[0].params["maxaveragebitrate"] = "510001";
1019 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1020 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001021 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001022
1023 codecs[0].params["maxaveragebitrate"] = "200000";
1024 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1025 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1026 EXPECT_EQ(200000, gcodec.rate);
1027}
1028
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001029// Test that we can enable NACK with opus as caller.
1030TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001031 EXPECT_TRUE(SetupEngine());
1032 int channel_num = voe_.GetLastChannel();
1033 std::vector<cricket::AudioCodec> codecs;
1034 codecs.push_back(kOpusCodec);
1035 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1036 cricket::kParamValueEmpty));
1037 EXPECT_FALSE(voe_.GetNACK(channel_num));
1038 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1039 EXPECT_TRUE(voe_.GetNACK(channel_num));
1040}
1041
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001042// Test that we can enable NACK with opus as callee.
1043TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001044 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02001045 channel_ = engine_.CreateChannel(cricket::AudioOptions());
1046 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001047
1048 int channel_num = voe_.GetLastChannel();
1049 std::vector<cricket::AudioCodec> codecs;
1050 codecs.push_back(kOpusCodec);
1051 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1052 cricket::kParamValueEmpty));
1053 EXPECT_FALSE(voe_.GetNACK(channel_num));
1054 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1055 EXPECT_FALSE(voe_.GetNACK(channel_num));
1056
1057 EXPECT_TRUE(channel_->AddSendStream(
1058 cricket::StreamParams::CreateLegacy(kSsrc1)));
1059 EXPECT_TRUE(voe_.GetNACK(channel_num));
1060}
1061
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062// Test that we can enable NACK on receive streams.
1063TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1064 EXPECT_TRUE(SetupEngine());
1065 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1066 int channel_num1 = voe_.GetLastChannel();
1067 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1068 int channel_num2 = voe_.GetLastChannel();
1069 std::vector<cricket::AudioCodec> codecs;
1070 codecs.push_back(kOpusCodec);
1071 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1072 cricket::kParamValueEmpty));
1073 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1074 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1075 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1076 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1077 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1078}
1079
1080// Test that we can disable NACK.
1081TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1082 EXPECT_TRUE(SetupEngine());
1083 int channel_num = voe_.GetLastChannel();
1084 std::vector<cricket::AudioCodec> codecs;
1085 codecs.push_back(kOpusCodec);
1086 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1087 cricket::kParamValueEmpty));
1088 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1089 EXPECT_TRUE(voe_.GetNACK(channel_num));
1090
1091 codecs.clear();
1092 codecs.push_back(kOpusCodec);
1093 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1094 EXPECT_FALSE(voe_.GetNACK(channel_num));
1095}
1096
1097// Test that we can disable NACK on receive streams.
1098TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1099 EXPECT_TRUE(SetupEngine());
1100 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1101 int channel_num1 = voe_.GetLastChannel();
1102 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1103 int channel_num2 = voe_.GetLastChannel();
1104 std::vector<cricket::AudioCodec> codecs;
1105 codecs.push_back(kOpusCodec);
1106 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1107 cricket::kParamValueEmpty));
1108 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1109 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1110 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1111
1112 codecs.clear();
1113 codecs.push_back(kOpusCodec);
1114 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1115 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1116 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1117}
1118
1119// Test that NACK is enabled on a new receive stream.
1120TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1121 EXPECT_TRUE(SetupEngine());
1122 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1123 int channel_num = voe_.GetLastChannel();
1124 std::vector<cricket::AudioCodec> codecs;
1125 codecs.push_back(kIsacCodec);
1126 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1127 cricket::kParamValueEmpty));
1128 codecs.push_back(kCn16000Codec);
1129 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1130 EXPECT_TRUE(voe_.GetNACK(channel_num));
1131
1132 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1133 channel_num = voe_.GetLastChannel();
1134 EXPECT_TRUE(voe_.GetNACK(channel_num));
1135 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1136 channel_num = voe_.GetLastChannel();
1137 EXPECT_TRUE(voe_.GetNACK(channel_num));
1138}
1139
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001140// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001141TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001142 EXPECT_TRUE(SetupEngine());
1143 int channel_num = voe_.GetLastChannel();
1144 std::vector<cricket::AudioCodec> codecs;
1145 codecs.push_back(kOpusCodec);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001146 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1147 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1148}
1149
1150// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001151TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001152 EXPECT_TRUE(SetupEngine());
1153 int channel_num = voe_.GetLastChannel();
1154 std::vector<cricket::AudioCodec> codecs;
1155 codecs.push_back(kOpusCodec);
1156 codecs[0].bitrate = 0;
1157 codecs[0].params["useinbandfec"] = "0";
1158 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1159 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1160 webrtc::CodecInst gcodec;
1161 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1162 EXPECT_STREQ("opus", gcodec.plname);
1163 EXPECT_EQ(1, gcodec.channels);
1164 EXPECT_EQ(32000, gcodec.rate);
1165}
1166
1167// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001168TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001169 EXPECT_TRUE(SetupEngine());
1170 int channel_num = voe_.GetLastChannel();
1171 std::vector<cricket::AudioCodec> codecs;
1172 codecs.push_back(kOpusCodec);
1173 codecs[0].bitrate = 0;
1174 codecs[0].params["useinbandfec"] = "1";
1175 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1176 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1177 webrtc::CodecInst gcodec;
1178 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1179 EXPECT_STREQ("opus", gcodec.plname);
1180 EXPECT_EQ(1, gcodec.channels);
1181 EXPECT_EQ(32000, gcodec.rate);
1182}
1183
1184// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001185TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001186 EXPECT_TRUE(SetupEngine());
1187 int channel_num = voe_.GetLastChannel();
1188 std::vector<cricket::AudioCodec> codecs;
1189 codecs.push_back(kOpusCodec);
1190 codecs[0].bitrate = 0;
1191 codecs[0].params["stereo"] = "1";
1192 codecs[0].params["useinbandfec"] = "1";
1193 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1194 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1195 webrtc::CodecInst gcodec;
1196 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1197 EXPECT_STREQ("opus", gcodec.plname);
1198 EXPECT_EQ(2, gcodec.channels);
1199 EXPECT_EQ(64000, gcodec.rate);
1200}
1201
1202// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001203TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001204 EXPECT_TRUE(SetupEngine());
1205 int channel_num = voe_.GetLastChannel();
1206 std::vector<cricket::AudioCodec> codecs;
1207 codecs.push_back(kIsacCodec);
1208 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1209 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1210}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001211
1212// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1213TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1214 EXPECT_TRUE(SetupEngine());
1215 int channel_num = voe_.GetLastChannel();
1216 std::vector<cricket::AudioCodec> codecs;
1217 codecs.push_back(kIsacCodec);
1218 codecs[0].params["useinbandfec"] = "1";
1219 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1220 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1221}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001222
1223// Test that Opus FEC status can be changed.
1224TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1225 EXPECT_TRUE(SetupEngine());
1226 int channel_num = voe_.GetLastChannel();
1227 std::vector<cricket::AudioCodec> codecs;
1228 codecs.push_back(kOpusCodec);
1229 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1230 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1231 codecs[0].params["useinbandfec"] = "1";
1232 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1233 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1234}
1235
1236// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1237TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1238 EXPECT_TRUE(SetupEngine());
1239 int channel_num = voe_.GetLastChannel();
1240 std::vector<cricket::AudioCodec> codecs;
1241 codecs.push_back(kOpusCodec);
1242 codecs[0].bitrate = 0;
1243 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1244 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1245 EXPECT_EQ(cricket::kOpusBandwidthNb,
1246 voe_.GetMaxEncodingBandwidth(channel_num));
1247 webrtc::CodecInst gcodec;
1248 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1249 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001250
1251 EXPECT_EQ(12000, gcodec.rate);
1252 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1253 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1254 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1255 EXPECT_EQ(24000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001256}
1257
1258// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1259TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1260 EXPECT_TRUE(SetupEngine());
1261 int channel_num = voe_.GetLastChannel();
1262 std::vector<cricket::AudioCodec> codecs;
1263 codecs.push_back(kOpusCodec);
1264 codecs[0].bitrate = 0;
1265 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1266 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1267 EXPECT_EQ(cricket::kOpusBandwidthMb,
1268 voe_.GetMaxEncodingBandwidth(channel_num));
1269 webrtc::CodecInst gcodec;
1270 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1271 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001272
1273 EXPECT_EQ(20000, gcodec.rate);
1274 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1275 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1276 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1277 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001278}
1279
1280// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1281TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1282 EXPECT_TRUE(SetupEngine());
1283 int channel_num = voe_.GetLastChannel();
1284 std::vector<cricket::AudioCodec> codecs;
1285 codecs.push_back(kOpusCodec);
1286 codecs[0].bitrate = 0;
1287 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1288 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1289 EXPECT_EQ(cricket::kOpusBandwidthWb,
1290 voe_.GetMaxEncodingBandwidth(channel_num));
1291 webrtc::CodecInst gcodec;
1292 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1293 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001294
1295 EXPECT_EQ(20000, gcodec.rate);
1296 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1297 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1298 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1299 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001300}
1301
1302// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1303TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1304 EXPECT_TRUE(SetupEngine());
1305 int channel_num = voe_.GetLastChannel();
1306 std::vector<cricket::AudioCodec> codecs;
1307 codecs.push_back(kOpusCodec);
1308 codecs[0].bitrate = 0;
1309 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1310 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1311 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1312 voe_.GetMaxEncodingBandwidth(channel_num));
1313 webrtc::CodecInst gcodec;
1314 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1315 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001316
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001317 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001318 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1319 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1320 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1321 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001322}
1323
1324// Test 24000 < maxplaybackrate triggers Opus full band mode.
1325TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1326 EXPECT_TRUE(SetupEngine());
1327 int channel_num = voe_.GetLastChannel();
1328 std::vector<cricket::AudioCodec> codecs;
1329 codecs.push_back(kOpusCodec);
1330 codecs[0].bitrate = 0;
1331 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1332 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1333 EXPECT_EQ(cricket::kOpusBandwidthFb,
1334 voe_.GetMaxEncodingBandwidth(channel_num));
1335 webrtc::CodecInst gcodec;
1336 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1337 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001338
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001339 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001340 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1341 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1342 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1343 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001344}
1345
1346// Test Opus that without maxplaybackrate, default playback rate is used.
1347TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1348 EXPECT_TRUE(SetupEngine());
1349 int channel_num = voe_.GetLastChannel();
1350 std::vector<cricket::AudioCodec> codecs;
1351 codecs.push_back(kOpusCodec);
1352 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1353 EXPECT_EQ(cricket::kOpusBandwidthFb,
1354 voe_.GetMaxEncodingBandwidth(channel_num));
1355}
1356
1357// Test the with non-Opus, maxplaybackrate has no effect.
1358TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1359 EXPECT_TRUE(SetupEngine());
1360 int channel_num = voe_.GetLastChannel();
1361 std::vector<cricket::AudioCodec> codecs;
1362 codecs.push_back(kIsacCodec);
1363 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1364 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1365 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1366}
1367
1368// Test maxplaybackrate can be set on two streams.
1369TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1370 EXPECT_TRUE(SetupEngine());
1371 int channel_num = voe_.GetLastChannel();
1372 std::vector<cricket::AudioCodec> codecs;
1373 codecs.push_back(kOpusCodec);
1374 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1375 // Default bandwidth is 24000.
1376 EXPECT_EQ(cricket::kOpusBandwidthFb,
1377 voe_.GetMaxEncodingBandwidth(channel_num));
1378
1379 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1380
1381 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1382 EXPECT_EQ(cricket::kOpusBandwidthNb,
1383 voe_.GetMaxEncodingBandwidth(channel_num));
1384
1385 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1386 channel_num = voe_.GetLastChannel();
1387 EXPECT_EQ(cricket::kOpusBandwidthNb,
1388 voe_.GetMaxEncodingBandwidth(channel_num));
1389}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001390
Minyue Li7100dcd2015-03-27 05:05:59 +01001391// Test that with usedtx=0, Opus DTX is off.
1392TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1393 EXPECT_TRUE(SetupEngine());
1394 int channel_num = voe_.GetLastChannel();
1395 std::vector<cricket::AudioCodec> codecs;
1396 codecs.push_back(kOpusCodec);
1397 codecs[0].params["usedtx"] = "0";
1398 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1399 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1400}
1401
1402// Test that with usedtx=1, Opus DTX is on.
1403TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
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"] = "1";
1409 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1410 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1411 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1412}
1413
1414// Test that usedtx=1 works with stereo Opus.
1415TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1416 EXPECT_TRUE(SetupEngine());
1417 int channel_num = voe_.GetLastChannel();
1418 std::vector<cricket::AudioCodec> codecs;
1419 codecs.push_back(kOpusCodec);
1420 codecs[0].params["usedtx"] = "1";
1421 codecs[0].params["stereo"] = "1";
1422 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1423 EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1424 EXPECT_FALSE(voe_.GetVAD(channel_num)); // Opus DTX should not affect VAD.
1425}
1426
1427// Test that usedtx=1 does not work with non Opus.
1428TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1429 EXPECT_TRUE(SetupEngine());
1430 int channel_num = voe_.GetLastChannel();
1431 std::vector<cricket::AudioCodec> codecs;
1432 codecs.push_back(kIsacCodec);
1433 codecs[0].params["usedtx"] = "1";
1434 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1435 EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1436}
1437
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001438// Test that we can switch back and forth between Opus and ISAC with CN.
1439TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001440 EXPECT_TRUE(SetupEngine());
1441 int channel_num = voe_.GetLastChannel();
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001442 std::vector<cricket::AudioCodec> opus_codecs;
1443 opus_codecs.push_back(kOpusCodec);
1444 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445 webrtc::CodecInst gcodec;
1446 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001447 EXPECT_EQ(111, gcodec.pltype);
1448 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449
1450 std::vector<cricket::AudioCodec> isac_codecs;
1451 isac_codecs.push_back(kIsacCodec);
1452 isac_codecs.push_back(kCn16000Codec);
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001453 isac_codecs.push_back(kOpusCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1455 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1456 EXPECT_EQ(103, gcodec.pltype);
1457 EXPECT_STREQ("ISAC", gcodec.plname);
1458
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001459 EXPECT_TRUE(channel_->SetSendCodecs(opus_codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00001461 EXPECT_EQ(111, gcodec.pltype);
1462 EXPECT_STREQ("opus", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001463}
1464
1465// Test that we handle various ways of specifying bitrate.
1466TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1467 EXPECT_TRUE(SetupEngine());
1468 int channel_num = voe_.GetLastChannel();
1469 std::vector<cricket::AudioCodec> codecs;
1470 codecs.push_back(kIsacCodec); // bitrate == 32000
1471 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1472 webrtc::CodecInst gcodec;
1473 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1474 EXPECT_EQ(103, gcodec.pltype);
1475 EXPECT_STREQ("ISAC", gcodec.plname);
1476 EXPECT_EQ(32000, gcodec.rate);
1477
1478 codecs[0].bitrate = 0; // bitrate == default
1479 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1480 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1481 EXPECT_EQ(103, gcodec.pltype);
1482 EXPECT_STREQ("ISAC", gcodec.plname);
1483 EXPECT_EQ(-1, gcodec.rate);
1484
1485 codecs[0].bitrate = 28000; // bitrate == 28000
1486 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1487 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1488 EXPECT_EQ(103, gcodec.pltype);
1489 EXPECT_STREQ("ISAC", gcodec.plname);
1490 EXPECT_EQ(28000, gcodec.rate);
1491
1492 codecs[0] = kPcmuCodec; // bitrate == 64000
1493 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1494 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1495 EXPECT_EQ(0, gcodec.pltype);
1496 EXPECT_STREQ("PCMU", gcodec.plname);
1497 EXPECT_EQ(64000, gcodec.rate);
1498
1499 codecs[0].bitrate = 0; // bitrate == default
1500 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1501 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1502 EXPECT_EQ(0, gcodec.pltype);
1503 EXPECT_STREQ("PCMU", gcodec.plname);
1504 EXPECT_EQ(64000, gcodec.rate);
1505
1506 codecs[0] = kOpusCodec;
1507 codecs[0].bitrate = 0; // bitrate == default
1508 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1509 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1510 EXPECT_EQ(111, gcodec.pltype);
1511 EXPECT_STREQ("opus", gcodec.plname);
1512 EXPECT_EQ(32000, gcodec.rate);
1513}
1514
Brave Yao5225dd82015-03-26 07:39:19 +08001515// Test that we could set packet size specified in kCodecParamPTime.
1516TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1517 EXPECT_TRUE(SetupEngine());
1518 int channel_num = voe_.GetLastChannel();
1519 std::vector<cricket::AudioCodec> codecs;
1520 codecs.push_back(kOpusCodec);
1521 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1522 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1523 webrtc::CodecInst gcodec;
1524 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1525 EXPECT_EQ(1920, gcodec.pacsize); // Opus gets 40ms.
1526
1527 codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Value below range.
1528 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1529 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1530 EXPECT_EQ(480, gcodec.pacsize); // Opus gets 10ms.
1531
1532 codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Value beyond range.
1533 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1534 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1535 EXPECT_EQ(2880, gcodec.pacsize); // Opus gets 60ms.
1536
1537 codecs[0] = kIsacCodec; // Also try Isac, and with unsupported size.
1538 codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Value within range.
1539 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1540 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1541 EXPECT_EQ(480, gcodec.pacsize); // Isac gets 30ms as the next smallest value.
1542
1543 codecs[0] = kG722CodecSdp; // Try G722 @8kHz as negotiated in SDP.
1544 codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1545 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1546 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1547 EXPECT_EQ(640, gcodec.pacsize); // G722 gets 40ms @16kHz as defined in VoE.
1548}
1549
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001550// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1552 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001553 std::vector<cricket::AudioCodec> codecs;
1554 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1555}
1556
1557// Test that we can set send codecs even with telephone-event codec as the first
1558// one on the list.
1559TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1560 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561 int channel_num = voe_.GetLastChannel();
1562 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001563 codecs.push_back(kTelephoneEventCodec);
1564 codecs.push_back(kIsacCodec);
1565 codecs.push_back(kPcmuCodec);
1566 codecs[0].id = 98; // DTMF
1567 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001568 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1569 webrtc::CodecInst gcodec;
1570 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001571 EXPECT_EQ(96, gcodec.pltype);
1572 EXPECT_STREQ("ISAC", gcodec.plname);
1573 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1574}
1575
1576// Test that we can set send codecs even with CN codec as the first
1577// one on the list.
1578TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1579 EXPECT_TRUE(SetupEngine());
1580 int channel_num = voe_.GetLastChannel();
1581 std::vector<cricket::AudioCodec> codecs;
1582 codecs.push_back(kCn16000Codec);
1583 codecs.push_back(kIsacCodec);
1584 codecs.push_back(kPcmuCodec);
1585 codecs[0].id = 98; // wideband CN
1586 codecs[1].id = 96;
1587 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1588 webrtc::CodecInst gcodec;
1589 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1590 EXPECT_EQ(96, gcodec.pltype);
1591 EXPECT_STREQ("ISAC", gcodec.plname);
1592 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001593}
1594
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001595// Test that we set VAD and DTMF types correctly as caller.
1596TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597 EXPECT_TRUE(SetupEngine());
1598 int channel_num = voe_.GetLastChannel();
1599 std::vector<cricket::AudioCodec> codecs;
1600 codecs.push_back(kIsacCodec);
1601 codecs.push_back(kPcmuCodec);
1602 // TODO(juberti): cn 32000
1603 codecs.push_back(kCn16000Codec);
1604 codecs.push_back(kCn8000Codec);
1605 codecs.push_back(kTelephoneEventCodec);
1606 codecs.push_back(kRedCodec);
1607 codecs[0].id = 96;
1608 codecs[2].id = 97; // wideband CN
1609 codecs[4].id = 98; // DTMF
1610 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1611 webrtc::CodecInst gcodec;
1612 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1613 EXPECT_EQ(96, gcodec.pltype);
1614 EXPECT_STREQ("ISAC", gcodec.plname);
1615 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001616 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1618 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1619 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1620}
1621
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001622// Test that we set VAD and DTMF types correctly as callee.
1623TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001624 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02001625 channel_ = engine_.CreateChannel(cricket::AudioOptions());
1626 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001627
1628 int channel_num = voe_.GetLastChannel();
1629 std::vector<cricket::AudioCodec> codecs;
1630 codecs.push_back(kIsacCodec);
1631 codecs.push_back(kPcmuCodec);
1632 // TODO(juberti): cn 32000
1633 codecs.push_back(kCn16000Codec);
1634 codecs.push_back(kCn8000Codec);
1635 codecs.push_back(kTelephoneEventCodec);
1636 codecs.push_back(kRedCodec);
1637 codecs[0].id = 96;
1638 codecs[2].id = 97; // wideband CN
1639 codecs[4].id = 98; // DTMF
1640 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1641 EXPECT_TRUE(channel_->AddSendStream(
1642 cricket::StreamParams::CreateLegacy(kSsrc1)));
1643
1644 webrtc::CodecInst gcodec;
1645 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1646 EXPECT_EQ(96, gcodec.pltype);
1647 EXPECT_STREQ("ISAC", gcodec.plname);
1648 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001649 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001650 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1651 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1652 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1653}
1654
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001655// Test that we only apply VAD if we have a CN codec that matches the
1656// send codec clockrate.
1657TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1658 EXPECT_TRUE(SetupEngine());
1659 int channel_num = voe_.GetLastChannel();
1660 std::vector<cricket::AudioCodec> codecs;
1661 // Set ISAC(16K) and CN(16K). VAD should be activated.
1662 codecs.push_back(kIsacCodec);
1663 codecs.push_back(kCn16000Codec);
1664 codecs[1].id = 97;
1665 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1666 webrtc::CodecInst gcodec;
1667 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1668 EXPECT_STREQ("ISAC", gcodec.plname);
1669 EXPECT_TRUE(voe_.GetVAD(channel_num));
1670 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1671 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1672 codecs[0] = kPcmuCodec;
1673 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1674 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1675 EXPECT_STREQ("PCMU", gcodec.plname);
1676 EXPECT_FALSE(voe_.GetVAD(channel_num));
1677 // Set PCMU(8K) and CN(8K). VAD should be activated.
1678 codecs[1] = kCn8000Codec;
1679 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1680 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1681 EXPECT_STREQ("PCMU", gcodec.plname);
1682 EXPECT_TRUE(voe_.GetVAD(channel_num));
1683 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
Brave Yao5225dd82015-03-26 07:39:19 +08001684 // Set ISAC(16K) and CN(8K). VAD should not be activated.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685 codecs[0] = kIsacCodec;
1686 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1687 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1688 EXPECT_STREQ("ISAC", gcodec.plname);
1689 EXPECT_FALSE(voe_.GetVAD(channel_num));
1690}
1691
1692// Test that we perform case-insensitive matching of codec names.
1693TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1694 EXPECT_TRUE(SetupEngine());
1695 int channel_num = voe_.GetLastChannel();
1696 std::vector<cricket::AudioCodec> codecs;
1697 codecs.push_back(kIsacCodec);
1698 codecs.push_back(kPcmuCodec);
1699 codecs.push_back(kCn16000Codec);
1700 codecs.push_back(kCn8000Codec);
1701 codecs.push_back(kTelephoneEventCodec);
1702 codecs.push_back(kRedCodec);
1703 codecs[0].name = "iSaC";
1704 codecs[0].id = 96;
1705 codecs[2].id = 97; // wideband CN
1706 codecs[4].id = 98; // DTMF
1707 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1708 webrtc::CodecInst gcodec;
1709 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1710 EXPECT_EQ(96, gcodec.pltype);
1711 EXPECT_STREQ("ISAC", gcodec.plname);
1712 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001713 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1715 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1716 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1717}
1718
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001719// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001720TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721 EXPECT_TRUE(SetupEngine());
1722 int channel_num = voe_.GetLastChannel();
1723 std::vector<cricket::AudioCodec> codecs;
1724 codecs.push_back(kRedCodec);
1725 codecs.push_back(kIsacCodec);
1726 codecs.push_back(kPcmuCodec);
1727 codecs[0].id = 127;
1728 codecs[0].params[""] = "96/96";
1729 codecs[1].id = 96;
1730 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1731 webrtc::CodecInst gcodec;
1732 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1733 EXPECT_EQ(96, gcodec.pltype);
1734 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001735 EXPECT_TRUE(voe_.GetRED(channel_num));
1736 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001737}
1738
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001739// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001740TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001741 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02001742 channel_ = engine_.CreateChannel(cricket::AudioOptions());
1743 EXPECT_TRUE(channel_ != nullptr);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001744
1745 int channel_num = voe_.GetLastChannel();
1746 std::vector<cricket::AudioCodec> codecs;
1747 codecs.push_back(kRedCodec);
1748 codecs.push_back(kIsacCodec);
1749 codecs.push_back(kPcmuCodec);
1750 codecs[0].id = 127;
1751 codecs[0].params[""] = "96/96";
1752 codecs[1].id = 96;
1753 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1754 EXPECT_TRUE(channel_->AddSendStream(
1755 cricket::StreamParams::CreateLegacy(kSsrc1)));
1756 webrtc::CodecInst gcodec;
1757 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1758 EXPECT_EQ(96, gcodec.pltype);
1759 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001760 EXPECT_TRUE(voe_.GetRED(channel_num));
1761 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001762}
1763
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001764// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1766 EXPECT_TRUE(SetupEngine());
1767 int channel_num = voe_.GetLastChannel();
1768 std::vector<cricket::AudioCodec> codecs;
1769 codecs.push_back(kRedCodec);
1770 codecs.push_back(kIsacCodec);
1771 codecs.push_back(kPcmuCodec);
1772 codecs[0].id = 127;
1773 codecs[1].id = 96;
1774 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1775 webrtc::CodecInst gcodec;
1776 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1777 EXPECT_EQ(96, gcodec.pltype);
1778 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001779 EXPECT_TRUE(voe_.GetRED(channel_num));
1780 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001781}
1782
1783// Test that we ignore RED if the parameters aren't named the way we expect.
1784TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1785 EXPECT_TRUE(SetupEngine());
1786 int channel_num = voe_.GetLastChannel();
1787 std::vector<cricket::AudioCodec> codecs;
1788 codecs.push_back(kRedCodec);
1789 codecs.push_back(kIsacCodec);
1790 codecs.push_back(kPcmuCodec);
1791 codecs[0].id = 127;
1792 codecs[0].params["ABC"] = "96/96";
1793 codecs[1].id = 96;
1794 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1795 webrtc::CodecInst gcodec;
1796 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1797 EXPECT_EQ(96, gcodec.pltype);
1798 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001799 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001800}
1801
1802// Test that we ignore RED if it uses different primary/secondary encoding.
1803TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1804 EXPECT_TRUE(SetupEngine());
1805 int channel_num = voe_.GetLastChannel();
1806 std::vector<cricket::AudioCodec> codecs;
1807 codecs.push_back(kRedCodec);
1808 codecs.push_back(kIsacCodec);
1809 codecs.push_back(kPcmuCodec);
1810 codecs[0].id = 127;
1811 codecs[0].params[""] = "96/0";
1812 codecs[1].id = 96;
1813 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1814 webrtc::CodecInst gcodec;
1815 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1816 EXPECT_EQ(96, gcodec.pltype);
1817 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001818 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001819}
1820
1821// Test that we ignore RED if it uses more than 2 encodings.
1822TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1823 EXPECT_TRUE(SetupEngine());
1824 int channel_num = voe_.GetLastChannel();
1825 std::vector<cricket::AudioCodec> codecs;
1826 codecs.push_back(kRedCodec);
1827 codecs.push_back(kIsacCodec);
1828 codecs.push_back(kPcmuCodec);
1829 codecs[0].id = 127;
1830 codecs[0].params[""] = "96/96/96";
1831 codecs[1].id = 96;
1832 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1833 webrtc::CodecInst gcodec;
1834 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1835 EXPECT_EQ(96, gcodec.pltype);
1836 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001837 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001838}
1839
1840// Test that we ignore RED if it has bogus codec ids.
1841TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1842 EXPECT_TRUE(SetupEngine());
1843 int channel_num = voe_.GetLastChannel();
1844 std::vector<cricket::AudioCodec> codecs;
1845 codecs.push_back(kRedCodec);
1846 codecs.push_back(kIsacCodec);
1847 codecs.push_back(kPcmuCodec);
1848 codecs[0].id = 127;
1849 codecs[0].params[""] = "ABC/ABC";
1850 codecs[1].id = 96;
1851 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1852 webrtc::CodecInst gcodec;
1853 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1854 EXPECT_EQ(96, gcodec.pltype);
1855 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001856 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001857}
1858
1859// Test that we ignore RED if it refers to a codec that is not present.
1860TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1861 EXPECT_TRUE(SetupEngine());
1862 int channel_num = voe_.GetLastChannel();
1863 std::vector<cricket::AudioCodec> codecs;
1864 codecs.push_back(kRedCodec);
1865 codecs.push_back(kIsacCodec);
1866 codecs.push_back(kPcmuCodec);
1867 codecs[0].id = 127;
1868 codecs[0].params[""] = "97/97";
1869 codecs[1].id = 96;
1870 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1871 webrtc::CodecInst gcodec;
1872 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1873 EXPECT_EQ(96, gcodec.pltype);
1874 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001875 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001876}
1877
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001878// Test support for audio level header extension.
1879TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1880 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001881}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001882TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1883 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1884}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001885
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001886// Test support for absolute send time header extension.
1887TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1888 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1889}
1890TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1891 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001892}
1893
1894// Test that we can create a channel and start sending/playing out on it.
1895TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1896 EXPECT_TRUE(SetupEngine());
1897 int channel_num = voe_.GetLastChannel();
1898 std::vector<cricket::AudioCodec> codecs;
1899 codecs.push_back(kPcmuCodec);
1900 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1901 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1902 EXPECT_TRUE(voe_.GetSend(channel_num));
1903 EXPECT_TRUE(channel_->SetPlayout(true));
1904 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1905 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1906 EXPECT_FALSE(voe_.GetSend(channel_num));
1907 EXPECT_TRUE(channel_->SetPlayout(false));
1908 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1909}
1910
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001911// Test that we can add and remove send streams.
1912TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1913 SetupForMultiSendStream();
1914
1915 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1916
1917 // Set the global state for sending.
1918 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1919
1920 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1921 EXPECT_TRUE(channel_->AddSendStream(
1922 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1923
1924 // Verify that we are in a sending state for all the created streams.
1925 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1926 EXPECT_TRUE(voe_.GetSend(channel_num));
1927 }
1928
1929 // Remove the first send channel, which is the default channel. It will only
1930 // recycle the default channel but not delete it.
1931 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1932 // Stream should already be Removed from the send stream list.
1933 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1934 // But the default still exists.
1935 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1936
1937 // Delete the rest of send channel streams.
1938 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1939 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1940 // Stream should already be deleted.
1941 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1942 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1943 }
1944}
1945
1946// Test SetSendCodecs correctly configure the codecs in all send streams.
1947TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1948 SetupForMultiSendStream();
1949
1950 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1951 // Create send streams.
1952 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1953 EXPECT_TRUE(channel_->AddSendStream(
1954 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1955 }
1956
1957 std::vector<cricket::AudioCodec> codecs;
1958 // Set ISAC(16K) and CN(16K). VAD should be activated.
1959 codecs.push_back(kIsacCodec);
1960 codecs.push_back(kCn16000Codec);
1961 codecs[1].id = 97;
1962 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1963
1964 // Verify ISAC and VAD are corrected configured on all send channels.
1965 webrtc::CodecInst gcodec;
1966 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1967 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1968 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1969 EXPECT_STREQ("ISAC", gcodec.plname);
1970 EXPECT_TRUE(voe_.GetVAD(channel_num));
1971 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1972 }
1973
1974 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1975 codecs[0] = kPcmuCodec;
1976 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
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("PCMU", gcodec.plname);
1981 EXPECT_FALSE(voe_.GetVAD(channel_num));
1982 }
1983}
1984
1985// Test we can SetSend on all send streams correctly.
1986TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1987 SetupForMultiSendStream();
1988
1989 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1990 // Create the send channels and they should be a SEND_NOTHING date.
1991 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1992 EXPECT_TRUE(channel_->AddSendStream(
1993 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1994 int channel_num = voe_.GetLastChannel();
1995 EXPECT_FALSE(voe_.GetSend(channel_num));
1996 }
1997
1998 // Set the global state for starting sending.
1999 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2000 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2001 // Verify that we are in a sending state for all the send streams.
2002 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2003 EXPECT_TRUE(voe_.GetSend(channel_num));
2004 }
2005
2006 // Set the global state for stopping sending.
2007 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2008 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
2009 // Verify that we are in a stop state for all the send streams.
2010 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
2011 EXPECT_FALSE(voe_.GetSend(channel_num));
2012 }
2013}
2014
2015// Test we can set the correct statistics on all send streams.
2016TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2017 SetupForMultiSendStream();
2018
2019 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
2020 // Create send streams.
2021 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
2022 EXPECT_TRUE(channel_->AddSendStream(
2023 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2024 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002025 // Create a receive stream to check that none of the send streams end up in
2026 // the receive stream stats.
2027 EXPECT_TRUE(channel_->AddRecvStream(
2028 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002029 // We need send codec to be set to get all stats.
2030 std::vector<cricket::AudioCodec> codecs;
2031 codecs.push_back(kPcmuCodec);
2032 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002033 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002034
2035 cricket::VoiceMediaInfo info;
2036 EXPECT_EQ(true, channel_->GetStats(&info));
2037 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
2038
2039 // Verify the statistic information is correct.
2040 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002041 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002042 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
2043 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
2044 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
2045 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
2046 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
2047 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
2048 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
2049 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002050 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002051 }
2052
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002053 EXPECT_EQ(0u, info.receivers.size());
2054 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2055 EXPECT_EQ(true, channel_->GetStats(&info));
2056
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002057 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002058 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2059 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2060 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2061 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2062 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002063 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2064 (1 << 14), info.receivers[0].expand_rate);
2065 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2066 (1 << 14), info.receivers[0].speech_expand_rate);
2067 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2068 (1 << 14), info.receivers[0].secondary_decoded_rate);
Henrik Lundin8e6fd462015-06-02 09:24:52 +02002069 EXPECT_EQ(
2070 static_cast<float>(cricket::kNetStats.currentAccelerateRate) / (1 << 14),
2071 info.receivers[0].accelerate_rate);
2072 EXPECT_EQ(
2073 static_cast<float>(cricket::kNetStats.currentPreemptiveRate) / (1 << 14),
2074 info.receivers[0].preemptive_expand_rate);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002075}
2076
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002077// Test that we can add and remove receive streams, and do proper send/playout.
2078// We can receive on multiple streams while sending one stream.
2079TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002080 EXPECT_TRUE(SetupEngine());
2081 int channel_num1 = voe_.GetLastChannel();
2082
2083 // Start playout on the default channel.
2084 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2085 EXPECT_TRUE(channel_->SetPlayout(true));
2086 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2087
2088 // Adding another stream should disable playout on the default channel.
2089 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2090 int channel_num2 = voe_.GetLastChannel();
2091 std::vector<cricket::AudioCodec> codecs;
2092 codecs.push_back(kPcmuCodec);
2093 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2094 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2095 EXPECT_TRUE(voe_.GetSend(channel_num1));
2096 EXPECT_FALSE(voe_.GetSend(channel_num2));
2097
2098 // Make sure only the new channel is played out.
2099 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2100 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2101
2102 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2103 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2104 int channel_num3 = voe_.GetLastChannel();
2105 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2106 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2107 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2108 EXPECT_FALSE(voe_.GetSend(channel_num3));
2109
2110 // Stop sending.
2111 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2112 EXPECT_FALSE(voe_.GetSend(channel_num1));
2113 EXPECT_FALSE(voe_.GetSend(channel_num2));
2114 EXPECT_FALSE(voe_.GetSend(channel_num3));
2115
2116 // Stop playout.
2117 EXPECT_TRUE(channel_->SetPlayout(false));
2118 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2119 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2120 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2121
2122 // Restart playout and make sure the default channel still is not played out.
2123 EXPECT_TRUE(channel_->SetPlayout(true));
2124 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2125 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2126 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2127
2128 // Now remove the new streams and verify that the default channel is
2129 // played out again.
2130 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2131 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2132
2133 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2134}
2135
2136// Test that we can set the devices to use.
2137TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2138 EXPECT_TRUE(SetupEngine());
2139 int channel_num = voe_.GetLastChannel();
2140 std::vector<cricket::AudioCodec> codecs;
2141 codecs.push_back(kPcmuCodec);
2142 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2143
2144 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2145 cricket::kFakeDefaultDeviceId);
2146 cricket::Device dev(cricket::kFakeDeviceName,
2147 cricket::kFakeDeviceId);
2148
2149 // Test SetDevices() while not sending or playing.
2150 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2151
2152 // Test SetDevices() while sending and playing.
2153 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2154 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2155 EXPECT_TRUE(channel_->SetPlayout(true));
2156 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2157 EXPECT_TRUE(voe_.GetSend(channel_num));
2158 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2159
2160 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2161
2162 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2163 EXPECT_TRUE(voe_.GetSend(channel_num));
2164 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2165
2166 // Test that failure to open newly selected devices does not prevent opening
2167 // ones after that.
2168 voe_.set_fail_start_recording_microphone(true);
2169 voe_.set_playout_fail_channel(channel_num);
2170 voe_.set_send_fail_channel(channel_num);
2171
2172 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2173
2174 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2175 EXPECT_FALSE(voe_.GetSend(channel_num));
2176 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2177
2178 voe_.set_fail_start_recording_microphone(false);
2179 voe_.set_playout_fail_channel(-1);
2180 voe_.set_send_fail_channel(-1);
2181
2182 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2183
2184 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2185 EXPECT_TRUE(voe_.GetSend(channel_num));
2186 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2187}
2188
2189// Test that we can set the devices to use even if we failed to
2190// open the initial ones.
2191TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2192 EXPECT_TRUE(SetupEngine());
2193 int channel_num = voe_.GetLastChannel();
2194 std::vector<cricket::AudioCodec> codecs;
2195 codecs.push_back(kPcmuCodec);
2196 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2197
2198 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2199 cricket::kFakeDefaultDeviceId);
2200 cricket::Device dev(cricket::kFakeDeviceName,
2201 cricket::kFakeDeviceId);
2202
2203 // Test that failure to open devices selected before starting
2204 // send/play does not prevent opening newly selected ones after that.
2205 voe_.set_fail_start_recording_microphone(true);
2206 voe_.set_playout_fail_channel(channel_num);
2207 voe_.set_send_fail_channel(channel_num);
2208
2209 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2210
2211 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2212 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2213 EXPECT_FALSE(channel_->SetPlayout(true));
2214 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2215 EXPECT_FALSE(voe_.GetSend(channel_num));
2216 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2217
2218 voe_.set_fail_start_recording_microphone(false);
2219 voe_.set_playout_fail_channel(-1);
2220 voe_.set_send_fail_channel(-1);
2221
2222 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2223
2224 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2225 EXPECT_TRUE(voe_.GetSend(channel_num));
2226 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2227}
2228
2229// Test that we can create a channel configured for multi-point conferences,
2230// and start sending/playing out on it.
2231TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2232 EXPECT_TRUE(SetupEngine());
2233 int channel_num = voe_.GetLastChannel();
2234 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2235 std::vector<cricket::AudioCodec> codecs;
2236 codecs.push_back(kPcmuCodec);
2237 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2238 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2239 EXPECT_TRUE(voe_.GetSend(channel_num));
2240}
2241
2242// Test that we can create a channel configured for Codian bridges,
2243// and start sending/playing out on it.
2244TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2245 EXPECT_TRUE(SetupEngine());
2246 int channel_num = voe_.GetLastChannel();
2247 webrtc::AgcConfig agc_config;
2248 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2249 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2250 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2251 std::vector<cricket::AudioCodec> codecs;
2252 codecs.push_back(kPcmuCodec);
2253 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2254 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2255 EXPECT_TRUE(voe_.GetSend(channel_num));
2256 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2257 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2258 EXPECT_TRUE(channel_->SetPlayout(true));
2259 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2260 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2261 EXPECT_FALSE(voe_.GetSend(channel_num));
2262 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2263 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2264 EXPECT_TRUE(channel_->SetPlayout(false));
2265 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2266}
2267
wu@webrtc.org97077a32013-10-25 21:18:33 +00002268TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2269 EXPECT_TRUE(SetupEngine());
2270 webrtc::AgcConfig agc_config;
2271 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2272 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2273
2274 cricket::AudioOptions options;
2275 options.tx_agc_target_dbov.Set(3);
2276 options.tx_agc_digital_compression_gain.Set(9);
2277 options.tx_agc_limiter.Set(true);
2278 options.auto_gain_control.Set(true);
2279 EXPECT_TRUE(engine_.SetOptions(options));
2280
2281 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2282 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2283 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2284 EXPECT_TRUE(agc_config.limiterEnable);
2285
2286 // Check interaction with adjust_agc_delta. Both should be respected, for
2287 // backwards compatibility.
2288 options.adjust_agc_delta.Set(-10);
2289 EXPECT_TRUE(engine_.SetOptions(options));
2290
2291 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2292 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2293}
2294
2295TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2296 EXPECT_TRUE(SetupEngine());
2297 int channel_num = voe_.GetLastChannel();
2298 cricket::AudioOptions options;
2299 options.rx_agc_target_dbov.Set(6);
2300 options.rx_agc_digital_compression_gain.Set(0);
2301 options.rx_agc_limiter.Set(true);
2302 options.rx_auto_gain_control.Set(true);
2303 EXPECT_TRUE(channel_->SetOptions(options));
2304
2305 webrtc::AgcConfig agc_config;
2306 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2307 channel_num, agc_config));
2308 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2309 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2310 EXPECT_TRUE(agc_config.limiterEnable);
2311}
2312
2313TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2314 EXPECT_TRUE(SetupEngine());
2315 cricket::AudioOptions options;
2316 options.recording_sample_rate.Set(48000u);
2317 options.playout_sample_rate.Set(44100u);
2318 EXPECT_TRUE(engine_.SetOptions(options));
2319
2320 unsigned int recording_sample_rate, playout_sample_rate;
2321 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2322 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2323 EXPECT_EQ(48000u, recording_sample_rate);
2324 EXPECT_EQ(44100u, playout_sample_rate);
2325}
2326
2327TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2328 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002329 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002330 EXPECT_EQ(
2331 // Info:
2332 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2333 // Warning:
2334 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2335 // Error:
2336 webrtc::kTraceError | webrtc::kTraceCritical,
2337 static_cast<int>(trace_wrapper_->filter_));
2338 // Now set it explicitly
2339 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002340 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2341 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002342 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2343 trace_wrapper_->filter_);
2344}
2345
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002346// Test that we can set the outgoing SSRC properly.
2347// SSRC is set in SetupEngine by calling AddSendStream.
2348TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2349 EXPECT_TRUE(SetupEngine());
2350 int channel_num = voe_.GetLastChannel();
2351 unsigned int send_ssrc;
2352 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2353 EXPECT_NE(0U, send_ssrc);
2354 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2355 EXPECT_EQ(kSsrc1, send_ssrc);
2356}
2357
2358TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2359 // Setup. We need send codec to be set to get all stats.
2360 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002361 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2362 // use a different SSRC.
2363 EXPECT_TRUE(channel_->AddRecvStream(
2364 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365 std::vector<cricket::AudioCodec> codecs;
2366 codecs.push_back(kPcmuCodec);
2367 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002368 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002369
2370 cricket::VoiceMediaInfo info;
2371 EXPECT_EQ(true, channel_->GetStats(&info));
2372 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002373 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2375 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2376 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2377 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2378 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2379 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2380 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2381 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002382 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002383 // TODO(sriniv): Add testing for more fields. These are not populated
2384 // in FakeWebrtcVoiceEngine yet.
2385 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2386 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2387 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2388 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2389 // EXPECT_EQ(cricket::kIntStatValue,
2390 // info.senders[0].echo_return_loss_enhancement);
2391
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002392 EXPECT_EQ(0u, info.receivers.size());
2393 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2394 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002395 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002396
2397 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2398 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2399 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2400 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2401 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +00002402 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentExpandRate) /
2403 (1 << 14), info.receivers[0].expand_rate);
2404 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSpeechExpandRate) /
2405 (1 << 14), info.receivers[0].speech_expand_rate);
2406 EXPECT_EQ(static_cast<float>(cricket::kNetStats.currentSecondaryDecodedRate) /
2407 (1 << 14), info.receivers[0].secondary_decoded_rate);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002408 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409}
2410
2411// Test that we can set the outgoing SSRC properly with multiple streams.
2412// SSRC is set in SetupEngine by calling AddSendStream.
2413TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2414 EXPECT_TRUE(SetupEngine());
2415 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2416 int channel_num1 = voe_.GetLastChannel();
2417 unsigned int send_ssrc;
2418 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2419 EXPECT_EQ(kSsrc1, send_ssrc);
2420
2421 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2422 int channel_num2 = voe_.GetLastChannel();
2423 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2424 EXPECT_EQ(kSsrc1, send_ssrc);
2425}
2426
2427// Test that the local SSRC is the same on sending and receiving channels if the
2428// receive channel is created before the send channel.
2429TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002430 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02002431 channel_ = engine_.CreateChannel(cricket::AudioOptions());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002432 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2433
2434 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2435 int receive_channel_num = voe_.GetLastChannel();
2436 EXPECT_TRUE(channel_->AddSendStream(
2437 cricket::StreamParams::CreateLegacy(1234)));
2438 int send_channel_num = voe_.GetLastChannel();
2439
2440 unsigned int ssrc = 0;
2441 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2442 EXPECT_EQ(1234U, ssrc);
2443 ssrc = 0;
2444 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2445 EXPECT_EQ(1234U, ssrc);
2446}
2447
2448// Test that we can properly receive packets.
2449TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2450 EXPECT_TRUE(SetupEngine());
2451 int channel_num = voe_.GetLastChannel();
2452 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2453 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2454 sizeof(kPcmuFrame)));
2455}
2456
2457// Test that we can properly receive packets on multiple streams.
2458TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2459 EXPECT_TRUE(SetupEngine());
2460 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2461 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2462 int channel_num1 = voe_.GetLastChannel();
2463 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2464 int channel_num2 = voe_.GetLastChannel();
2465 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2466 int channel_num3 = voe_.GetLastChannel();
2467 // Create packets with the right SSRCs.
2468 char packets[4][sizeof(kPcmuFrame)];
2469 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2470 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002471 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472 }
2473 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2474 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2475 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2476 DeliverPacket(packets[0], sizeof(packets[0]));
2477 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2478 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2479 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2480 DeliverPacket(packets[1], sizeof(packets[1]));
2481 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2482 sizeof(packets[1])));
2483 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2484 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2485 DeliverPacket(packets[2], sizeof(packets[2]));
2486 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2487 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2488 sizeof(packets[2])));
2489 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2490 DeliverPacket(packets[3], sizeof(packets[3]));
2491 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2492 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2493 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2494 sizeof(packets[3])));
2495 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2496 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2497 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2498}
2499
2500// Test that we properly handle failures to add a stream.
2501TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2502 EXPECT_TRUE(SetupEngine());
2503 voe_.set_fail_create_channel(true);
2504 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2505 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2506
2507 // In 1:1 call, we should not try to create a new channel.
2508 cricket::AudioOptions options_no_conference_;
2509 options_no_conference_.conference_mode.Set(false);
2510 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2511 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2512}
2513
2514// Test that AddRecvStream doesn't create new channel for 1:1 call.
2515TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2516 EXPECT_TRUE(SetupEngine());
2517 int channel_num = voe_.GetLastChannel();
2518 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2519 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2520}
2521
2522// Test that after adding a recv stream, we do not decode more codecs than
2523// those previously passed into SetRecvCodecs.
2524TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2525 EXPECT_TRUE(SetupEngine());
2526 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2527 std::vector<cricket::AudioCodec> codecs;
2528 codecs.push_back(kIsacCodec);
2529 codecs.push_back(kPcmuCodec);
2530 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2531 EXPECT_TRUE(channel_->AddRecvStream(
2532 cricket::StreamParams::CreateLegacy(kSsrc1)));
2533 int channel_num2 = voe_.GetLastChannel();
2534 webrtc::CodecInst gcodec;
minyue@webrtc.orgf9b5c1b2015-02-17 12:36:41 +00002535 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "opus");
2536 gcodec.plfreq = 48000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002537 gcodec.channels = 2;
2538 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2539}
2540
2541// Test that we properly clean up any streams that were added, even if
2542// not explicitly removed.
2543TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2544 EXPECT_TRUE(SetupEngine());
2545 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2546 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2547 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2548 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2549 delete channel_;
2550 channel_ = NULL;
2551 EXPECT_EQ(0, voe_.GetNumChannels());
2552}
2553
wu@webrtc.org78187522013-10-07 23:32:02 +00002554TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2555 EXPECT_TRUE(SetupEngine());
2556 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2557}
2558
2559TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2560 EXPECT_TRUE(SetupEngine());
2561 // Stream 1 reuses default channel.
2562 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2563 // Manually delete default channel to simulate a failure.
2564 int default_channel = voe_.GetLastChannel();
2565 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2566 // Add recv stream 2 should fail because default channel is gone.
2567 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2568 int new_channel = voe_.GetLastChannel();
2569 EXPECT_NE(default_channel, new_channel);
2570 // The last created channel should have already been deleted.
2571 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2572}
2573
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002574// Test the InsertDtmf on default send stream as caller.
2575TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2576 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002577}
2578
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002579// Test the InsertDtmf on default send stream as callee
2580TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2581 TestInsertDtmf(0, false);
2582}
2583
2584// Test the InsertDtmf on specified send stream as caller.
2585TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2586 TestInsertDtmf(kSsrc1, true);
2587}
2588
2589// Test the InsertDtmf on specified send stream as callee.
2590TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2591 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002592}
2593
2594// Test that we can play a ringback tone properly in a single-stream call.
2595TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2596 EXPECT_TRUE(SetupEngine());
2597 int channel_num = voe_.GetLastChannel();
2598 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2599 // Check we fail if no ringback tone specified.
2600 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2601 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2602 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002603 EXPECT_TRUE(channel_->SetRingbackTone(
2604 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002605 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2606 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2607 // Check we can stop the tone manually.
2608 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2609 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2610 // Check we stop the tone if a packet arrives.
2611 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2612 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2613 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2614 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2615}
2616
2617// Test that we can play a ringback tone properly in a multi-stream call.
2618TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2619 EXPECT_TRUE(SetupEngine());
2620 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2621 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2622 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2623 int channel_num = voe_.GetLastChannel();
2624 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2625 // Check we fail if no ringback tone specified.
2626 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2627 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2628 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002629 EXPECT_TRUE(channel_->SetRingbackTone(
2630 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002631 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2632 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2633 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2634 // Check we can stop the tone manually.
2635 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2636 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2637 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2638 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2639 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2640 // Send a packet with SSRC 1; the tone should not stop.
2641 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2642 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2643 // Send a packet with SSRC 2; the tone should stop.
2644 char packet[sizeof(kPcmuFrame)];
2645 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002646 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002647 DeliverPacket(packet, sizeof(packet));
2648 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2649}
2650
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002652 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002653 cricket::WebRtcVoiceMediaChannel* media_channel;
2654 unsigned int ssrc = 0;
2655
2656 EXPECT_TRUE(SetupEngine());
2657 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2658 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2659
2660 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2661 listener.reset(new ChannelErrorListener(channel_));
2662
2663 // Test on WebRtc VoE channel.
2664 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2665 VE_SATURATION_WARNING);
2666 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2667 listener->error());
2668 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2669 EXPECT_EQ(ssrc, listener->ssrc());
2670
2671 listener->Reset();
2672 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2673 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2674 listener->error());
2675 EXPECT_EQ(0U, listener->ssrc());
2676
2677 // Add another stream and test on that.
2678 ++ssrc;
2679 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2680 ssrc)));
2681 listener->Reset();
2682 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2683 VE_SATURATION_WARNING);
2684 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2685 listener->error());
2686 EXPECT_EQ(ssrc, listener->ssrc());
2687
2688 // Testing a non-existing channel.
2689 listener->Reset();
2690 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2691 VE_SATURATION_WARNING);
2692 EXPECT_EQ(0, listener->error());
2693}
2694
2695TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2696 EXPECT_TRUE(SetupEngine());
2697 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2698 std::vector<cricket::AudioCodec> codecs;
2699 codecs.push_back(kPcmuCodec);
2700 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2701 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2702 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2703 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2704 EXPECT_TRUE(channel_->SetPlayout(true));
2705 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2706 EXPECT_TRUE(channel_->SetPlayout(false));
2707 EXPECT_FALSE(channel_->SetPlayout(true));
2708}
2709
2710// Test that the Registering/Unregistering with the
2711// webrtcvoiceengine works as expected
2712TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2713 EXPECT_TRUE(SetupEngine());
2714 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2715 EXPECT_TRUE(channel_->AddRecvStream(
2716 cricket::StreamParams::CreateLegacy(kSsrc2)));
2717 cricket::FakeMediaProcessor vp_1;
2718 cricket::FakeMediaProcessor vp_2;
2719
2720 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2721 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2722 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2723 voe_.TriggerProcessPacket(cricket::MPD_RX);
2724 voe_.TriggerProcessPacket(cricket::MPD_TX);
2725
2726 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2727 EXPECT_EQ(1, vp_1.voice_frame_count());
2728 EXPECT_EQ(1, vp_2.voice_frame_count());
2729
2730 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2731 &vp_2,
2732 cricket::MPD_RX));
2733 voe_.TriggerProcessPacket(cricket::MPD_RX);
2734 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2735 EXPECT_EQ(1, vp_2.voice_frame_count());
2736 EXPECT_EQ(2, vp_1.voice_frame_count());
2737
2738 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2739 &vp_1,
2740 cricket::MPD_RX));
2741 voe_.TriggerProcessPacket(cricket::MPD_RX);
2742 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2743 EXPECT_EQ(2, vp_1.voice_frame_count());
2744
2745 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2746 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2747 voe_.TriggerProcessPacket(cricket::MPD_RX);
2748 voe_.TriggerProcessPacket(cricket::MPD_TX);
2749 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2750 EXPECT_EQ(3, vp_1.voice_frame_count());
2751
2752 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2753 &vp_1,
2754 cricket::MPD_RX_AND_TX));
2755 voe_.TriggerProcessPacket(cricket::MPD_TX);
2756 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2757 EXPECT_EQ(3, vp_1.voice_frame_count());
2758 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2759 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2760 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2761
2762 // Test that we can register a processor on the receive channel on SSRC 0.
2763 // This tests the 1:1 case when the receive SSRC is unknown.
2764 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2765 voe_.TriggerProcessPacket(cricket::MPD_RX);
2766 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2767 EXPECT_EQ(4, vp_1.voice_frame_count());
2768 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2769 &vp_1,
2770 cricket::MPD_RX));
2771
2772 // The following tests test that FindChannelNumFromSsrc is doing
2773 // what we expect.
2774 // pick an invalid ssrc and make sure we can't register
2775 EXPECT_FALSE(engine_.RegisterProcessor(99,
2776 &vp_1,
2777 cricket::MPD_RX));
2778 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2779 EXPECT_TRUE(engine_.RegisterProcessor(1,
2780 &vp_1,
2781 cricket::MPD_RX));
2782 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2783 &vp_1,
2784 cricket::MPD_RX));
2785 EXPECT_FALSE(engine_.RegisterProcessor(1,
2786 &vp_1,
2787 cricket::MPD_TX));
2788 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2789}
2790
2791TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2792 EXPECT_TRUE(SetupEngine());
2793
2794 bool ec_enabled;
2795 webrtc::EcModes ec_mode;
2796 bool ec_metrics_enabled;
2797 webrtc::AecmModes aecm_mode;
2798 bool cng_enabled;
2799 bool agc_enabled;
2800 webrtc::AgcModes agc_mode;
2801 webrtc::AgcConfig agc_config;
2802 bool ns_enabled;
2803 webrtc::NsModes ns_mode;
2804 bool highpass_filter_enabled;
2805 bool stereo_swapping_enabled;
2806 bool typing_detection_enabled;
2807 voe_.GetEcStatus(ec_enabled, ec_mode);
2808 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2809 voe_.GetAecmMode(aecm_mode, cng_enabled);
2810 voe_.GetAgcStatus(agc_enabled, agc_mode);
2811 voe_.GetAgcConfig(agc_config);
2812 voe_.GetNsStatus(ns_enabled, ns_mode);
2813 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2814 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2815 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2816 EXPECT_TRUE(ec_enabled);
2817 EXPECT_TRUE(ec_metrics_enabled);
2818 EXPECT_FALSE(cng_enabled);
2819 EXPECT_TRUE(agc_enabled);
2820 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2821 EXPECT_TRUE(ns_enabled);
2822 EXPECT_TRUE(highpass_filter_enabled);
2823 EXPECT_FALSE(stereo_swapping_enabled);
2824 EXPECT_TRUE(typing_detection_enabled);
2825 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2826 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2827
2828 // Nothing set, so all ignored.
2829 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002830 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002831 voe_.GetEcStatus(ec_enabled, ec_mode);
2832 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2833 voe_.GetAecmMode(aecm_mode, cng_enabled);
2834 voe_.GetAgcStatus(agc_enabled, agc_mode);
2835 voe_.GetAgcConfig(agc_config);
2836 voe_.GetNsStatus(ns_enabled, ns_mode);
2837 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2838 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2839 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2840 EXPECT_TRUE(ec_enabled);
2841 EXPECT_TRUE(ec_metrics_enabled);
2842 EXPECT_FALSE(cng_enabled);
2843 EXPECT_TRUE(agc_enabled);
2844 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2845 EXPECT_TRUE(ns_enabled);
2846 EXPECT_TRUE(highpass_filter_enabled);
2847 EXPECT_FALSE(stereo_swapping_enabled);
2848 EXPECT_TRUE(typing_detection_enabled);
2849 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2850 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
Henrik Lundin64dad832015-05-11 12:44:23 +02002851 EXPECT_EQ(50, voe_.GetNetEqCapacity()); // From GetDefaultEngineOptions().
Henrik Lundin5263b3c2015-06-01 10:29:41 +02002852 EXPECT_FALSE(
2853 voe_.GetNetEqFastAccelerate()); // From GetDefaultEngineOptions().
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002854
2855 // Turn echo cancellation off
2856 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002857 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002858 voe_.GetEcStatus(ec_enabled, ec_mode);
2859 EXPECT_FALSE(ec_enabled);
2860
2861 // Turn echo cancellation back on, with settings, and make sure
2862 // nothing else changed.
2863 options.echo_cancellation.Set(true);
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_TRUE(agc_enabled);
2877 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2878 EXPECT_TRUE(ns_enabled);
2879 EXPECT_TRUE(highpass_filter_enabled);
2880 EXPECT_FALSE(stereo_swapping_enabled);
2881 EXPECT_TRUE(typing_detection_enabled);
2882 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2883 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2884
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002885 // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2886 // control.
2887 options.delay_agnostic_aec.Set(true);
2888 ASSERT_TRUE(engine_.SetOptions(options));
2889 voe_.GetEcStatus(ec_enabled, ec_mode);
2890 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2891 voe_.GetAecmMode(aecm_mode, cng_enabled);
2892 EXPECT_TRUE(ec_enabled);
2893 EXPECT_TRUE(ec_metrics_enabled);
2894 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2895
2896 // Turn off echo cancellation and delay agnostic aec.
2897 options.delay_agnostic_aec.Set(false);
Henrik Lundin441f6342015-06-09 16:03:13 +02002898 options.extended_filter_aec.Set(false);
Bjorn Volckerbf395c12015-03-25 22:45:56 +01002899 options.echo_cancellation.Set(false);
2900 ASSERT_TRUE(engine_.SetOptions(options));
2901 voe_.GetEcStatus(ec_enabled, ec_mode);
2902 EXPECT_FALSE(ec_enabled);
2903 // Turning delay agnostic aec back on should also turn on echo cancellation.
2904 options.delay_agnostic_aec.Set(true);
2905 ASSERT_TRUE(engine_.SetOptions(options));
2906 voe_.GetEcStatus(ec_enabled, ec_mode);
2907 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2908 EXPECT_TRUE(ec_enabled);
2909 EXPECT_TRUE(ec_metrics_enabled);
2910 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2911
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002912 // Turn off AGC
2913 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002914 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915 voe_.GetAgcStatus(agc_enabled, agc_mode);
2916 EXPECT_FALSE(agc_enabled);
2917
2918 // Turn AGC back on
2919 options.auto_gain_control.Set(true);
2920 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002921 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002922 voe_.GetAgcStatus(agc_enabled, agc_mode);
2923 EXPECT_TRUE(agc_enabled);
2924 voe_.GetAgcConfig(agc_config);
2925 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2926
2927 // Turn off other options (and stereo swapping on).
2928 options.noise_suppression.Set(false);
2929 options.highpass_filter.Set(false);
2930 options.typing_detection.Set(false);
2931 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002932 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933 voe_.GetNsStatus(ns_enabled, ns_mode);
2934 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2935 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2936 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2937 EXPECT_FALSE(ns_enabled);
2938 EXPECT_FALSE(highpass_filter_enabled);
2939 EXPECT_FALSE(typing_detection_enabled);
2940 EXPECT_TRUE(stereo_swapping_enabled);
2941
2942 // Turn on "conference mode" to ensure it has no impact.
2943 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002944 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002945 voe_.GetEcStatus(ec_enabled, ec_mode);
2946 voe_.GetNsStatus(ns_enabled, ns_mode);
2947 EXPECT_TRUE(ec_enabled);
2948 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2949 EXPECT_FALSE(ns_enabled);
2950 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2951}
2952
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002953TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002954 EXPECT_TRUE(SetupEngine());
2955
2956 bool ec_enabled;
2957 webrtc::EcModes ec_mode;
2958 bool ec_metrics_enabled;
2959 bool agc_enabled;
2960 webrtc::AgcModes agc_mode;
2961 bool ns_enabled;
2962 webrtc::NsModes ns_mode;
2963 bool highpass_filter_enabled;
2964 bool stereo_swapping_enabled;
2965 bool typing_detection_enabled;
2966
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002967 voe_.GetEcStatus(ec_enabled, ec_mode);
2968 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2969 voe_.GetAgcStatus(agc_enabled, agc_mode);
2970 voe_.GetNsStatus(ns_enabled, ns_mode);
2971 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2972 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2973 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2974 EXPECT_TRUE(ec_enabled);
2975 EXPECT_TRUE(agc_enabled);
2976 EXPECT_TRUE(ns_enabled);
2977 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002978 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002980}
2981
2982TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2983 webrtc::AgcConfig set_config = {0};
2984 set_config.targetLeveldBOv = 3;
2985 set_config.digitalCompressionGaindB = 9;
2986 set_config.limiterEnable = true;
2987 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002988 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002989
2990 webrtc::AgcConfig config = {0};
2991 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2992 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2993 EXPECT_EQ(set_config.digitalCompressionGaindB,
2994 config.digitalCompressionGaindB);
2995 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2996}
2997
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2999 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003000 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
Jelena Marusicc28a8962015-05-29 15:05:44 +02003001 engine_.CreateChannel(cricket::AudioOptions()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003002 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
Jelena Marusicc28a8962015-05-29 15:05:44 +02003003 engine_.CreateChannel(cricket::AudioOptions()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003004
3005 // Have to add a stream to make SetSend work.
3006 cricket::StreamParams stream1;
3007 stream1.ssrcs.push_back(1);
3008 channel1->AddSendStream(stream1);
3009 cricket::StreamParams stream2;
3010 stream2.ssrcs.push_back(2);
3011 channel2->AddSendStream(stream2);
3012
3013 // AEC and AGC and NS
3014 cricket::AudioOptions options_all;
3015 options_all.echo_cancellation.Set(true);
3016 options_all.auto_gain_control.Set(true);
3017 options_all.noise_suppression.Set(true);
3018
3019 ASSERT_TRUE(channel1->SetOptions(options_all));
3020 cricket::AudioOptions expected_options = options_all;
3021 cricket::AudioOptions actual_options;
3022 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3023 EXPECT_EQ(expected_options, actual_options);
3024 ASSERT_TRUE(channel2->SetOptions(options_all));
3025 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3026 EXPECT_EQ(expected_options, actual_options);
3027
3028 // unset NS
3029 cricket::AudioOptions options_no_ns;
3030 options_no_ns.noise_suppression.Set(false);
3031 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
3032
3033 expected_options.echo_cancellation.Set(true);
3034 expected_options.auto_gain_control.Set(true);
3035 expected_options.noise_suppression.Set(false);
3036 ASSERT_TRUE(channel1->GetOptions(&actual_options));
3037 EXPECT_EQ(expected_options, actual_options);
3038
3039 // unset AGC
3040 cricket::AudioOptions options_no_agc;
3041 options_no_agc.auto_gain_control.Set(false);
3042 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
3043
3044 expected_options.echo_cancellation.Set(true);
3045 expected_options.auto_gain_control.Set(false);
3046 expected_options.noise_suppression.Set(true);
3047 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3048 EXPECT_EQ(expected_options, actual_options);
3049
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003050 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003051 bool ec_enabled;
3052 webrtc::EcModes ec_mode;
3053 bool agc_enabled;
3054 webrtc::AgcModes agc_mode;
3055 bool ns_enabled;
3056 webrtc::NsModes ns_mode;
3057 voe_.GetEcStatus(ec_enabled, ec_mode);
3058 voe_.GetAgcStatus(agc_enabled, agc_mode);
3059 voe_.GetNsStatus(ns_enabled, ns_mode);
3060 EXPECT_TRUE(ec_enabled);
3061 EXPECT_TRUE(agc_enabled);
3062 EXPECT_TRUE(ns_enabled);
3063
3064 channel1->SetSend(cricket::SEND_MICROPHONE);
3065 voe_.GetEcStatus(ec_enabled, ec_mode);
3066 voe_.GetAgcStatus(agc_enabled, agc_mode);
3067 voe_.GetNsStatus(ns_enabled, ns_mode);
3068 EXPECT_TRUE(ec_enabled);
3069 EXPECT_TRUE(agc_enabled);
3070 EXPECT_FALSE(ns_enabled);
3071
3072 channel1->SetSend(cricket::SEND_NOTHING);
3073 voe_.GetEcStatus(ec_enabled, ec_mode);
3074 voe_.GetAgcStatus(agc_enabled, agc_mode);
3075 voe_.GetNsStatus(ns_enabled, ns_mode);
3076 EXPECT_TRUE(ec_enabled);
3077 EXPECT_TRUE(agc_enabled);
3078 EXPECT_TRUE(ns_enabled);
3079
3080 channel2->SetSend(cricket::SEND_MICROPHONE);
3081 voe_.GetEcStatus(ec_enabled, ec_mode);
3082 voe_.GetAgcStatus(agc_enabled, agc_mode);
3083 voe_.GetNsStatus(ns_enabled, ns_mode);
3084 EXPECT_TRUE(ec_enabled);
3085 EXPECT_FALSE(agc_enabled);
3086 EXPECT_TRUE(ns_enabled);
3087
3088 channel2->SetSend(cricket::SEND_NOTHING);
3089 voe_.GetEcStatus(ec_enabled, ec_mode);
3090 voe_.GetAgcStatus(agc_enabled, agc_mode);
3091 voe_.GetNsStatus(ns_enabled, ns_mode);
3092 EXPECT_TRUE(ec_enabled);
3093 EXPECT_TRUE(agc_enabled);
3094 EXPECT_TRUE(ns_enabled);
3095
3096 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003097 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003098 cricket::AudioOptions options_no_agc_nor_ns;
3099 options_no_agc_nor_ns.auto_gain_control.Set(false);
3100 options_no_agc_nor_ns.noise_suppression.Set(false);
3101 channel2->SetSend(cricket::SEND_MICROPHONE);
3102 channel2->SetOptions(options_no_agc_nor_ns);
3103
3104 expected_options.echo_cancellation.Set(true);
3105 expected_options.auto_gain_control.Set(false);
3106 expected_options.noise_suppression.Set(false);
3107 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3108 EXPECT_EQ(expected_options, actual_options);
3109 voe_.GetEcStatus(ec_enabled, ec_mode);
3110 voe_.GetAgcStatus(agc_enabled, agc_mode);
3111 voe_.GetNsStatus(ns_enabled, ns_mode);
3112 EXPECT_TRUE(ec_enabled);
3113 EXPECT_FALSE(agc_enabled);
3114 EXPECT_FALSE(ns_enabled);
3115}
3116
wu@webrtc.orgde305012013-10-31 15:40:38 +00003117// This test verifies DSCP settings are properly applied on voice media channel.
3118TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3119 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003120 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
Jelena Marusicc28a8962015-05-29 15:05:44 +02003121 engine_.CreateChannel(cricket::AudioOptions()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003122 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003123 new cricket::FakeNetworkInterface);
3124 channel->SetInterface(network_interface.get());
3125 cricket::AudioOptions options;
3126 options.dscp.Set(true);
3127 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003128 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003129 // Verify previous value is not modified if dscp option is not set.
3130 cricket::AudioOptions options1;
3131 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003132 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003133 options.dscp.Set(false);
3134 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003135 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003136}
3137
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00003138TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3139 cricket::WebRtcVoiceEngine engine;
3140 cricket::AudioOptions options = engine.GetOptions();
3141 // The default options should have at least a few things set. We purposefully
3142 // don't check the option values here, though.
3143 EXPECT_TRUE(options.echo_cancellation.IsSet());
3144 EXPECT_TRUE(options.auto_gain_control.IsSet());
3145 EXPECT_TRUE(options.noise_suppression.IsSet());
3146}
3147
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003148// Test that GetReceiveChannelNum returns the default channel for the first
3149// recv stream in 1-1 calls.
3150TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3151 EXPECT_TRUE(SetupEngine());
3152 cricket::WebRtcVoiceMediaChannel* media_channel =
3153 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3154 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3155 EXPECT_EQ(media_channel->voe_channel(),
3156 media_channel->GetReceiveChannelNum(0));
3157 cricket::StreamParams stream;
3158 stream.ssrcs.push_back(kSsrc2);
3159 EXPECT_TRUE(channel_->AddRecvStream(stream));
3160 EXPECT_EQ(media_channel->voe_channel(),
3161 media_channel->GetReceiveChannelNum(kSsrc2));
3162}
3163
3164// Test that GetReceiveChannelNum doesn't return the default channel for the
3165// first recv stream in conference calls.
3166TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3167 EXPECT_TRUE(SetupEngine());
3168 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3169 cricket::StreamParams stream;
3170 stream.ssrcs.push_back(kSsrc2);
3171 EXPECT_TRUE(channel_->AddRecvStream(stream));
3172 cricket::WebRtcVoiceMediaChannel* media_channel =
3173 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3174 EXPECT_LT(media_channel->voe_channel(),
3175 media_channel->GetReceiveChannelNum(kSsrc2));
3176}
3177
3178TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3179 EXPECT_TRUE(SetupEngine());
3180 double left, right;
3181 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
3182 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
3183 EXPECT_DOUBLE_EQ(1, left);
3184 EXPECT_DOUBLE_EQ(2, right);
3185
3186 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3187 cricket::StreamParams stream;
3188 stream.ssrcs.push_back(kSsrc2);
3189 EXPECT_TRUE(channel_->AddRecvStream(stream));
3190
3191 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
3192 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
3193 EXPECT_DOUBLE_EQ(2, left);
3194 EXPECT_DOUBLE_EQ(1, right);
3195}
3196
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003197// Tests for the actual WebRtc VoE library.
3198
3199// Tests that the library initializes and shuts down properly.
3200TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3201 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003202 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
Jelena Marusicc28a8962015-05-29 15:05:44 +02003203 cricket::VoiceMediaChannel* channel =
3204 engine.CreateChannel(cricket::AudioOptions());
3205 EXPECT_TRUE(channel != nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003206 delete channel;
3207 engine.Terminate();
3208
3209 // Reinit to catch regression where VoiceEngineObserver reference is lost
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003210 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003211 engine.Terminate();
3212}
3213
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003214// Tests that the library is configured with the codecs we want.
3215TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3216 cricket::WebRtcVoiceEngine engine;
3217 // Check codecs by name.
3218 EXPECT_TRUE(engine.FindCodec(
3219 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3220 EXPECT_TRUE(engine.FindCodec(
3221 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3222 EXPECT_TRUE(engine.FindCodec(
3223 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3224 // Check that name matching is case-insensitive.
3225 EXPECT_TRUE(engine.FindCodec(
3226 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3227 EXPECT_TRUE(engine.FindCodec(
3228 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3229 EXPECT_TRUE(engine.FindCodec(
3230 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3231 EXPECT_TRUE(engine.FindCodec(
3232 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3233 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003234 cricket::AudioCodec(96, "G722", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003235 EXPECT_TRUE(engine.FindCodec(
3236 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003237 EXPECT_TRUE(engine.FindCodec(
3238 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3239 EXPECT_TRUE(engine.FindCodec(
3240 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3241 EXPECT_TRUE(engine.FindCodec(
3242 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3243 EXPECT_TRUE(engine.FindCodec(
3244 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3245 // Check codecs with an id by id.
3246 EXPECT_TRUE(engine.FindCodec(
3247 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3248 EXPECT_TRUE(engine.FindCodec(
3249 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3250 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003251 cricket::AudioCodec(9, "", 8000, 0, 1, 0))); // G722
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003252 EXPECT_TRUE(engine.FindCodec(
3253 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3254 // Check sample/bitrate matching.
3255 EXPECT_TRUE(engine.FindCodec(
3256 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3257 // Check that bad codecs fail.
3258 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3259 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3260 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3261 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3262 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003263 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3264 for (std::vector<cricket::AudioCodec>::const_iterator it =
3265 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3266 if (it->name == "CN" && it->clockrate == 16000) {
3267 EXPECT_EQ(105, it->id);
3268 } else if (it->name == "CN" && it->clockrate == 32000) {
3269 EXPECT_EQ(106, it->id);
3270 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3271 EXPECT_EQ(103, it->id);
3272 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3273 EXPECT_EQ(104, it->id);
henrik.lundin@webrtc.orgf85dbce2014-11-07 12:25:00 +00003274 } else if (it->name == "G722" && it->clockrate == 8000) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003275 EXPECT_EQ(9, it->id);
3276 } else if (it->name == "telephone-event") {
3277 EXPECT_EQ(126, it->id);
3278 } else if (it->name == "red") {
3279 EXPECT_EQ(127, it->id);
3280 } else if (it->name == "opus") {
3281 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003282 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003283 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003284 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003285 EXPECT_EQ("60", it->params.find("maxptime")->second);
minyue@webrtc.org4ef22d12014-11-17 09:26:39 +00003286 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3287 EXPECT_EQ("1", it->params.find("useinbandfec")->second);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003288 }
3289 }
3290
3291 engine.Terminate();
3292}
3293
3294// Tests that VoE supports at least 32 channels
3295TEST(WebRtcVoiceEngineTest, Has32Channels) {
3296 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003297 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003298
3299 cricket::VoiceMediaChannel* channels[32];
3300 int num_channels = 0;
3301
3302 while (num_channels < ARRAY_SIZE(channels)) {
Jelena Marusicc28a8962015-05-29 15:05:44 +02003303 cricket::VoiceMediaChannel* channel =
3304 engine.CreateChannel(cricket::AudioOptions());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003305 if (!channel)
3306 break;
3307
3308 channels[num_channels++] = channel;
3309 }
3310
3311 int expected = ARRAY_SIZE(channels);
3312 EXPECT_EQ(expected, num_channels);
3313
3314 while (num_channels > 0) {
3315 delete channels[--num_channels];
3316 }
3317
3318 engine.Terminate();
3319}
3320
3321// Test that we set our preferred codecs properly.
3322TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3323 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003324 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003325 cricket::WebRtcVoiceMediaChannel channel(&engine);
3326 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3327}
3328
3329#ifdef WIN32
3330// Test our workarounds to WebRtc VoE' munging of the coinit count
3331TEST(WebRtcVoiceEngineTest, CoInitialize) {
3332 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3333
3334 // Initial refcount should be 0.
3335 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3336
3337 // Engine should start even with COM already inited.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003338 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003339 engine->Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003340 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003341 engine->Terminate();
3342
3343 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3344 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3345 // Decrement refcount to (hopefully) 0.
3346 CoUninitialize();
3347 CoUninitialize();
3348 delete engine;
3349
3350 // Ensure refcount is 0.
3351 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3352 CoUninitialize();
3353}
3354#endif
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003355
pbos8fc7fa72015-07-15 08:02:58 -07003356TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
3357 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3358 const uint32 kAudioSsrc = 123;
3359 const std::string kSyncLabel = "AvSyncLabel";
3360
3361 EXPECT_TRUE(SetupEngine());
3362 cricket::WebRtcVoiceMediaChannel* media_channel =
3363 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3364 media_channel->SetCall(&call);
3365 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
3366 sp.sync_label = kSyncLabel;
3367 // Creating two channels to make sure that sync label is set properly for both
3368 // the default voice channel and following ones.
3369 EXPECT_TRUE(channel_->AddRecvStream(sp));
3370 sp.ssrcs[0] += 1;
3371 EXPECT_TRUE(channel_->AddRecvStream(sp));
3372
3373 ASSERT_EQ(2, call.GetAudioReceiveStreams().size());
3374 EXPECT_EQ(kSyncLabel,
3375 call.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
3376 << "SyncGroup should be set based on sync_label";
3377 EXPECT_EQ(kSyncLabel,
3378 call.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
3379 << "SyncGroup should be set based on sync_label";
3380
3381 media_channel->SetCall(nullptr);
3382}
3383
pbos6bb1b6e2015-07-24 07:10:18 -07003384TEST_F(WebRtcVoiceEngineTestFake, CanChangeCombinedBweOption) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003385 // Test that changing the combined_audio_video_bwe option results in the
3386 // expected state changes on an associated Call.
3387 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3388 const uint32 kAudioSsrc1 = 223;
3389 const uint32 kAudioSsrc2 = 224;
3390
3391 EXPECT_TRUE(SetupEngine());
3392 cricket::WebRtcVoiceMediaChannel* media_channel =
3393 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
pbos8fc7fa72015-07-15 08:02:58 -07003394 const auto& rtp_extensions = engine_.rtp_header_extensions();
3395 media_channel->SetRecvRtpHeaderExtensions(rtp_extensions);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003396 media_channel->SetCall(&call);
3397 EXPECT_TRUE(media_channel->AddRecvStream(
3398 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3399 EXPECT_TRUE(media_channel->AddRecvStream(
3400 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3401
pbos6bb1b6e2015-07-24 07:10:18 -07003402 // Combined BWE should not be set up yet.
pbos8fc7fa72015-07-15 08:02:58 -07003403 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
pbos6bb1b6e2015-07-24 07:10:18 -07003404 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc1)
3405 ->GetConfig()
3406 .combined_audio_video_bwe);
3407 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc2)
3408 ->GetConfig()
3409 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003410
3411 // Enable combined BWE option - now it should be set up.
3412 cricket::AudioOptions options;
3413 options.combined_audio_video_bwe.Set(true);
3414 EXPECT_TRUE(media_channel->SetOptions(options));
3415 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
pbos6bb1b6e2015-07-24 07:10:18 -07003416 EXPECT_TRUE(call.GetAudioReceiveStream(kAudioSsrc1)
3417 ->GetConfig()
3418 .combined_audio_video_bwe);
3419 EXPECT_TRUE(call.GetAudioReceiveStream(kAudioSsrc2)
3420 ->GetConfig()
3421 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003422
3423 // Disable combined BWE option - should be disabled again.
3424 options.combined_audio_video_bwe.Set(false);
3425 EXPECT_TRUE(media_channel->SetOptions(options));
pbos8fc7fa72015-07-15 08:02:58 -07003426 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
pbos6bb1b6e2015-07-24 07:10:18 -07003427 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc1)
3428 ->GetConfig()
3429 .combined_audio_video_bwe);
3430 EXPECT_FALSE(call.GetAudioReceiveStream(kAudioSsrc2)
3431 ->GetConfig()
3432 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003433
3434 media_channel->SetCall(nullptr);
3435}
3436
pbos6bb1b6e2015-07-24 07:10:18 -07003437TEST_F(WebRtcVoiceEngineTestFake, SetCallConfiguresAudioReceiveChannels) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003438 // Test that calling SetCall() on the voice media channel results in the
3439 // expected state changes in Call.
3440 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3441 cricket::FakeCall call2(webrtc::Call::Config(nullptr));
3442 const uint32 kAudioSsrc1 = 223;
3443 const uint32 kAudioSsrc2 = 224;
3444
3445 EXPECT_TRUE(SetupEngine());
3446 cricket::WebRtcVoiceMediaChannel* media_channel =
3447 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003448 EXPECT_TRUE(media_channel->AddRecvStream(
3449 cricket::StreamParams::CreateLegacy(kAudioSsrc1)));
3450 EXPECT_TRUE(media_channel->AddRecvStream(
3451 cricket::StreamParams::CreateLegacy(kAudioSsrc2)));
3452
3453 // Combined BWE should not be set up yet.
3454 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3455
3456 // Register - should be enabled.
3457 media_channel->SetCall(&call);
3458 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3459 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc1));
3460 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kAudioSsrc2));
3461
3462 // Re-register - should now be enabled on new call.
3463 media_channel->SetCall(&call2);
3464 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3465 EXPECT_EQ(2, call2.GetAudioReceiveStreams().size());
3466 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc1));
3467 EXPECT_NE(nullptr, call2.GetAudioReceiveStream(kAudioSsrc2));
3468
3469 // Unregister - should be disabled again.
3470 media_channel->SetCall(nullptr);
3471 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3472}
3473
pbos6bb1b6e2015-07-24 07:10:18 -07003474TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003475 // Test that adding receive streams after enabling combined bandwidth
3476 // estimation will correctly configure each channel.
3477 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3478
3479 EXPECT_TRUE(SetupEngine());
3480 cricket::WebRtcVoiceMediaChannel* media_channel =
3481 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3482 media_channel->SetCall(&call);
3483 cricket::AudioOptions options;
3484 options.combined_audio_video_bwe.Set(true);
3485 EXPECT_TRUE(media_channel->SetOptions(options));
3486
3487 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3488 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3489 EXPECT_TRUE(media_channel->AddRecvStream(
3490 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3491 EXPECT_NE(nullptr, call.GetAudioReceiveStream(kSsrcs[i]));
pbos6bb1b6e2015-07-24 07:10:18 -07003492 EXPECT_TRUE(call.GetAudioReceiveStream(kSsrcs[i])
3493 ->GetConfig()
3494 .combined_audio_video_bwe);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003495 }
3496 EXPECT_EQ(ARRAY_SIZE(kSsrcs), call.GetAudioReceiveStreams().size());
3497
3498 media_channel->SetCall(nullptr);
3499 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3500}
3501
pbos6bb1b6e2015-07-24 07:10:18 -07003502TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003503 // Test that setting the header extensions results in the expected state
3504 // changes on an associated Call.
3505 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3506 std::vector<uint32> ssrcs;
3507 ssrcs.push_back(223);
3508 ssrcs.push_back(224);
3509
3510 EXPECT_TRUE(SetupEngine());
3511 cricket::WebRtcVoiceMediaChannel* media_channel =
3512 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3513 media_channel->SetCall(&call);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +02003514 for (uint32 ssrc : ssrcs) {
3515 EXPECT_TRUE(media_channel->AddRecvStream(
3516 cricket::StreamParams::CreateLegacy(ssrc)));
3517 }
3518
3519 // Combined BWE should be set up, but with no configured extensions.
3520 EXPECT_EQ(2, call.GetAudioReceiveStreams().size());
3521 for (uint32 ssrc : ssrcs) {
3522 const auto* s = call.GetAudioReceiveStream(ssrc);
3523 EXPECT_NE(nullptr, s);
3524 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3525 }
3526
3527 // Set up receive extensions.
3528 const auto& e_exts = engine_.rtp_header_extensions();
3529 channel_->SetRecvRtpHeaderExtensions(e_exts);
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 const auto& s_exts = s->GetConfig().rtp.extensions;
3535 EXPECT_EQ(e_exts.size(), s_exts.size());
3536 for (const auto& e_ext : e_exts) {
3537 for (const auto& s_ext : s_exts) {
3538 if (e_ext.id == s_ext.id) {
3539 EXPECT_EQ(e_ext.uri, s_ext.name);
3540 }
3541 }
3542 }
3543 }
3544
3545 // Disable receive extensions.
3546 std::vector<cricket::RtpHeaderExtension> extensions;
3547 channel_->SetRecvRtpHeaderExtensions(extensions);
3548 for (uint32 ssrc : ssrcs) {
3549 const auto* s = call.GetAudioReceiveStream(ssrc);
3550 EXPECT_NE(nullptr, s);
3551 EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3552 }
3553
3554 media_channel->SetCall(nullptr);
3555}
3556
3557TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3558 // Test that packets are forwarded to the Call when configured accordingly.
3559 cricket::FakeCall call(webrtc::Call::Config(nullptr));
3560 const uint32 kAudioSsrc = 1;
3561 rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3562 static const unsigned char kRtcp[] = {
3563 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3564 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3567 };
3568 rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3569
3570 EXPECT_TRUE(SetupEngine());
3571 cricket::WebRtcVoiceMediaChannel* media_channel =
3572 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3573 cricket::AudioOptions options;
3574 options.combined_audio_video_bwe.Set(true);
3575 EXPECT_TRUE(media_channel->SetOptions(options));
3576 EXPECT_TRUE(media_channel->AddRecvStream(
3577 cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3578
3579 // Call not set on media channel, so no packets can be forwarded.
3580 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3581 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3582 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3583 EXPECT_EQ(0, call.GetAudioReceiveStreams().size());
3584
3585 // Set Call, now there should be a receive stream which is forwarded packets.
3586 media_channel->SetCall(&call);
3587 EXPECT_EQ(1, call.GetAudioReceiveStreams().size());
3588 const cricket::FakeAudioReceiveStream* s =
3589 call.GetAudioReceiveStream(kAudioSsrc);
3590 EXPECT_EQ(0, s->received_packets());
3591 channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3592 EXPECT_EQ(1, s->received_packets());
3593 channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3594 EXPECT_EQ(2, s->received_packets());
3595
3596 media_channel->SetCall(nullptr);
3597}
Minyue2013aec2015-05-13 14:14:42 +02003598
3599// Associate channel should not set on 1:1 call, since the receive channel also
3600// sends RTCP SR.
3601TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelUnset1On1) {
3602 EXPECT_TRUE(SetupEngine());
3603 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3604 int recv_ch = voe_.GetLastChannel();
3605 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3606}
3607
3608// This test is an extension of AssociateChannelUnset1On1. We create two receive
3609// channels. The second should be associated with the default channel, since it
3610// does not send RTCP SR.
3611TEST_F(WebRtcVoiceEngineTestFake, AssociateDefaultChannelOnSecondRecvChannel) {
3612 EXPECT_TRUE(SetupEngine());
3613 cricket::WebRtcVoiceMediaChannel* media_channel =
3614 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3615 int default_channel = media_channel->voe_channel();
3616 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3617 int recv_ch_1 = voe_.GetLastChannel();
3618 EXPECT_EQ(recv_ch_1, default_channel);
3619 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
3620 int recv_ch_2 = voe_.GetLastChannel();
3621 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_1), -1);
3622 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_2), default_channel);
3623 // Add send stream, the association remains.
3624 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
3625 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_1), -1);
3626 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch_2), default_channel);
3627}
3628
3629// In conference mode, all receive channels should be associated with the
3630// default channel, since they do not send RTCP SR.
3631TEST_F(WebRtcVoiceEngineTestFake, AssociateDefaultChannelOnConference) {
3632 EXPECT_TRUE(SetupEngine());
3633 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3634 cricket::WebRtcVoiceMediaChannel* media_channel =
3635 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3636 int default_channel = media_channel->voe_channel();
3637 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3638 int recv_ch = voe_.GetLastChannel();
3639 EXPECT_NE(recv_ch, default_channel);
3640 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3641 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3642 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3643}
3644
3645TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
3646 EXPECT_TRUE(SetupEngine());
3647 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3648
3649 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3650 int recv_ch = voe_.GetLastChannel();
3651
3652 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3653 int send_ch = voe_.GetLastChannel();
3654
3655 // Manually associate |recv_ch| to |send_ch|. This test is to verify a
3656 // deleting logic, i.e., deleting |send_ch| will reset the associate send
3657 // channel of |recv_ch|.This is not a common case, since, normally, only the
3658 // default channel can be associated. However, the default is not deletable.
3659 // So we force the |recv_ch| to associate with a non-default channel.
3660 EXPECT_EQ(0, voe_.AssociateSendChannel(recv_ch, send_ch));
3661 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), send_ch);
3662
3663 EXPECT_TRUE(channel_->RemoveSendStream(2));
3664 EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3665}