~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/libjingle/talk/session/phone/webrtcvoiceengine_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2008 Google Inc. All Rights Reserved.
 
2
//
 
3
// Author: Justin Uberti (juberti@google.com)
 
4
 
 
5
#include "talk/base/byteorder.h"
 
6
#include "talk/base/gunit.h"
 
7
#include "talk/p2p/base/fakesession.h"
 
8
#include "talk/session/phone/channel.h"
 
9
#include "talk/session/phone/fakemediaengine.h"
 
10
#include "talk/session/phone/fakemediaprocessor.h"
 
11
#include "talk/session/phone/fakertp.h"
 
12
#include "talk/session/phone/fakewebrtcvoiceengine.h"
 
13
#include "talk/session/phone/webrtcvoiceengine.h"
 
14
 
 
15
// Tests for the WebRtcVoiceEngine/VoiceChannel code.
 
16
 
 
17
static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
 
18
static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
 
19
static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
 
20
static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
 
21
static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
 
22
static const cricket::AudioCodec
 
23
    kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
 
24
static const cricket::AudioCodec* const kAudioCodecs[] = {
 
25
    &kPcmuCodec, &kIsacCodec, &kRedCodec, &kCn8000Codec, &kCn16000Codec,
 
26
    &kTelephoneEventCodec,
 
27
};
 
28
const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
 
29
static uint32 kSsrc1 = 0x99;
 
30
 
 
31
class FakeVoEWrapper : public cricket::VoEWrapper {
 
32
 public:
 
33
  explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
 
34
      : cricket::VoEWrapper(engine,  // processing
 
35
                            engine,  // base
 
36
                            engine,  // codec
 
37
                            engine,  // dtmf
 
38
                            engine,  // file
 
39
                            engine,  // hw
 
40
                            engine,  // media
 
41
                            engine,  // neteq
 
42
                            engine,  // network
 
43
                            engine,  // rtp
 
44
                            engine,  // sync
 
45
                            engine) {  // volume
 
46
  }
 
47
};
 
48
 
 
49
class NullVoETraceWrapper : public cricket::VoETraceWrapper {
 
50
 public:
 
51
  virtual int SetTraceFilter(const unsigned int filter) {
 
52
    return 0;
 
53
  }
 
54
  virtual int SetTraceFile(const char* fileNameUTF8) {
 
55
    return 0;
 
56
  }
 
57
  virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
 
58
    return 0;
 
59
  }
 
60
};
 
61
 
 
62
class WebRtcVoiceEngineTestFake : public testing::Test {
 
63
 public:
 
64
  class ChannelErrorListener : public sigslot::has_slots<> {
 
65
   public:
 
66
    explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
 
67
        : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
 
68
      ASSERT(channel != NULL);
 
69
      channel->SignalMediaError.connect(
 
70
          this, &ChannelErrorListener::OnVoiceChannelError);
 
71
    }
 
72
    void OnVoiceChannelError(uint32 ssrc,
 
73
                             cricket::VoiceMediaChannel::Error error) {
 
74
      ssrc_ = ssrc;
 
75
      error_ = error;
 
76
    }
 
77
    void Reset() {
 
78
      ssrc_ = 0;
 
79
      error_ = cricket::VoiceMediaChannel::ERROR_NONE;
 
80
    }
 
81
    uint32 ssrc() const {
 
82
      return ssrc_;
 
83
    }
 
84
    cricket::VoiceMediaChannel::Error error() const {
 
85
      return error_;
 
86
    }
 
87
 
 
88
   private:
 
89
    uint32 ssrc_;
 
90
    cricket::VoiceMediaChannel::Error error_;
 
91
  };
 
92
 
 
93
  WebRtcVoiceEngineTestFake()
 
94
      : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
 
95
        voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
 
96
        engine_(new FakeVoEWrapper(&voe_),
 
97
                new FakeVoEWrapper(&voe_sc_),
 
98
                new NullVoETraceWrapper()),
 
99
        channel_(NULL), soundclip_(NULL) {
 
100
  }
 
101
  bool SetupEngine() {
 
102
    bool result = engine_.Init();
 
103
    if (result) {
 
104
      channel_ = engine_.CreateChannel();
 
105
      result = (channel_ != NULL);
 
106
    }
 
107
    if (result) {
 
108
      result = channel_->AddSendStream(
 
109
          cricket::StreamParams::CreateLegacy(kSsrc1));
 
110
    }
 
111
    return result;
 
112
  }
 
113
  void DeliverPacket(const void* data, int len) {
 
114
    talk_base::Buffer packet(data, len);
 
115
    channel_->OnPacketReceived(&packet);
 
116
  }
 
117
  virtual void TearDown() {
 
118
    delete soundclip_;
 
119
    delete channel_;
 
120
    engine_.Terminate();
 
121
  }
 
122
 
 
123
 protected:
 
124
  cricket::FakeWebRtcVoiceEngine voe_;
 
125
  cricket::FakeWebRtcVoiceEngine voe_sc_;
 
126
  cricket::WebRtcVoiceEngine engine_;
 
127
  cricket::VoiceMediaChannel* channel_;
 
128
  cricket::SoundclipMedia* soundclip_;
 
129
};
 
130
 
 
131
// Tests that our stub library "works".
 
132
TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
 
133
  EXPECT_FALSE(voe_.IsInited());
 
134
  EXPECT_FALSE(voe_sc_.IsInited());
 
135
  EXPECT_TRUE(engine_.Init());
 
136
  EXPECT_TRUE(voe_.IsInited());
 
137
  EXPECT_TRUE(voe_sc_.IsInited());
 
138
  engine_.Terminate();
 
139
  EXPECT_FALSE(voe_.IsInited());
 
140
  EXPECT_FALSE(voe_sc_.IsInited());
 
141
}
 
142
 
 
143
// Tests that we can create and destroy a channel.
 
144
TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
 
145
  EXPECT_TRUE(engine_.Init());
 
146
  channel_ = engine_.CreateChannel();
 
147
  EXPECT_TRUE(channel_ != NULL);
 
148
}
 
149
 
 
150
// Tests that we properly handle failures in CreateChannel.
 
151
TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
 
152
  voe_.set_fail_create_channel(true);
 
153
  EXPECT_TRUE(engine_.Init());
 
154
  channel_ = engine_.CreateChannel();
 
155
  EXPECT_TRUE(channel_ == NULL);
 
156
}
 
157
 
 
158
// Tests that the list of supported codecs is created properly and ordered
 
159
// correctly
 
160
TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
 
161
  const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
 
162
  ASSERT_FALSE(codecs.empty());
 
163
  EXPECT_EQ("ISAC", codecs[0].name);
 
164
  EXPECT_EQ(16000, codecs[0].clockrate);
 
165
  EXPECT_EQ(0, codecs[0].bitrate);
 
166
  int pref = codecs[0].preference;
 
167
  for (size_t i = 1; i < codecs.size(); ++i) {
 
168
    EXPECT_GT(pref, codecs[i].preference);
 
169
    pref = codecs[i].preference;
 
170
  }
 
171
}
 
172
 
 
173
// Tests that we can find codecs by name or id, and that we interpret the
 
174
// clockrate and bitrate fields properly.
 
175
TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
 
176
  cricket::AudioCodec codec;
 
177
  webrtc::CodecInst codec_inst;
 
178
  // Find PCMU with explicit clockrate and bitrate.
 
179
  EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
 
180
  // Find ISAC with explicit clockrate and 0 bitrate.
 
181
  EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
 
182
  // Find telephone-event with explicit clockrate and 0 bitrate.
 
183
  EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
 
184
  // Find ISAC with a different payload id.
 
185
  codec = kIsacCodec;
 
