blob: 5deabd290561d626593895677057e3f18d7a69c0 [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"
40#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +000041#include "talk/media/webrtc/webrtcvie.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042#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);
53static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
54static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
55static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
56static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
57static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
58static const cricket::AudioCodec
59 kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
60static const cricket::AudioCodec* const kAudioCodecs[] = {
henrik.lundin@webrtc.orgdced5d72014-11-06 15:27:43 +000061 &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
62 &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063};
64const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
65static uint32 kSsrc1 = 0x99;
66static uint32 kSsrc2 = 0x98;
67
68class FakeVoEWrapper : public cricket::VoEWrapper {
69 public:
70 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
71 : cricket::VoEWrapper(engine, // processing
72 engine, // base
73 engine, // codec
74 engine, // dtmf
75 engine, // file
76 engine, // hw
77 engine, // media
78 engine, // neteq
79 engine, // network
80 engine, // rtp
81 engine, // sync
82 engine) { // volume
83 }
84};
85
wu@webrtc.org97077a32013-10-25 21:18:33 +000086class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 public:
88 virtual int SetTraceFilter(const unsigned int filter) {
wu@webrtc.org97077a32013-10-25 21:18:33 +000089 filter_ = filter;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090 return 0;
91 }
92 virtual int SetTraceFile(const char* fileNameUTF8) {
93 return 0;
94 }
95 virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
96 return 0;
97 }
wu@webrtc.org97077a32013-10-25 21:18:33 +000098 unsigned int filter_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099};
100
101class WebRtcVoiceEngineTestFake : public testing::Test {
102 public:
103 class ChannelErrorListener : public sigslot::has_slots<> {
104 public:
105 explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
106 : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
107 ASSERT(channel != NULL);
108 channel->SignalMediaError.connect(
109 this, &ChannelErrorListener::OnVoiceChannelError);
110 }
111 void OnVoiceChannelError(uint32 ssrc,
112 cricket::VoiceMediaChannel::Error error) {
113 ssrc_ = ssrc;
114 error_ = error;
115 }
116 void Reset() {
117 ssrc_ = 0;
118 error_ = cricket::VoiceMediaChannel::ERROR_NONE;
119 }
120 uint32 ssrc() const {
121 return ssrc_;
122 }
123 cricket::VoiceMediaChannel::Error error() const {
124 return error_;
125 }
126
127 private:
128 uint32 ssrc_;
129 cricket::VoiceMediaChannel::Error error_;
130 };
131
132 WebRtcVoiceEngineTestFake()
133 : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
134 voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000135 trace_wrapper_(new FakeVoETraceWrapper()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136 engine_(new FakeVoEWrapper(&voe_),
137 new FakeVoEWrapper(&voe_sc_),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000138 trace_wrapper_),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139 channel_(NULL), soundclip_(NULL) {
140 options_conference_.conference_mode.Set(true);
141 options_adjust_agc_.adjust_agc_delta.Set(-10);
142 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000143 bool SetupEngineWithoutStream() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000144 if (!engine_.Init(rtc::Thread::Current())) {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000145 return false;
146 }
147 channel_ = engine_.CreateChannel();
148 return (channel_ != NULL);
149 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150 bool SetupEngine() {
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000151 if (!SetupEngineWithoutStream()) {
152 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000154 return channel_->AddSendStream(
155 cricket::StreamParams::CreateLegacy(kSsrc1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000156 }
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000157 void SetupForMultiSendStream() {
158 EXPECT_TRUE(SetupEngine());
159 // Remove stream added in Setup, which is corresponding to default channel.
160 int default_channel_num = voe_.GetLastChannel();
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000161 uint32 default_send_ssrc = 0u;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000162 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
163 EXPECT_EQ(kSsrc1, default_send_ssrc);
164 EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
165
166 // Verify the default channel still exists.
167 EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
168 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169 void DeliverPacket(const void* data, int len) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000170 rtc::Buffer packet(data, len);
171 channel_->OnPacketReceived(&packet, rtc::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 }
173 virtual void TearDown() {
174 delete soundclip_;
175 delete channel_;
176 engine_.Terminate();
177 }
178
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000179 void TestInsertDtmf(uint32 ssrc, bool caller) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000180 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000181 channel_ = engine_.CreateChannel();
182 EXPECT_TRUE(channel_ != NULL);
183 if (caller) {
184 // if this is a caller, local description will be applied and add the
185 // send stream.
186 EXPECT_TRUE(channel_->AddSendStream(
187 cricket::StreamParams::CreateLegacy(kSsrc1)));
188 }
189 int channel_id = voe_.GetLastChannel();
190
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000191 // Test we can only InsertDtmf when the other side supports telephone-event.
192 std::vector<cricket::AudioCodec> codecs;
193 codecs.push_back(kPcmuCodec);
194 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
195 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
196 EXPECT_FALSE(channel_->CanInsertDtmf());
197 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
198 codecs.push_back(kTelephoneEventCodec);
199 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
200 EXPECT_TRUE(channel_->CanInsertDtmf());
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000201
202 if (!caller) {
203 // There's no active send channel yet.
204 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
205 EXPECT_TRUE(channel_->AddSendStream(
206 cricket::StreamParams::CreateLegacy(kSsrc1)));
207 }
208
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 // Check we fail if the ssrc is invalid.
210 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
211
212 // Test send
213 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
214 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
215 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
216
217 // Test play
218 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
219 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
220 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
221
222 // Test send and play
223 EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
224 EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
225 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
226 cricket::DF_PLAY | cricket::DF_SEND));
227 EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
228 EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
229 }
230
231 // Test that send bandwidth is set correctly.
232 // |codec| is the codec under test.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000233 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
234 // |expected_result| is the expected result from SetMaxSendBandwidth().
235 // |expected_bitrate| is the expected audio bitrate afterward.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 void TestSendBandwidth(const cricket::AudioCodec& codec,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000237 int max_bitrate,
238 bool expected_result,
239 int expected_bitrate) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 int channel_num = voe_.GetLastChannel();
241 std::vector<cricket::AudioCodec> codecs;
242
243 codecs.push_back(codec);
244 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
245
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000246 bool result = channel_->SetMaxSendBandwidth(max_bitrate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 EXPECT_EQ(expected_result, result);
248
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000249 webrtc::CodecInst temp_codec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
251
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000252 EXPECT_EQ(expected_bitrate, temp_codec.rate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 }
254
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000255 void TestSetSendRtpHeaderExtensions(const std::string& ext) {
256 EXPECT_TRUE(SetupEngineWithoutStream());
257 int channel_num = voe_.GetLastChannel();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000258
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000259 // Ensure extensions are off by default.
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000260 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000261
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000262 std::vector<cricket::RtpHeaderExtension> extensions;
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000263 // Ensure unknown extensions won't cause an error.
264 extensions.push_back(cricket::RtpHeaderExtension(
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000265 "urn:ietf:params:unknownextention", 1));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000266 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000267 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000268
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000269 // Ensure extensions stay off with an empty list of headers.
270 extensions.clear();
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000271 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000272 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000273
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000274 // Ensure extension is set properly.
275 const int id = 1;
276 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000277 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000278 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000279
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000280 // Ensure extension is set properly on new channel.
281 // The first stream to occupy the default channel.
282 EXPECT_TRUE(channel_->AddSendStream(
283 cricket::StreamParams::CreateLegacy(123)));
284 EXPECT_TRUE(channel_->AddSendStream(
285 cricket::StreamParams::CreateLegacy(234)));
286 int new_channel_num = voe_.GetLastChannel();
287 EXPECT_NE(channel_num, new_channel_num);
288 EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000289
290 // Ensure all extensions go back off with an empty list.
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000291 extensions.clear();
292 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000293 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
294 EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000295 }
296
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000297 void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
298 EXPECT_TRUE(SetupEngineWithoutStream());
299 int channel_num = voe_.GetLastChannel();
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000300
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000301 // Ensure extensions are off by default.
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 std::vector<cricket::RtpHeaderExtension> extensions;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000305 // Ensure unknown extensions won't cause an error.
306 extensions.push_back(cricket::RtpHeaderExtension(
307 "urn:ietf:params:unknownextention", 1));
308 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000309 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000310
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000311 // Ensure extensions stay off with an empty list of headers.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000312 extensions.clear();
313 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000314 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000315
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000316 // Ensure extension is set properly.
317 const int id = 2;
318 extensions.push_back(cricket::RtpHeaderExtension(ext, id));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000319 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000320 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000321
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000322 // Ensure extension is set properly on new channel.
323 // The first stream to occupy the default channel.
324 EXPECT_TRUE(channel_->AddRecvStream(
325 cricket::StreamParams::CreateLegacy(345)));
326 EXPECT_TRUE(channel_->AddRecvStream(
327 cricket::StreamParams::CreateLegacy(456)));
328 int new_channel_num = voe_.GetLastChannel();
329 EXPECT_NE(channel_num, new_channel_num);
330 EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
331
332 // Ensure all extensions go back off with an empty list.
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000333 extensions.clear();
334 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000335 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
336 EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000337 }
338
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 protected:
340 cricket::FakeWebRtcVoiceEngine voe_;
341 cricket::FakeWebRtcVoiceEngine voe_sc_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000342 FakeVoETraceWrapper* trace_wrapper_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 cricket::WebRtcVoiceEngine engine_;
344 cricket::VoiceMediaChannel* channel_;
345 cricket::SoundclipMedia* soundclip_;
346
347 cricket::AudioOptions options_conference_;
348 cricket::AudioOptions options_adjust_agc_;
349};
350
351// Tests that our stub library "works".
352TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
353 EXPECT_FALSE(voe_.IsInited());
354 EXPECT_FALSE(voe_sc_.IsInited());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000355 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 EXPECT_TRUE(voe_.IsInited());
wu@webrtc.org4551b792013-10-09 15:37:36 +0000357 // The soundclip engine is lazily initialized.
358 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 engine_.Terminate();
360 EXPECT_FALSE(voe_.IsInited());
361 EXPECT_FALSE(voe_sc_.IsInited());
362}
363
364// Tests that we can create and destroy a channel.
365TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000366 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367 channel_ = engine_.CreateChannel();
368 EXPECT_TRUE(channel_ != NULL);
369}
370
371// Tests that we properly handle failures in CreateChannel.
372TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
373 voe_.set_fail_create_channel(true);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000374 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000375 channel_ = engine_.CreateChannel();
376 EXPECT_TRUE(channel_ == NULL);
377}
378
379// Tests that the list of supported codecs is created properly and ordered
380// correctly
381TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
382 const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
383 ASSERT_FALSE(codecs.empty());
384 EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
385 EXPECT_EQ(48000, codecs[0].clockrate);
386 EXPECT_EQ(2, codecs[0].channels);
387 EXPECT_EQ(64000, codecs[0].bitrate);
388 int pref = codecs[0].preference;
389 for (size_t i = 1; i < codecs.size(); ++i) {
390 EXPECT_GT(pref, codecs[i].preference);
391 pref = codecs[i].preference;
392 }
393}
394
395// Tests that we can find codecs by name or id, and that we interpret the
396// clockrate and bitrate fields properly.
397TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
398 cricket::AudioCodec codec;
399 webrtc::CodecInst codec_inst;
400 // Find PCMU with explicit clockrate and bitrate.
401 EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
402 // Find ISAC with explicit clockrate and 0 bitrate.
403 EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
404 // Find telephone-event with explicit clockrate and 0 bitrate.
405 EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
406 // Find ISAC with a different payload id.
407 codec = kIsacCodec;
408 codec.id = 127;
409 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
410 EXPECT_EQ(codec.id, codec_inst.pltype);
411 // Find PCMU with a 0 clockrate.
412 codec = kPcmuCodec;
413 codec.clockrate = 0;
414 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
415 EXPECT_EQ(codec.id, codec_inst.pltype);
416 EXPECT_EQ(8000, codec_inst.plfreq);
417 // Find PCMU with a 0 bitrate.
418 codec = kPcmuCodec;
419 codec.bitrate = 0;
420 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
421 EXPECT_EQ(codec.id, codec_inst.pltype);
422 EXPECT_EQ(64000, codec_inst.rate);
423 // Find ISAC with an explicit bitrate.
424 codec = kIsacCodec;
425 codec.bitrate = 32000;
426 EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
427 EXPECT_EQ(codec.id, codec_inst.pltype);
428 EXPECT_EQ(32000, codec_inst.rate);
429}
430
431// Test that we set our inbound codecs properly, including changing PT.
432TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
433 EXPECT_TRUE(SetupEngine());
434 int channel_num = voe_.GetLastChannel();
435 std::vector<cricket::AudioCodec> codecs;
436 codecs.push_back(kIsacCodec);
437 codecs.push_back(kPcmuCodec);
438 codecs.push_back(kTelephoneEventCodec);
439 codecs[0].id = 106; // collide with existing telephone-event
440 codecs[2].id = 126;
441 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
442 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000443 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 gcodec.plfreq = 16000;
445 gcodec.channels = 1;
446 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
447 EXPECT_EQ(106, gcodec.pltype);
448 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000449 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 "telephone-event");
451 gcodec.plfreq = 8000;
452 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
453 EXPECT_EQ(126, gcodec.pltype);
454 EXPECT_STREQ("telephone-event", gcodec.plname);
455}
456
457// Test that we fail to set an unknown inbound codec.
458TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
459 EXPECT_TRUE(SetupEngine());
460 std::vector<cricket::AudioCodec> codecs;
461 codecs.push_back(kIsacCodec);
462 codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
463 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
464}
465
466// Test that we fail if we have duplicate types in the inbound list.
467TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
468 EXPECT_TRUE(SetupEngine());
469 std::vector<cricket::AudioCodec> codecs;
470 codecs.push_back(kIsacCodec);
471 codecs.push_back(kCn16000Codec);
472 codecs[1].id = kIsacCodec.id;
473 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
474}
475
476// Test that we can decode OPUS without stereo parameters.
477TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
478 EXPECT_TRUE(SetupEngine());
479 EXPECT_TRUE(channel_->SetOptions(options_conference_));
480 std::vector<cricket::AudioCodec> codecs;
481 codecs.push_back(kIsacCodec);
482 codecs.push_back(kPcmuCodec);
483 codecs.push_back(kOpusCodec);
484 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
485 EXPECT_TRUE(channel_->AddRecvStream(
486 cricket::StreamParams::CreateLegacy(kSsrc1)));
487 int channel_num2 = voe_.GetLastChannel();
488 webrtc::CodecInst opus;
489 engine_.FindWebRtcCodec(kOpusCodec, &opus);
490 // Even without stereo parameters, recv codecs still specify channels = 2.
491 EXPECT_EQ(2, opus.channels);
492 EXPECT_EQ(111, opus.pltype);
493 EXPECT_STREQ("opus", opus.plname);
494 opus.pltype = 0;
495 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
496 EXPECT_EQ(111, opus.pltype);
497}
498
499// Test that we can decode OPUS with stereo = 0.
500TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
501 EXPECT_TRUE(SetupEngine());
502 EXPECT_TRUE(channel_->SetOptions(options_conference_));
503 std::vector<cricket::AudioCodec> codecs;
504 codecs.push_back(kIsacCodec);
505 codecs.push_back(kPcmuCodec);
506 codecs.push_back(kOpusCodec);
507 codecs[2].params["stereo"] = "0";
508 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
509 EXPECT_TRUE(channel_->AddRecvStream(
510 cricket::StreamParams::CreateLegacy(kSsrc1)));
511 int channel_num2 = voe_.GetLastChannel();
512 webrtc::CodecInst opus;
513 engine_.FindWebRtcCodec(kOpusCodec, &opus);
514 // Even when stereo is off, recv codecs still specify channels = 2.
515 EXPECT_EQ(2, opus.channels);
516 EXPECT_EQ(111, opus.pltype);
517 EXPECT_STREQ("opus", opus.plname);
518 opus.pltype = 0;
519 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
520 EXPECT_EQ(111, opus.pltype);
521}
522
523// Test that we can decode OPUS with stereo = 1.
524TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
525 EXPECT_TRUE(SetupEngine());
526 EXPECT_TRUE(channel_->SetOptions(options_conference_));
527 std::vector<cricket::AudioCodec> codecs;
528 codecs.push_back(kIsacCodec);
529 codecs.push_back(kPcmuCodec);
530 codecs.push_back(kOpusCodec);
531 codecs[2].params["stereo"] = "1";
532 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
533 EXPECT_TRUE(channel_->AddRecvStream(
534 cricket::StreamParams::CreateLegacy(kSsrc1)));
535 int channel_num2 = voe_.GetLastChannel();
536 webrtc::CodecInst opus;
537 engine_.FindWebRtcCodec(kOpusCodec, &opus);
538 EXPECT_EQ(2, opus.channels);
539 EXPECT_EQ(111, opus.pltype);
540 EXPECT_STREQ("opus", opus.plname);
541 opus.pltype = 0;
542 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
543 EXPECT_EQ(111, opus.pltype);
544}
545
546// Test that changes to recv codecs are applied to all streams.
547TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
548 EXPECT_TRUE(SetupEngine());
549 EXPECT_TRUE(channel_->SetOptions(options_conference_));
550 std::vector<cricket::AudioCodec> codecs;
551 codecs.push_back(kIsacCodec);
552 codecs.push_back(kPcmuCodec);
553 codecs.push_back(kTelephoneEventCodec);
554 codecs[0].id = 106; // collide with existing telephone-event
555 codecs[2].id = 126;
556 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
557 EXPECT_TRUE(channel_->AddRecvStream(
558 cricket::StreamParams::CreateLegacy(kSsrc1)));
559 int channel_num2 = voe_.GetLastChannel();
560 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000561 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562 gcodec.plfreq = 16000;
563 gcodec.channels = 1;
564 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
565 EXPECT_EQ(106, gcodec.pltype);
566 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000567 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568 "telephone-event");
569 gcodec.plfreq = 8000;
570 gcodec.channels = 1;
571 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
572 EXPECT_EQ(126, gcodec.pltype);
573 EXPECT_STREQ("telephone-event", gcodec.plname);
574}
575
576TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
577 EXPECT_TRUE(SetupEngine());
578 EXPECT_TRUE(channel_->SetOptions(options_conference_));
579 std::vector<cricket::AudioCodec> codecs;
580 codecs.push_back(kIsacCodec);
581 codecs[0].id = 106; // collide with existing telephone-event
582
583 EXPECT_TRUE(channel_->AddRecvStream(
584 cricket::StreamParams::CreateLegacy(kSsrc1)));
585 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
586
587 int channel_num2 = voe_.GetLastChannel();
588 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000589 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590 gcodec.plfreq = 16000;
591 gcodec.channels = 1;
592 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
593 EXPECT_EQ(106, gcodec.pltype);
594 EXPECT_STREQ("ISAC", gcodec.plname);
595}
596
597// Test that we can apply the same set of codecs again while playing.
598TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
599 EXPECT_TRUE(SetupEngine());
600 int channel_num = voe_.GetLastChannel();
601 std::vector<cricket::AudioCodec> codecs;
602 codecs.push_back(kIsacCodec);
603 codecs.push_back(kCn16000Codec);
604 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
605 EXPECT_TRUE(channel_->SetPlayout(true));
606 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
607
608 // Changing the payload type of a codec should fail.
609 codecs[0].id = 127;
610 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
611 EXPECT_TRUE(voe_.GetPlayout(channel_num));
612}
613
614// Test that we can add a codec while playing.
615TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
616 EXPECT_TRUE(SetupEngine());
617 int channel_num = voe_.GetLastChannel();
618 std::vector<cricket::AudioCodec> codecs;
619 codecs.push_back(kIsacCodec);
620 codecs.push_back(kCn16000Codec);
621 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
622 EXPECT_TRUE(channel_->SetPlayout(true));
623
624 codecs.push_back(kOpusCodec);
625 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
626 EXPECT_TRUE(voe_.GetPlayout(channel_num));
627 webrtc::CodecInst gcodec;
628 EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
629 EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
630}
631
632TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
633 EXPECT_TRUE(SetupEngine());
634 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
635
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000636 // Test that when autobw is enabled, bitrate is kept as the default
637 // value. autobw is enabled for the following tests because the target
638 // bitrate is <= 0.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639
640 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000641 TestSendBandwidth(kIsacCodec, 0, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000642
643 // PCMU, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000644 TestSendBandwidth(kPcmuCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645
646 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000647 TestSendBandwidth(kCeltCodec, 0, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000648
649 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000650 TestSendBandwidth(kOpusCodec, -1, true, 64000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651}
652
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000653TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000654 EXPECT_TRUE(SetupEngine());
655 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
656
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000657 // Test that the bitrate of a multi-rate codec is always the maximum.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000658
659 // ISAC, default bitrate == 32000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000660 TestSendBandwidth(kIsacCodec, 128000, true, 128000);
661 TestSendBandwidth(kIsacCodec, 16000, true, 16000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662
663 // CELT, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000664 TestSendBandwidth(kCeltCodec, 96000, true, 96000);
665 TestSendBandwidth(kCeltCodec, 32000, true, 32000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000666
667 // opus, default bitrate == 64000.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000668 TestSendBandwidth(kOpusCodec, 96000, true, 96000);
669 TestSendBandwidth(kOpusCodec, 48000, true, 48000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670}
671
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000672TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
673 EXPECT_TRUE(SetupEngine());
674 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
675
676 // Test that we can only set a maximum bitrate for a fixed-rate codec
677 // if it's bigger than the fixed rate.
678
679 // PCMU, fixed bitrate == 64000.
680 TestSendBandwidth(kPcmuCodec, 0, true, 64000);
681 TestSendBandwidth(kPcmuCodec, 1, false, 64000);
682 TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
683 TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
684 TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
685 TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
686 TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
687}
688
689TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000690 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000691 channel_ = engine_.CreateChannel();
692 EXPECT_TRUE(channel_ != NULL);
693 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
694
695 int desired_bitrate = 128000;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000696 EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +0000697
698 EXPECT_TRUE(channel_->AddSendStream(
699 cricket::StreamParams::CreateLegacy(kSsrc1)));
700
701 int channel_num = voe_.GetLastChannel();
702 webrtc::CodecInst codec;
703 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
704 EXPECT_EQ(desired_bitrate, codec.rate);
705}
706
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707// Test that bitrate cannot be set for CBR codecs.
708// Bitrate is ignored if it is higher than the fixed bitrate.
709// Bitrate less then the fixed bitrate is an error.
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000710TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 EXPECT_TRUE(SetupEngine());
712 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
713
714 webrtc::CodecInst codec;
715 int channel_num = voe_.GetLastChannel();
716 std::vector<cricket::AudioCodec> codecs;
717
718 // PCMU, default bitrate == 64000.
719 codecs.push_back(kPcmuCodec);
720 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
721 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
722 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000723 EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
725 EXPECT_EQ(64000, codec.rate);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000726 EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000727 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
728 EXPECT_EQ(64000, codec.rate);
729}
730
731// Test that we apply codecs properly.
732TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
733 EXPECT_TRUE(SetupEngine());
734 int channel_num = voe_.GetLastChannel();
735 std::vector<cricket::AudioCodec> codecs;
736 codecs.push_back(kIsacCodec);
737 codecs.push_back(kPcmuCodec);
738 codecs.push_back(kRedCodec);
739 codecs[0].id = 96;
740 codecs[0].bitrate = 48000;
741 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000742 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743 webrtc::CodecInst gcodec;
744 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
745 EXPECT_EQ(96, gcodec.pltype);
746 EXPECT_EQ(48000, gcodec.rate);
747 EXPECT_STREQ("ISAC", gcodec.plname);
748 EXPECT_FALSE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000749 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
751 EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
752 EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
753}
754
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000755// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
756// to apply.
757TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
758 EXPECT_TRUE(SetupEngine());
759 std::vector<cricket::AudioCodec> codecs;
760 codecs.push_back(kIsacCodec);
761 codecs.push_back(kPcmuCodec);
762 codecs.push_back(kRedCodec);
763 codecs[0].id = 96;
764 codecs[0].bitrate = 48000;
765 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
766 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
767 // Calling SetSendCodec again with same codec which is already set.
768 // In this case media channel shouldn't send codec to VoE.
769 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
770 EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
771}
772
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000773// Test that if clockrate is not 48000 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000774TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
775 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000776 std::vector<cricket::AudioCodec> codecs;
777 codecs.push_back(kOpusCodec);
778 codecs[0].bitrate = 0;
779 codecs[0].clockrate = 50000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000780 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000781}
782
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000783// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
785 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786 std::vector<cricket::AudioCodec> codecs;
787 codecs.push_back(kOpusCodec);
788 codecs[0].bitrate = 0;
789 codecs[0].channels = 0;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000790 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791}
792
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000793// Test that if channels=0 for opus, we fail.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
795 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 std::vector<cricket::AudioCodec> codecs;
797 codecs.push_back(kOpusCodec);
798 codecs[0].bitrate = 0;
799 codecs[0].channels = 0;
800 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000801 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802}
803
804// Test that if channel is 1 for opus and there's no stereo, we fail.
805TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
806 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807 std::vector<cricket::AudioCodec> codecs;
808 codecs.push_back(kOpusCodec);
809 codecs[0].bitrate = 0;
810 codecs[0].channels = 1;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000811 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812}
813
814// Test that if channel is 1 for opus and stereo=0, we fail.
815TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
816 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817 std::vector<cricket::AudioCodec> codecs;
818 codecs.push_back(kOpusCodec);
819 codecs[0].bitrate = 0;
820 codecs[0].channels = 1;
821 codecs[0].params["stereo"] = "0";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000822 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823}
824
825// Test that if channel is 1 for opus and stereo=1, we fail.
826TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
827 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 std::vector<cricket::AudioCodec> codecs;
829 codecs.push_back(kOpusCodec);
830 codecs[0].bitrate = 0;
831 codecs[0].channels = 1;
832 codecs[0].params["stereo"] = "1";
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000833 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000834}
835
836// Test that with bitrate=0 and no stereo,
837// channels and bitrate are 1 and 32000.
838TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
839 EXPECT_TRUE(SetupEngine());
840 int channel_num = voe_.GetLastChannel();
841 std::vector<cricket::AudioCodec> codecs;
842 codecs.push_back(kOpusCodec);
843 codecs[0].bitrate = 0;
844 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
845 webrtc::CodecInst gcodec;
846 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
847 EXPECT_STREQ("opus", gcodec.plname);
848 EXPECT_EQ(1, gcodec.channels);
849 EXPECT_EQ(32000, gcodec.rate);
850}
851
852// Test that with bitrate=0 and stereo=0,
853// channels and bitrate are 1 and 32000.
854TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
855 EXPECT_TRUE(SetupEngine());
856 int channel_num = voe_.GetLastChannel();
857 std::vector<cricket::AudioCodec> codecs;
858 codecs.push_back(kOpusCodec);
859 codecs[0].bitrate = 0;
860 codecs[0].params["stereo"] = "0";
861 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
862 webrtc::CodecInst gcodec;
863 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
864 EXPECT_STREQ("opus", gcodec.plname);
865 EXPECT_EQ(1, gcodec.channels);
866 EXPECT_EQ(32000, gcodec.rate);
867}
868
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000869// Test that with bitrate=invalid and stereo=0,
870// channels and bitrate are 1 and 32000.
871TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
872 EXPECT_TRUE(SetupEngine());
873 int channel_num = voe_.GetLastChannel();
874 std::vector<cricket::AudioCodec> codecs;
875 codecs.push_back(kOpusCodec);
876 codecs[0].params["stereo"] = "0";
877 webrtc::CodecInst gcodec;
878
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000879 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000880 codecs[0].bitrate = 5999;
881 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
882 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
883 EXPECT_STREQ("opus", gcodec.plname);
884 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000885 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000886
887 codecs[0].bitrate = 510001;
888 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
889 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
890 EXPECT_STREQ("opus", gcodec.plname);
891 EXPECT_EQ(1, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000892 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000893}
894
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895// Test that with bitrate=0 and stereo=1,
896// channels and bitrate are 2 and 64000.
897TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
898 EXPECT_TRUE(SetupEngine());
899 int channel_num = voe_.GetLastChannel();
900 std::vector<cricket::AudioCodec> codecs;
901 codecs.push_back(kOpusCodec);
902 codecs[0].bitrate = 0;
903 codecs[0].params["stereo"] = "1";
904 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
905 webrtc::CodecInst gcodec;
906 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
907 EXPECT_STREQ("opus", gcodec.plname);
908 EXPECT_EQ(2, gcodec.channels);
909 EXPECT_EQ(64000, gcodec.rate);
910}
911
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000912// Test that with bitrate=invalid and stereo=1,
913// channels and bitrate are 2 and 64000.
914TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
915 EXPECT_TRUE(SetupEngine());
916 int channel_num = voe_.GetLastChannel();
917 std::vector<cricket::AudioCodec> codecs;
918 codecs.push_back(kOpusCodec);
919 codecs[0].params["stereo"] = "1";
920 webrtc::CodecInst gcodec;
921
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000922 // bitrate that's out of the range between 6000 and 510000 will be clamped.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000923 codecs[0].bitrate = 5999;
924 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
925 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
926 EXPECT_STREQ("opus", gcodec.plname);
927 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000928 EXPECT_EQ(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000929
930 codecs[0].bitrate = 510001;
931 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
932 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
933 EXPECT_STREQ("opus", gcodec.plname);
934 EXPECT_EQ(2, gcodec.channels);
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +0000935 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000936}
937
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938// Test that with bitrate=N and stereo unset,
939// channels and bitrate are 1 and N.
940TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
941 EXPECT_TRUE(SetupEngine());
942 int channel_num = voe_.GetLastChannel();
943 std::vector<cricket::AudioCodec> codecs;
944 codecs.push_back(kOpusCodec);
945 codecs[0].bitrate = 96000;
946 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
947 webrtc::CodecInst gcodec;
948 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
949 EXPECT_EQ(111, gcodec.pltype);
950 EXPECT_EQ(96000, gcodec.rate);
951 EXPECT_STREQ("opus", gcodec.plname);
952 EXPECT_EQ(1, gcodec.channels);
953 EXPECT_EQ(48000, gcodec.plfreq);
954}
955
956// Test that with bitrate=N and stereo=0,
957// channels and bitrate are 1 and N.
958TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
959 EXPECT_TRUE(SetupEngine());
960 int channel_num = voe_.GetLastChannel();
961 std::vector<cricket::AudioCodec> codecs;
962 codecs.push_back(kOpusCodec);
963 codecs[0].bitrate = 30000;
964 codecs[0].params["stereo"] = "0";
965 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
966 webrtc::CodecInst gcodec;
967 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
968 EXPECT_EQ(1, gcodec.channels);
969 EXPECT_EQ(30000, gcodec.rate);
970 EXPECT_STREQ("opus", gcodec.plname);
971}
972
973// Test that with bitrate=N and without any parameters,
974// channels and bitrate are 1 and N.
975TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
976 EXPECT_TRUE(SetupEngine());
977 int channel_num = voe_.GetLastChannel();
978 std::vector<cricket::AudioCodec> codecs;
979 codecs.push_back(kOpusCodec);
980 codecs[0].bitrate = 30000;
981 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
982 webrtc::CodecInst gcodec;
983 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
984 EXPECT_EQ(1, gcodec.channels);
985 EXPECT_EQ(30000, gcodec.rate);
986 EXPECT_STREQ("opus", gcodec.plname);
987}
988
989// Test that with bitrate=N and stereo=1,
990// channels and bitrate are 2 and N.
991TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
992 EXPECT_TRUE(SetupEngine());
993 int channel_num = voe_.GetLastChannel();
994 std::vector<cricket::AudioCodec> codecs;
995 codecs.push_back(kOpusCodec);
996 codecs[0].bitrate = 30000;
997 codecs[0].params["stereo"] = "1";
998 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
999 webrtc::CodecInst gcodec;
1000 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1001 EXPECT_EQ(2, gcodec.channels);
1002 EXPECT_EQ(30000, gcodec.rate);
1003 EXPECT_STREQ("opus", gcodec.plname);
1004}
1005
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001006// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1007// Also test that the "maxaveragebitrate" can't be set to values outside the
1008// range of 6000 and 510000
1009TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1010 EXPECT_TRUE(SetupEngine());
1011 int channel_num = voe_.GetLastChannel();
1012 std::vector<cricket::AudioCodec> codecs;
1013 codecs.push_back(kOpusCodec);
1014 codecs[0].bitrate = 30000;
1015 webrtc::CodecInst gcodec;
1016
1017 // Ignore if less than 6000.
1018 codecs[0].params["maxaveragebitrate"] = "5999";
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(6000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001022
1023 // Ignore if larger than 510000.
1024 codecs[0].params["maxaveragebitrate"] = "510001";
1025 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1026 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
buildbot@webrtc.org9d446f22014-10-23 12:22:06 +00001027 EXPECT_EQ(510000, gcodec.rate);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001028
1029 codecs[0].params["maxaveragebitrate"] = "200000";
1030 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1031 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1032 EXPECT_EQ(200000, gcodec.rate);
1033}
1034
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001035// Test that we can enable NACK with opus as caller.
1036TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001037 EXPECT_TRUE(SetupEngine());
1038 int channel_num = voe_.GetLastChannel();
1039 std::vector<cricket::AudioCodec> codecs;
1040 codecs.push_back(kOpusCodec);
1041 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1042 cricket::kParamValueEmpty));
1043 EXPECT_FALSE(voe_.GetNACK(channel_num));
1044 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1045 EXPECT_TRUE(voe_.GetNACK(channel_num));
1046}
1047
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001048// Test that we can enable NACK with opus as callee.
1049TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001050 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001051 channel_ = engine_.CreateChannel();
1052 EXPECT_TRUE(channel_ != NULL);
1053
1054 int channel_num = voe_.GetLastChannel();
1055 std::vector<cricket::AudioCodec> codecs;
1056 codecs.push_back(kOpusCodec);
1057 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1058 cricket::kParamValueEmpty));
1059 EXPECT_FALSE(voe_.GetNACK(channel_num));
1060 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1061 EXPECT_FALSE(voe_.GetNACK(channel_num));
1062
1063 EXPECT_TRUE(channel_->AddSendStream(
1064 cricket::StreamParams::CreateLegacy(kSsrc1)));
1065 EXPECT_TRUE(voe_.GetNACK(channel_num));
1066}
1067
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001068// Test that we can enable NACK on receive streams.
1069TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1070 EXPECT_TRUE(SetupEngine());
1071 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1072 int channel_num1 = voe_.GetLastChannel();
1073 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1074 int channel_num2 = voe_.GetLastChannel();
1075 std::vector<cricket::AudioCodec> codecs;
1076 codecs.push_back(kOpusCodec);
1077 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1078 cricket::kParamValueEmpty));
1079 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1080 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1081 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1082 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1083 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1084}
1085
1086// Test that we can disable NACK.
1087TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1088 EXPECT_TRUE(SetupEngine());
1089 int channel_num = voe_.GetLastChannel();
1090 std::vector<cricket::AudioCodec> codecs;
1091 codecs.push_back(kOpusCodec);
1092 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1093 cricket::kParamValueEmpty));
1094 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1095 EXPECT_TRUE(voe_.GetNACK(channel_num));
1096
1097 codecs.clear();
1098 codecs.push_back(kOpusCodec);
1099 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1100 EXPECT_FALSE(voe_.GetNACK(channel_num));
1101}
1102
1103// Test that we can disable NACK on receive streams.
1104TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1105 EXPECT_TRUE(SetupEngine());
1106 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1107 int channel_num1 = voe_.GetLastChannel();
1108 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1109 int channel_num2 = voe_.GetLastChannel();
1110 std::vector<cricket::AudioCodec> codecs;
1111 codecs.push_back(kOpusCodec);
1112 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1113 cricket::kParamValueEmpty));
1114 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1115 EXPECT_TRUE(voe_.GetNACK(channel_num1));
1116 EXPECT_TRUE(voe_.GetNACK(channel_num2));
1117
1118 codecs.clear();
1119 codecs.push_back(kOpusCodec);
1120 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1121 EXPECT_FALSE(voe_.GetNACK(channel_num1));
1122 EXPECT_FALSE(voe_.GetNACK(channel_num2));
1123}
1124
1125// Test that NACK is enabled on a new receive stream.
1126TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1127 EXPECT_TRUE(SetupEngine());
1128 EXPECT_TRUE(channel_->SetOptions(options_conference_));
1129 int channel_num = voe_.GetLastChannel();
1130 std::vector<cricket::AudioCodec> codecs;
1131 codecs.push_back(kIsacCodec);
1132 codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1133 cricket::kParamValueEmpty));
1134 codecs.push_back(kCn16000Codec);
1135 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1136 EXPECT_TRUE(voe_.GetNACK(channel_num));
1137
1138 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1139 channel_num = voe_.GetLastChannel();
1140 EXPECT_TRUE(voe_.GetNACK(channel_num));
1141 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1142 channel_num = voe_.GetLastChannel();
1143 EXPECT_TRUE(voe_.GetNACK(channel_num));
1144}
1145
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001146#ifdef USE_WEBRTC_DEV_BRANCH
1147// Test that without useinbandfec, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001148TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001149 EXPECT_TRUE(SetupEngine());
1150 int channel_num = voe_.GetLastChannel();
1151 std::vector<cricket::AudioCodec> codecs;
1152 codecs.push_back(kOpusCodec);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001153 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1154 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1155}
1156
1157// Test that with useinbandfec=0, Opus FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001158TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001159 EXPECT_TRUE(SetupEngine());
1160 int channel_num = voe_.GetLastChannel();
1161 std::vector<cricket::AudioCodec> codecs;
1162 codecs.push_back(kOpusCodec);
1163 codecs[0].bitrate = 0;
1164 codecs[0].params["useinbandfec"] = "0";
1165 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1166 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1167 webrtc::CodecInst gcodec;
1168 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1169 EXPECT_STREQ("opus", gcodec.plname);
1170 EXPECT_EQ(1, gcodec.channels);
1171 EXPECT_EQ(32000, gcodec.rate);
1172}
1173
1174// Test that with useinbandfec=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001175TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001176 EXPECT_TRUE(SetupEngine());
1177 int channel_num = voe_.GetLastChannel();
1178 std::vector<cricket::AudioCodec> codecs;
1179 codecs.push_back(kOpusCodec);
1180 codecs[0].bitrate = 0;
1181 codecs[0].params["useinbandfec"] = "1";
1182 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1183 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1184 webrtc::CodecInst gcodec;
1185 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1186 EXPECT_STREQ("opus", gcodec.plname);
1187 EXPECT_EQ(1, gcodec.channels);
1188 EXPECT_EQ(32000, gcodec.rate);
1189}
1190
1191// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001192TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001193 EXPECT_TRUE(SetupEngine());
1194 int channel_num = voe_.GetLastChannel();
1195 std::vector<cricket::AudioCodec> codecs;
1196 codecs.push_back(kOpusCodec);
1197 codecs[0].bitrate = 0;
1198 codecs[0].params["stereo"] = "1";
1199 codecs[0].params["useinbandfec"] = "1";
1200 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1201 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1202 webrtc::CodecInst gcodec;
1203 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1204 EXPECT_STREQ("opus", gcodec.plname);
1205 EXPECT_EQ(2, gcodec.channels);
1206 EXPECT_EQ(64000, gcodec.rate);
1207}
1208
1209// Test that with non-Opus, codec FEC is off.
buildbot@webrtc.orgd27d9ae2014-06-19 01:56:46 +00001210TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001211 EXPECT_TRUE(SetupEngine());
1212 int channel_num = voe_.GetLastChannel();
1213 std::vector<cricket::AudioCodec> codecs;
1214 codecs.push_back(kIsacCodec);
1215 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1216 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1217}
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +00001218
1219// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1220TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1221 EXPECT_TRUE(SetupEngine());
1222 int channel_num = voe_.GetLastChannel();
1223 std::vector<cricket::AudioCodec> codecs;
1224 codecs.push_back(kIsacCodec);
1225 codecs[0].params["useinbandfec"] = "1";
1226 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1227 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1228}
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001229
1230// Test that Opus FEC status can be changed.
1231TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1232 EXPECT_TRUE(SetupEngine());
1233 int channel_num = voe_.GetLastChannel();
1234 std::vector<cricket::AudioCodec> codecs;
1235 codecs.push_back(kOpusCodec);
1236 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1237 EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1238 codecs[0].params["useinbandfec"] = "1";
1239 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1240 EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1241}
1242
1243// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1244TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1245 EXPECT_TRUE(SetupEngine());
1246 int channel_num = voe_.GetLastChannel();
1247 std::vector<cricket::AudioCodec> codecs;
1248 codecs.push_back(kOpusCodec);
1249 codecs[0].bitrate = 0;
1250 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1251 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1252 EXPECT_EQ(cricket::kOpusBandwidthNb,
1253 voe_.GetMaxEncodingBandwidth(channel_num));
1254 webrtc::CodecInst gcodec;
1255 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1256 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001257
1258 EXPECT_EQ(12000, gcodec.rate);
1259 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1260 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1261 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1262 EXPECT_EQ(24000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001263}
1264
1265// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1266TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1267 EXPECT_TRUE(SetupEngine());
1268 int channel_num = voe_.GetLastChannel();
1269 std::vector<cricket::AudioCodec> codecs;
1270 codecs.push_back(kOpusCodec);
1271 codecs[0].bitrate = 0;
1272 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1273 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1274 EXPECT_EQ(cricket::kOpusBandwidthMb,
1275 voe_.GetMaxEncodingBandwidth(channel_num));
1276 webrtc::CodecInst gcodec;
1277 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1278 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001279
1280 EXPECT_EQ(20000, gcodec.rate);
1281 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1282 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1283 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1284 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001285}
1286
1287// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1288TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1289 EXPECT_TRUE(SetupEngine());
1290 int channel_num = voe_.GetLastChannel();
1291 std::vector<cricket::AudioCodec> codecs;
1292 codecs.push_back(kOpusCodec);
1293 codecs[0].bitrate = 0;
1294 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1295 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1296 EXPECT_EQ(cricket::kOpusBandwidthWb,
1297 voe_.GetMaxEncodingBandwidth(channel_num));
1298 webrtc::CodecInst gcodec;
1299 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1300 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001301
1302 EXPECT_EQ(20000, gcodec.rate);
1303 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1304 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1305 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1306 EXPECT_EQ(40000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001307}
1308
1309// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1310TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1311 EXPECT_TRUE(SetupEngine());
1312 int channel_num = voe_.GetLastChannel();
1313 std::vector<cricket::AudioCodec> codecs;
1314 codecs.push_back(kOpusCodec);
1315 codecs[0].bitrate = 0;
1316 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1317 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1318 EXPECT_EQ(cricket::kOpusBandwidthSwb,
1319 voe_.GetMaxEncodingBandwidth(channel_num));
1320 webrtc::CodecInst gcodec;
1321 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1322 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001323
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001324 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001325 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1326 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1327 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1328 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001329}
1330
1331// Test 24000 < maxplaybackrate triggers Opus full band mode.
1332TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1333 EXPECT_TRUE(SetupEngine());
1334 int channel_num = voe_.GetLastChannel();
1335 std::vector<cricket::AudioCodec> codecs;
1336 codecs.push_back(kOpusCodec);
1337 codecs[0].bitrate = 0;
1338 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1339 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1340 EXPECT_EQ(cricket::kOpusBandwidthFb,
1341 voe_.GetMaxEncodingBandwidth(channel_num));
1342 webrtc::CodecInst gcodec;
1343 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1344 EXPECT_STREQ("opus", gcodec.plname);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001345
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001346 EXPECT_EQ(32000, gcodec.rate);
minyue@webrtc.org2dc6f312014-10-31 05:33:10 +00001347 codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1348 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1349 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1350 EXPECT_EQ(64000, gcodec.rate);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +00001351}
1352
1353// Test Opus that without maxplaybackrate, default playback rate is used.
1354TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1355 EXPECT_TRUE(SetupEngine());
1356 int channel_num = voe_.GetLastChannel();
1357 std::vector<cricket::AudioCodec> codecs;
1358 codecs.push_back(kOpusCodec);
1359 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1360 EXPECT_EQ(cricket::kOpusBandwidthFb,
1361 voe_.GetMaxEncodingBandwidth(channel_num));
1362}
1363
1364// Test the with non-Opus, maxplaybackrate has no effect.
1365TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1366 EXPECT_TRUE(SetupEngine());
1367 int channel_num = voe_.GetLastChannel();
1368 std::vector<cricket::AudioCodec> codecs;
1369 codecs.push_back(kIsacCodec);
1370 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1371 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1372 EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1373}
1374
1375// Test maxplaybackrate can be set on two streams.
1376TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1377 EXPECT_TRUE(SetupEngine());
1378 int channel_num = voe_.GetLastChannel();
1379 std::vector<cricket::AudioCodec> codecs;
1380 codecs.push_back(kOpusCodec);
1381 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1382 // Default bandwidth is 24000.
1383 EXPECT_EQ(cricket::kOpusBandwidthFb,
1384 voe_.GetMaxEncodingBandwidth(channel_num));
1385
1386 codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1387
1388 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1389 EXPECT_EQ(cricket::kOpusBandwidthNb,
1390 voe_.GetMaxEncodingBandwidth(channel_num));
1391
1392 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1393 channel_num = voe_.GetLastChannel();
1394 EXPECT_EQ(cricket::kOpusBandwidthNb,
1395 voe_.GetMaxEncodingBandwidth(channel_num));
1396}
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001397#endif // USE_WEBRTC_DEV_BRANCH
1398
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001399// Test that we can apply CELT with stereo mode but fail with mono mode.
1400TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1401 EXPECT_TRUE(SetupEngine());
1402 int channel_num = voe_.GetLastChannel();
1403 std::vector<cricket::AudioCodec> codecs;
1404 codecs.push_back(kCeltCodec);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001405 codecs.push_back(kIsacCodec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406 codecs[0].id = 96;
1407 codecs[0].channels = 2;
1408 codecs[0].bitrate = 96000;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001409 codecs[1].bitrate = 64000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001410 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1411 webrtc::CodecInst gcodec;
1412 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1413 EXPECT_EQ(96, gcodec.pltype);
1414 EXPECT_EQ(96000, gcodec.rate);
1415 EXPECT_EQ(2, gcodec.channels);
1416 EXPECT_STREQ("CELT", gcodec.plname);
1417 // Doesn't support mono, expect it to fall back to the next codec in the list.
1418 codecs[0].channels = 1;
1419 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1420 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001421 EXPECT_EQ(103, gcodec.pltype);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001422 EXPECT_EQ(1, gcodec.channels);
1423 EXPECT_EQ(64000, gcodec.rate);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001424 EXPECT_STREQ("ISAC", gcodec.plname);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001425}
1426
1427// Test that we can switch back and forth between CELT and ISAC with CN.
1428TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1429 EXPECT_TRUE(SetupEngine());
1430 int channel_num = voe_.GetLastChannel();
1431 std::vector<cricket::AudioCodec> celt_codecs;
1432 celt_codecs.push_back(kCeltCodec);
1433 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1434 webrtc::CodecInst gcodec;
1435 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1436 EXPECT_EQ(110, gcodec.pltype);
1437 EXPECT_STREQ("CELT", gcodec.plname);
1438
1439 std::vector<cricket::AudioCodec> isac_codecs;
1440 isac_codecs.push_back(kIsacCodec);
1441 isac_codecs.push_back(kCn16000Codec);
1442 isac_codecs.push_back(kCeltCodec);
1443 EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1444 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1445 EXPECT_EQ(103, gcodec.pltype);
1446 EXPECT_STREQ("ISAC", gcodec.plname);
1447
1448 EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1449 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1450 EXPECT_EQ(110, gcodec.pltype);
1451 EXPECT_STREQ("CELT", gcodec.plname);
1452}
1453
1454// Test that we handle various ways of specifying bitrate.
1455TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1456 EXPECT_TRUE(SetupEngine());
1457 int channel_num = voe_.GetLastChannel();
1458 std::vector<cricket::AudioCodec> codecs;
1459 codecs.push_back(kIsacCodec); // bitrate == 32000
1460 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1461 webrtc::CodecInst gcodec;
1462 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1463 EXPECT_EQ(103, gcodec.pltype);
1464 EXPECT_STREQ("ISAC", gcodec.plname);
1465 EXPECT_EQ(32000, gcodec.rate);
1466
1467 codecs[0].bitrate = 0; // bitrate == default
1468 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1469 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1470 EXPECT_EQ(103, gcodec.pltype);
1471 EXPECT_STREQ("ISAC", gcodec.plname);
1472 EXPECT_EQ(-1, gcodec.rate);
1473
1474 codecs[0].bitrate = 28000; // bitrate == 28000
1475 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1476 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1477 EXPECT_EQ(103, gcodec.pltype);
1478 EXPECT_STREQ("ISAC", gcodec.plname);
1479 EXPECT_EQ(28000, gcodec.rate);
1480
1481 codecs[0] = kPcmuCodec; // bitrate == 64000
1482 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1483 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1484 EXPECT_EQ(0, gcodec.pltype);
1485 EXPECT_STREQ("PCMU", gcodec.plname);
1486 EXPECT_EQ(64000, gcodec.rate);
1487
1488 codecs[0].bitrate = 0; // bitrate == default
1489 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1490 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1491 EXPECT_EQ(0, gcodec.pltype);
1492 EXPECT_STREQ("PCMU", gcodec.plname);
1493 EXPECT_EQ(64000, gcodec.rate);
1494
1495 codecs[0] = kOpusCodec;
1496 codecs[0].bitrate = 0; // bitrate == default
1497 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1498 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1499 EXPECT_EQ(111, gcodec.pltype);
1500 EXPECT_STREQ("opus", gcodec.plname);
1501 EXPECT_EQ(32000, gcodec.rate);
1502}
1503
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001504// Test that we fail if no codecs are specified.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1506 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001507 std::vector<cricket::AudioCodec> codecs;
1508 EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1509}
1510
1511// Test that we can set send codecs even with telephone-event codec as the first
1512// one on the list.
1513TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1514 EXPECT_TRUE(SetupEngine());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001515 int channel_num = voe_.GetLastChannel();
1516 std::vector<cricket::AudioCodec> codecs;
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001517 codecs.push_back(kTelephoneEventCodec);
1518 codecs.push_back(kIsacCodec);
1519 codecs.push_back(kPcmuCodec);
1520 codecs[0].id = 98; // DTMF
1521 codecs[1].id = 96;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001522 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1523 webrtc::CodecInst gcodec;
1524 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +00001525 EXPECT_EQ(96, gcodec.pltype);
1526 EXPECT_STREQ("ISAC", gcodec.plname);
1527 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1528}
1529
1530// Test that we can set send codecs even with CN codec as the first
1531// one on the list.
1532TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1533 EXPECT_TRUE(SetupEngine());
1534 int channel_num = voe_.GetLastChannel();
1535 std::vector<cricket::AudioCodec> codecs;
1536 codecs.push_back(kCn16000Codec);
1537 codecs.push_back(kIsacCodec);
1538 codecs.push_back(kPcmuCodec);
1539 codecs[0].id = 98; // wideband CN
1540 codecs[1].id = 96;
1541 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1542 webrtc::CodecInst gcodec;
1543 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1544 EXPECT_EQ(96, gcodec.pltype);
1545 EXPECT_STREQ("ISAC", gcodec.plname);
1546 EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547}
1548
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001549// Test that we set VAD and DTMF types correctly as caller.
1550TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551 EXPECT_TRUE(SetupEngine());
1552 int channel_num = voe_.GetLastChannel();
1553 std::vector<cricket::AudioCodec> codecs;
1554 codecs.push_back(kIsacCodec);
1555 codecs.push_back(kPcmuCodec);
1556 // TODO(juberti): cn 32000
1557 codecs.push_back(kCn16000Codec);
1558 codecs.push_back(kCn8000Codec);
1559 codecs.push_back(kTelephoneEventCodec);
1560 codecs.push_back(kRedCodec);
1561 codecs[0].id = 96;
1562 codecs[2].id = 97; // wideband CN
1563 codecs[4].id = 98; // DTMF
1564 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1565 webrtc::CodecInst gcodec;
1566 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1567 EXPECT_EQ(96, gcodec.pltype);
1568 EXPECT_STREQ("ISAC", gcodec.plname);
1569 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001570 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001571 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1572 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1573 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1574}
1575
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001576// Test that we set VAD and DTMF types correctly as callee.
1577TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001578 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001579 channel_ = engine_.CreateChannel();
1580 EXPECT_TRUE(channel_ != NULL);
1581
1582 int channel_num = voe_.GetLastChannel();
1583 std::vector<cricket::AudioCodec> codecs;
1584 codecs.push_back(kIsacCodec);
1585 codecs.push_back(kPcmuCodec);
1586 // TODO(juberti): cn 32000
1587 codecs.push_back(kCn16000Codec);
1588 codecs.push_back(kCn8000Codec);
1589 codecs.push_back(kTelephoneEventCodec);
1590 codecs.push_back(kRedCodec);
1591 codecs[0].id = 96;
1592 codecs[2].id = 97; // wideband CN
1593 codecs[4].id = 98; // DTMF
1594 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1595 EXPECT_TRUE(channel_->AddSendStream(
1596 cricket::StreamParams::CreateLegacy(kSsrc1)));
1597
1598 webrtc::CodecInst gcodec;
1599 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1600 EXPECT_EQ(96, gcodec.pltype);
1601 EXPECT_STREQ("ISAC", gcodec.plname);
1602 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001603 EXPECT_FALSE(voe_.GetRED(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001604 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1605 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1606 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1607}
1608
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001609// Test that we only apply VAD if we have a CN codec that matches the
1610// send codec clockrate.
1611TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1612 EXPECT_TRUE(SetupEngine());
1613 int channel_num = voe_.GetLastChannel();
1614 std::vector<cricket::AudioCodec> codecs;
1615 // Set ISAC(16K) and CN(16K). VAD should be activated.
1616 codecs.push_back(kIsacCodec);
1617 codecs.push_back(kCn16000Codec);
1618 codecs[1].id = 97;
1619 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1620 webrtc::CodecInst gcodec;
1621 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1622 EXPECT_STREQ("ISAC", gcodec.plname);
1623 EXPECT_TRUE(voe_.GetVAD(channel_num));
1624 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1625 // Set PCMU(8K) and CN(16K). VAD should not be activated.
1626 codecs[0] = kPcmuCodec;
1627 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1628 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1629 EXPECT_STREQ("PCMU", gcodec.plname);
1630 EXPECT_FALSE(voe_.GetVAD(channel_num));
1631 // Set PCMU(8K) and CN(8K). VAD should be activated.
1632 codecs[1] = kCn8000Codec;
1633 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1634 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1635 EXPECT_STREQ("PCMU", gcodec.plname);
1636 EXPECT_TRUE(voe_.GetVAD(channel_num));
1637 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1638 // Set ISAC(16K) and CN(8K). VAD should not be activated.
1639 codecs[0] = kIsacCodec;
1640 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1641 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1642 EXPECT_STREQ("ISAC", gcodec.plname);
1643 EXPECT_FALSE(voe_.GetVAD(channel_num));
1644}
1645
1646// Test that we perform case-insensitive matching of codec names.
1647TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1648 EXPECT_TRUE(SetupEngine());
1649 int channel_num = voe_.GetLastChannel();
1650 std::vector<cricket::AudioCodec> codecs;
1651 codecs.push_back(kIsacCodec);
1652 codecs.push_back(kPcmuCodec);
1653 codecs.push_back(kCn16000Codec);
1654 codecs.push_back(kCn8000Codec);
1655 codecs.push_back(kTelephoneEventCodec);
1656 codecs.push_back(kRedCodec);
1657 codecs[0].name = "iSaC";
1658 codecs[0].id = 96;
1659 codecs[2].id = 97; // wideband CN
1660 codecs[4].id = 98; // DTMF
1661 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1662 webrtc::CodecInst gcodec;
1663 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1664 EXPECT_EQ(96, gcodec.pltype);
1665 EXPECT_STREQ("ISAC", gcodec.plname);
1666 EXPECT_TRUE(voe_.GetVAD(channel_num));
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001667 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001668 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1669 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1670 EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1671}
1672
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001673// Test that we set up RED correctly as caller.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001674TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001675 EXPECT_TRUE(SetupEngine());
1676 int channel_num = voe_.GetLastChannel();
1677 std::vector<cricket::AudioCodec> codecs;
1678 codecs.push_back(kRedCodec);
1679 codecs.push_back(kIsacCodec);
1680 codecs.push_back(kPcmuCodec);
1681 codecs[0].id = 127;
1682 codecs[0].params[""] = "96/96";
1683 codecs[1].id = 96;
1684 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1685 webrtc::CodecInst gcodec;
1686 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1687 EXPECT_EQ(96, gcodec.pltype);
1688 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001689 EXPECT_TRUE(voe_.GetRED(channel_num));
1690 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001691}
1692
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001693// Test that we set up RED correctly as callee.
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001694TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001695 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001696 channel_ = engine_.CreateChannel();
1697 EXPECT_TRUE(channel_ != NULL);
1698
1699 int channel_num = voe_.GetLastChannel();
1700 std::vector<cricket::AudioCodec> codecs;
1701 codecs.push_back(kRedCodec);
1702 codecs.push_back(kIsacCodec);
1703 codecs.push_back(kPcmuCodec);
1704 codecs[0].id = 127;
1705 codecs[0].params[""] = "96/96";
1706 codecs[1].id = 96;
1707 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1708 EXPECT_TRUE(channel_->AddSendStream(
1709 cricket::StreamParams::CreateLegacy(kSsrc1)));
1710 webrtc::CodecInst gcodec;
1711 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1712 EXPECT_EQ(96, gcodec.pltype);
1713 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001714 EXPECT_TRUE(voe_.GetRED(channel_num));
1715 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001716}
1717
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001718// Test that we set up RED correctly if params are omitted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001719TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1720 EXPECT_TRUE(SetupEngine());
1721 int channel_num = voe_.GetLastChannel();
1722 std::vector<cricket::AudioCodec> codecs;
1723 codecs.push_back(kRedCodec);
1724 codecs.push_back(kIsacCodec);
1725 codecs.push_back(kPcmuCodec);
1726 codecs[0].id = 127;
1727 codecs[1].id = 96;
1728 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1729 webrtc::CodecInst gcodec;
1730 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1731 EXPECT_EQ(96, gcodec.pltype);
1732 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001733 EXPECT_TRUE(voe_.GetRED(channel_num));
1734 EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735}
1736
1737// Test that we ignore RED if the parameters aren't named the way we expect.
1738TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1739 EXPECT_TRUE(SetupEngine());
1740 int channel_num = voe_.GetLastChannel();
1741 std::vector<cricket::AudioCodec> codecs;
1742 codecs.push_back(kRedCodec);
1743 codecs.push_back(kIsacCodec);
1744 codecs.push_back(kPcmuCodec);
1745 codecs[0].id = 127;
1746 codecs[0].params["ABC"] = "96/96";
1747 codecs[1].id = 96;
1748 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1749 webrtc::CodecInst gcodec;
1750 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1751 EXPECT_EQ(96, gcodec.pltype);
1752 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001753 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001754}
1755
1756// Test that we ignore RED if it uses different primary/secondary encoding.
1757TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1758 EXPECT_TRUE(SetupEngine());
1759 int channel_num = voe_.GetLastChannel();
1760 std::vector<cricket::AudioCodec> codecs;
1761 codecs.push_back(kRedCodec);
1762 codecs.push_back(kIsacCodec);
1763 codecs.push_back(kPcmuCodec);
1764 codecs[0].id = 127;
1765 codecs[0].params[""] = "96/0";
1766 codecs[1].id = 96;
1767 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1768 webrtc::CodecInst gcodec;
1769 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1770 EXPECT_EQ(96, gcodec.pltype);
1771 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001772 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001773}
1774
1775// Test that we ignore RED if it uses more than 2 encodings.
1776TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1777 EXPECT_TRUE(SetupEngine());
1778 int channel_num = voe_.GetLastChannel();
1779 std::vector<cricket::AudioCodec> codecs;
1780 codecs.push_back(kRedCodec);
1781 codecs.push_back(kIsacCodec);
1782 codecs.push_back(kPcmuCodec);
1783 codecs[0].id = 127;
1784 codecs[0].params[""] = "96/96/96";
1785 codecs[1].id = 96;
1786 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1787 webrtc::CodecInst gcodec;
1788 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1789 EXPECT_EQ(96, gcodec.pltype);
1790 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001791 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001792}
1793
1794// Test that we ignore RED if it has bogus codec ids.
1795TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1796 EXPECT_TRUE(SetupEngine());
1797 int channel_num = voe_.GetLastChannel();
1798 std::vector<cricket::AudioCodec> codecs;
1799 codecs.push_back(kRedCodec);
1800 codecs.push_back(kIsacCodec);
1801 codecs.push_back(kPcmuCodec);
1802 codecs[0].id = 127;
1803 codecs[0].params[""] = "ABC/ABC";
1804 codecs[1].id = 96;
1805 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1806 webrtc::CodecInst gcodec;
1807 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1808 EXPECT_EQ(96, gcodec.pltype);
1809 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001810 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811}
1812
1813// Test that we ignore RED if it refers to a codec that is not present.
1814TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1815 EXPECT_TRUE(SetupEngine());
1816 int channel_num = voe_.GetLastChannel();
1817 std::vector<cricket::AudioCodec> codecs;
1818 codecs.push_back(kRedCodec);
1819 codecs.push_back(kIsacCodec);
1820 codecs.push_back(kPcmuCodec);
1821 codecs[0].id = 127;
1822 codecs[0].params[""] = "97/97";
1823 codecs[1].id = 96;
1824 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1825 webrtc::CodecInst gcodec;
1826 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1827 EXPECT_EQ(96, gcodec.pltype);
1828 EXPECT_STREQ("ISAC", gcodec.plname);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +00001829 EXPECT_FALSE(voe_.GetRED(channel_num));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001830}
1831
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001832// Test support for audio level header extension.
1833TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1834 TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001835}
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001836TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1837 TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1838}
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001839
buildbot@webrtc.org150835e2014-05-06 15:54:38 +00001840// Test support for absolute send time header extension.
1841TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1842 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1843}
1844TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1845 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001846}
1847
1848// Test that we can create a channel and start sending/playing out on it.
1849TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1850 EXPECT_TRUE(SetupEngine());
1851 int channel_num = voe_.GetLastChannel();
1852 std::vector<cricket::AudioCodec> codecs;
1853 codecs.push_back(kPcmuCodec);
1854 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1855 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1856 EXPECT_TRUE(voe_.GetSend(channel_num));
1857 EXPECT_TRUE(channel_->SetPlayout(true));
1858 EXPECT_TRUE(voe_.GetPlayout(channel_num));
1859 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1860 EXPECT_FALSE(voe_.GetSend(channel_num));
1861 EXPECT_TRUE(channel_->SetPlayout(false));
1862 EXPECT_FALSE(voe_.GetPlayout(channel_num));
1863}
1864
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001865// Test that we can add and remove send streams.
1866TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1867 SetupForMultiSendStream();
1868
1869 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1870
1871 // Set the global state for sending.
1872 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1873
1874 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1875 EXPECT_TRUE(channel_->AddSendStream(
1876 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1877
1878 // Verify that we are in a sending state for all the created streams.
1879 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1880 EXPECT_TRUE(voe_.GetSend(channel_num));
1881 }
1882
1883 // Remove the first send channel, which is the default channel. It will only
1884 // recycle the default channel but not delete it.
1885 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1886 // Stream should already be Removed from the send stream list.
1887 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1888 // But the default still exists.
1889 EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1890
1891 // Delete the rest of send channel streams.
1892 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1893 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1894 // Stream should already be deleted.
1895 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1896 EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1897 }
1898}
1899
1900// Test SetSendCodecs correctly configure the codecs in all send streams.
1901TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1902 SetupForMultiSendStream();
1903
1904 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1905 // Create send streams.
1906 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1907 EXPECT_TRUE(channel_->AddSendStream(
1908 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1909 }
1910
1911 std::vector<cricket::AudioCodec> codecs;
1912 // Set ISAC(16K) and CN(16K). VAD should be activated.
1913 codecs.push_back(kIsacCodec);
1914 codecs.push_back(kCn16000Codec);
1915 codecs[1].id = 97;
1916 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1917
1918 // Verify ISAC and VAD are corrected configured on all send channels.
1919 webrtc::CodecInst gcodec;
1920 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1921 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1922 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1923 EXPECT_STREQ("ISAC", gcodec.plname);
1924 EXPECT_TRUE(voe_.GetVAD(channel_num));
1925 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1926 }
1927
1928 // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1929 codecs[0] = kPcmuCodec;
1930 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1931 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1932 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1933 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1934 EXPECT_STREQ("PCMU", gcodec.plname);
1935 EXPECT_FALSE(voe_.GetVAD(channel_num));
1936 }
1937}
1938
1939// Test we can SetSend on all send streams correctly.
1940TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1941 SetupForMultiSendStream();
1942
1943 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1944 // Create the send channels and they should be a SEND_NOTHING date.
1945 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1946 EXPECT_TRUE(channel_->AddSendStream(
1947 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1948 int channel_num = voe_.GetLastChannel();
1949 EXPECT_FALSE(voe_.GetSend(channel_num));
1950 }
1951
1952 // Set the global state for starting sending.
1953 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1954 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1955 // Verify that we are in a sending state for all the send streams.
1956 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1957 EXPECT_TRUE(voe_.GetSend(channel_num));
1958 }
1959
1960 // Set the global state for stopping sending.
1961 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1962 for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1963 // Verify that we are in a stop state for all the send streams.
1964 int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1965 EXPECT_FALSE(voe_.GetSend(channel_num));
1966 }
1967}
1968
1969// Test we can set the correct statistics on all send streams.
1970TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1971 SetupForMultiSendStream();
1972
1973 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1974 // Create send streams.
1975 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1976 EXPECT_TRUE(channel_->AddSendStream(
1977 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1978 }
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001979 // Create a receive stream to check that none of the send streams end up in
1980 // the receive stream stats.
1981 EXPECT_TRUE(channel_->AddRecvStream(
1982 cricket::StreamParams::CreateLegacy(kSsrc2)));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001983 // We need send codec to be set to get all stats.
1984 std::vector<cricket::AudioCodec> codecs;
1985 codecs.push_back(kPcmuCodec);
1986 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00001987 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001988
1989 cricket::VoiceMediaInfo info;
1990 EXPECT_EQ(true, channel_->GetStats(&info));
1991 EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1992
1993 // Verify the statistic information is correct.
1994 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00001995 EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
wu@webrtc.org9dba5252013-08-05 20:36:57 +00001996 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1997 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1998 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1999 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
2000 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
2001 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
2002 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
2003 EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002004 EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002005 }
2006
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002007 EXPECT_EQ(0u, info.receivers.size());
2008 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2009 EXPECT_EQ(true, channel_->GetStats(&info));
2010
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002011 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002012 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2013 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2014 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2015 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2016 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002017}
2018
wu@webrtc.org9dba5252013-08-05 20:36:57 +00002019// Test that we can add and remove receive streams, and do proper send/playout.
2020// We can receive on multiple streams while sending one stream.
2021TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002022 EXPECT_TRUE(SetupEngine());
2023 int channel_num1 = voe_.GetLastChannel();
2024
2025 // Start playout on the default channel.
2026 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2027 EXPECT_TRUE(channel_->SetPlayout(true));
2028 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2029
2030 // Adding another stream should disable playout on the default channel.
2031 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2032 int channel_num2 = voe_.GetLastChannel();
2033 std::vector<cricket::AudioCodec> codecs;
2034 codecs.push_back(kPcmuCodec);
2035 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2036 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2037 EXPECT_TRUE(voe_.GetSend(channel_num1));
2038 EXPECT_FALSE(voe_.GetSend(channel_num2));
2039
2040 // Make sure only the new channel is played out.
2041 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2042 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2043
2044 // Adding yet another stream should have stream 2 and 3 enabled for playout.
2045 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2046 int channel_num3 = voe_.GetLastChannel();
2047 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2048 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2049 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2050 EXPECT_FALSE(voe_.GetSend(channel_num3));
2051
2052 // Stop sending.
2053 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2054 EXPECT_FALSE(voe_.GetSend(channel_num1));
2055 EXPECT_FALSE(voe_.GetSend(channel_num2));
2056 EXPECT_FALSE(voe_.GetSend(channel_num3));
2057
2058 // Stop playout.
2059 EXPECT_TRUE(channel_->SetPlayout(false));
2060 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2061 EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2062 EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2063
2064 // Restart playout and make sure the default channel still is not played out.
2065 EXPECT_TRUE(channel_->SetPlayout(true));
2066 EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2067 EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2068 EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2069
2070 // Now remove the new streams and verify that the default channel is
2071 // played out again.
2072 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2073 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2074
2075 EXPECT_TRUE(voe_.GetPlayout(channel_num1));
2076}
2077
2078// Test that we can set the devices to use.
2079TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
2080 EXPECT_TRUE(SetupEngine());
2081 int channel_num = voe_.GetLastChannel();
2082 std::vector<cricket::AudioCodec> codecs;
2083 codecs.push_back(kPcmuCodec);
2084 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2085
2086 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2087 cricket::kFakeDefaultDeviceId);
2088 cricket::Device dev(cricket::kFakeDeviceName,
2089 cricket::kFakeDeviceId);
2090
2091 // Test SetDevices() while not sending or playing.
2092 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2093
2094 // Test SetDevices() while sending and playing.
2095 EXPECT_TRUE(engine_.SetLocalMonitor(true));
2096 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2097 EXPECT_TRUE(channel_->SetPlayout(true));
2098 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2099 EXPECT_TRUE(voe_.GetSend(channel_num));
2100 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2101
2102 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2103
2104 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2105 EXPECT_TRUE(voe_.GetSend(channel_num));
2106 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2107
2108 // Test that failure to open newly selected devices does not prevent opening
2109 // ones after that.
2110 voe_.set_fail_start_recording_microphone(true);
2111 voe_.set_playout_fail_channel(channel_num);
2112 voe_.set_send_fail_channel(channel_num);
2113
2114 EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
2115
2116 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2117 EXPECT_FALSE(voe_.GetSend(channel_num));
2118 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2119
2120 voe_.set_fail_start_recording_microphone(false);
2121 voe_.set_playout_fail_channel(-1);
2122 voe_.set_send_fail_channel(-1);
2123
2124 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2125
2126 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2127 EXPECT_TRUE(voe_.GetSend(channel_num));
2128 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2129}
2130
2131// Test that we can set the devices to use even if we failed to
2132// open the initial ones.
2133TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
2134 EXPECT_TRUE(SetupEngine());
2135 int channel_num = voe_.GetLastChannel();
2136 std::vector<cricket::AudioCodec> codecs;
2137 codecs.push_back(kPcmuCodec);
2138 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2139
2140 cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2141 cricket::kFakeDefaultDeviceId);
2142 cricket::Device dev(cricket::kFakeDeviceName,
2143 cricket::kFakeDeviceId);
2144
2145 // Test that failure to open devices selected before starting
2146 // send/play does not prevent opening newly selected ones after that.
2147 voe_.set_fail_start_recording_microphone(true);
2148 voe_.set_playout_fail_channel(channel_num);
2149 voe_.set_send_fail_channel(channel_num);
2150
2151 EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2152
2153 EXPECT_FALSE(engine_.SetLocalMonitor(true));
2154 EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2155 EXPECT_FALSE(channel_->SetPlayout(true));
2156 EXPECT_FALSE(voe_.GetRecordingMicrophone());
2157 EXPECT_FALSE(voe_.GetSend(channel_num));
2158 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2159
2160 voe_.set_fail_start_recording_microphone(false);
2161 voe_.set_playout_fail_channel(-1);
2162 voe_.set_send_fail_channel(-1);
2163
2164 EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2165
2166 EXPECT_TRUE(voe_.GetRecordingMicrophone());
2167 EXPECT_TRUE(voe_.GetSend(channel_num));
2168 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2169}
2170
2171// Test that we can create a channel configured for multi-point conferences,
2172// and start sending/playing out on it.
2173TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2174 EXPECT_TRUE(SetupEngine());
2175 int channel_num = voe_.GetLastChannel();
2176 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2177 std::vector<cricket::AudioCodec> codecs;
2178 codecs.push_back(kPcmuCodec);
2179 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2180 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2181 EXPECT_TRUE(voe_.GetSend(channel_num));
2182}
2183
2184// Test that we can create a channel configured for Codian bridges,
2185// and start sending/playing out on it.
2186TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2187 EXPECT_TRUE(SetupEngine());
2188 int channel_num = voe_.GetLastChannel();
2189 webrtc::AgcConfig agc_config;
2190 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2191 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2192 EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2193 std::vector<cricket::AudioCodec> codecs;
2194 codecs.push_back(kPcmuCodec);
2195 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2196 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2197 EXPECT_TRUE(voe_.GetSend(channel_num));
2198 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2199 EXPECT_EQ(agc_config.targetLeveldBOv, 10); // level was attenuated
2200 EXPECT_TRUE(channel_->SetPlayout(true));
2201 EXPECT_TRUE(voe_.GetPlayout(channel_num));
2202 EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2203 EXPECT_FALSE(voe_.GetSend(channel_num));
2204 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2205 EXPECT_EQ(0, agc_config.targetLeveldBOv); // level was restored
2206 EXPECT_TRUE(channel_->SetPlayout(false));
2207 EXPECT_FALSE(voe_.GetPlayout(channel_num));
2208}
2209
wu@webrtc.org97077a32013-10-25 21:18:33 +00002210TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2211 EXPECT_TRUE(SetupEngine());
2212 webrtc::AgcConfig agc_config;
2213 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2214 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2215
2216 cricket::AudioOptions options;
2217 options.tx_agc_target_dbov.Set(3);
2218 options.tx_agc_digital_compression_gain.Set(9);
2219 options.tx_agc_limiter.Set(true);
2220 options.auto_gain_control.Set(true);
2221 EXPECT_TRUE(engine_.SetOptions(options));
2222
2223 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2224 EXPECT_EQ(3, agc_config.targetLeveldBOv);
2225 EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2226 EXPECT_TRUE(agc_config.limiterEnable);
2227
2228 // Check interaction with adjust_agc_delta. Both should be respected, for
2229 // backwards compatibility.
2230 options.adjust_agc_delta.Set(-10);
2231 EXPECT_TRUE(engine_.SetOptions(options));
2232
2233 EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2234 EXPECT_EQ(13, agc_config.targetLeveldBOv);
2235}
2236
2237TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2238 EXPECT_TRUE(SetupEngine());
2239 int channel_num = voe_.GetLastChannel();
2240 cricket::AudioOptions options;
2241 options.rx_agc_target_dbov.Set(6);
2242 options.rx_agc_digital_compression_gain.Set(0);
2243 options.rx_agc_limiter.Set(true);
2244 options.rx_auto_gain_control.Set(true);
2245 EXPECT_TRUE(channel_->SetOptions(options));
2246
2247 webrtc::AgcConfig agc_config;
2248 EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2249 channel_num, agc_config));
2250 EXPECT_EQ(6, agc_config.targetLeveldBOv);
2251 EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2252 EXPECT_TRUE(agc_config.limiterEnable);
2253}
2254
2255TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2256 EXPECT_TRUE(SetupEngine());
2257 cricket::AudioOptions options;
2258 options.recording_sample_rate.Set(48000u);
2259 options.playout_sample_rate.Set(44100u);
2260 EXPECT_TRUE(engine_.SetOptions(options));
2261
2262 unsigned int recording_sample_rate, playout_sample_rate;
2263 EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2264 EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2265 EXPECT_EQ(48000u, recording_sample_rate);
2266 EXPECT_EQ(44100u, playout_sample_rate);
2267}
2268
2269TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2270 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002271 engine_.SetLogging(rtc::LS_INFO, "");
wu@webrtc.org97077a32013-10-25 21:18:33 +00002272 EXPECT_EQ(
2273 // Info:
2274 webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2275 // Warning:
2276 webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2277 // Error:
2278 webrtc::kTraceError | webrtc::kTraceCritical,
2279 static_cast<int>(trace_wrapper_->filter_));
2280 // Now set it explicitly
2281 std::string filter =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002282 "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2283 engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
wu@webrtc.org97077a32013-10-25 21:18:33 +00002284 EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2285 trace_wrapper_->filter_);
2286}
2287
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288// Test that we can set the outgoing SSRC properly.
2289// SSRC is set in SetupEngine by calling AddSendStream.
2290TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2291 EXPECT_TRUE(SetupEngine());
2292 int channel_num = voe_.GetLastChannel();
2293 unsigned int send_ssrc;
2294 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2295 EXPECT_NE(0U, send_ssrc);
2296 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2297 EXPECT_EQ(kSsrc1, send_ssrc);
2298}
2299
2300TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2301 // Setup. We need send codec to be set to get all stats.
2302 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002303 // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2304 // use a different SSRC.
2305 EXPECT_TRUE(channel_->AddRecvStream(
2306 cricket::StreamParams::CreateLegacy(kSsrc2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307 std::vector<cricket::AudioCodec> codecs;
2308 codecs.push_back(kPcmuCodec);
2309 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002310 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002311
2312 cricket::VoiceMediaInfo info;
2313 EXPECT_EQ(true, channel_->GetStats(&info));
2314 EXPECT_EQ(1u, info.senders.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +00002315 EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002316 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2317 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2318 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2319 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2320 EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2321 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2322 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2323 EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002324 EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002325 // TODO(sriniv): Add testing for more fields. These are not populated
2326 // in FakeWebrtcVoiceEngine yet.
2327 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2328 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2329 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2330 // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2331 // EXPECT_EQ(cricket::kIntStatValue,
2332 // info.senders[0].echo_return_loss_enhancement);
2333
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002334 EXPECT_EQ(0u, info.receivers.size());
2335 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2336 EXPECT_EQ(true, channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002337 EXPECT_EQ(1u, info.receivers.size());
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +00002338
2339 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2340 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2341 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2342 EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2343 EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
2344 // TODO(sriniv): Add testing for more receiver fields.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002345}
2346
2347// Test that we can set the outgoing SSRC properly with multiple streams.
2348// SSRC is set in SetupEngine by calling AddSendStream.
2349TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2350 EXPECT_TRUE(SetupEngine());
2351 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2352 int channel_num1 = voe_.GetLastChannel();
2353 unsigned int send_ssrc;
2354 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2355 EXPECT_EQ(kSsrc1, send_ssrc);
2356
2357 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2358 int channel_num2 = voe_.GetLastChannel();
2359 EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2360 EXPECT_EQ(kSsrc1, send_ssrc);
2361}
2362
2363// Test that the local SSRC is the same on sending and receiving channels if the
2364// receive channel is created before the send channel.
2365TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002366 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002367 channel_ = engine_.CreateChannel();
2368 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2369
2370 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2371 int receive_channel_num = voe_.GetLastChannel();
2372 EXPECT_TRUE(channel_->AddSendStream(
2373 cricket::StreamParams::CreateLegacy(1234)));
2374 int send_channel_num = voe_.GetLastChannel();
2375
2376 unsigned int ssrc = 0;
2377 EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2378 EXPECT_EQ(1234U, ssrc);
2379 ssrc = 0;
2380 EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2381 EXPECT_EQ(1234U, ssrc);
2382}
2383
2384// Test that we can properly receive packets.
2385TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2386 EXPECT_TRUE(SetupEngine());
2387 int channel_num = voe_.GetLastChannel();
2388 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2389 EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2390 sizeof(kPcmuFrame)));
2391}
2392
2393// Test that we can properly receive packets on multiple streams.
2394TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2395 EXPECT_TRUE(SetupEngine());
2396 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2397 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2398 int channel_num1 = voe_.GetLastChannel();
2399 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2400 int channel_num2 = voe_.GetLastChannel();
2401 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2402 int channel_num3 = voe_.GetLastChannel();
2403 // Create packets with the right SSRCs.
2404 char packets[4][sizeof(kPcmuFrame)];
2405 for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2406 memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002407 rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002408 }
2409 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2410 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2411 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2412 DeliverPacket(packets[0], sizeof(packets[0]));
2413 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2414 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2415 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2416 DeliverPacket(packets[1], sizeof(packets[1]));
2417 EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2418 sizeof(packets[1])));
2419 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2420 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2421 DeliverPacket(packets[2], sizeof(packets[2]));
2422 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2423 EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2424 sizeof(packets[2])));
2425 EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2426 DeliverPacket(packets[3], sizeof(packets[3]));
2427 EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2428 EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2429 EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2430 sizeof(packets[3])));
2431 EXPECT_TRUE(channel_->RemoveRecvStream(3));
2432 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2433 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2434}
2435
2436// Test that we properly handle failures to add a stream.
2437TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2438 EXPECT_TRUE(SetupEngine());
2439 voe_.set_fail_create_channel(true);
2440 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2441 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2442
2443 // In 1:1 call, we should not try to create a new channel.
2444 cricket::AudioOptions options_no_conference_;
2445 options_no_conference_.conference_mode.Set(false);
2446 EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2447 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2448}
2449
2450// Test that AddRecvStream doesn't create new channel for 1:1 call.
2451TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2452 EXPECT_TRUE(SetupEngine());
2453 int channel_num = voe_.GetLastChannel();
2454 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2455 EXPECT_EQ(channel_num, voe_.GetLastChannel());
2456}
2457
2458// Test that after adding a recv stream, we do not decode more codecs than
2459// those previously passed into SetRecvCodecs.
2460TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2461 EXPECT_TRUE(SetupEngine());
2462 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2463 std::vector<cricket::AudioCodec> codecs;
2464 codecs.push_back(kIsacCodec);
2465 codecs.push_back(kPcmuCodec);
2466 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2467 EXPECT_TRUE(channel_->AddRecvStream(
2468 cricket::StreamParams::CreateLegacy(kSsrc1)));
2469 int channel_num2 = voe_.GetLastChannel();
2470 webrtc::CodecInst gcodec;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002471 rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002472 gcodec.plfreq = 32000;
2473 gcodec.channels = 2;
2474 EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2475}
2476
2477// Test that we properly clean up any streams that were added, even if
2478// not explicitly removed.
2479TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2480 EXPECT_TRUE(SetupEngine());
2481 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2482 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2483 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2484 EXPECT_EQ(3, voe_.GetNumChannels()); // default channel + 2 added
2485 delete channel_;
2486 channel_ = NULL;
2487 EXPECT_EQ(0, voe_.GetNumChannels());
2488}
2489
wu@webrtc.org78187522013-10-07 23:32:02 +00002490TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2491 EXPECT_TRUE(SetupEngine());
2492 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2493}
2494
2495TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2496 EXPECT_TRUE(SetupEngine());
2497 // Stream 1 reuses default channel.
2498 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2499 // Manually delete default channel to simulate a failure.
2500 int default_channel = voe_.GetLastChannel();
2501 EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2502 // Add recv stream 2 should fail because default channel is gone.
2503 EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2504 int new_channel = voe_.GetLastChannel();
2505 EXPECT_NE(default_channel, new_channel);
2506 // The last created channel should have already been deleted.
2507 EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2508}
2509
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002510// Test the InsertDtmf on default send stream as caller.
2511TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2512 TestInsertDtmf(0, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002513}
2514
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002515// Test the InsertDtmf on default send stream as callee
2516TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2517 TestInsertDtmf(0, false);
2518}
2519
2520// Test the InsertDtmf on specified send stream as caller.
2521TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2522 TestInsertDtmf(kSsrc1, true);
2523}
2524
2525// Test the InsertDtmf on specified send stream as callee.
2526TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2527 TestInsertDtmf(kSsrc1, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002528}
2529
2530// Test that we can play a ringback tone properly in a single-stream call.
2531TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2532 EXPECT_TRUE(SetupEngine());
2533 int channel_num = voe_.GetLastChannel();
2534 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2535 // Check we fail if no ringback tone specified.
2536 EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2537 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2538 // Check we can set and play a ringback tone.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002539 EXPECT_TRUE(channel_->SetRingbackTone(
2540 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002541 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2542 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2543 // Check we can stop the tone manually.
2544 EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2545 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2546 // Check we stop the tone if a packet arrives.
2547 EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2548 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2549 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2550 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2551}
2552
2553// Test that we can play a ringback tone properly in a multi-stream call.
2554TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2555 EXPECT_TRUE(SetupEngine());
2556 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2557 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2558 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2559 int channel_num = voe_.GetLastChannel();
2560 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2561 // Check we fail if no ringback tone specified.
2562 EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2563 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2564 // Check we can set and play a ringback tone on the correct ssrc.
wu@webrtc.org9caf2762013-12-11 18:25:07 +00002565 EXPECT_TRUE(channel_->SetRingbackTone(
2566 kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002567 EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2568 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2569 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2570 // Check we can stop the tone manually.
2571 EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2572 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2573 // Check we stop the tone if a packet arrives, but only with the right SSRC.
2574 EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2575 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2576 // Send a packet with SSRC 1; the tone should not stop.
2577 DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2578 EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2579 // Send a packet with SSRC 2; the tone should stop.
2580 char packet[sizeof(kPcmuFrame)];
2581 memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002582 rtc::SetBE32(packet + 8, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002583 DeliverPacket(packet, sizeof(packet));
2584 EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2585}
2586
2587// Tests creating soundclips, and make sure they come from the right engine.
2588TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002589 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
wu@webrtc.org4551b792013-10-09 15:37:36 +00002590 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002591 soundclip_ = engine_.CreateSoundclip();
wu@webrtc.org4551b792013-10-09 15:37:36 +00002592 EXPECT_TRUE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002593 ASSERT_TRUE(soundclip_ != NULL);
2594 EXPECT_EQ(0, voe_.GetNumChannels());
2595 EXPECT_EQ(1, voe_sc_.GetNumChannels());
2596 int channel_num = voe_sc_.GetLastChannel();
2597 EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2598 delete soundclip_;
2599 soundclip_ = NULL;
2600 EXPECT_EQ(0, voe_sc_.GetNumChannels());
wu@webrtc.org4551b792013-10-09 15:37:36 +00002601 // Make sure the soundclip engine is uninitialized on shutdown, now that
2602 // we've initialized it by creating a soundclip.
2603 engine_.Terminate();
2604 EXPECT_FALSE(voe_sc_.IsInited());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002605}
2606
2607// Tests playing out a fake sound.
2608TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2609 static const char kZeroes[16000] = {};
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002610 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002611 soundclip_ = engine_.CreateSoundclip();
2612 ASSERT_TRUE(soundclip_ != NULL);
2613 EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2614}
2615
2616TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002617 rtc::scoped_ptr<ChannelErrorListener> listener;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002618 cricket::WebRtcVoiceMediaChannel* media_channel;
2619 unsigned int ssrc = 0;
2620
2621 EXPECT_TRUE(SetupEngine());
2622 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2623 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2624
2625 media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2626 listener.reset(new ChannelErrorListener(channel_));
2627
2628 // Test on WebRtc VoE channel.
2629 voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2630 VE_SATURATION_WARNING);
2631 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2632 listener->error());
2633 EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2634 EXPECT_EQ(ssrc, listener->ssrc());
2635
2636 listener->Reset();
2637 voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2638 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2639 listener->error());
2640 EXPECT_EQ(0U, listener->ssrc());
2641
2642 // Add another stream and test on that.
2643 ++ssrc;
2644 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2645 ssrc)));
2646 listener->Reset();
2647 voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2648 VE_SATURATION_WARNING);
2649 EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2650 listener->error());
2651 EXPECT_EQ(ssrc, listener->ssrc());
2652
2653 // Testing a non-existing channel.
2654 listener->Reset();
2655 voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2656 VE_SATURATION_WARNING);
2657 EXPECT_EQ(0, listener->error());
2658}
2659
2660TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2661 EXPECT_TRUE(SetupEngine());
2662 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2663 std::vector<cricket::AudioCodec> codecs;
2664 codecs.push_back(kPcmuCodec);
2665 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2666 EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2667 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2668 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2669 EXPECT_TRUE(channel_->SetPlayout(true));
2670 voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2671 EXPECT_TRUE(channel_->SetPlayout(false));
2672 EXPECT_FALSE(channel_->SetPlayout(true));
2673}
2674
2675// Test that the Registering/Unregistering with the
2676// webrtcvoiceengine works as expected
2677TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2678 EXPECT_TRUE(SetupEngine());
2679 EXPECT_TRUE(channel_->SetOptions(options_conference_));
2680 EXPECT_TRUE(channel_->AddRecvStream(
2681 cricket::StreamParams::CreateLegacy(kSsrc2)));
2682 cricket::FakeMediaProcessor vp_1;
2683 cricket::FakeMediaProcessor vp_2;
2684
2685 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2686 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2687 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2688 voe_.TriggerProcessPacket(cricket::MPD_RX);
2689 voe_.TriggerProcessPacket(cricket::MPD_TX);
2690
2691 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2692 EXPECT_EQ(1, vp_1.voice_frame_count());
2693 EXPECT_EQ(1, vp_2.voice_frame_count());
2694
2695 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2696 &vp_2,
2697 cricket::MPD_RX));
2698 voe_.TriggerProcessPacket(cricket::MPD_RX);
2699 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2700 EXPECT_EQ(1, vp_2.voice_frame_count());
2701 EXPECT_EQ(2, vp_1.voice_frame_count());
2702
2703 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2704 &vp_1,
2705 cricket::MPD_RX));
2706 voe_.TriggerProcessPacket(cricket::MPD_RX);
2707 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2708 EXPECT_EQ(2, vp_1.voice_frame_count());
2709
2710 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2711 EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2712 voe_.TriggerProcessPacket(cricket::MPD_RX);
2713 voe_.TriggerProcessPacket(cricket::MPD_TX);
2714 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2715 EXPECT_EQ(3, vp_1.voice_frame_count());
2716
2717 EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2718 &vp_1,
2719 cricket::MPD_RX_AND_TX));
2720 voe_.TriggerProcessPacket(cricket::MPD_TX);
2721 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2722 EXPECT_EQ(3, vp_1.voice_frame_count());
2723 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2724 EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2725 EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2726
2727 // Test that we can register a processor on the receive channel on SSRC 0.
2728 // This tests the 1:1 case when the receive SSRC is unknown.
2729 EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2730 voe_.TriggerProcessPacket(cricket::MPD_RX);
2731 EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2732 EXPECT_EQ(4, vp_1.voice_frame_count());
2733 EXPECT_TRUE(engine_.UnregisterProcessor(0,
2734 &vp_1,
2735 cricket::MPD_RX));
2736
2737 // The following tests test that FindChannelNumFromSsrc is doing
2738 // what we expect.
2739 // pick an invalid ssrc and make sure we can't register
2740 EXPECT_FALSE(engine_.RegisterProcessor(99,
2741 &vp_1,
2742 cricket::MPD_RX));
2743 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2744 EXPECT_TRUE(engine_.RegisterProcessor(1,
2745 &vp_1,
2746 cricket::MPD_RX));
2747 EXPECT_TRUE(engine_.UnregisterProcessor(1,
2748 &vp_1,
2749 cricket::MPD_RX));
2750 EXPECT_FALSE(engine_.RegisterProcessor(1,
2751 &vp_1,
2752 cricket::MPD_TX));
2753 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2754}
2755
2756TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2757 EXPECT_TRUE(SetupEngine());
2758
2759 bool ec_enabled;
2760 webrtc::EcModes ec_mode;
2761 bool ec_metrics_enabled;
2762 webrtc::AecmModes aecm_mode;
2763 bool cng_enabled;
2764 bool agc_enabled;
2765 webrtc::AgcModes agc_mode;
2766 webrtc::AgcConfig agc_config;
2767 bool ns_enabled;
2768 webrtc::NsModes ns_mode;
2769 bool highpass_filter_enabled;
2770 bool stereo_swapping_enabled;
2771 bool typing_detection_enabled;
2772 voe_.GetEcStatus(ec_enabled, ec_mode);
2773 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2774 voe_.GetAecmMode(aecm_mode, cng_enabled);
2775 voe_.GetAgcStatus(agc_enabled, agc_mode);
2776 voe_.GetAgcConfig(agc_config);
2777 voe_.GetNsStatus(ns_enabled, ns_mode);
2778 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2779 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2780 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2781 EXPECT_TRUE(ec_enabled);
2782 EXPECT_TRUE(ec_metrics_enabled);
2783 EXPECT_FALSE(cng_enabled);
2784 EXPECT_TRUE(agc_enabled);
2785 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2786 EXPECT_TRUE(ns_enabled);
2787 EXPECT_TRUE(highpass_filter_enabled);
2788 EXPECT_FALSE(stereo_swapping_enabled);
2789 EXPECT_TRUE(typing_detection_enabled);
2790 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2791 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2792
2793 // Nothing set, so all ignored.
2794 cricket::AudioOptions options;
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002795 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002796 voe_.GetEcStatus(ec_enabled, ec_mode);
2797 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2798 voe_.GetAecmMode(aecm_mode, cng_enabled);
2799 voe_.GetAgcStatus(agc_enabled, agc_mode);
2800 voe_.GetAgcConfig(agc_config);
2801 voe_.GetNsStatus(ns_enabled, ns_mode);
2802 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2803 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2804 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2805 EXPECT_TRUE(ec_enabled);
2806 EXPECT_TRUE(ec_metrics_enabled);
2807 EXPECT_FALSE(cng_enabled);
2808 EXPECT_TRUE(agc_enabled);
2809 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2810 EXPECT_TRUE(ns_enabled);
2811 EXPECT_TRUE(highpass_filter_enabled);
2812 EXPECT_FALSE(stereo_swapping_enabled);
2813 EXPECT_TRUE(typing_detection_enabled);
2814 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2815 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2816
2817 // Turn echo cancellation off
2818 options.echo_cancellation.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002819 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002820 voe_.GetEcStatus(ec_enabled, ec_mode);
2821 EXPECT_FALSE(ec_enabled);
2822
2823 // Turn echo cancellation back on, with settings, and make sure
2824 // nothing else changed.
2825 options.echo_cancellation.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002826 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002827 voe_.GetEcStatus(ec_enabled, ec_mode);
2828 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2829 voe_.GetAecmMode(aecm_mode, cng_enabled);
2830 voe_.GetAgcStatus(agc_enabled, agc_mode);
2831 voe_.GetAgcConfig(agc_config);
2832 voe_.GetNsStatus(ns_enabled, ns_mode);
2833 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2834 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2835 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2836 EXPECT_TRUE(ec_enabled);
2837 EXPECT_TRUE(ec_metrics_enabled);
2838 EXPECT_TRUE(agc_enabled);
2839 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2840 EXPECT_TRUE(ns_enabled);
2841 EXPECT_TRUE(highpass_filter_enabled);
2842 EXPECT_FALSE(stereo_swapping_enabled);
2843 EXPECT_TRUE(typing_detection_enabled);
2844 EXPECT_EQ(ec_mode, webrtc::kEcConference);
2845 EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2846
2847 // Turn off AGC
2848 options.auto_gain_control.Set(false);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002849 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002850 voe_.GetAgcStatus(agc_enabled, agc_mode);
2851 EXPECT_FALSE(agc_enabled);
2852
2853 // Turn AGC back on
2854 options.auto_gain_control.Set(true);
2855 options.adjust_agc_delta.Clear();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002856 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002857 voe_.GetAgcStatus(agc_enabled, agc_mode);
2858 EXPECT_TRUE(agc_enabled);
2859 voe_.GetAgcConfig(agc_config);
2860 EXPECT_EQ(0, agc_config.targetLeveldBOv);
2861
2862 // Turn off other options (and stereo swapping on).
2863 options.noise_suppression.Set(false);
2864 options.highpass_filter.Set(false);
2865 options.typing_detection.Set(false);
2866 options.stereo_swapping.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002867 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868 voe_.GetNsStatus(ns_enabled, ns_mode);
2869 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2870 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2871 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2872 EXPECT_FALSE(ns_enabled);
2873 EXPECT_FALSE(highpass_filter_enabled);
2874 EXPECT_FALSE(typing_detection_enabled);
2875 EXPECT_TRUE(stereo_swapping_enabled);
2876
2877 // Turn on "conference mode" to ensure it has no impact.
2878 options.conference_mode.Set(true);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002879 ASSERT_TRUE(engine_.SetOptions(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002880 voe_.GetEcStatus(ec_enabled, ec_mode);
2881 voe_.GetNsStatus(ns_enabled, ns_mode);
2882 EXPECT_TRUE(ec_enabled);
2883 EXPECT_EQ(webrtc::kEcConference, ec_mode);
2884 EXPECT_FALSE(ns_enabled);
2885 EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2886}
2887
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002888TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002889 EXPECT_TRUE(SetupEngine());
2890
2891 bool ec_enabled;
2892 webrtc::EcModes ec_mode;
2893 bool ec_metrics_enabled;
2894 bool agc_enabled;
2895 webrtc::AgcModes agc_mode;
2896 bool ns_enabled;
2897 webrtc::NsModes ns_mode;
2898 bool highpass_filter_enabled;
2899 bool stereo_swapping_enabled;
2900 bool typing_detection_enabled;
2901
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902 voe_.GetEcStatus(ec_enabled, ec_mode);
2903 voe_.GetEcMetricsStatus(ec_metrics_enabled);
2904 voe_.GetAgcStatus(agc_enabled, agc_mode);
2905 voe_.GetNsStatus(ns_enabled, ns_mode);
2906 highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2907 stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2908 voe_.GetTypingDetectionStatus(typing_detection_enabled);
2909 EXPECT_TRUE(ec_enabled);
2910 EXPECT_TRUE(agc_enabled);
2911 EXPECT_TRUE(ns_enabled);
2912 EXPECT_TRUE(highpass_filter_enabled);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002913 EXPECT_TRUE(typing_detection_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002914 EXPECT_FALSE(stereo_swapping_enabled);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002915}
2916
2917TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2918 webrtc::AgcConfig set_config = {0};
2919 set_config.targetLeveldBOv = 3;
2920 set_config.digitalCompressionGaindB = 9;
2921 set_config.limiterEnable = true;
2922 EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002923 EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002924
2925 webrtc::AgcConfig config = {0};
2926 EXPECT_EQ(0, voe_.GetAgcConfig(config));
2927 EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2928 EXPECT_EQ(set_config.digitalCompressionGaindB,
2929 config.digitalCompressionGaindB);
2930 EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2931}
2932
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002933TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2934 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002935 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002936 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002937 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002938 engine_.CreateChannel());
2939
2940 // Have to add a stream to make SetSend work.
2941 cricket::StreamParams stream1;
2942 stream1.ssrcs.push_back(1);
2943 channel1->AddSendStream(stream1);
2944 cricket::StreamParams stream2;
2945 stream2.ssrcs.push_back(2);
2946 channel2->AddSendStream(stream2);
2947
2948 // AEC and AGC and NS
2949 cricket::AudioOptions options_all;
2950 options_all.echo_cancellation.Set(true);
2951 options_all.auto_gain_control.Set(true);
2952 options_all.noise_suppression.Set(true);
2953
2954 ASSERT_TRUE(channel1->SetOptions(options_all));
2955 cricket::AudioOptions expected_options = options_all;
2956 cricket::AudioOptions actual_options;
2957 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2958 EXPECT_EQ(expected_options, actual_options);
2959 ASSERT_TRUE(channel2->SetOptions(options_all));
2960 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2961 EXPECT_EQ(expected_options, actual_options);
2962
2963 // unset NS
2964 cricket::AudioOptions options_no_ns;
2965 options_no_ns.noise_suppression.Set(false);
2966 ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2967
2968 expected_options.echo_cancellation.Set(true);
2969 expected_options.auto_gain_control.Set(true);
2970 expected_options.noise_suppression.Set(false);
2971 ASSERT_TRUE(channel1->GetOptions(&actual_options));
2972 EXPECT_EQ(expected_options, actual_options);
2973
2974 // unset AGC
2975 cricket::AudioOptions options_no_agc;
2976 options_no_agc.auto_gain_control.Set(false);
2977 ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2978
2979 expected_options.echo_cancellation.Set(true);
2980 expected_options.auto_gain_control.Set(false);
2981 expected_options.noise_suppression.Set(true);
2982 ASSERT_TRUE(channel2->GetOptions(&actual_options));
2983 EXPECT_EQ(expected_options, actual_options);
2984
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00002985 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002986 bool ec_enabled;
2987 webrtc::EcModes ec_mode;
2988 bool agc_enabled;
2989 webrtc::AgcModes agc_mode;
2990 bool ns_enabled;
2991 webrtc::NsModes ns_mode;
2992 voe_.GetEcStatus(ec_enabled, ec_mode);
2993 voe_.GetAgcStatus(agc_enabled, agc_mode);
2994 voe_.GetNsStatus(ns_enabled, ns_mode);
2995 EXPECT_TRUE(ec_enabled);
2996 EXPECT_TRUE(agc_enabled);
2997 EXPECT_TRUE(ns_enabled);
2998
2999 channel1->SetSend(cricket::SEND_MICROPHONE);
3000 voe_.GetEcStatus(ec_enabled, ec_mode);
3001 voe_.GetAgcStatus(agc_enabled, agc_mode);
3002 voe_.GetNsStatus(ns_enabled, ns_mode);
3003 EXPECT_TRUE(ec_enabled);
3004 EXPECT_TRUE(agc_enabled);
3005 EXPECT_FALSE(ns_enabled);
3006
3007 channel1->SetSend(cricket::SEND_NOTHING);
3008 voe_.GetEcStatus(ec_enabled, ec_mode);
3009 voe_.GetAgcStatus(agc_enabled, agc_mode);
3010 voe_.GetNsStatus(ns_enabled, ns_mode);
3011 EXPECT_TRUE(ec_enabled);
3012 EXPECT_TRUE(agc_enabled);
3013 EXPECT_TRUE(ns_enabled);
3014
3015 channel2->SetSend(cricket::SEND_MICROPHONE);
3016 voe_.GetEcStatus(ec_enabled, ec_mode);
3017 voe_.GetAgcStatus(agc_enabled, agc_mode);
3018 voe_.GetNsStatus(ns_enabled, ns_mode);
3019 EXPECT_TRUE(ec_enabled);
3020 EXPECT_FALSE(agc_enabled);
3021 EXPECT_TRUE(ns_enabled);
3022
3023 channel2->SetSend(cricket::SEND_NOTHING);
3024 voe_.GetEcStatus(ec_enabled, ec_mode);
3025 voe_.GetAgcStatus(agc_enabled, agc_mode);
3026 voe_.GetNsStatus(ns_enabled, ns_mode);
3027 EXPECT_TRUE(ec_enabled);
3028 EXPECT_TRUE(agc_enabled);
3029 EXPECT_TRUE(ns_enabled);
3030
3031 // Make sure settings take effect while we are sending.
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003032 ASSERT_TRUE(engine_.SetOptions(options_all));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003033 cricket::AudioOptions options_no_agc_nor_ns;
3034 options_no_agc_nor_ns.auto_gain_control.Set(false);
3035 options_no_agc_nor_ns.noise_suppression.Set(false);
3036 channel2->SetSend(cricket::SEND_MICROPHONE);
3037 channel2->SetOptions(options_no_agc_nor_ns);
3038
3039 expected_options.echo_cancellation.Set(true);
3040 expected_options.auto_gain_control.Set(false);
3041 expected_options.noise_suppression.Set(false);
3042 ASSERT_TRUE(channel2->GetOptions(&actual_options));
3043 EXPECT_EQ(expected_options, actual_options);
3044 voe_.GetEcStatus(ec_enabled, ec_mode);
3045 voe_.GetAgcStatus(agc_enabled, agc_mode);
3046 voe_.GetNsStatus(ns_enabled, ns_mode);
3047 EXPECT_TRUE(ec_enabled);
3048 EXPECT_FALSE(agc_enabled);
3049 EXPECT_FALSE(ns_enabled);
3050}
3051
wu@webrtc.orgde305012013-10-31 15:40:38 +00003052// This test verifies DSCP settings are properly applied on voice media channel.
3053TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
3054 EXPECT_TRUE(SetupEngine());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003055 rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003056 engine_.CreateChannel());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003057 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
wu@webrtc.orgde305012013-10-31 15:40:38 +00003058 new cricket::FakeNetworkInterface);
3059 channel->SetInterface(network_interface.get());
3060 cricket::AudioOptions options;
3061 options.dscp.Set(true);
3062 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003063 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003064 // Verify previous value is not modified if dscp option is not set.
3065 cricket::AudioOptions options1;
3066 EXPECT_TRUE(channel->SetOptions(options1));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003067 EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003068 options.dscp.Set(false);
3069 EXPECT_TRUE(channel->SetOptions(options));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003070 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
wu@webrtc.orgde305012013-10-31 15:40:38 +00003071}
3072
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00003073TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
3074 cricket::WebRtcVoiceEngine engine;
3075 cricket::AudioOptions options = engine.GetOptions();
3076 // The default options should have at least a few things set. We purposefully
3077 // don't check the option values here, though.
3078 EXPECT_TRUE(options.echo_cancellation.IsSet());
3079 EXPECT_TRUE(options.auto_gain_control.IsSet());
3080 EXPECT_TRUE(options.noise_suppression.IsSet());
3081}
3082
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003083// Test that GetReceiveChannelNum returns the default channel for the first
3084// recv stream in 1-1 calls.
3085TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
3086 EXPECT_TRUE(SetupEngine());
3087 cricket::WebRtcVoiceMediaChannel* media_channel =
3088 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3089 // Test that GetChannelNum returns the default channel if the SSRC is unknown.
3090 EXPECT_EQ(media_channel->voe_channel(),
3091 media_channel->GetReceiveChannelNum(0));
3092 cricket::StreamParams stream;
3093 stream.ssrcs.push_back(kSsrc2);
3094 EXPECT_TRUE(channel_->AddRecvStream(stream));
3095 EXPECT_EQ(media_channel->voe_channel(),
3096 media_channel->GetReceiveChannelNum(kSsrc2));
3097}
3098
3099// Test that GetReceiveChannelNum doesn't return the default channel for the
3100// first recv stream in conference calls.
3101TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
3102 EXPECT_TRUE(SetupEngine());
3103 EXPECT_TRUE(channel_->SetOptions(options_conference_));
3104 cricket::StreamParams stream;
3105 stream.ssrcs.push_back(kSsrc2);
3106 EXPECT_TRUE(channel_->AddRecvStream(stream));
3107 cricket::WebRtcVoiceMediaChannel* media_channel =
3108 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3109 EXPECT_LT(media_channel->voe_channel(),
3110 media_channel->GetReceiveChannelNum(kSsrc2));
3111}
3112
3113TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
3114 EXPECT_TRUE(SetupEngine());
3115 double left, right;
3116 EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
3117 EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
3118 EXPECT_DOUBLE_EQ(1, left);
3119 EXPECT_DOUBLE_EQ(2, right);
3120
3121 EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
3122 cricket::StreamParams stream;
3123 stream.ssrcs.push_back(kSsrc2);
3124 EXPECT_TRUE(channel_->AddRecvStream(stream));
3125
3126 EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
3127 EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
3128 EXPECT_DOUBLE_EQ(2, left);
3129 EXPECT_DOUBLE_EQ(1, right);
3130}
3131
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003132// Tests for the actual WebRtc VoE library.
3133
3134// Tests that the library initializes and shuts down properly.
3135TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3136 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003137 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003138 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3139 EXPECT_TRUE(channel != NULL);
3140 delete channel;
3141 engine.Terminate();
3142
3143 // Reinit to catch regression where VoiceEngineObserver reference is lost
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003144 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003145 engine.Terminate();
3146}
3147
3148// Tests that the logging from the library is cleartext.
3149TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
3150 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003151 rtc::scoped_ptr<rtc::MemoryStream> stream(
3152 new rtc::MemoryStream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003153 size_t size = 0;
3154 bool cleartext = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003155 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3156 engine.SetLogging(rtc::LS_VERBOSE, "");
3157 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003158 EXPECT_TRUE(stream->GetSize(&size));
3159 EXPECT_GT(size, 0U);
3160 engine.Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003161 rtc::LogMessage::RemoveLogToStream(stream.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003162 const char* buf = stream->GetBuffer();
3163 for (size_t i = 0; i < size && cleartext; ++i) {
3164 int ch = static_cast<int>(buf[i]);
3165 ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
3166 << std::hex << ch;
3167 cleartext = (isprint(ch) || isspace(ch));
3168 }
3169 EXPECT_TRUE(cleartext);
3170}
3171
3172// Tests we do not see any references to a monitor thread being spun up
3173// when initiating the engine.
3174TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
3175 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003176 rtc::scoped_ptr<rtc::MemoryStream> stream(
3177 new rtc::MemoryStream);
3178 rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3179 engine.SetLogging(rtc::LS_VERBOSE, "");
3180 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003181 engine.Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003182 rtc::LogMessage::RemoveLogToStream(stream.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003183
3184 size_t size = 0;
3185 EXPECT_TRUE(stream->GetSize(&size));
3186 EXPECT_GT(size, 0U);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003187 const std::string logs(stream->GetBuffer(), size);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003188 EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
3189}
3190
3191// Tests that the library is configured with the codecs we want.
3192TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3193 cricket::WebRtcVoiceEngine engine;
3194 // Check codecs by name.
3195 EXPECT_TRUE(engine.FindCodec(
3196 cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3197 EXPECT_TRUE(engine.FindCodec(
3198 cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3199 EXPECT_TRUE(engine.FindCodec(
3200 cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3201 // Check that name matching is case-insensitive.
3202 EXPECT_TRUE(engine.FindCodec(
3203 cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3204 EXPECT_TRUE(engine.FindCodec(
3205 cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3206 EXPECT_TRUE(engine.FindCodec(
3207 cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3208 EXPECT_TRUE(engine.FindCodec(
3209 cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3210 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgdced5d72014-11-06 15:27:43 +00003211 cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003212 EXPECT_TRUE(engine.FindCodec(
3213 cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003214 EXPECT_TRUE(engine.FindCodec(
3215 cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3216 EXPECT_TRUE(engine.FindCodec(
3217 cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3218 EXPECT_TRUE(engine.FindCodec(
3219 cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3220 EXPECT_TRUE(engine.FindCodec(
3221 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3222 // Check codecs with an id by id.
3223 EXPECT_TRUE(engine.FindCodec(
3224 cricket::AudioCodec(0, "", 8000, 0, 1, 0))); // PCMU
3225 EXPECT_TRUE(engine.FindCodec(
3226 cricket::AudioCodec(8, "", 8000, 0, 1, 0))); // PCMA
3227 EXPECT_TRUE(engine.FindCodec(
henrik.lundin@webrtc.orgdced5d72014-11-06 15:27:43 +00003228 cricket::AudioCodec(9, "", 16000, 0, 1, 0))); // G722
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003229 EXPECT_TRUE(engine.FindCodec(
3230 cricket::AudioCodec(13, "", 8000, 0, 1, 0))); // CN
3231 // Check sample/bitrate matching.
3232 EXPECT_TRUE(engine.FindCodec(
3233 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3234 // Check that bad codecs fail.
3235 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3236 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3237 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3238 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3239 EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003240 // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3241 for (std::vector<cricket::AudioCodec>::const_iterator it =
3242 engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3243 if (it->name == "CN" && it->clockrate == 16000) {
3244 EXPECT_EQ(105, it->id);
3245 } else if (it->name == "CN" && it->clockrate == 32000) {
3246 EXPECT_EQ(106, it->id);
3247 } else if (it->name == "ISAC" && it->clockrate == 16000) {
3248 EXPECT_EQ(103, it->id);
3249 } else if (it->name == "ISAC" && it->clockrate == 32000) {
3250 EXPECT_EQ(104, it->id);
henrik.lundin@webrtc.orgdced5d72014-11-06 15:27:43 +00003251 } else if (it->name == "G722" && it->clockrate == 16000) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003252 EXPECT_EQ(9, it->id);
3253 } else if (it->name == "telephone-event") {
3254 EXPECT_EQ(126, it->id);
3255 } else if (it->name == "red") {
3256 EXPECT_EQ(127, it->id);
3257 } else if (it->name == "opus") {
3258 EXPECT_EQ(111, it->id);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003259 ASSERT_TRUE(it->params.find("minptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003260 EXPECT_EQ("10", it->params.find("minptime")->second);
wu@webrtc.org9caf2762013-12-11 18:25:07 +00003261 ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003262 EXPECT_EQ("60", it->params.find("maxptime")->second);
3263 }
3264 }
3265
3266 engine.Terminate();
3267}
3268
3269// Tests that VoE supports at least 32 channels
3270TEST(WebRtcVoiceEngineTest, Has32Channels) {
3271 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003272 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003273
3274 cricket::VoiceMediaChannel* channels[32];
3275 int num_channels = 0;
3276
3277 while (num_channels < ARRAY_SIZE(channels)) {
3278 cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3279 if (!channel)
3280 break;
3281
3282 channels[num_channels++] = channel;
3283 }
3284
3285 int expected = ARRAY_SIZE(channels);
3286 EXPECT_EQ(expected, num_channels);
3287
3288 while (num_channels > 0) {
3289 delete channels[--num_channels];
3290 }
3291
3292 engine.Terminate();
3293}
3294
3295// Test that we set our preferred codecs properly.
3296TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3297 cricket::WebRtcVoiceEngine engine;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003298 EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003299 cricket::WebRtcVoiceMediaChannel channel(&engine);
3300 EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3301}
3302
3303#ifdef WIN32
3304// Test our workarounds to WebRtc VoE' munging of the coinit count
3305TEST(WebRtcVoiceEngineTest, CoInitialize) {
3306 cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3307
3308 // Initial refcount should be 0.
3309 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3310
3311 // Engine should start even with COM already inited.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003312 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003313 engine->Terminate();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003314 EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003315 engine->Terminate();
3316
3317 // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3318 EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3319 // Decrement refcount to (hopefully) 0.
3320 CoUninitialize();
3321 CoUninitialize();
3322 delete engine;
3323
3324 // Ensure refcount is 0.
3325 EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3326 CoUninitialize();
3327}
3328#endif
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003329
3330TEST_F(WebRtcVoiceEngineTestFake, ChangeCombinedAudioVideoBweOption) {
3331 // Test that changing the combined_audio_video_bwe option results in the
3332 // expected state changes in VoiceEngine.
3333 cricket::ViEWrapper vie;
3334 const int kVieCh = 667;
3335
3336 EXPECT_TRUE(SetupEngine());
3337 cricket::WebRtcVoiceMediaChannel* media_channel =
3338 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3339 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(),
3340 kVieCh));
3341 EXPECT_TRUE(media_channel->AddRecvStream(
3342 cricket::StreamParams::CreateLegacy(2)));
3343 int recv_ch = voe_.GetLastChannel();
3344
3345 // Combined BWE should not be set up yet.
3346 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3347 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3348
3349 // Enable combined BWE option - now it should be set up.
3350 cricket::AudioOptions options;
3351 options.combined_audio_video_bwe.Set(true);
3352 EXPECT_TRUE(media_channel->SetOptions(options));
3353 EXPECT_EQ(vie.network(), voe_.GetViENetwork(recv_ch));
3354 EXPECT_EQ(kVieCh, voe_.GetVideoChannel(recv_ch));
3355
3356 // Disable combined BWE option - should be disabled again.
3357 options.combined_audio_video_bwe.Set(false);
3358 EXPECT_TRUE(media_channel->SetOptions(options));
3359 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3360 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3361
3362 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3363}
3364
3365TEST_F(WebRtcVoiceEngineTestFake, SetupSharedBandwidthEstimation) {
3366 // Test that calling SetupSharedBandwidthEstimation() on the voice media
3367 // channel results in the expected state changes in VoiceEngine.
3368 cricket::ViEWrapper vie1;
3369 cricket::ViEWrapper vie2;
3370 const int kVieCh1 = 667;
3371 const int kVieCh2 = 70;
3372
3373 EXPECT_TRUE(SetupEngine());
3374 cricket::WebRtcVoiceMediaChannel* media_channel =
3375 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3376 cricket::AudioOptions options;
3377 options.combined_audio_video_bwe.Set(true);
3378 EXPECT_TRUE(media_channel->SetOptions(options));
3379 EXPECT_TRUE(media_channel->AddRecvStream(
3380 cricket::StreamParams::CreateLegacy(2)));
3381 int recv_ch = voe_.GetLastChannel();
3382
3383 // Combined BWE should not be set up yet.
3384 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3385 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3386
3387 // Register - should be enabled.
3388 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie1.engine(),
3389 kVieCh1));
3390 EXPECT_EQ(vie1.network(), voe_.GetViENetwork(recv_ch));
3391 EXPECT_EQ(kVieCh1, voe_.GetVideoChannel(recv_ch));
3392
3393 // Re-register - should still be enabled.
3394 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie2.engine(),
3395 kVieCh2));
3396 EXPECT_EQ(vie2.network(), voe_.GetViENetwork(recv_ch));
3397 EXPECT_EQ(kVieCh2, voe_.GetVideoChannel(recv_ch));
3398
3399 // Unregister - should be disabled again.
3400 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3401 EXPECT_EQ(NULL, voe_.GetViENetwork(recv_ch));
3402 EXPECT_EQ(-1, voe_.GetVideoChannel(recv_ch));
3403}
3404
3405TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
3406 // Test that adding receive streams after enabling combined bandwidth
3407 // estimation will correctly configure each channel.
3408 cricket::ViEWrapper vie;
3409 const int kVieCh = 667;
3410
3411 EXPECT_TRUE(SetupEngine());
3412 cricket::WebRtcVoiceMediaChannel* media_channel =
3413 static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3414 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(vie.engine(),
3415 kVieCh));
3416 cricket::AudioOptions options;
3417 options.combined_audio_video_bwe.Set(true);
3418 EXPECT_TRUE(media_channel->SetOptions(options));
3419
3420 static const uint32 kSsrcs[] = {1, 2, 3, 4};
3421 int voe_channels[ARRAY_SIZE(kSsrcs)] = {0};
3422 for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
3423 EXPECT_TRUE(media_channel->AddRecvStream(
3424 cricket::StreamParams::CreateLegacy(kSsrcs[i])));
3425 int recv_ch = media_channel->GetReceiveChannelNum(kSsrcs[i]);
3426 EXPECT_NE(-1, recv_ch);
3427 voe_channels[i] = recv_ch;
3428 EXPECT_EQ(vie.network(), voe_.GetViENetwork(recv_ch));
3429 EXPECT_EQ(kVieCh, voe_.GetVideoChannel(recv_ch));
3430 }
3431
3432 EXPECT_TRUE(media_channel->SetupSharedBandwidthEstimation(NULL, -1));
3433
3434 for (unsigned int i = 0; i < ARRAY_SIZE(voe_channels); ++i) {
3435 EXPECT_EQ(NULL, voe_.GetViENetwork(voe_channels[i]));
3436 EXPECT_EQ(-1, voe_.GetVideoChannel(voe_channels[i]));
3437 }
3438}