186
  codec.id = 127;
 
187
  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
 
188
  EXPECT_EQ(codec.id, codec_inst.pltype);
 
189
  // Find PCMU with a 0 clockrate.
 
190
  codec = kPcmuCodec;
 
191
  codec.clockrate = 0;
 
192
  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
 
193
  EXPECT_EQ(codec.id, codec_inst.pltype);
 
194
  EXPECT_EQ(8000, codec_inst.plfreq);
 
195
  // Find PCMU with a 0 bitrate.
 
196
  codec = kPcmuCodec;
 
197
  codec.bitrate = 0;
 
198
  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
 
199
  EXPECT_EQ(codec.id, codec_inst.pltype);
 
200
  EXPECT_EQ(64000, codec_inst.rate);
 
201
  // Find ISAC with an explicit bitrate.
 
202
  codec = kIsacCodec;
 
203
  codec.bitrate = 32000;
 
204
  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
 
205
  EXPECT_EQ(codec.id, codec_inst.pltype);
 
206
  EXPECT_EQ(32000, codec_inst.rate);
 
207
}
 
208
 
 
209
// Test that we set our inbound codecs properly, including changing PT.
 
210
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
 
211
  EXPECT_TRUE(SetupEngine());
 
212
  int channel_num = voe_.GetLastChannel();
 
213
  std::vector<cricket::AudioCodec> codecs;
 
214
  codecs.push_back(kIsacCodec);
 
215
  codecs.push_back(kPcmuCodec);
 
216
  codecs.push_back(kTelephoneEventCodec);
 
217
  codecs[0].id = 106;  // collide with existing telephone-event
 
218
  codecs[2].id = 126;
 
219
  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
 
220
  webrtc::CodecInst gcodec;
 
221
  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
 
222
  gcodec.plfreq = 16000;
 
223
  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
 
224
  EXPECT_EQ(106, gcodec.pltype);
 
225
  EXPECT_STREQ("ISAC", gcodec.plname);
 
226
  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
 
227
      "telephone-event");
 
228
  gcodec.plfreq = 8000;
 
229
  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
 
230
  EXPECT_EQ(126, gcodec.pltype);
 
231
  EXPECT_STREQ("telephone-event", gcodec.plname);
 
232
}
 
233
 
 
234
// Test that we fail to set an unknown inbound codec.
 
235
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
 
236
  EXPECT_TRUE(SetupEngine());
 
237
  std::vector<cricket::AudioCodec> codecs;
 
238
  codecs.push_back(kIsacCodec);
 
239
  codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
 
240
  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
 
241
}
 
242
 
 
243
// Test that we fail if we have duplicate types in the inbound list.
 
244
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
 
245
  EXPECT_TRUE(SetupEngine());
 
246
  std::vector<cricket::AudioCodec> codecs;
 
247
  codecs.push_back(kIsacCodec);
 
248
  codecs.push_back(kCn16000Codec);
 
249
  codecs[1].id = kIsacCodec.id;
 
250
  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
 
251
}
 
252
 
 
253
// Test that changes to recv codecs are applied to all streams.
 
254
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
 
255
  EXPECT_TRUE(SetupEngine());
 
256
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
257
  std::vector<cricket::AudioCodec> codecs;
 
258
  codecs.push_back(kIsacCodec);
 
259
  codecs.push_back(kPcmuCodec);
 
260
  codecs.push_back(kTelephoneEventCodec);
 
261
  codecs[0].id = 106;  // collide with existing telephone-event
 
262
  codecs[2].id = 126;
 
263
  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
 
264
  EXPECT_TRUE(channel_->AddRecvStream(
 
265
      cricket::StreamParams::CreateLegacy(kSsrc1)));
 
266
  int channel_num2 = voe_.GetLastChannel();
 
267
  webrtc::CodecInst gcodec;
 
268
  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
 
269
  gcodec.plfreq = 16000;
 
270
  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
 
271
  EXPECT_EQ(106, gcodec.pltype);
 
272
  EXPECT_STREQ("ISAC", gcodec.plname);
 
273
  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
 
274
      "telephone-event");
 
275
  gcodec.plfreq = 8000;
 
276
  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
 
277
  EXPECT_EQ(126, gcodec.pltype);
 
278
  EXPECT_STREQ("telephone-event", gcodec.plname);
 
279
}
 
280
 
 
281
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
 
282
  EXPECT_TRUE(SetupEngine());
 
283
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
284
  std::vector<cricket::AudioCodec> codecs;
 
285
  codecs.push_back(kIsacCodec);
 
286
  codecs[0].id = 106;  // collide with existing telephone-event
 
287
 
 
288
  EXPECT_TRUE(channel_->AddRecvStream(
 
289
      cricket::StreamParams::CreateLegacy(kSsrc1)));
 
290
  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
 
291
 
 
292
  int channel_num2 = voe_.GetLastChannel();
 
293
  webrtc::CodecInst gcodec;
 
294
  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
 
295
  gcodec.plfreq = 16000;
 
296
  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
 
297
  EXPECT_EQ(106, gcodec.pltype);
 
298
  EXPECT_STREQ("ISAC", gcodec.plname);
 
299
}
 
300
 
 
301
// Test that we apply codecs properly.
 
302
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
 
303
  EXPECT_TRUE(SetupEngine());
 
304
  int channel_num = voe_.GetLastChannel();
 
305
  std::vector<cricket::AudioCodec> codecs;
 
306
  codecs.push_back(kIsacCodec);
 
307
  codecs.push_back(kPcmuCodec);
 
308
  codecs.push_back(kRedCodec);
 
309
  codecs[0].id = 96;
 
310
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
311
  webrtc::CodecInst gcodec;
 
312
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
313
  EXPECT_EQ(96, gcodec.pltype);
 
314
  EXPECT_STREQ("ISAC", gcodec.plname);
 
315
  EXPECT_FALSE(voe_.GetVAD(channel_num));
 
316
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
317
  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
 
318
  EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
 
319
  EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
 
320
}
 
321
 
 
322
// Test that we handle various ways of specifying bitrate.
 
323
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
 
324
  EXPECT_TRUE(SetupEngine());
 
325
  int channel_num = voe_.GetLastChannel();
 
326
  std::vector<cricket::AudioCodec> codecs;
 
327
  codecs.push_back(kIsacCodec);  // bitrate == 32000
 
328
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
329
  webrtc::CodecInst gcodec;
 
330
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
331
  EXPECT_EQ(103, gcodec.pltype);
 
332
  EXPECT_STREQ("ISAC", gcodec.plname);
 
333
  EXPECT_EQ(32000, gcodec.rate);
 
334
  codecs[0].bitrate = 0;         // bitrate == default
 
335
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
336
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
337
  EXPECT_EQ(103, gcodec.pltype);
 
338
  EXPECT_STREQ("ISAC", gcodec.plname);
 
339
  EXPECT_EQ(-1, gcodec.rate);
 
340
  codecs[0].bitrate = 28000;     // bitrate == 28000
 
341
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
342
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
343
  EXPECT_EQ(103, gcodec.pltype);
 
344
  EXPECT_STREQ("ISAC", gcodec.plname);
 
345
  EXPECT_EQ(28000, gcodec.rate);
 
346
  codecs[0] = kPcmuCodec;        // bitrate == 64000
 
347
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
348
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
349
  EXPECT_EQ(0, gcodec.pltype);
 
350
  EXPECT_STREQ("PCMU", gcodec.plname);
 
351
  EXPECT_EQ(64000, gcodec.rate);
 
352
  codecs[0].bitrate = 0;         // bitrate == default
 
353
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
354
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
355
  EXPECT_EQ(0, gcodec.pltype);
 
356
  EXPECT_STREQ("PCMU", gcodec.plname);
 
357
  EXPECT_EQ(64000, gcodec.rate);
 
358
}
 
359
 
 
360
// Test that we fall back to PCMU if no codecs are specified.
 
361
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
 
362
  EXPECT_TRUE(SetupEngine());
 
363
  int channel_num = voe_.GetLastChannel();
 
364
  std::vector<cricket::AudioCodec> codecs;
 
365
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
366
  webrtc::CodecInst gcodec;
 
367
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
368
  EXPECT_EQ(0, gcodec.pltype);
 
369
  EXPECT_STREQ("PCMU", gcodec.plname);
 
370
  EXPECT_FALSE(voe_.GetVAD(channel_num));
 
371
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
372
  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
 
373
  EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
 
374
  EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
 
375
}
 
376
 
 
377
// Test that we set VAD and DTMF types correctly.
 
378
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMF) {
 
379
  EXPECT_TRUE(SetupEngine());
 
380
  int channel_num = voe_.GetLastChannel();
 
381
  std::vector<cricket::AudioCodec> codecs;
 
382
  codecs.push_back(kIsacCodec);
 
383
  codecs.push_back(kPcmuCodec);
 
384
  // TODO: cn 32000
 
385
  codecs.push_back(kCn16000Codec);
 
386
  codecs.push_back(kCn8000Codec);
 
387
  codecs.push_back(kTelephoneEventCodec);
 
388
  codecs.push_back(kRedCodec);
 
389
  codecs[0].id = 96;
 
390
  codecs[2].id = 97;  // wideband CN
 
391
  codecs[4].id = 98;  // DTMF
 
392
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
393
  webrtc::CodecInst gcodec;
 
394
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
395
  EXPECT_EQ(96, gcodec.pltype);
 
396
  EXPECT_STREQ("ISAC", gcodec.plname);
 
397
  EXPECT_TRUE(voe_.GetVAD(channel_num));
 
398
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
399
  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
 
400
  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
 
401
  EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
 
402
}
 
403
 
 
404
// Test that we perform case-insensitive matching of codec names.
 
405
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
 
406
  EXPECT_TRUE(SetupEngine());
 
407
  int channel_num = voe_.GetLastChannel();
 
408
  std::vector<cricket::AudioCodec> codecs;
 
409
  codecs.push_back(kIsacCodec);
 
410
  codecs.push_back(kPcmuCodec);
 
411
  codecs.push_back(kCn16000Codec);
 
412
  codecs.push_back(kCn8000Codec);
 
413
  codecs.push_back(kTelephoneEventCodec);
 
414
  codecs.push_back(kRedCodec);
 
415
  codecs[0].name = "iSaC";
 
416
  codecs[0].id = 96;
 
417
  codecs[2].id = 97;  // wideband CN
 
418
  codecs[4].id = 98;  // DTMF
 
419
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
420
  webrtc::CodecInst gcodec;
 
421
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
422
  EXPECT_EQ(96, gcodec.pltype);
 
423
  EXPECT_STREQ("ISAC", gcodec.plname);
 
424
  EXPECT_TRUE(voe_.GetVAD(channel_num));
 
425
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
426
  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
 
427
  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
 
428
  EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
 
429
}
 
430
 
 
431
// Test that we set up FEC correctly.
 
432
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsRED) {
 
433
  EXPECT_TRUE(SetupEngine());
 
434
  int channel_num = voe_.GetLastChannel();
 
435
  std::vector<cricket::AudioCodec> codecs;
 
436
  codecs.push_back(kRedCodec);
 
437
  codecs.push_back(kIsacCodec);
 
438
  codecs.push_back(kPcmuCodec);
 
439
  codecs[0].id = 127;
 
440
  codecs[0].params[""] = "96/96";
 
441
  codecs[1].id = 96;
 
442
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
443
  webrtc::CodecInst gcodec;
 
444
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
445
  EXPECT_EQ(96, gcodec.pltype);
 
446
  EXPECT_STREQ("ISAC", gcodec.plname);
 
447
  EXPECT_TRUE(voe_.GetFEC(channel_num));
 
448
  EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
 
449
}
 
450
 
 
451
// Test that we set up FEC correctly if params are omitted.
 
452
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
 
453
  EXPECT_TRUE(SetupEngine());
 
454
  int channel_num = voe_.GetLastChannel();
 
455
  std::vector<cricket::AudioCodec> codecs;
 
456
  codecs.push_back(kRedCodec);
 
457
  codecs.push_back(kIsacCodec);
 
458
  codecs.push_back(kPcmuCodec);
 
459
  codecs[0].id = 127;
 
460
  codecs[1].id = 96;
 
461
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
462
  webrtc::CodecInst gcodec;
 
463
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
464
  EXPECT_EQ(96, gcodec.pltype);
 
465
  EXPECT_STREQ("ISAC", gcodec.plname);
 
466
  EXPECT_TRUE(voe_.GetFEC(channel_num));
 
467
  EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
 
468
}
 
469
 
 
470
// Test that we ignore RED if the parameters aren't named the way we expect.
 
471
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
 
472
  EXPECT_TRUE(SetupEngine());
 
473
  int channel_num = voe_.GetLastChannel();
 
474
  std::vector<cricket::AudioCodec> codecs;
 
475
  codecs.push_back(kRedCodec);
 
476
  codecs.push_back(kIsacCodec);
 
477
  codecs.push_back(kPcmuCodec);
 
478
  codecs[0].id = 127;
 
479
  codecs[0].params["ABC"] = "96/96";
 
480
  codecs[1].id = 96;
 
481
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
482
  webrtc::CodecInst gcodec;
 
483
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
484
  EXPECT_EQ(96, gcodec.pltype);
 
485
  EXPECT_STREQ("ISAC", gcodec.plname);
 
486
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
487
}
 
488
 
 
489
// Test that we ignore RED if it uses different primary/secondary encoding.
 
490
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
 
491
  EXPECT_TRUE(SetupEngine());
 
492
  int channel_num = voe_.GetLastChannel();
 
493
  std::vector<cricket::AudioCodec> codecs;
 
494
  codecs.push_back(kRedCodec);
 
495
  codecs.push_back(kIsacCodec);
 
496
  codecs.push_back(kPcmuCodec);
 
497
  codecs[0].id = 127;
 
498
  codecs[0].params[""] = "96/0";
 
499
  codecs[1].id = 96;
 
500
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
501
  webrtc::CodecInst gcodec;
 
502
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
503
  EXPECT_EQ(96, gcodec.pltype);
 
504
  EXPECT_STREQ("ISAC", gcodec.plname);
 
505
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
506
}
 
507
 
 
508
// Test that we ignore RED if it uses more than 2 encodings.
 
509
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
 
510
  EXPECT_TRUE(SetupEngine());
 
511
  int channel_num = voe_.GetLastChannel();
 
512
  std::vector<cricket::AudioCodec> codecs;
 
513
  codecs.push_back(kRedCodec);
 
514
  codecs.push_back(kIsacCodec);
 
515
  codecs.push_back(kPcmuCodec);
 
516
  codecs[0].id = 127;
 
517
  codecs[0].params[""] = "96/96/96";
 
518
  codecs[1].id = 96;
 
519
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
520
  webrtc::CodecInst gcodec;
 
521
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
522
  EXPECT_EQ(96, gcodec.pltype);
 
523
  EXPECT_STREQ("ISAC", gcodec.plname);
 
524
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
525
}
 
526
 
 
527
// Test that we ignore RED if it has bogus codec ids.
 
528
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
 
529
  EXPECT_TRUE(SetupEngine());
 
530
  int channel_num = voe_.GetLastChannel();
 
531
  std::vector<cricket::AudioCodec> codecs;
 
532
  codecs.push_back(kRedCodec);
 
533
  codecs.push_back(kIsacCodec);
 
534
  codecs.push_back(kPcmuCodec);
 
535
  codecs[0].id = 127;
 
536
  codecs[0].params[""] = "ABC/ABC";
 
537
  codecs[1].id = 96;
 
538
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
539
  webrtc::CodecInst gcodec;
 
540
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
541
  EXPECT_EQ(96, gcodec.pltype);
 
542
  EXPECT_STREQ("ISAC", gcodec.plname);
 
543
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
544
}
 
545
 
 
546
// Test that we ignore RED if it refers to a codec that is not present.
 
547
TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
 
548
  EXPECT_TRUE(SetupEngine());
 
549
  int channel_num = voe_.GetLastChannel();
 
550
  std::vector<cricket::AudioCodec> codecs;
 
551
  codecs.push_back(kRedCodec);
 
552
  codecs.push_back(kIsacCodec);
 
553
  codecs.push_back(kPcmuCodec);
 
554
  codecs[0].id = 127;
 
555
  codecs[0].params[""] = "97/97";
 
556
  codecs[1].id = 96;
 
557
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
558
  webrtc::CodecInst gcodec;
 
559
  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
 
560
  EXPECT_EQ(96, gcodec.pltype);
 
561
  EXPECT_STREQ("ISAC", gcodec.plname);
 
562
  EXPECT_FALSE(voe_.GetFEC(channel_num));
 
563
}
 
564
 
 
565
// Test that we support setting an empty list of recv header extensions.
 
566
TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
 
567
  EXPECT_TRUE(SetupEngine());
 
568
  std::vector<cricket::RtpHeaderExtension> extensions;
 
569
  int channel_num = voe_.GetLastChannel();
 
570
  bool enable = false;
 
571
  unsigned char id = 0;
 
572
 
 
573
  // An empty list shouldn't cause audio-level headers to be enabled.
 
574
  EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
 
575
  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
 
576
      channel_num, enable, id));
 
577
  EXPECT_FALSE(enable);
 
578
 
 
579
  // Nor should indicating we can receive the audio-level header.
 
580
  extensions.push_back(cricket::RtpHeaderExtension(
 
581
      "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
 
582
  EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
 
583
  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
 
584
      channel_num, enable, id));
 
585
  EXPECT_FALSE(enable);
 
586
}
 
587
 
 
588
// Test that we support setting certain send header extensions.
 
589
TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
 
590
  EXPECT_TRUE(SetupEngine());
 
591
  std::vector<cricket::RtpHeaderExtension> extensions;
 
592
  int channel_num = voe_.GetLastChannel();
 
593
  bool enable = false;
 
594
  unsigned char id = 0;
 
595
 
 
596
  // Ensure audio levels are off by default.
 
597
  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
 
598
      channel_num, enable, id));
 
599
  EXPECT_FALSE(enable);
 
600
 
 
601
  // Ensure audio levels stay off with an empty list of headers.
 
602
  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
 
603
  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
 
604
      channel_num, enable, id));
 
605
  EXPECT_FALSE(enable);
 
606
 
 
607
  // Ensure audio levels are enabled if the audio-level header is specified.
 
608
  extensions.push_back(cricket::RtpHeaderExtension(
 
609
      "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
 
610
  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
 
611
  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
 
612
      channel_num, enable, id));
 
613
  EXPECT_TRUE(enable);
 
614
  EXPECT_EQ(8, id);
 
615
 
 
616
  // Ensure audio levels go back off with an empty list.
 
617
  extensions.clear();
 
618
  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
 
619
  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
 
620
      channel_num, enable, id));
 
621
  EXPECT_FALSE(enable);
 
622
}
 
623
 
 
624
// Test that we can create a channel and start sending/playing out on it.
 
625
TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
 
626
  EXPECT_TRUE(SetupEngine());
 
627
  int channel_num = voe_.GetLastChannel();
 
628
  std::vector<cricket::AudioCodec> codecs;
 
629
  codecs.push_back(kPcmuCodec);
 
630
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
631
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
632
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
633
  EXPECT_TRUE(channel_->SetPlayout(true));
 
634
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
635
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
 
636
  EXPECT_FALSE(voe_.GetSend(channel_num));
 
637
  EXPECT_TRUE(channel_->SetPlayout(false));
 
638
  EXPECT_FALSE(voe_.GetPlayout(channel_num));
 
639
}
 
640
 
 
641
// Test that we can add and remove streams, and do proper send/playout.
 
642
// We can receive on multiple streams, but will only send on one.
 
643
TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayoutWithMultipleStreams) {
 
644
  EXPECT_TRUE(SetupEngine());
 
645
  int channel_num1 = voe_.GetLastChannel();
 
646
 
 
647
  // Start playout on the default channel.
 
648
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
649
  EXPECT_TRUE(channel_->SetPlayout(true));
 
650
  EXPECT_TRUE(voe_.GetPlayout(channel_num1));
 
651
 
 
652
  // Adding another stream should disable playout on the default channel.
 
653
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
654
  int channel_num2 = voe_.GetLastChannel();
 
655
  std::vector<cricket::AudioCodec> codecs;
 
656
  codecs.push_back(kPcmuCodec);
 
657
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
658
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
659
  EXPECT_TRUE(voe_.GetSend(channel_num1));
 
660
  EXPECT_FALSE(voe_.GetSend(channel_num2));
 
661
 
 
662
  // Make sure only the new channel is played out.
 
663
  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
 
664
  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
 
665
 
 
666
  // Adding yet another stream should have stream 2 and 3 enabled for playout.
 
667
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
 
668
  int channel_num3 = voe_.GetLastChannel();
 
669
  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
 
670
  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
 
671
  EXPECT_TRUE(voe_.GetPlayout(channel_num3));
 
672
  EXPECT_FALSE(voe_.GetSend(channel_num3));
 
673
 
 
674
  // Stop sending.
 
675
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
 
676
  EXPECT_FALSE(voe_.GetSend(channel_num1));
 
677
  EXPECT_FALSE(voe_.GetSend(channel_num2));
 
678
  EXPECT_FALSE(voe_.GetSend(channel_num3));
 
679
 
 
680
  // Stop playout.
 
681
  EXPECT_TRUE(channel_->SetPlayout(false));
 
682
  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
 
683
  EXPECT_FALSE(voe_.GetPlayout(channel_num2));
 
684
  EXPECT_FALSE(voe_.GetPlayout(channel_num3));
 
685
 
 
686
  // Restart playout and make sure the default channel still is not played out.
 
687
  EXPECT_TRUE(channel_->SetPlayout(true));
 
688
  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
 
689
  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
 
690
  EXPECT_TRUE(voe_.GetPlayout(channel_num3));
 
691
 
 
692
  // Now remove the new streams and verify that the default channel is
 
693
  // played out again.
 
694
  EXPECT_TRUE(channel_->RemoveRecvStream(3));
 
695
  EXPECT_TRUE(channel_->RemoveRecvStream(2));
 
696
 
 
697
  EXPECT_TRUE(voe_.GetPlayout(channel_num1));
 
698
}
 
699
 
 
700
// Test that we can set the devices to use.
 
701
TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
 
702
  EXPECT_TRUE(SetupEngine());
 
703
  int channel_num = voe_.GetLastChannel();
 
704
  std::vector<cricket::AudioCodec> codecs;
 
705
  codecs.push_back(kPcmuCodec);
 
706
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
707
 
 
708
  cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
 
709
                              cricket::kFakeDefaultDeviceId);
 
710
  cricket::Device dev(cricket::kFakeDeviceName,
 
711
                      cricket::kFakeDeviceId);
 
712
 
 
713
  // Test SetDevices() while not sending or playing.
 
714
  EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
 
715
 
 
716
  // Test SetDevices() while sending and playing.
 
717
  EXPECT_TRUE(engine_.SetLocalMonitor(true));
 
718
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
719
  EXPECT_TRUE(channel_->SetPlayout(true));
 
720
  EXPECT_TRUE(voe_.GetRecordingMicrophone());
 
721
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
722
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
723
 
 
724
  EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
 
725
 
 
726
  EXPECT_TRUE(voe_.GetRecordingMicrophone());
 
727
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
728
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
729
 
 
730
  // Test that failure to open newly selected devices does not prevent opening
 
731
  // ones after that.
 
732
  voe_.set_fail_start_recording_microphone(true);
 
733
  voe_.set_playout_fail_channel(channel_num);
 
734
  voe_.set_send_fail_channel(channel_num);
 
735
 
 
736
  EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
 
737
 
 
738
  EXPECT_FALSE(voe_.GetRecordingMicrophone());
 
739
  EXPECT_FALSE(voe_.GetSend(channel_num));
 
740
  EXPECT_FALSE(voe_.GetPlayout(channel_num));
 
741
 
 
742
  voe_.set_fail_start_recording_microphone(false);
 
743
  voe_.set_playout_fail_channel(-1);
 
744
  voe_.set_send_fail_channel(-1);
 
745
 
 
746
  EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
 
747
 
 
748
  EXPECT_TRUE(voe_.GetRecordingMicrophone());
 
749
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
750
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
751
}
 
752
 
 
753
// Test that we can set the devices to use even if we failed to
 
754
// open the initial ones.
 
755
TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
 
756
  EXPECT_TRUE(SetupEngine());
 
757
  int channel_num = voe_.GetLastChannel();
 
758
  std::vector<cricket::AudioCodec> codecs;
 
759
  codecs.push_back(kPcmuCodec);
 
760
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
761
 
 
762
  cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
 
763
                              cricket::kFakeDefaultDeviceId);
 
764
  cricket::Device dev(cricket::kFakeDeviceName,
 
765
                      cricket::kFakeDeviceId);
 
766
 
 
767
  // Test that failure to open devices selected before starting
 
768
  // send/play does not prevent opening newly selected ones after that.
 
769
  voe_.set_fail_start_recording_microphone(true);
 
770
  voe_.set_playout_fail_channel(channel_num);
 
771
  voe_.set_send_fail_channel(channel_num);
 
772
 
 
773
  EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
 
774
 
 
775
  EXPECT_FALSE(engine_.SetLocalMonitor(true));
 
776
  EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
777
  EXPECT_FALSE(channel_->SetPlayout(true));
 
778
  EXPECT_FALSE(voe_.GetRecordingMicrophone());
 
779
  EXPECT_FALSE(voe_.GetSend(channel_num));
 
780
  EXPECT_FALSE(voe_.GetPlayout(channel_num));
 
781
 
 
782
  voe_.set_fail_start_recording_microphone(false);
 
783
  voe_.set_playout_fail_channel(-1);
 
784
  voe_.set_send_fail_channel(-1);
 
785
 
 
786
  EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
 
787
 
 
788
  EXPECT_TRUE(voe_.GetRecordingMicrophone());
 
789
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
790
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
791
}
 
792
 
 
793
// Test that we can create a channel configured for multi-point conferences,
 
794
// and start sending/playing out on it.
 
795
TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
 
796
  EXPECT_TRUE(SetupEngine());
 
797
  int channel_num = voe_.GetLastChannel();
 
798
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
799
  std::vector<cricket::AudioCodec> codecs;
 
800
  codecs.push_back(kPcmuCodec);
 
801
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
802
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
803
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
804
 
 
805
  bool enabled;
 
806
  webrtc::EcModes ec_mode;
 
807
  webrtc::NsModes ns_mode;
 
808
  EXPECT_EQ(0, voe_.GetEcStatus(enabled, ec_mode));
 
809
#ifdef CHROMEOS
 
810
  EXPECT_EQ(webrtc::kEcDefault, ec_mode);
 
811
#else
 
812
  EXPECT_EQ(webrtc::kEcConference, ec_mode);
 
813
#endif
 
814
  EXPECT_EQ(0, voe_.GetNsStatus(enabled, ns_mode));
 
815
  EXPECT_TRUE(enabled);
 
816
#ifdef CHROMEOS
 
817
  EXPECT_EQ(webrtc::kNsDefault, ns_mode);
 
818
#else
 
819
  EXPECT_EQ(webrtc::kNsConference, ns_mode);
 
820
#endif
 
821
 
 
822
  EXPECT_TRUE(channel_->SetPlayout(true));
 
823
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
824
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
 
825
  EXPECT_FALSE(voe_.GetSend(channel_num));
 
826
 
 
827
  EXPECT_EQ(0, voe_.GetEcStatus(enabled, ec_mode));
 
828
  EXPECT_EQ(webrtc::kEcDefault, ec_mode);
 
829
  EXPECT_EQ(0, voe_.GetNsStatus(enabled, ns_mode));
 
830
  EXPECT_EQ(webrtc::kNsDefault, ns_mode);
 
831
 
 
832
  EXPECT_TRUE(channel_->SetPlayout(false));
 
833
  EXPECT_FALSE(voe_.GetPlayout(channel_num));
 
834
}
 
835
 
 
836
// Test that we can create a channel configured for Codian bridges,
 
837
// and start sending/playing out on it.
 
838
TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
 
839
  EXPECT_TRUE(SetupEngine());
 
840
  int channel_num = voe_.GetLastChannel();
 
841
  webrtc::AgcConfig agc_config;
 
842
  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
 
843
  EXPECT_EQ(0, agc_config.targetLeveldBOv);
 
844
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_AGC_MINUS_10DB));
 
845
  std::vector<cricket::AudioCodec> codecs;
 
846
  codecs.push_back(kPcmuCodec);
 
847
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
848
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
849
  EXPECT_TRUE(voe_.GetSend(channel_num));
 
850
  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
 
851
  EXPECT_GT(agc_config.targetLeveldBOv, 0);  // level was attenuated
 
852
  EXPECT_TRUE(channel_->SetPlayout(true));
 
853
  EXPECT_TRUE(voe_.GetPlayout(channel_num));
 
854
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
 
855
  EXPECT_FALSE(voe_.GetSend(channel_num));
 
856
  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
 
857
  EXPECT_EQ(0, agc_config.targetLeveldBOv);  // level was restored
 
858
  EXPECT_TRUE(channel_->SetPlayout(false));
 
859
  EXPECT_FALSE(voe_.GetPlayout(channel_num));
 
860
}
 
861
 
 
862
// Test that we can set the outgoing SSRC properly.
 
863
// SSRC is set in SetupEngine by calling AddSendStream.
 
864
TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
 
865
  EXPECT_TRUE(SetupEngine());
 
866
  int channel_num = voe_.GetLastChannel();
 
867
  unsigned int send_ssrc;
 
868
  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
 
869
  EXPECT_NE(0U, send_ssrc);
 
870
  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
 
871
  EXPECT_EQ(kSsrc1, send_ssrc);
 
872
}
 
873
 
 
874
// Test that we can set the outgoing SSRC properly with multiple streams.
 
875
// SSRC is set in SetupEngine by calling AddSendStream.
 
876
TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
 
877
  EXPECT_TRUE(SetupEngine());
 
878
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
879
  int channel_num1 = voe_.GetLastChannel();
 
880
  unsigned int send_ssrc;
 
881
  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
 
882
  EXPECT_EQ(kSsrc1, send_ssrc);
 
883
 
 
884
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
885
  int channel_num2 = voe_.GetLastChannel();
 
886
  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
 
887
  EXPECT_EQ(kSsrc1, send_ssrc);
 
888
}
 
889
 
 
890
// Test that the local SSRC is the same on sending and receiving channels if the
 
891
// receive channel is created before the send channel.
 
892
TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
 
893
  EXPECT_TRUE(engine_.Init());
 
894
  channel_ = engine_.CreateChannel();
 
895
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
896
 
 
897
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
 
898
  int receive_channel_num = voe_.GetLastChannel();
 
899
  EXPECT_TRUE(channel_->AddSendStream(
 
900
      cricket::StreamParams::CreateLegacy(1234)));
 
901
  int send_channel_num = voe_.GetLastChannel();
 
902
 
 
903
  unsigned int ssrc = 0;
 
904
  EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
 
905
  EXPECT_EQ(1234U, ssrc);
 
906
  ssrc = 0;
 
907
  EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
 
908
  EXPECT_EQ(1234U, ssrc);
 
909
}
 
910
 
 
911
// Test that we can properly receive packets.
 
912
TEST_F(WebRtcVoiceEngineTestFake, Recv) {
 
913
  EXPECT_TRUE(SetupEngine());
 
914
  int channel_num = voe_.GetLastChannel();
 
915
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
 
916
  EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
 
917
                               sizeof(kPcmuFrame)));
 
918
}
 
919
 
 
920
// Test that we can properly receive packets on multiple streams.
 
921
TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
 
922
  EXPECT_TRUE(SetupEngine());
 
923
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
924
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
 
925
  int channel_num1 = voe_.GetLastChannel();
 
926
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
927
  int channel_num2 = voe_.GetLastChannel();
 
928
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
 
929
  int channel_num3 = voe_.GetLastChannel();
 
930
  // Create packets with the right SSRCs.
 
931
  char packets[4][sizeof(kPcmuFrame)];
 
932
  for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
 
933
    memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
 
934
    talk_base::SetBE32(packets[i] + 8, i);
 
935
  }
 
936
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
 
937
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
 
938
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
 
939
  DeliverPacket(packets[0], sizeof(packets[0]));
 
940
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
 
941
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
 
942
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
 
943
  DeliverPacket(packets[1], sizeof(packets[1]));
 
944
  EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
 
945
                               sizeof(packets[1])));
 
946
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
 
947
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
 
948
  DeliverPacket(packets[2], sizeof(packets[2]));
 
949
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
 
950
  EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
 
951
                               sizeof(packets[2])));
 
952
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
 
953
  DeliverPacket(packets[3], sizeof(packets[3]));
 
954
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
 
955
  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
 
956
  EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
 
957
                               sizeof(packets[3])));
 
958
  EXPECT_TRUE(channel_->RemoveRecvStream(3));
 
959
  EXPECT_TRUE(channel_->RemoveRecvStream(2));
 
960
  EXPECT_TRUE(channel_->RemoveRecvStream(1));
 
961
}
 
962
 
 
963
// Test that we properly handle failures to add a stream.
 
964
TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
 
965
  EXPECT_TRUE(SetupEngine());
 
966
  voe_.set_fail_create_channel(true);
 
967
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
968
  EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
969
 
 
970
  // In 1:1 call, we should not try to create a new channel.
 
971
  EXPECT_TRUE(channel_->SetOptions(0));
 
972
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
973
}
 
974
 
 
975
// Test that AddRecvStream doesn't create new channel for 1:1 call.
 
976
TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
 
977
  EXPECT_TRUE(SetupEngine());
 
978
  int channel_num = voe_.GetLastChannel();
 
979
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
 
980
  EXPECT_EQ(channel_num, voe_.GetLastChannel());
 
981
}
 
982
 
 
983
// Test that we properly clean up any streams that were added, even if
 
984
// not explicitly removed.
 
985
TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
 
986
  EXPECT_TRUE(SetupEngine());
 
987
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
988
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
 
989
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
990
  EXPECT_EQ(3, voe_.GetNumChannels());  // default channel + 2 added
 
991
  delete channel_;
 
992
  channel_ = NULL;
 
993
  EXPECT_EQ(0, voe_.GetNumChannels());
 
994
}
 
995
 
 
996
// Test that we can send DTMF properly, but only if the other side supports
 
997
// telephone-event.
 
998
TEST_F(WebRtcVoiceEngineTestFake, SendDtmf) {
 
999
  EXPECT_TRUE(SetupEngine());
 
1000
  std::vector<cricket::AudioCodec> codecs;
 
1001
  codecs.push_back(kPcmuCodec);
 
1002
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
1003
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
1004
  EXPECT_FALSE(channel_->PressDTMF(1, true));
 
1005
  codecs.push_back(kTelephoneEventCodec);
 
1006
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
1007
  EXPECT_TRUE(channel_->PressDTMF(1, true));
 
1008
}
 
1009
 
 
1010
// Test that we can play a ringback tone properly in a single-stream call.
 
1011
TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
 
1012
  EXPECT_TRUE(SetupEngine());
 
1013
  int channel_num = voe_.GetLastChannel();
 
1014
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1015
  // Check we fail if no ringback tone specified.
 
1016
  EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
 
1017
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1018
  // Check we can set and play a ringback tone.
 
1019
  EXPECT_TRUE(channel_->SetRingbackTone(kRingbackTone, strlen(kRingbackTone)));
 
1020
  EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
 
1021
  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
 
1022
  // Check we can stop the tone manually.
 
1023
  EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
 
1024
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1025
  // Check we stop the tone if a packet arrives.
 
1026
  EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
 
1027
  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
 
1028
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
 
1029
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1030
}
 
1031
 
 
1032
// Test that we can play a ringback tone properly in a multi-stream call.
 
1033
TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
 
1034
  EXPECT_TRUE(SetupEngine());
 
1035
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
1036
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
 
1037
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
1038
  int channel_num = voe_.GetLastChannel();
 
1039
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1040
  // Check we fail if no ringback tone specified.
 
1041
  EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
 
1042
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1043
  // Check we can set and play a ringback tone on the correct ssrc.
 
1044
  EXPECT_TRUE(channel_->SetRingbackTone(kRingbackTone, strlen(kRingbackTone)));
 
1045
  EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
 
1046
  EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
 
1047
  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
 
1048
  // Check we can stop the tone manually.
 
1049
  EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
 
1050
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1051
  // Check we stop the tone if a packet arrives, but only with the right SSRC.
 
1052
  EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
 
1053
  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
 
1054
  // Send a packet with SSRC 1; the tone should not stop.
 
1055
  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
 
1056
  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
 
1057
  // Send a packet with SSRC 2; the tone should stop.
 
1058
  char packet[sizeof(kPcmuFrame)];
 
1059
  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
 
1060
  talk_base::SetBE32(packet + 8, 2);
 
1061
  DeliverPacket(packet, sizeof(packet));
 
1062
  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
 
1063
}
 
1064
 
 
1065
// Tests creating soundclips, and make sure they come from the right engine.
 
1066
TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
 
1067
  EXPECT_TRUE(engine_.Init());
 
1068
  soundclip_ = engine_.CreateSoundclip();
 
1069
  ASSERT_TRUE(soundclip_ != NULL);
 
1070
  EXPECT_EQ(0, voe_.GetNumChannels());
 
1071
  EXPECT_EQ(1, voe_sc_.GetNumChannels());
 
1072
  int channel_num = voe_sc_.GetLastChannel();
 
1073
  EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
 
1074
  delete soundclip_;
 
1075
  soundclip_ = NULL;
 
1076
  EXPECT_EQ(0, voe_sc_.GetNumChannels());
 
1077
}
 
1078
 
 
1079
// Tests playing out a fake sound.
 
1080
TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
 
1081
  static const char kZeroes[16000] = {};
 
1082
  EXPECT_TRUE(engine_.Init());
 
1083
  soundclip_ = engine_.CreateSoundclip();
 
1084
  ASSERT_TRUE(soundclip_ != NULL);
 
1085
  EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
 
1086
}
 
1087
 
 
1088
TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
 
1089
  talk_base::scoped_ptr<ChannelErrorListener> listener;
 
1090
  cricket::WebRtcVoiceMediaChannel* media_channel;
 
1091
  unsigned int ssrc = 0;
 
1092
 
 
1093
  EXPECT_TRUE(SetupEngine());
 
1094
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
1095
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
1096
 
 
1097
  media_channel = reinterpret_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
 
1098
  listener.reset(new ChannelErrorListener(channel_));
 
1099
 
 
1100
  // Test on WebRtc VoE channel.
 
1101
  voe_.TriggerCallbackOnError(media_channel->voe_channel(),
 
1102
                              VE_SATURATION_WARNING);
 
1103
  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
 
1104
            listener->error());
 
1105
  EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
 
1106
  EXPECT_EQ(ssrc, listener->ssrc());
 
1107
 
 
1108
  listener->Reset();
 
1109
  voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
 
1110
  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
 
1111
            listener->error());
 
1112
  EXPECT_EQ(0U, listener->ssrc());
 
1113
 
 
1114
  // Add another stream and test on that.
 
1115
  ++ssrc;
 
1116
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
 
1117
      ssrc)));
 
1118
  listener->Reset();
 
1119
  voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
 
1120
                              VE_SATURATION_WARNING);
 
1121
  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
 
1122
            listener->error());
 
1123
  EXPECT_EQ(ssrc, listener->ssrc());
 
1124
 
 
1125
  // Testing a non-existing channel.
 
1126
  listener->Reset();
 
1127
  voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
 
1128
                              VE_SATURATION_WARNING);
 
1129
  EXPECT_EQ(0, listener->error());
 
1130
}
 
1131
 
 
1132
TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
 
1133
  EXPECT_TRUE(SetupEngine());
 
1134
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
1135
  std::vector<cricket::AudioCodec> codecs;
 
1136
  codecs.push_back(kPcmuCodec);
 
1137
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
 
1138
  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
 
1139
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
 
1140
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
 
1141
  EXPECT_TRUE(channel_->SetPlayout(true));
 
1142
  voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
 
1143
  EXPECT_TRUE(channel_->SetPlayout(false));
 
1144
  EXPECT_FALSE(channel_->SetPlayout(true));
 
1145
}
 
1146
 
 
1147
// Test that the Registering/Unregistering with the
 
1148
// webrtcvoiceengine works as expected
 
1149
TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
 
1150
  EXPECT_TRUE(SetupEngine());
 
1151
  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
 
1152
  EXPECT_TRUE(channel_->AddRecvStream(
 
1153
      cricket::StreamParams::CreateLegacy(kSsrc1)));
 
1154
  uint32 ssrc = 0;
 
1155
  voe_.GetLocalSSRC(0, ssrc);
 
1156
  cricket::FakeMediaProcessor vp_1;
 
1157
  cricket::FakeMediaProcessor vp_2;
 
1158
 
 
1159
  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_1, cricket::MPD_RX));
 
1160
  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_2, cricket::MPD_RX));
 
1161
  voe_.TriggerProcessPacket(cricket::MPD_RX);
 
1162
  voe_.TriggerProcessPacket(cricket::MPD_TX);
 
1163
 
 
1164
  EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
 
1165
  EXPECT_EQ(1, vp_1.voice_frame_count());
 
1166
  EXPECT_EQ(1, vp_2.voice_frame_count());
 
1167
 
 
1168
  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc,
 
1169
                                          &vp_2,
 
1170
                                          cricket::MPD_RX));
 
1171
  voe_.TriggerProcessPacket(cricket::MPD_RX);
 
1172
  EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
 
1173
  EXPECT_EQ(1, vp_2.voice_frame_count());
 
1174
  EXPECT_EQ(2, vp_1.voice_frame_count());
 
1175
 
 
1176
  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc,
 
1177
                                          &vp_1,
 
1178
                                          cricket::MPD_RX));
 
1179
  voe_.TriggerProcessPacket(cricket::MPD_RX);
 
1180
  EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
 
1181
  EXPECT_EQ(2, vp_1.voice_frame_count());
 
1182
 
 
1183
  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_1, cricket::MPD_TX));
 
1184
  voe_.TriggerProcessPacket(cricket::MPD_RX);
 
1185
  voe_.TriggerProcessPacket(cricket::MPD_TX);
 
1186
  EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
 
1187
  EXPECT_EQ(3, vp_1.voice_frame_count());
 
1188
 
 
1189
  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc,
 
1190
                                          &vp_1,
 
1191
                                          cricket::MPD_RX_AND_TX));
 
1192
  voe_.TriggerProcessPacket(cricket::MPD_TX);
 
1193
  EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
 
1194
  EXPECT_EQ(3, vp_1.voice_frame_count());
 
1195
  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc1));
 
1196
 
 
1197
  // Test that after removing the recvstream we can we can still register
 
1198
  // the processor. This tests the 1:1 case.
 
1199
  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_1, cricket::MPD_RX));
 
1200
  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc, &vp_1, cricket::MPD_RX_AND_TX));
 
1201
 
 
1202
  // The following tests test that FindChannelNumFromSsrc is doing
 
1203
  // what we expect.
 
1204
  // pick an invalid ssrc and make sure we can't register
 
1205
  EXPECT_FALSE(engine_.RegisterProcessor(0,
 
1206
                                         &vp_1,
 
1207
                                         cricket::MPD_RX));
 
1208
  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
 
1209
  EXPECT_TRUE(engine_.RegisterProcessor(1,
 
1210
                                        &vp_1,
 
1211
                                        cricket::MPD_RX));
 
1212
  EXPECT_TRUE(engine_.UnregisterProcessor(1,
 
1213
                                          &vp_1,
 
1214
                                          cricket::MPD_RX));
 
1215
  EXPECT_FALSE(engine_.RegisterProcessor(1,
 
1216
                                         &vp_1,
 
1217
                                         cricket::MPD_TX));
 
1218
  EXPECT_TRUE(channel_->RemoveRecvStream(1));
 
1219
}
 
1220
 
 
1221
// Tests for the actual WebRtc VoE library.
 
1222
 
 
1223
// Tests that the library initializes and shuts down properly.
 
1224
TEST(WebRtcVoiceEngineTest, StartupShutdown) {
 
1225
  cricket::WebRtcVoiceEngine engine;
 
1226
  EXPECT_TRUE(engine.Init());
 
1227
  cricket::VoiceMediaChannel* channel = engine.CreateChannel();
 
1228
  EXPECT_TRUE(channel != NULL);
 
1229
  delete channel;
 
1230
  engine.Terminate();
 
1231
 
 
1232
  // Reinit to catch regression where VoiceEngineObserver reference is lost
 
1233
  EXPECT_TRUE(engine.Init());
 
1234
  engine.Terminate();
 
1235
}
 
1236
 
 
1237
// Tests that the logging from the library is cleartext.
 
1238
TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
 
1239
  cricket::WebRtcVoiceEngine engine;
 
1240
  talk_base::scoped_ptr<talk_base::MemoryStream> stream(
 
1241
      new talk_base::MemoryStream);
 
1242
  size_t size = 0;
 
1243
  bool cleartext = true;
 
1244
  talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
 
1245
  engine.SetLogging(talk_base::LS_VERBOSE, "");
 
1246
  EXPECT_TRUE(engine.Init());
 
1247
  EXPECT_TRUE(stream->GetSize(&size));
 
1248
  EXPECT_GT(size, 0U);
 
1249
  engine.Terminate();
 
1250
  talk_base::LogMessage::RemoveLogToStream(stream.get());
 
1251
  const char* buf = stream->GetBuffer();
 
1252
  for (size_t i = 0; i < size && cleartext; ++i) {
 
1253
    int ch = static_cast<int>(buf[i]);
 
1254
    ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
 
1255
                     << std::hex << ch;
 
1256
    cleartext = (isprint(ch) || isspace(ch));
 
1257
  }
 
1258
  EXPECT_TRUE(cleartext);
 
1259
}
 
1260
 
 
1261
// Tests we do not see any references to a monitor thread being spun up
 
1262
// when initiating the engine.
 
1263
TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
 
1264
  cricket::WebRtcVoiceEngine engine;
 
1265
  talk_base::scoped_ptr<talk_base::MemoryStream> stream(
 
1266
      new talk_base::MemoryStream);
 
1267
  talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
 
1268
  engine.SetLogging(talk_base::LS_VERBOSE, "");
 
1269
  EXPECT_TRUE(engine.Init());
 
1270
  engine.Terminate();
 
1271
  talk_base::LogMessage::RemoveLogToStream(stream.get());
 
1272
 
 
1273
  size_t size = 0;
 
1274
  EXPECT_TRUE(stream->GetSize(&size));
 
1275
  EXPECT_GT(size, 0U);
 
1276
  const std::string logs(stream->GetBuffer());
 
1277
  EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
 
1278
}
 
1279
 
 
1280
// Tests that the library is configured with the codecs we want.
 
1281
TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
 
1282
  cricket::WebRtcVoiceEngine engine;
 
1283
  // Check codecs by name.
 
1284
  EXPECT_TRUE(engine.FindCodec(
 
1285
      cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
 
1286
  EXPECT_TRUE(engine.FindCodec(
 
1287
      cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
 
1288
  // Check that name matching is case-insensitive.
 
1289
  EXPECT_TRUE(engine.FindCodec(
 
1290
      cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
 
1291
  EXPECT_TRUE(engine.FindCodec(
 
1292
      cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
 
1293
  EXPECT_TRUE(engine.FindCodec(
 
1294
      cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
 
1295
  EXPECT_TRUE(engine.FindCodec(
 
1296
      cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
 
1297
  EXPECT_TRUE(engine.FindCodec(
 
1298
      cricket::AudioCodec(96, "speex", 16000, 0, 1, 0)));
 
1299
  EXPECT_TRUE(engine.FindCodec(
 
1300
      cricket::AudioCodec(96, "speex", 8000, 0, 1, 0)));
 
1301
  EXPECT_TRUE(engine.FindCodec(
 
1302
      cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
 
1303
  EXPECT_TRUE(engine.FindCodec(
 
1304
      cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
 
1305
  EXPECT_TRUE(engine.FindCodec(
 
1306
      cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
 
1307
  EXPECT_TRUE(engine.FindCodec(
 
1308
      cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
 
1309
  EXPECT_TRUE(engine.FindCodec(
 
1310
      cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
 
1311
  EXPECT_TRUE(engine.FindCodec(
 
1312
      cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
 
1313
  // Check codecs with an id by id.
 
1314
  EXPECT_TRUE(engine.FindCodec(
 
1315
      cricket::AudioCodec(0, "", 8000, 0, 1, 0)));   // PCMU
 
1316
  EXPECT_TRUE(engine.FindCodec(
 
1317
      cricket::AudioCodec(8, "", 8000, 0, 1, 0)));   // PCMA
 
1318
  EXPECT_TRUE(engine.FindCodec(
 
1319
      cricket::AudioCodec(9, "", 16000, 0, 1, 0)));  // G722
 
1320
  EXPECT_TRUE(engine.FindCodec(
 
1321
      cricket::AudioCodec(13, "", 8000, 0, 1, 0)));  // CN
 
1322
  // Check sample/bitrate matching.
 
1323
  EXPECT_TRUE(engine.FindCodec(
 
1324
      cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
 
1325
  // Check that bad codecs fail.
 
1326
  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
 
1327
  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
 
1328
  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
 
1329
  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
 
1330
  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
 
1331
  // Check that there aren't any extra codecs lying around.
 
1332
  EXPECT_EQ(13U, engine.codecs().size());
 
1333
  // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
 
1334
  for (std::vector<cricket::AudioCodec>::const_iterator it =
 
1335
      engine.codecs().begin(); it != engine.codecs().end(); ++it) {
 
1336
    if (it->name == "CN" && it->clockrate == 16000) {
 
1337
      EXPECT_EQ(105, it->id);
 
1338
    } else if (it->name == "CN" && it->clockrate == 32000) {
 
1339
      EXPECT_EQ(106, it->id);
 
1340
    } else if (it->name == "ISAC" && it->clockrate == 16000) {
 
1341
      EXPECT_EQ(103, it->id);
 
1342
    } else if (it->name == "ISAC" && it->clockrate == 32000) {
 
1343
      EXPECT_EQ(104, it->id);
 
1344
    } else if (it->name == "G722" && it->clockrate == 16000) {
 
1345
      EXPECT_EQ(9, it->id);
 
1346
    } else if (it->name == "telephone-event") {
 
1347
      EXPECT_EQ(126, it->id);
 
1348
    } else if (it->name == "red") {
 
1349
      EXPECT_EQ(127, it->id);
 
1350
    }
 
1351
  }
 
1352
 
 
1353
  engine.Terminate();
 
1354
}
 
1355
 
 
1356
// Tests that VoE supports at least 32 channels
 
1357
TEST(WebRtcVoiceEngineTest, Has32Channels) {
 
1358
  cricket::WebRtcVoiceEngine engine;
 
1359
  EXPECT_TRUE(engine.Init());
 
1360
 
 
1361
  cricket::VoiceMediaChannel* channels[32];
 
1362
  int num_channels = 0;
 
1363
 
 
1364
  while (num_channels < ARRAY_SIZE(channels)) {
 
1365
    cricket::VoiceMediaChannel* channel = engine.CreateChannel();
 
1366
    if (!channel)
 
1367
      break;
 
1368
 
 
1369
    channels[num_channels++] = channel;
 
1370
  }
 
1371
 
 
1372
  int expected = ARRAY_SIZE(channels);
 
1373
  EXPECT_EQ(expected, num_channels);
 
1374
 
 
1375
  while (num_channels > 0) {
 
1376
    delete channels[--num_channels];
 
1377
  }
 
1378
 
 
1379
  engine.Terminate();
 
1380
}
 
1381
 
 
1382
#ifdef WIN32
 
1383
// Test our workarounds to WebRtc VoE' munging of the coinit count
 
1384
TEST(WebRtcVoiceEngineTest, CoInitialize) {
 
1385
  cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
 
1386
 
 
1387
  // Initial refcount should be 0.
 
1388
  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
 
1389
 
 
1390
  // Engine should start even with COM already inited.
 
1391
  EXPECT_TRUE(engine->Init());
 
1392
  engine->Terminate();
 
1393
  EXPECT_TRUE(engine->Init());
 
1394
  engine->Terminate();
 
1395
 
 
1396
  // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
 
1397
  EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
 
1398
  // Decrement refcount to (hopefully) 0.
 
1399
  CoUninitialize();
 
1400
  CoUninitialize();
 
1401
  delete engine;
 
1402
 
 
1403
  // Ensure refcount is 0.
 
1404
  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
 
1405
  CoUninitialize();
 
1406
}
 
1407
#endif