Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / media / webrtc / webrtcvoiceengine_unittest.cc
1 /*
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  */
27
28 #ifdef WIN32
29 #include "webrtc/base/win32.h"
30 #include <objbase.h>
31 #endif
32
33 #include "webrtc/base/byteorder.h"
34 #include "webrtc/base/gunit.h"
35 #include "talk/media/base/constants.h"
36 #include "talk/media/base/fakemediaengine.h"
37 #include "talk/media/base/fakemediaprocessor.h"
38 #include "talk/media/base/fakenetworkinterface.h"
39 #include "talk/media/base/fakertp.h"
40 #include "talk/media/webrtc/fakewebrtcvoiceengine.h"
41 #include "talk/media/webrtc/webrtcvoiceengine.h"
42 #include "talk/p2p/base/fakesession.h"
43 #include "talk/session/media/channel.h"
44
45 // Tests for the WebRtcVoiceEngine/VoiceChannel code.
46
47 using cricket::kRtpAudioLevelHeaderExtension;
48 using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
49
50 static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
51 static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
52 static const cricket::AudioCodec kCeltCodec(110, "CELT", 32000, 64000, 2, 0);
53 static const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
54 static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
55 static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
56 static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
57 static const cricket::AudioCodec
58     kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
59 static const cricket::AudioCodec* const kAudioCodecs[] = {
60     &kPcmuCodec, &kIsacCodec, &kCeltCodec, &kOpusCodec, &kRedCodec,
61     &kCn8000Codec, &kCn16000Codec, &kTelephoneEventCodec,
62 };
63 const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
64 static uint32 kSsrc1 = 0x99;
65 static uint32 kSsrc2 = 0x98;
66
67 class FakeVoEWrapper : public cricket::VoEWrapper {
68  public:
69   explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
70       : cricket::VoEWrapper(engine,  // processing
71                             engine,  // base
72                             engine,  // codec
73                             engine,  // dtmf
74                             engine,  // file
75                             engine,  // hw
76                             engine,  // media
77                             engine,  // neteq
78                             engine,  // network
79                             engine,  // rtp
80                             engine,  // sync
81                             engine) {  // volume
82   }
83 };
84
85 class FakeVoETraceWrapper : public cricket::VoETraceWrapper {
86  public:
87   virtual int SetTraceFilter(const unsigned int filter) {
88     filter_ = filter;
89     return 0;
90   }
91   virtual int SetTraceFile(const char* fileNameUTF8) {
92     return 0;
93   }
94   virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
95     return 0;
96   }
97   unsigned int filter_;
98 };
99
100 class WebRtcVoiceEngineTestFake : public testing::Test {
101  public:
102   class ChannelErrorListener : public sigslot::has_slots<> {
103    public:
104     explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
105         : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
106       ASSERT(channel != NULL);
107       channel->SignalMediaError.connect(
108           this, &ChannelErrorListener::OnVoiceChannelError);
109     }
110     void OnVoiceChannelError(uint32 ssrc,
111                              cricket::VoiceMediaChannel::Error error) {
112       ssrc_ = ssrc;
113       error_ = error;
114     }
115     void Reset() {
116       ssrc_ = 0;
117       error_ = cricket::VoiceMediaChannel::ERROR_NONE;
118     }
119     uint32 ssrc() const {
120       return ssrc_;
121     }
122     cricket::VoiceMediaChannel::Error error() const {
123       return error_;
124     }
125
126    private:
127     uint32 ssrc_;
128     cricket::VoiceMediaChannel::Error error_;
129   };
130
131   WebRtcVoiceEngineTestFake()
132       : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
133         voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
134         trace_wrapper_(new FakeVoETraceWrapper()),
135         engine_(new FakeVoEWrapper(&voe_),
136                 new FakeVoEWrapper(&voe_sc_),
137                 trace_wrapper_),
138         channel_(NULL), soundclip_(NULL) {
139     options_conference_.conference_mode.Set(true);
140     options_adjust_agc_.adjust_agc_delta.Set(-10);
141   }
142   bool SetupEngineWithoutStream() {
143     if (!engine_.Init(rtc::Thread::Current())) {
144       return false;
145     }
146     channel_ = engine_.CreateChannel();
147     return (channel_ != NULL);
148   }
149   bool SetupEngine() {
150     if (!SetupEngineWithoutStream()) {
151       return false;
152     }
153     return channel_->AddSendStream(
154         cricket::StreamParams::CreateLegacy(kSsrc1));
155   }
156   void SetupForMultiSendStream() {
157     EXPECT_TRUE(SetupEngine());
158     // Remove stream added in Setup, which is corresponding to default channel.
159     int default_channel_num = voe_.GetLastChannel();
160     uint32 default_send_ssrc = 0u;
161     EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
162     EXPECT_EQ(kSsrc1, default_send_ssrc);
163     EXPECT_TRUE(channel_->RemoveSendStream(default_send_ssrc));
164
165     // Verify the default channel still exists.
166     EXPECT_EQ(0, voe_.GetLocalSSRC(default_channel_num, default_send_ssrc));
167   }
168   void DeliverPacket(const void* data, int len) {
169     rtc::Buffer packet(data, len);
170     channel_->OnPacketReceived(&packet, rtc::PacketTime());
171   }
172   virtual void TearDown() {
173     delete soundclip_;
174     delete channel_;
175     engine_.Terminate();
176   }
177
178   void TestInsertDtmf(uint32 ssrc, bool caller) {
179     EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
180     channel_ = engine_.CreateChannel();
181     EXPECT_TRUE(channel_ != NULL);
182     if (caller) {
183       // if this is a caller, local description will be applied and add the
184       // send stream.
185       EXPECT_TRUE(channel_->AddSendStream(
186           cricket::StreamParams::CreateLegacy(kSsrc1)));
187     }
188     int channel_id = voe_.GetLastChannel();
189
190     // Test we can only InsertDtmf when the other side supports telephone-event.
191     std::vector<cricket::AudioCodec> codecs;
192     codecs.push_back(kPcmuCodec);
193     EXPECT_TRUE(channel_->SetSendCodecs(codecs));
194     EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
195     EXPECT_FALSE(channel_->CanInsertDtmf());
196     EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111, cricket::DF_SEND));
197     codecs.push_back(kTelephoneEventCodec);
198     EXPECT_TRUE(channel_->SetSendCodecs(codecs));
199     EXPECT_TRUE(channel_->CanInsertDtmf());
200
201     if (!caller) {
202       // There's no active send channel yet.
203       EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
204       EXPECT_TRUE(channel_->AddSendStream(
205           cricket::StreamParams::CreateLegacy(kSsrc1)));
206     }
207
208     // Check we fail if the ssrc is invalid.
209     EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111, cricket::DF_SEND));
210
211     // Test send
212     EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
213     EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123, cricket::DF_SEND));
214     EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 2, 123));
215
216     // Test play
217     EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(3, 134));
218     EXPECT_TRUE(channel_->InsertDtmf(ssrc, 3, 134, cricket::DF_PLAY));
219     EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(3, 134));
220
221     // Test send and play
222     EXPECT_FALSE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
223     EXPECT_FALSE(voe_.WasPlayDtmfToneCalled(4, 145));
224     EXPECT_TRUE(channel_->InsertDtmf(ssrc, 4, 145,
225                                      cricket::DF_PLAY | cricket::DF_SEND));
226     EXPECT_TRUE(voe_.WasSendTelephoneEventCalled(channel_id, 4, 145));
227     EXPECT_TRUE(voe_.WasPlayDtmfToneCalled(4, 145));
228   }
229
230   // Test that send bandwidth is set correctly.
231   // |codec| is the codec under test.
232   // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
233   // |expected_result| is the expected result from SetMaxSendBandwidth().
234   // |expected_bitrate| is the expected audio bitrate afterward.
235   void TestSendBandwidth(const cricket::AudioCodec& codec,
236                          int max_bitrate,
237                          bool expected_result,
238                          int expected_bitrate) {
239     int channel_num = voe_.GetLastChannel();
240     std::vector<cricket::AudioCodec> codecs;
241
242     codecs.push_back(codec);
243     EXPECT_TRUE(channel_->SetSendCodecs(codecs));
244
245     bool result = channel_->SetMaxSendBandwidth(max_bitrate);
246     EXPECT_EQ(expected_result, result);
247
248     webrtc::CodecInst temp_codec;
249     EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
250
251     EXPECT_EQ(expected_bitrate, temp_codec.rate);
252   }
253
254   void TestSetSendRtpHeaderExtensions(const std::string& ext) {
255     EXPECT_TRUE(SetupEngineWithoutStream());
256     int channel_num = voe_.GetLastChannel();
257
258     // Ensure extensions are off by default.
259     EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
260
261     std::vector<cricket::RtpHeaderExtension> extensions;
262     // Ensure unknown extensions won't cause an error.
263     extensions.push_back(cricket::RtpHeaderExtension(
264         "urn:ietf:params:unknownextention", 1));
265     EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
266     EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
267
268     // Ensure extensions stay off with an empty list of headers.
269     extensions.clear();
270     EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
271     EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
272
273     // Ensure extension is set properly.
274     const int id = 1;
275     extensions.push_back(cricket::RtpHeaderExtension(ext, id));
276     EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
277     EXPECT_EQ(id, voe_.GetSendRtpExtensionId(channel_num, ext));
278
279     // Ensure extension is set properly on new channel.
280     // The first stream to occupy the default channel.
281     EXPECT_TRUE(channel_->AddSendStream(
282         cricket::StreamParams::CreateLegacy(123)));
283     EXPECT_TRUE(channel_->AddSendStream(
284         cricket::StreamParams::CreateLegacy(234)));
285     int new_channel_num = voe_.GetLastChannel();
286     EXPECT_NE(channel_num, new_channel_num);
287     EXPECT_EQ(id, voe_.GetSendRtpExtensionId(new_channel_num, ext));
288
289     // Ensure all extensions go back off with an empty list.
290     extensions.clear();
291     EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
292     EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(channel_num, ext));
293     EXPECT_EQ(-1, voe_.GetSendRtpExtensionId(new_channel_num, ext));
294   }
295
296   void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
297     EXPECT_TRUE(SetupEngineWithoutStream());
298     int channel_num = voe_.GetLastChannel();
299
300     // Ensure extensions are off by default.
301     EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
302
303     std::vector<cricket::RtpHeaderExtension> extensions;
304     // Ensure unknown extensions won't cause an error.
305     extensions.push_back(cricket::RtpHeaderExtension(
306         "urn:ietf:params:unknownextention", 1));
307     EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
308     EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
309
310     // Ensure extensions stay off with an empty list of headers.
311     extensions.clear();
312     EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
313     EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
314
315     // Ensure extension is set properly.
316     const int id = 2;
317     extensions.push_back(cricket::RtpHeaderExtension(ext, id));
318     EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
319     EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(channel_num, ext));
320
321     // Ensure extension is set properly on new channel.
322     // The first stream to occupy the default channel.
323     EXPECT_TRUE(channel_->AddRecvStream(
324         cricket::StreamParams::CreateLegacy(345)));
325     EXPECT_TRUE(channel_->AddRecvStream(
326         cricket::StreamParams::CreateLegacy(456)));
327     int new_channel_num = voe_.GetLastChannel();
328     EXPECT_NE(channel_num, new_channel_num);
329     EXPECT_EQ(id, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
330
331     // Ensure all extensions go back off with an empty list.
332     extensions.clear();
333     EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
334     EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(channel_num, ext));
335     EXPECT_EQ(-1, voe_.GetReceiveRtpExtensionId(new_channel_num, ext));
336   }
337
338  protected:
339   cricket::FakeWebRtcVoiceEngine voe_;
340   cricket::FakeWebRtcVoiceEngine voe_sc_;
341   FakeVoETraceWrapper* trace_wrapper_;
342   cricket::WebRtcVoiceEngine engine_;
343   cricket::VoiceMediaChannel* channel_;
344   cricket::SoundclipMedia* soundclip_;
345
346   cricket::AudioOptions options_conference_;
347   cricket::AudioOptions options_adjust_agc_;
348 };
349
350 // Tests that our stub library "works".
351 TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
352   EXPECT_FALSE(voe_.IsInited());
353   EXPECT_FALSE(voe_sc_.IsInited());
354   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
355   EXPECT_TRUE(voe_.IsInited());
356   // The soundclip engine is lazily initialized.
357   EXPECT_FALSE(voe_sc_.IsInited());
358   engine_.Terminate();
359   EXPECT_FALSE(voe_.IsInited());
360   EXPECT_FALSE(voe_sc_.IsInited());
361 }
362
363 // Tests that we can create and destroy a channel.
364 TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
365   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
366   channel_ = engine_.CreateChannel();
367   EXPECT_TRUE(channel_ != NULL);
368 }
369
370 // Tests that we properly handle failures in CreateChannel.
371 TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
372   voe_.set_fail_create_channel(true);
373   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
374   channel_ = engine_.CreateChannel();
375   EXPECT_TRUE(channel_ == NULL);
376 }
377
378 // Tests that the list of supported codecs is created properly and ordered
379 // correctly
380 TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
381   const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
382   ASSERT_FALSE(codecs.empty());
383   EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
384   EXPECT_EQ(48000, codecs[0].clockrate);
385   EXPECT_EQ(2, codecs[0].channels);
386   EXPECT_EQ(64000, codecs[0].bitrate);
387   int pref = codecs[0].preference;
388   for (size_t i = 1; i < codecs.size(); ++i) {
389     EXPECT_GT(pref, codecs[i].preference);
390     pref = codecs[i].preference;
391   }
392 }
393
394 // Tests that we can find codecs by name or id, and that we interpret the
395 // clockrate and bitrate fields properly.
396 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
397   cricket::AudioCodec codec;
398   webrtc::CodecInst codec_inst;
399   // Find PCMU with explicit clockrate and bitrate.
400   EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
401   // Find ISAC with explicit clockrate and 0 bitrate.
402   EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
403   // Find telephone-event with explicit clockrate and 0 bitrate.
404   EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
405   // Find ISAC with a different payload id.
406   codec = kIsacCodec;
407   codec.id = 127;
408   EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
409   EXPECT_EQ(codec.id, codec_inst.pltype);
410   // Find PCMU with a 0 clockrate.
411   codec = kPcmuCodec;
412   codec.clockrate = 0;
413   EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
414   EXPECT_EQ(codec.id, codec_inst.pltype);
415   EXPECT_EQ(8000, codec_inst.plfreq);
416   // Find PCMU with a 0 bitrate.
417   codec = kPcmuCodec;
418   codec.bitrate = 0;
419   EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
420   EXPECT_EQ(codec.id, codec_inst.pltype);
421   EXPECT_EQ(64000, codec_inst.rate);
422   // Find ISAC with an explicit bitrate.
423   codec = kIsacCodec;
424   codec.bitrate = 32000;
425   EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
426   EXPECT_EQ(codec.id, codec_inst.pltype);
427   EXPECT_EQ(32000, codec_inst.rate);
428 }
429
430 // Test that we set our inbound codecs properly, including changing PT.
431 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
432   EXPECT_TRUE(SetupEngine());
433   int channel_num = voe_.GetLastChannel();
434   std::vector<cricket::AudioCodec> codecs;
435   codecs.push_back(kIsacCodec);
436   codecs.push_back(kPcmuCodec);
437   codecs.push_back(kTelephoneEventCodec);
438   codecs[0].id = 106;  // collide with existing telephone-event
439   codecs[2].id = 126;
440   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
441   webrtc::CodecInst gcodec;
442   rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
443   gcodec.plfreq = 16000;
444   gcodec.channels = 1;
445   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
446   EXPECT_EQ(106, gcodec.pltype);
447   EXPECT_STREQ("ISAC", gcodec.plname);
448   rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
449       "telephone-event");
450   gcodec.plfreq = 8000;
451   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
452   EXPECT_EQ(126, gcodec.pltype);
453   EXPECT_STREQ("telephone-event", gcodec.plname);
454 }
455
456 // Test that we fail to set an unknown inbound codec.
457 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
458   EXPECT_TRUE(SetupEngine());
459   std::vector<cricket::AudioCodec> codecs;
460   codecs.push_back(kIsacCodec);
461   codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
462   EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
463 }
464
465 // Test that we fail if we have duplicate types in the inbound list.
466 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
467   EXPECT_TRUE(SetupEngine());
468   std::vector<cricket::AudioCodec> codecs;
469   codecs.push_back(kIsacCodec);
470   codecs.push_back(kCn16000Codec);
471   codecs[1].id = kIsacCodec.id;
472   EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
473 }
474
475 // Test that we can decode OPUS without stereo parameters.
476 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
477   EXPECT_TRUE(SetupEngine());
478   EXPECT_TRUE(channel_->SetOptions(options_conference_));
479   std::vector<cricket::AudioCodec> codecs;
480   codecs.push_back(kIsacCodec);
481   codecs.push_back(kPcmuCodec);
482   codecs.push_back(kOpusCodec);
483   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
484   EXPECT_TRUE(channel_->AddRecvStream(
485       cricket::StreamParams::CreateLegacy(kSsrc1)));
486   int channel_num2 = voe_.GetLastChannel();
487   webrtc::CodecInst opus;
488   engine_.FindWebRtcCodec(kOpusCodec, &opus);
489   // Even without stereo parameters, recv codecs still specify channels = 2.
490   EXPECT_EQ(2, opus.channels);
491   EXPECT_EQ(111, opus.pltype);
492   EXPECT_STREQ("opus", opus.plname);
493   opus.pltype = 0;
494   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
495   EXPECT_EQ(111, opus.pltype);
496 }
497
498 // Test that we can decode OPUS with stereo = 0.
499 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
500   EXPECT_TRUE(SetupEngine());
501   EXPECT_TRUE(channel_->SetOptions(options_conference_));
502   std::vector<cricket::AudioCodec> codecs;
503   codecs.push_back(kIsacCodec);
504   codecs.push_back(kPcmuCodec);
505   codecs.push_back(kOpusCodec);
506   codecs[2].params["stereo"] = "0";
507   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
508   EXPECT_TRUE(channel_->AddRecvStream(
509       cricket::StreamParams::CreateLegacy(kSsrc1)));
510   int channel_num2 = voe_.GetLastChannel();
511   webrtc::CodecInst opus;
512   engine_.FindWebRtcCodec(kOpusCodec, &opus);
513   // Even when stereo is off, recv codecs still specify channels = 2.
514   EXPECT_EQ(2, opus.channels);
515   EXPECT_EQ(111, opus.pltype);
516   EXPECT_STREQ("opus", opus.plname);
517   opus.pltype = 0;
518   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
519   EXPECT_EQ(111, opus.pltype);
520 }
521
522 // Test that we can decode OPUS with stereo = 1.
523 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
524   EXPECT_TRUE(SetupEngine());
525   EXPECT_TRUE(channel_->SetOptions(options_conference_));
526   std::vector<cricket::AudioCodec> codecs;
527   codecs.push_back(kIsacCodec);
528   codecs.push_back(kPcmuCodec);
529   codecs.push_back(kOpusCodec);
530   codecs[2].params["stereo"] = "1";
531   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
532   EXPECT_TRUE(channel_->AddRecvStream(
533       cricket::StreamParams::CreateLegacy(kSsrc1)));
534   int channel_num2 = voe_.GetLastChannel();
535   webrtc::CodecInst opus;
536   engine_.FindWebRtcCodec(kOpusCodec, &opus);
537   EXPECT_EQ(2, opus.channels);
538   EXPECT_EQ(111, opus.pltype);
539   EXPECT_STREQ("opus", opus.plname);
540   opus.pltype = 0;
541   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
542   EXPECT_EQ(111, opus.pltype);
543 }
544
545 // Test that changes to recv codecs are applied to all streams.
546 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
547   EXPECT_TRUE(SetupEngine());
548   EXPECT_TRUE(channel_->SetOptions(options_conference_));
549   std::vector<cricket::AudioCodec> codecs;
550   codecs.push_back(kIsacCodec);
551   codecs.push_back(kPcmuCodec);
552   codecs.push_back(kTelephoneEventCodec);
553   codecs[0].id = 106;  // collide with existing telephone-event
554   codecs[2].id = 126;
555   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
556   EXPECT_TRUE(channel_->AddRecvStream(
557       cricket::StreamParams::CreateLegacy(kSsrc1)));
558   int channel_num2 = voe_.GetLastChannel();
559   webrtc::CodecInst gcodec;
560   rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
561   gcodec.plfreq = 16000;
562   gcodec.channels = 1;
563   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
564   EXPECT_EQ(106, gcodec.pltype);
565   EXPECT_STREQ("ISAC", gcodec.plname);
566   rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
567       "telephone-event");
568   gcodec.plfreq = 8000;
569   gcodec.channels = 1;
570   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
571   EXPECT_EQ(126, gcodec.pltype);
572   EXPECT_STREQ("telephone-event", gcodec.plname);
573 }
574
575 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
576   EXPECT_TRUE(SetupEngine());
577   EXPECT_TRUE(channel_->SetOptions(options_conference_));
578   std::vector<cricket::AudioCodec> codecs;
579   codecs.push_back(kIsacCodec);
580   codecs[0].id = 106;  // collide with existing telephone-event
581
582   EXPECT_TRUE(channel_->AddRecvStream(
583       cricket::StreamParams::CreateLegacy(kSsrc1)));
584   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
585
586   int channel_num2 = voe_.GetLastChannel();
587   webrtc::CodecInst gcodec;
588   rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
589   gcodec.plfreq = 16000;
590   gcodec.channels = 1;
591   EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
592   EXPECT_EQ(106, gcodec.pltype);
593   EXPECT_STREQ("ISAC", gcodec.plname);
594 }
595
596 // Test that we can apply the same set of codecs again while playing.
597 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
598   EXPECT_TRUE(SetupEngine());
599   int channel_num = voe_.GetLastChannel();
600   std::vector<cricket::AudioCodec> codecs;
601   codecs.push_back(kIsacCodec);
602   codecs.push_back(kCn16000Codec);
603   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
604   EXPECT_TRUE(channel_->SetPlayout(true));
605   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
606
607   // Changing the payload type of a codec should fail.
608   codecs[0].id = 127;
609   EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
610   EXPECT_TRUE(voe_.GetPlayout(channel_num));
611 }
612
613 // Test that we can add a codec while playing.
614 TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
615   EXPECT_TRUE(SetupEngine());
616   int channel_num = voe_.GetLastChannel();
617   std::vector<cricket::AudioCodec> codecs;
618   codecs.push_back(kIsacCodec);
619   codecs.push_back(kCn16000Codec);
620   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
621   EXPECT_TRUE(channel_->SetPlayout(true));
622
623   codecs.push_back(kOpusCodec);
624   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
625   EXPECT_TRUE(voe_.GetPlayout(channel_num));
626   webrtc::CodecInst gcodec;
627   EXPECT_TRUE(engine_.FindWebRtcCodec(kOpusCodec, &gcodec));
628   EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
629 }
630
631 TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
632   EXPECT_TRUE(SetupEngine());
633   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
634
635   // Test that when autobw is enabled, bitrate is kept as the default
636   // value. autobw is enabled for the following tests because the target
637   // bitrate is <= 0.
638
639   // ISAC, default bitrate == 32000.
640   TestSendBandwidth(kIsacCodec, 0, true, 32000);
641
642   // PCMU, default bitrate == 64000.
643   TestSendBandwidth(kPcmuCodec, -1, true, 64000);
644
645   // CELT, default bitrate == 64000.
646   TestSendBandwidth(kCeltCodec, 0, true, 64000);
647
648   // opus, default bitrate == 64000.
649   TestSendBandwidth(kOpusCodec, -1, true, 64000);
650 }
651
652 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
653   EXPECT_TRUE(SetupEngine());
654   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
655
656   // Test that the bitrate of a multi-rate codec is always the maximum.
657
658   // ISAC, default bitrate == 32000.
659   TestSendBandwidth(kIsacCodec, 128000, true, 128000);
660   TestSendBandwidth(kIsacCodec, 16000, true, 16000);
661
662   // CELT, default bitrate == 64000.
663   TestSendBandwidth(kCeltCodec, 96000, true, 96000);
664   TestSendBandwidth(kCeltCodec, 32000, true, 32000);
665
666   // opus, default bitrate == 64000.
667   TestSendBandwidth(kOpusCodec, 96000, true, 96000);
668   TestSendBandwidth(kOpusCodec, 48000, true, 48000);
669 }
670
671 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
672   EXPECT_TRUE(SetupEngine());
673   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
674
675   // Test that we can only set a maximum bitrate for a fixed-rate codec
676   // if it's bigger than the fixed rate.
677
678   // PCMU, fixed bitrate == 64000.
679   TestSendBandwidth(kPcmuCodec, 0, true, 64000);
680   TestSendBandwidth(kPcmuCodec, 1, false, 64000);
681   TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
682   TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
683   TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
684   TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
685   TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
686 }
687
688 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
689   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
690   channel_ = engine_.CreateChannel();
691   EXPECT_TRUE(channel_ != NULL);
692   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
693
694   int desired_bitrate = 128000;
695   EXPECT_TRUE(channel_->SetMaxSendBandwidth(desired_bitrate));
696
697   EXPECT_TRUE(channel_->AddSendStream(
698       cricket::StreamParams::CreateLegacy(kSsrc1)));
699
700   int channel_num = voe_.GetLastChannel();
701   webrtc::CodecInst codec;
702   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
703   EXPECT_EQ(desired_bitrate, codec.rate);
704 }
705
706 // Test that bitrate cannot be set for CBR codecs.
707 // Bitrate is ignored if it is higher than the fixed bitrate.
708 // Bitrate less then the fixed bitrate is an error.
709 TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
710   EXPECT_TRUE(SetupEngine());
711   EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
712
713   webrtc::CodecInst codec;
714   int channel_num = voe_.GetLastChannel();
715   std::vector<cricket::AudioCodec> codecs;
716
717   // PCMU, default bitrate == 64000.
718   codecs.push_back(kPcmuCodec);
719   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
720   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
721   EXPECT_EQ(64000, codec.rate);
722   EXPECT_TRUE(channel_->SetMaxSendBandwidth(128000));
723   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
724   EXPECT_EQ(64000, codec.rate);
725   EXPECT_FALSE(channel_->SetMaxSendBandwidth(128));
726   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
727   EXPECT_EQ(64000, codec.rate);
728 }
729
730 // Test that we apply codecs properly.
731 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
732   EXPECT_TRUE(SetupEngine());
733   int channel_num = voe_.GetLastChannel();
734   std::vector<cricket::AudioCodec> codecs;
735   codecs.push_back(kIsacCodec);
736   codecs.push_back(kPcmuCodec);
737   codecs.push_back(kRedCodec);
738   codecs[0].id = 96;
739   codecs[0].bitrate = 48000;
740   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
741   EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
742   webrtc::CodecInst gcodec;
743   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
744   EXPECT_EQ(96, gcodec.pltype);
745   EXPECT_EQ(48000, gcodec.rate);
746   EXPECT_STREQ("ISAC", gcodec.plname);
747   EXPECT_FALSE(voe_.GetVAD(channel_num));
748   EXPECT_FALSE(voe_.GetRED(channel_num));
749   EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
750   EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
751   EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
752 }
753
754 // Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
755 // to apply.
756 TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
757   EXPECT_TRUE(SetupEngine());
758   std::vector<cricket::AudioCodec> codecs;
759   codecs.push_back(kIsacCodec);
760   codecs.push_back(kPcmuCodec);
761   codecs.push_back(kRedCodec);
762   codecs[0].id = 96;
763   codecs[0].bitrate = 48000;
764   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
765   EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
766   // Calling SetSendCodec again with same codec which is already set.
767   // In this case media channel shouldn't send codec to VoE.
768   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
769   EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
770 }
771
772 // Test that if clockrate is not 48000 for opus, we fail.
773 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
774   EXPECT_TRUE(SetupEngine());
775   std::vector<cricket::AudioCodec> codecs;
776   codecs.push_back(kOpusCodec);
777   codecs[0].bitrate = 0;
778   codecs[0].clockrate = 50000;
779   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
780 }
781
782 // Test that if channels=0 for opus, we fail.
783 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
784   EXPECT_TRUE(SetupEngine());
785   std::vector<cricket::AudioCodec> codecs;
786   codecs.push_back(kOpusCodec);
787   codecs[0].bitrate = 0;
788   codecs[0].channels = 0;
789   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
790 }
791
792 // Test that if channels=0 for opus, we fail.
793 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
794   EXPECT_TRUE(SetupEngine());
795   std::vector<cricket::AudioCodec> codecs;
796   codecs.push_back(kOpusCodec);
797   codecs[0].bitrate = 0;
798   codecs[0].channels = 0;
799   codecs[0].params["stereo"] = "1";
800   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
801 }
802
803 // Test that if channel is 1 for opus and there's no stereo, we fail.
804 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
805   EXPECT_TRUE(SetupEngine());
806   std::vector<cricket::AudioCodec> codecs;
807   codecs.push_back(kOpusCodec);
808   codecs[0].bitrate = 0;
809   codecs[0].channels = 1;
810   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
811 }
812
813 // Test that if channel is 1 for opus and stereo=0, we fail.
814 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
815   EXPECT_TRUE(SetupEngine());
816   std::vector<cricket::AudioCodec> codecs;
817   codecs.push_back(kOpusCodec);
818   codecs[0].bitrate = 0;
819   codecs[0].channels = 1;
820   codecs[0].params["stereo"] = "0";
821   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
822 }
823
824 // Test that if channel is 1 for opus and stereo=1, we fail.
825 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
826   EXPECT_TRUE(SetupEngine());
827   std::vector<cricket::AudioCodec> codecs;
828   codecs.push_back(kOpusCodec);
829   codecs[0].bitrate = 0;
830   codecs[0].channels = 1;
831   codecs[0].params["stereo"] = "1";
832   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
833 }
834
835 // Test that with bitrate=0 and no stereo,
836 // channels and bitrate are 1 and 32000.
837 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
838   EXPECT_TRUE(SetupEngine());
839   int channel_num = voe_.GetLastChannel();
840   std::vector<cricket::AudioCodec> codecs;
841   codecs.push_back(kOpusCodec);
842   codecs[0].bitrate = 0;
843   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
844   webrtc::CodecInst gcodec;
845   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
846   EXPECT_STREQ("opus", gcodec.plname);
847   EXPECT_EQ(1, gcodec.channels);
848   EXPECT_EQ(32000, gcodec.rate);
849 }
850
851 // Test that with bitrate=0 and stereo=0,
852 // channels and bitrate are 1 and 32000.
853 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
854   EXPECT_TRUE(SetupEngine());
855   int channel_num = voe_.GetLastChannel();
856   std::vector<cricket::AudioCodec> codecs;
857   codecs.push_back(kOpusCodec);
858   codecs[0].bitrate = 0;
859   codecs[0].params["stereo"] = "0";
860   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
861   webrtc::CodecInst gcodec;
862   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
863   EXPECT_STREQ("opus", gcodec.plname);
864   EXPECT_EQ(1, gcodec.channels);
865   EXPECT_EQ(32000, gcodec.rate);
866 }
867
868 // Test that with bitrate=invalid and stereo=0,
869 // channels and bitrate are 1 and 32000.
870 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
871   EXPECT_TRUE(SetupEngine());
872   int channel_num = voe_.GetLastChannel();
873   std::vector<cricket::AudioCodec> codecs;
874   codecs.push_back(kOpusCodec);
875   codecs[0].params["stereo"] = "0";
876   webrtc::CodecInst gcodec;
877
878   // bitrate that's out of the range between 6000 and 510000 will be considered
879   // as invalid and ignored.
880   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);
885   EXPECT_EQ(32000, gcodec.rate);
886
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);
892   EXPECT_EQ(32000, gcodec.rate);
893 }
894
895 // Test that with bitrate=0 and stereo=1,
896 // channels and bitrate are 2 and 64000.
897 TEST_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
912 // Test that with bitrate=invalid and stereo=1,
913 // channels and bitrate are 2 and 64000.
914 TEST_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
922   // bitrate that's out of the range between 6000 and 510000 will be considered
923   // as invalid and ignored.
924   codecs[0].bitrate = 5999;
925   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
926   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
927   EXPECT_STREQ("opus", gcodec.plname);
928   EXPECT_EQ(2, gcodec.channels);
929   EXPECT_EQ(64000, gcodec.rate);
930
931   codecs[0].bitrate = 510001;
932   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
933   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
934   EXPECT_STREQ("opus", gcodec.plname);
935   EXPECT_EQ(2, gcodec.channels);
936   EXPECT_EQ(64000, gcodec.rate);
937 }
938
939 // Test that with bitrate=N and stereo unset,
940 // channels and bitrate are 1 and N.
941 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
942   EXPECT_TRUE(SetupEngine());
943   int channel_num = voe_.GetLastChannel();
944   std::vector<cricket::AudioCodec> codecs;
945   codecs.push_back(kOpusCodec);
946   codecs[0].bitrate = 96000;
947   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
948   webrtc::CodecInst gcodec;
949   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
950   EXPECT_EQ(111, gcodec.pltype);
951   EXPECT_EQ(96000, gcodec.rate);
952   EXPECT_STREQ("opus", gcodec.plname);
953   EXPECT_EQ(1, gcodec.channels);
954   EXPECT_EQ(48000, gcodec.plfreq);
955 }
956
957 // Test that with bitrate=N and stereo=0,
958 // channels and bitrate are 1 and N.
959 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
960   EXPECT_TRUE(SetupEngine());
961   int channel_num = voe_.GetLastChannel();
962   std::vector<cricket::AudioCodec> codecs;
963   codecs.push_back(kOpusCodec);
964   codecs[0].bitrate = 30000;
965   codecs[0].params["stereo"] = "0";
966   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
967   webrtc::CodecInst gcodec;
968   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
969   EXPECT_EQ(1, gcodec.channels);
970   EXPECT_EQ(30000, gcodec.rate);
971   EXPECT_STREQ("opus", gcodec.plname);
972 }
973
974 // Test that with bitrate=N and without any parameters,
975 // channels and bitrate are 1 and N.
976 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
977   EXPECT_TRUE(SetupEngine());
978   int channel_num = voe_.GetLastChannel();
979   std::vector<cricket::AudioCodec> codecs;
980   codecs.push_back(kOpusCodec);
981   codecs[0].bitrate = 30000;
982   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
983   webrtc::CodecInst gcodec;
984   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
985   EXPECT_EQ(1, gcodec.channels);
986   EXPECT_EQ(30000, gcodec.rate);
987   EXPECT_STREQ("opus", gcodec.plname);
988 }
989
990 // Test that with bitrate=N and stereo=1,
991 // channels and bitrate are 2 and N.
992 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
993   EXPECT_TRUE(SetupEngine());
994   int channel_num = voe_.GetLastChannel();
995   std::vector<cricket::AudioCodec> codecs;
996   codecs.push_back(kOpusCodec);
997   codecs[0].bitrate = 30000;
998   codecs[0].params["stereo"] = "1";
999   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1000   webrtc::CodecInst gcodec;
1001   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1002   EXPECT_EQ(2, gcodec.channels);
1003   EXPECT_EQ(30000, gcodec.rate);
1004   EXPECT_STREQ("opus", gcodec.plname);
1005 }
1006
1007 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1008 // Also test that the "maxaveragebitrate" can't be set to values outside the
1009 // range of 6000 and 510000
1010 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1011   EXPECT_TRUE(SetupEngine());
1012   int channel_num = voe_.GetLastChannel();
1013   std::vector<cricket::AudioCodec> codecs;
1014   codecs.push_back(kOpusCodec);
1015   codecs[0].bitrate = 30000;
1016   webrtc::CodecInst gcodec;
1017
1018   // Ignore if less than 6000.
1019   codecs[0].params["maxaveragebitrate"] = "5999";
1020   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1021   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1022   EXPECT_EQ(30000, gcodec.rate);
1023
1024   // Ignore if larger than 510000.
1025   codecs[0].params["maxaveragebitrate"] = "510001";
1026   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1027   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1028   EXPECT_EQ(30000, gcodec.rate);
1029
1030   codecs[0].params["maxaveragebitrate"] = "200000";
1031   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1032   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1033   EXPECT_EQ(200000, gcodec.rate);
1034 }
1035
1036 // Test that we can enable NACK with opus as caller.
1037 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
1038   EXPECT_TRUE(SetupEngine());
1039   int channel_num = voe_.GetLastChannel();
1040   std::vector<cricket::AudioCodec> codecs;
1041   codecs.push_back(kOpusCodec);
1042   codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1043                                                     cricket::kParamValueEmpty));
1044   EXPECT_FALSE(voe_.GetNACK(channel_num));
1045   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1046   EXPECT_TRUE(voe_.GetNACK(channel_num));
1047 }
1048
1049 // Test that we can enable NACK with opus as callee.
1050 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1051   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1052   channel_ = engine_.CreateChannel();
1053   EXPECT_TRUE(channel_ != NULL);
1054
1055   int channel_num = voe_.GetLastChannel();
1056   std::vector<cricket::AudioCodec> codecs;
1057   codecs.push_back(kOpusCodec);
1058   codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1059                                                     cricket::kParamValueEmpty));
1060   EXPECT_FALSE(voe_.GetNACK(channel_num));
1061   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1062   EXPECT_FALSE(voe_.GetNACK(channel_num));
1063
1064   EXPECT_TRUE(channel_->AddSendStream(
1065       cricket::StreamParams::CreateLegacy(kSsrc1)));
1066   EXPECT_TRUE(voe_.GetNACK(channel_num));
1067 }
1068
1069 // Test that we can enable NACK on receive streams.
1070 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1071   EXPECT_TRUE(SetupEngine());
1072   EXPECT_TRUE(channel_->SetOptions(options_conference_));
1073   int channel_num1 = voe_.GetLastChannel();
1074   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1075   int channel_num2 = voe_.GetLastChannel();
1076   std::vector<cricket::AudioCodec> codecs;
1077   codecs.push_back(kOpusCodec);
1078   codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1079                                                     cricket::kParamValueEmpty));
1080   EXPECT_FALSE(voe_.GetNACK(channel_num1));
1081   EXPECT_FALSE(voe_.GetNACK(channel_num2));
1082   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1083   EXPECT_TRUE(voe_.GetNACK(channel_num1));
1084   EXPECT_TRUE(voe_.GetNACK(channel_num2));
1085 }
1086
1087 // Test that we can disable NACK.
1088 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1089   EXPECT_TRUE(SetupEngine());
1090   int channel_num = voe_.GetLastChannel();
1091   std::vector<cricket::AudioCodec> codecs;
1092   codecs.push_back(kOpusCodec);
1093   codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1094                                                     cricket::kParamValueEmpty));
1095   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1096   EXPECT_TRUE(voe_.GetNACK(channel_num));
1097
1098   codecs.clear();
1099   codecs.push_back(kOpusCodec);
1100   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1101   EXPECT_FALSE(voe_.GetNACK(channel_num));
1102 }
1103
1104 // Test that we can disable NACK on receive streams.
1105 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1106   EXPECT_TRUE(SetupEngine());
1107   EXPECT_TRUE(channel_->SetOptions(options_conference_));
1108   int channel_num1 = voe_.GetLastChannel();
1109   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1110   int channel_num2 = voe_.GetLastChannel();
1111   std::vector<cricket::AudioCodec> codecs;
1112   codecs.push_back(kOpusCodec);
1113   codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1114                                                     cricket::kParamValueEmpty));
1115   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1116   EXPECT_TRUE(voe_.GetNACK(channel_num1));
1117   EXPECT_TRUE(voe_.GetNACK(channel_num2));
1118
1119   codecs.clear();
1120   codecs.push_back(kOpusCodec);
1121   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1122   EXPECT_FALSE(voe_.GetNACK(channel_num1));
1123   EXPECT_FALSE(voe_.GetNACK(channel_num2));
1124 }
1125
1126 // Test that NACK is enabled on a new receive stream.
1127 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1128   EXPECT_TRUE(SetupEngine());
1129   EXPECT_TRUE(channel_->SetOptions(options_conference_));
1130   int channel_num = voe_.GetLastChannel();
1131   std::vector<cricket::AudioCodec> codecs;
1132   codecs.push_back(kIsacCodec);
1133   codecs[0].AddFeedbackParam(cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1134                                                     cricket::kParamValueEmpty));
1135   codecs.push_back(kCn16000Codec);
1136   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1137   EXPECT_TRUE(voe_.GetNACK(channel_num));
1138
1139   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1140   channel_num = voe_.GetLastChannel();
1141   EXPECT_TRUE(voe_.GetNACK(channel_num));
1142   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1143   channel_num = voe_.GetLastChannel();
1144   EXPECT_TRUE(voe_.GetNACK(channel_num));
1145 }
1146
1147 #ifdef USE_WEBRTC_DEV_BRANCH
1148 // Test that without useinbandfec, Opus FEC is off.
1149 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
1150   EXPECT_TRUE(SetupEngine());
1151   int channel_num = voe_.GetLastChannel();
1152   std::vector<cricket::AudioCodec> codecs;
1153   codecs.push_back(kOpusCodec);
1154   codecs[0].bitrate = 0;
1155   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1156   EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1157 }
1158
1159 // Test that with useinbandfec=0, Opus FEC is off.
1160 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
1161   EXPECT_TRUE(SetupEngine());
1162   int channel_num = voe_.GetLastChannel();
1163   std::vector<cricket::AudioCodec> codecs;
1164   codecs.push_back(kOpusCodec);
1165   codecs[0].bitrate = 0;
1166   codecs[0].params["useinbandfec"] = "0";
1167   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1168   EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1169   webrtc::CodecInst gcodec;
1170   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1171   EXPECT_STREQ("opus", gcodec.plname);
1172   EXPECT_EQ(1, gcodec.channels);
1173   EXPECT_EQ(32000, gcodec.rate);
1174 }
1175
1176 // Test that with useinbandfec=1, Opus FEC is on.
1177 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
1178   EXPECT_TRUE(SetupEngine());
1179   int channel_num = voe_.GetLastChannel();
1180   std::vector<cricket::AudioCodec> codecs;
1181   codecs.push_back(kOpusCodec);
1182   codecs[0].bitrate = 0;
1183   codecs[0].params["useinbandfec"] = "1";
1184   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1185   EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1186   webrtc::CodecInst gcodec;
1187   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1188   EXPECT_STREQ("opus", gcodec.plname);
1189   EXPECT_EQ(1, gcodec.channels);
1190   EXPECT_EQ(32000, gcodec.rate);
1191 }
1192
1193 // Test that with useinbandfec=1, stereo=1, Opus FEC is on.
1194 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
1195   EXPECT_TRUE(SetupEngine());
1196   int channel_num = voe_.GetLastChannel();
1197   std::vector<cricket::AudioCodec> codecs;
1198   codecs.push_back(kOpusCodec);
1199   codecs[0].bitrate = 0;
1200   codecs[0].params["stereo"] = "1";
1201   codecs[0].params["useinbandfec"] = "1";
1202   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1203   EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1204   webrtc::CodecInst gcodec;
1205   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1206   EXPECT_STREQ("opus", gcodec.plname);
1207   EXPECT_EQ(2, gcodec.channels);
1208   EXPECT_EQ(64000, gcodec.rate);
1209 }
1210
1211 // Test that with non-Opus, codec FEC is off.
1212 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
1213   EXPECT_TRUE(SetupEngine());
1214   int channel_num = voe_.GetLastChannel();
1215   std::vector<cricket::AudioCodec> codecs;
1216   codecs.push_back(kIsacCodec);
1217   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1218   EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1219 }
1220
1221 // Test the with non-Opus, even if useinbandfec=1, FEC is off.
1222 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1223   EXPECT_TRUE(SetupEngine());
1224   int channel_num = voe_.GetLastChannel();
1225   std::vector<cricket::AudioCodec> codecs;
1226   codecs.push_back(kIsacCodec);
1227   codecs[0].params["useinbandfec"] = "1";
1228   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1229   EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1230 }
1231 #endif  // USE_WEBRTC_DEV_BRANCH
1232
1233 // Test AudioOptions controls whether opus FEC is supported in codec list.
1234 TEST_F(WebRtcVoiceEngineTestFake, OpusFecViaOptions) {
1235   EXPECT_TRUE(SetupEngine());
1236   std::vector<cricket::AudioCodec> codecs = engine_.codecs();
1237   int value;
1238   for (std::vector<cricket::AudioCodec>::const_iterator it = codecs.begin();
1239       it != codecs.end(); ++it) {
1240     if (_stricmp(it->name.c_str(), cricket::kOpusCodecName) == 0) {
1241       EXPECT_FALSE(it->GetParam(cricket::kCodecParamUseInbandFec, &value));
1242     }
1243   }
1244
1245   cricket::AudioOptions options;
1246   options.opus_fec.Set(true);
1247   EXPECT_TRUE(engine_.SetOptions(options));
1248   codecs = engine_.codecs();
1249   for (std::vector<cricket::AudioCodec>::const_iterator it = codecs.begin();
1250       it != codecs.end(); ++it) {
1251     if (_stricmp(it->name.c_str(), cricket::kOpusCodecName) == 0) {
1252       EXPECT_TRUE(it->GetParam(cricket::kCodecParamUseInbandFec, &value));
1253       EXPECT_EQ(1, value);
1254     }
1255   }
1256 }
1257
1258 // Test that we can apply CELT with stereo mode but fail with mono mode.
1259 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCelt) {
1260   EXPECT_TRUE(SetupEngine());
1261   int channel_num = voe_.GetLastChannel();
1262   std::vector<cricket::AudioCodec> codecs;
1263   codecs.push_back(kCeltCodec);
1264   codecs.push_back(kIsacCodec);
1265   codecs[0].id = 96;
1266   codecs[0].channels = 2;
1267   codecs[0].bitrate = 96000;
1268   codecs[1].bitrate = 64000;
1269   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1270   webrtc::CodecInst gcodec;
1271   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1272   EXPECT_EQ(96, gcodec.pltype);
1273   EXPECT_EQ(96000, gcodec.rate);
1274   EXPECT_EQ(2, gcodec.channels);
1275   EXPECT_STREQ("CELT", gcodec.plname);
1276   // Doesn't support mono, expect it to fall back to the next codec in the list.
1277   codecs[0].channels = 1;
1278   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1279   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1280   EXPECT_EQ(103, gcodec.pltype);
1281   EXPECT_EQ(1, gcodec.channels);
1282   EXPECT_EQ(64000, gcodec.rate);
1283   EXPECT_STREQ("ISAC", gcodec.plname);
1284 }
1285
1286 // Test that we can switch back and forth between CELT and ISAC with CN.
1287 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacCeltSwitching) {
1288   EXPECT_TRUE(SetupEngine());
1289   int channel_num = voe_.GetLastChannel();
1290   std::vector<cricket::AudioCodec> celt_codecs;
1291   celt_codecs.push_back(kCeltCodec);
1292   EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1293   webrtc::CodecInst gcodec;
1294   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1295   EXPECT_EQ(110, gcodec.pltype);
1296   EXPECT_STREQ("CELT", gcodec.plname);
1297
1298   std::vector<cricket::AudioCodec> isac_codecs;
1299   isac_codecs.push_back(kIsacCodec);
1300   isac_codecs.push_back(kCn16000Codec);
1301   isac_codecs.push_back(kCeltCodec);
1302   EXPECT_TRUE(channel_->SetSendCodecs(isac_codecs));
1303   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1304   EXPECT_EQ(103, gcodec.pltype);
1305   EXPECT_STREQ("ISAC", gcodec.plname);
1306
1307   EXPECT_TRUE(channel_->SetSendCodecs(celt_codecs));
1308   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1309   EXPECT_EQ(110, gcodec.pltype);
1310   EXPECT_STREQ("CELT", gcodec.plname);
1311 }
1312
1313 // Test that we handle various ways of specifying bitrate.
1314 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1315   EXPECT_TRUE(SetupEngine());
1316   int channel_num = voe_.GetLastChannel();
1317   std::vector<cricket::AudioCodec> codecs;
1318   codecs.push_back(kIsacCodec);  // bitrate == 32000
1319   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1320   webrtc::CodecInst gcodec;
1321   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1322   EXPECT_EQ(103, gcodec.pltype);
1323   EXPECT_STREQ("ISAC", gcodec.plname);
1324   EXPECT_EQ(32000, gcodec.rate);
1325
1326   codecs[0].bitrate = 0;         // bitrate == default
1327   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1328   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1329   EXPECT_EQ(103, gcodec.pltype);
1330   EXPECT_STREQ("ISAC", gcodec.plname);
1331   EXPECT_EQ(-1, gcodec.rate);
1332
1333   codecs[0].bitrate = 28000;     // bitrate == 28000
1334   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1335   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1336   EXPECT_EQ(103, gcodec.pltype);
1337   EXPECT_STREQ("ISAC", gcodec.plname);
1338   EXPECT_EQ(28000, gcodec.rate);
1339
1340   codecs[0] = kPcmuCodec;        // bitrate == 64000
1341   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1342   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1343   EXPECT_EQ(0, gcodec.pltype);
1344   EXPECT_STREQ("PCMU", gcodec.plname);
1345   EXPECT_EQ(64000, gcodec.rate);
1346
1347   codecs[0].bitrate = 0;         // bitrate == default
1348   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1349   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1350   EXPECT_EQ(0, gcodec.pltype);
1351   EXPECT_STREQ("PCMU", gcodec.plname);
1352   EXPECT_EQ(64000, gcodec.rate);
1353
1354   codecs[0] = kOpusCodec;
1355   codecs[0].bitrate = 0;         // bitrate == default
1356   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1357   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1358   EXPECT_EQ(111, gcodec.pltype);
1359   EXPECT_STREQ("opus", gcodec.plname);
1360   EXPECT_EQ(32000, gcodec.rate);
1361 }
1362
1363 // Test that we fail if no codecs are specified.
1364 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1365   EXPECT_TRUE(SetupEngine());
1366   std::vector<cricket::AudioCodec> codecs;
1367   EXPECT_FALSE(channel_->SetSendCodecs(codecs));
1368 }
1369
1370 // Test that we can set send codecs even with telephone-event codec as the first
1371 // one on the list.
1372 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1373   EXPECT_TRUE(SetupEngine());
1374   int channel_num = voe_.GetLastChannel();
1375   std::vector<cricket::AudioCodec> codecs;
1376   codecs.push_back(kTelephoneEventCodec);
1377   codecs.push_back(kIsacCodec);
1378   codecs.push_back(kPcmuCodec);
1379   codecs[0].id = 98;  // DTMF
1380   codecs[1].id = 96;
1381   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1382   webrtc::CodecInst gcodec;
1383   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1384   EXPECT_EQ(96, gcodec.pltype);
1385   EXPECT_STREQ("ISAC", gcodec.plname);
1386   EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1387 }
1388
1389 // Test that we can set send codecs even with CN codec as the first
1390 // one on the list.
1391 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1392   EXPECT_TRUE(SetupEngine());
1393   int channel_num = voe_.GetLastChannel();
1394   std::vector<cricket::AudioCodec> codecs;
1395   codecs.push_back(kCn16000Codec);
1396   codecs.push_back(kIsacCodec);
1397   codecs.push_back(kPcmuCodec);
1398   codecs[0].id = 98;  // wideband CN
1399   codecs[1].id = 96;
1400   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1401   webrtc::CodecInst gcodec;
1402   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1403   EXPECT_EQ(96, gcodec.pltype);
1404   EXPECT_STREQ("ISAC", gcodec.plname);
1405   EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
1406 }
1407
1408 // Test that we set VAD and DTMF types correctly as caller.
1409 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
1410   EXPECT_TRUE(SetupEngine());
1411   int channel_num = voe_.GetLastChannel();
1412   std::vector<cricket::AudioCodec> codecs;
1413   codecs.push_back(kIsacCodec);
1414   codecs.push_back(kPcmuCodec);
1415   // TODO(juberti): cn 32000
1416   codecs.push_back(kCn16000Codec);
1417   codecs.push_back(kCn8000Codec);
1418   codecs.push_back(kTelephoneEventCodec);
1419   codecs.push_back(kRedCodec);
1420   codecs[0].id = 96;
1421   codecs[2].id = 97;  // wideband CN
1422   codecs[4].id = 98;  // DTMF
1423   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1424   webrtc::CodecInst gcodec;
1425   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1426   EXPECT_EQ(96, gcodec.pltype);
1427   EXPECT_STREQ("ISAC", gcodec.plname);
1428   EXPECT_TRUE(voe_.GetVAD(channel_num));
1429   EXPECT_FALSE(voe_.GetRED(channel_num));
1430   EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1431   EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1432   EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1433 }
1434
1435 // Test that we set VAD and DTMF types correctly as callee.
1436 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1437   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1438   channel_ = engine_.CreateChannel();
1439   EXPECT_TRUE(channel_ != NULL);
1440
1441   int channel_num = voe_.GetLastChannel();
1442   std::vector<cricket::AudioCodec> codecs;
1443   codecs.push_back(kIsacCodec);
1444   codecs.push_back(kPcmuCodec);
1445   // TODO(juberti): cn 32000
1446   codecs.push_back(kCn16000Codec);
1447   codecs.push_back(kCn8000Codec);
1448   codecs.push_back(kTelephoneEventCodec);
1449   codecs.push_back(kRedCodec);
1450   codecs[0].id = 96;
1451   codecs[2].id = 97;  // wideband CN
1452   codecs[4].id = 98;  // DTMF
1453   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1454   EXPECT_TRUE(channel_->AddSendStream(
1455       cricket::StreamParams::CreateLegacy(kSsrc1)));
1456
1457   webrtc::CodecInst gcodec;
1458   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1459   EXPECT_EQ(96, gcodec.pltype);
1460   EXPECT_STREQ("ISAC", gcodec.plname);
1461   EXPECT_TRUE(voe_.GetVAD(channel_num));
1462   EXPECT_FALSE(voe_.GetRED(channel_num));
1463   EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1464   EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1465   EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1466 }
1467
1468 // Test that we only apply VAD if we have a CN codec that matches the
1469 // send codec clockrate.
1470 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1471   EXPECT_TRUE(SetupEngine());
1472   int channel_num = voe_.GetLastChannel();
1473   std::vector<cricket::AudioCodec> codecs;
1474   // Set ISAC(16K) and CN(16K). VAD should be activated.
1475   codecs.push_back(kIsacCodec);
1476   codecs.push_back(kCn16000Codec);
1477   codecs[1].id = 97;
1478   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1479   webrtc::CodecInst gcodec;
1480   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1481   EXPECT_STREQ("ISAC", gcodec.plname);
1482   EXPECT_TRUE(voe_.GetVAD(channel_num));
1483   EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1484   // Set PCMU(8K) and CN(16K). VAD should not be activated.
1485   codecs[0] = kPcmuCodec;
1486   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1487   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1488   EXPECT_STREQ("PCMU", gcodec.plname);
1489   EXPECT_FALSE(voe_.GetVAD(channel_num));
1490   // Set PCMU(8K) and CN(8K). VAD should be activated.
1491   codecs[1] = kCn8000Codec;
1492   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1493   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1494   EXPECT_STREQ("PCMU", gcodec.plname);
1495   EXPECT_TRUE(voe_.GetVAD(channel_num));
1496   EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1497    // Set ISAC(16K) and CN(8K). VAD should not be activated.
1498   codecs[0] = kIsacCodec;
1499   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1500   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1501   EXPECT_STREQ("ISAC", gcodec.plname);
1502   EXPECT_FALSE(voe_.GetVAD(channel_num));
1503 }
1504
1505 // Test that we perform case-insensitive matching of codec names.
1506 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1507   EXPECT_TRUE(SetupEngine());
1508   int channel_num = voe_.GetLastChannel();
1509   std::vector<cricket::AudioCodec> codecs;
1510   codecs.push_back(kIsacCodec);
1511   codecs.push_back(kPcmuCodec);
1512   codecs.push_back(kCn16000Codec);
1513   codecs.push_back(kCn8000Codec);
1514   codecs.push_back(kTelephoneEventCodec);
1515   codecs.push_back(kRedCodec);
1516   codecs[0].name = "iSaC";
1517   codecs[0].id = 96;
1518   codecs[2].id = 97;  // wideband CN
1519   codecs[4].id = 98;  // DTMF
1520   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1521   webrtc::CodecInst gcodec;
1522   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1523   EXPECT_EQ(96, gcodec.pltype);
1524   EXPECT_STREQ("ISAC", gcodec.plname);
1525   EXPECT_TRUE(voe_.GetVAD(channel_num));
1526   EXPECT_FALSE(voe_.GetRED(channel_num));
1527   EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1528   EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1529   EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
1530 }
1531
1532 // Test that we set up RED correctly as caller.
1533 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
1534   EXPECT_TRUE(SetupEngine());
1535   int channel_num = voe_.GetLastChannel();
1536   std::vector<cricket::AudioCodec> codecs;
1537   codecs.push_back(kRedCodec);
1538   codecs.push_back(kIsacCodec);
1539   codecs.push_back(kPcmuCodec);
1540   codecs[0].id = 127;
1541   codecs[0].params[""] = "96/96";
1542   codecs[1].id = 96;
1543   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1544   webrtc::CodecInst gcodec;
1545   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1546   EXPECT_EQ(96, gcodec.pltype);
1547   EXPECT_STREQ("ISAC", gcodec.plname);
1548   EXPECT_TRUE(voe_.GetRED(channel_num));
1549   EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1550 }
1551
1552 // Test that we set up RED correctly as callee.
1553 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1554   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1555   channel_ = engine_.CreateChannel();
1556   EXPECT_TRUE(channel_ != NULL);
1557
1558   int channel_num = voe_.GetLastChannel();
1559   std::vector<cricket::AudioCodec> codecs;
1560   codecs.push_back(kRedCodec);
1561   codecs.push_back(kIsacCodec);
1562   codecs.push_back(kPcmuCodec);
1563   codecs[0].id = 127;
1564   codecs[0].params[""] = "96/96";
1565   codecs[1].id = 96;
1566   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1567   EXPECT_TRUE(channel_->AddSendStream(
1568       cricket::StreamParams::CreateLegacy(kSsrc1)));
1569   webrtc::CodecInst gcodec;
1570   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1571   EXPECT_EQ(96, gcodec.pltype);
1572   EXPECT_STREQ("ISAC", gcodec.plname);
1573   EXPECT_TRUE(voe_.GetRED(channel_num));
1574   EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1575 }
1576
1577 // Test that we set up RED correctly if params are omitted.
1578 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1579   EXPECT_TRUE(SetupEngine());
1580   int channel_num = voe_.GetLastChannel();
1581   std::vector<cricket::AudioCodec> codecs;
1582   codecs.push_back(kRedCodec);
1583   codecs.push_back(kIsacCodec);
1584   codecs.push_back(kPcmuCodec);
1585   codecs[0].id = 127;
1586   codecs[1].id = 96;
1587   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1588   webrtc::CodecInst gcodec;
1589   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1590   EXPECT_EQ(96, gcodec.pltype);
1591   EXPECT_STREQ("ISAC", gcodec.plname);
1592   EXPECT_TRUE(voe_.GetRED(channel_num));
1593   EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1594 }
1595
1596 // Test that we ignore RED if the parameters aren't named the way we expect.
1597 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1598   EXPECT_TRUE(SetupEngine());
1599   int channel_num = voe_.GetLastChannel();
1600   std::vector<cricket::AudioCodec> codecs;
1601   codecs.push_back(kRedCodec);
1602   codecs.push_back(kIsacCodec);
1603   codecs.push_back(kPcmuCodec);
1604   codecs[0].id = 127;
1605   codecs[0].params["ABC"] = "96/96";
1606   codecs[1].id = 96;
1607   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1608   webrtc::CodecInst gcodec;
1609   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1610   EXPECT_EQ(96, gcodec.pltype);
1611   EXPECT_STREQ("ISAC", gcodec.plname);
1612   EXPECT_FALSE(voe_.GetRED(channel_num));
1613 }
1614
1615 // Test that we ignore RED if it uses different primary/secondary encoding.
1616 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1617   EXPECT_TRUE(SetupEngine());
1618   int channel_num = voe_.GetLastChannel();
1619   std::vector<cricket::AudioCodec> codecs;
1620   codecs.push_back(kRedCodec);
1621   codecs.push_back(kIsacCodec);
1622   codecs.push_back(kPcmuCodec);
1623   codecs[0].id = 127;
1624   codecs[0].params[""] = "96/0";
1625   codecs[1].id = 96;
1626   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1627   webrtc::CodecInst gcodec;
1628   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1629   EXPECT_EQ(96, gcodec.pltype);
1630   EXPECT_STREQ("ISAC", gcodec.plname);
1631   EXPECT_FALSE(voe_.GetRED(channel_num));
1632 }
1633
1634 // Test that we ignore RED if it uses more than 2 encodings.
1635 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1636   EXPECT_TRUE(SetupEngine());
1637   int channel_num = voe_.GetLastChannel();
1638   std::vector<cricket::AudioCodec> codecs;
1639   codecs.push_back(kRedCodec);
1640   codecs.push_back(kIsacCodec);
1641   codecs.push_back(kPcmuCodec);
1642   codecs[0].id = 127;
1643   codecs[0].params[""] = "96/96/96";
1644   codecs[1].id = 96;
1645   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1646   webrtc::CodecInst gcodec;
1647   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1648   EXPECT_EQ(96, gcodec.pltype);
1649   EXPECT_STREQ("ISAC", gcodec.plname);
1650   EXPECT_FALSE(voe_.GetRED(channel_num));
1651 }
1652
1653 // Test that we ignore RED if it has bogus codec ids.
1654 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1655   EXPECT_TRUE(SetupEngine());
1656   int channel_num = voe_.GetLastChannel();
1657   std::vector<cricket::AudioCodec> codecs;
1658   codecs.push_back(kRedCodec);
1659   codecs.push_back(kIsacCodec);
1660   codecs.push_back(kPcmuCodec);
1661   codecs[0].id = 127;
1662   codecs[0].params[""] = "ABC/ABC";
1663   codecs[1].id = 96;
1664   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1665   webrtc::CodecInst gcodec;
1666   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1667   EXPECT_EQ(96, gcodec.pltype);
1668   EXPECT_STREQ("ISAC", gcodec.plname);
1669   EXPECT_FALSE(voe_.GetRED(channel_num));
1670 }
1671
1672 // Test that we ignore RED if it refers to a codec that is not present.
1673 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1674   EXPECT_TRUE(SetupEngine());
1675   int channel_num = voe_.GetLastChannel();
1676   std::vector<cricket::AudioCodec> codecs;
1677   codecs.push_back(kRedCodec);
1678   codecs.push_back(kIsacCodec);
1679   codecs.push_back(kPcmuCodec);
1680   codecs[0].id = 127;
1681   codecs[0].params[""] = "97/97";
1682   codecs[1].id = 96;
1683   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1684   webrtc::CodecInst gcodec;
1685   EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1686   EXPECT_EQ(96, gcodec.pltype);
1687   EXPECT_STREQ("ISAC", gcodec.plname);
1688   EXPECT_FALSE(voe_.GetRED(channel_num));
1689 }
1690
1691 // Test support for audio level header extension.
1692 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1693   TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1694 }
1695 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1696   TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1697 }
1698
1699 // Test support for absolute send time header extension.
1700 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1701   TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1702 }
1703 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1704   TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1705 }
1706
1707 // Test that we can create a channel and start sending/playing out on it.
1708 TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
1709   EXPECT_TRUE(SetupEngine());
1710   int channel_num = voe_.GetLastChannel();
1711   std::vector<cricket::AudioCodec> codecs;
1712   codecs.push_back(kPcmuCodec);
1713   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1714   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1715   EXPECT_TRUE(voe_.GetSend(channel_num));
1716   EXPECT_TRUE(channel_->SetPlayout(true));
1717   EXPECT_TRUE(voe_.GetPlayout(channel_num));
1718   EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1719   EXPECT_FALSE(voe_.GetSend(channel_num));
1720   EXPECT_TRUE(channel_->SetPlayout(false));
1721   EXPECT_FALSE(voe_.GetPlayout(channel_num));
1722 }
1723
1724 // Test that we can add and remove send streams.
1725 TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1726   SetupForMultiSendStream();
1727
1728   static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1729
1730   // Set the global state for sending.
1731   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1732
1733   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1734     EXPECT_TRUE(channel_->AddSendStream(
1735         cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1736
1737     // Verify that we are in a sending state for all the created streams.
1738     int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1739     EXPECT_TRUE(voe_.GetSend(channel_num));
1740   }
1741
1742   // Remove the first send channel, which is the default channel. It will only
1743   // recycle the default channel but not delete it.
1744   EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[0]));
1745   // Stream should already be Removed from the send stream list.
1746   EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[0]));
1747   // But the default still exists.
1748   EXPECT_EQ(0, voe_.GetChannelFromLocalSsrc(kSsrcs4[0]));
1749
1750   // Delete the rest of send channel streams.
1751   for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1752     EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[i]));
1753     // Stream should already be deleted.
1754     EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[i]));
1755     EXPECT_EQ(-1, voe_.GetChannelFromLocalSsrc(kSsrcs4[i]));
1756   }
1757 }
1758
1759 // Test SetSendCodecs correctly configure the codecs in all send streams.
1760 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1761   SetupForMultiSendStream();
1762
1763   static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1764   // Create send streams.
1765   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1766     EXPECT_TRUE(channel_->AddSendStream(
1767         cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1768   }
1769
1770   std::vector<cricket::AudioCodec> codecs;
1771   // Set ISAC(16K) and CN(16K). VAD should be activated.
1772   codecs.push_back(kIsacCodec);
1773   codecs.push_back(kCn16000Codec);
1774   codecs[1].id = 97;
1775   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1776
1777   // Verify ISAC and VAD are corrected configured on all send channels.
1778   webrtc::CodecInst gcodec;
1779   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1780     int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1781     EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1782     EXPECT_STREQ("ISAC", gcodec.plname);
1783     EXPECT_TRUE(voe_.GetVAD(channel_num));
1784     EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1785   }
1786
1787   // Change to PCMU(8K) and CN(16K). VAD should not be activated.
1788   codecs[0] = kPcmuCodec;
1789   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1790   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1791     int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1792     EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1793     EXPECT_STREQ("PCMU", gcodec.plname);
1794     EXPECT_FALSE(voe_.GetVAD(channel_num));
1795   }
1796 }
1797
1798 // Test we can SetSend on all send streams correctly.
1799 TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
1800   SetupForMultiSendStream();
1801
1802   static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1803   // Create the send channels and they should be a SEND_NOTHING date.
1804   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1805     EXPECT_TRUE(channel_->AddSendStream(
1806         cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1807     int channel_num = voe_.GetLastChannel();
1808     EXPECT_FALSE(voe_.GetSend(channel_num));
1809   }
1810
1811   // Set the global state for starting sending.
1812   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1813   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1814     // Verify that we are in a sending state for all the send streams.
1815     int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1816     EXPECT_TRUE(voe_.GetSend(channel_num));
1817   }
1818
1819   // Set the global state for stopping sending.
1820   EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1821   for (unsigned int i = 1; i < ARRAY_SIZE(kSsrcs4); ++i) {
1822     // Verify that we are in a stop state for all the send streams.
1823     int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
1824     EXPECT_FALSE(voe_.GetSend(channel_num));
1825   }
1826 }
1827
1828 // Test we can set the correct statistics on all send streams.
1829 TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
1830   SetupForMultiSendStream();
1831
1832   static const uint32 kSsrcs4[] = {1, 2, 3, 4};
1833   // Create send streams.
1834   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1835     EXPECT_TRUE(channel_->AddSendStream(
1836         cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1837   }
1838   // Create a receive stream to check that none of the send streams end up in
1839   // the receive stream stats.
1840   EXPECT_TRUE(channel_->AddRecvStream(
1841       cricket::StreamParams::CreateLegacy(kSsrc2)));
1842   // We need send codec to be set to get all stats.
1843   std::vector<cricket::AudioCodec> codecs;
1844   codecs.push_back(kPcmuCodec);
1845   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1846   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1847
1848   cricket::VoiceMediaInfo info;
1849   EXPECT_EQ(true, channel_->GetStats(&info));
1850   EXPECT_EQ(static_cast<size_t>(ARRAY_SIZE(kSsrcs4)), info.senders.size());
1851
1852   // Verify the statistic information is correct.
1853   for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
1854     EXPECT_EQ(kSsrcs4[i], info.senders[i].ssrc());
1855     EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1856     EXPECT_EQ(cricket::kIntStatValue, info.senders[i].bytes_sent);
1857     EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_sent);
1858     EXPECT_EQ(cricket::kIntStatValue, info.senders[i].packets_lost);
1859     EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[i].fraction_lost);
1860     EXPECT_EQ(cricket::kIntStatValue, info.senders[i].ext_seqnum);
1861     EXPECT_EQ(cricket::kIntStatValue, info.senders[i].rtt_ms);
1862     EXPECT_EQ(cricket::kIntStatValue, info.senders[i].jitter_ms);
1863     EXPECT_EQ(kPcmuCodec.name, info.senders[i].codec_name);
1864   }
1865
1866   EXPECT_EQ(0u, info.receivers.size());
1867   DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
1868   EXPECT_EQ(true, channel_->GetStats(&info));
1869
1870   EXPECT_EQ(1u, info.receivers.size());
1871   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
1872   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
1873   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
1874   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
1875   EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
1876 }
1877
1878 // Test that we can add and remove receive streams, and do proper send/playout.
1879 // We can receive on multiple streams while sending one stream.
1880 TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
1881   EXPECT_TRUE(SetupEngine());
1882   int channel_num1 = voe_.GetLastChannel();
1883
1884   // Start playout on the default channel.
1885   EXPECT_TRUE(channel_->SetOptions(options_conference_));
1886   EXPECT_TRUE(channel_->SetPlayout(true));
1887   EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1888
1889   // Adding another stream should disable playout on the default channel.
1890   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1891   int channel_num2 = voe_.GetLastChannel();
1892   std::vector<cricket::AudioCodec> codecs;
1893   codecs.push_back(kPcmuCodec);
1894   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1895   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1896   EXPECT_TRUE(voe_.GetSend(channel_num1));
1897   EXPECT_FALSE(voe_.GetSend(channel_num2));
1898
1899   // Make sure only the new channel is played out.
1900   EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1901   EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1902
1903   // Adding yet another stream should have stream 2 and 3 enabled for playout.
1904   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1905   int channel_num3 = voe_.GetLastChannel();
1906   EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1907   EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1908   EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1909   EXPECT_FALSE(voe_.GetSend(channel_num3));
1910
1911   // Stop sending.
1912   EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1913   EXPECT_FALSE(voe_.GetSend(channel_num1));
1914   EXPECT_FALSE(voe_.GetSend(channel_num2));
1915   EXPECT_FALSE(voe_.GetSend(channel_num3));
1916
1917   // Stop playout.
1918   EXPECT_TRUE(channel_->SetPlayout(false));
1919   EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1920   EXPECT_FALSE(voe_.GetPlayout(channel_num2));
1921   EXPECT_FALSE(voe_.GetPlayout(channel_num3));
1922
1923   // Restart playout and make sure the default channel still is not played out.
1924   EXPECT_TRUE(channel_->SetPlayout(true));
1925   EXPECT_FALSE(voe_.GetPlayout(channel_num1));
1926   EXPECT_TRUE(voe_.GetPlayout(channel_num2));
1927   EXPECT_TRUE(voe_.GetPlayout(channel_num3));
1928
1929   // Now remove the new streams and verify that the default channel is
1930   // played out again.
1931   EXPECT_TRUE(channel_->RemoveRecvStream(3));
1932   EXPECT_TRUE(channel_->RemoveRecvStream(2));
1933
1934   EXPECT_TRUE(voe_.GetPlayout(channel_num1));
1935 }
1936
1937 // Test that we can set the devices to use.
1938 TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
1939   EXPECT_TRUE(SetupEngine());
1940   int channel_num = voe_.GetLastChannel();
1941   std::vector<cricket::AudioCodec> codecs;
1942   codecs.push_back(kPcmuCodec);
1943   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1944
1945   cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
1946                               cricket::kFakeDefaultDeviceId);
1947   cricket::Device dev(cricket::kFakeDeviceName,
1948                       cricket::kFakeDeviceId);
1949
1950   // Test SetDevices() while not sending or playing.
1951   EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
1952
1953   // Test SetDevices() while sending and playing.
1954   EXPECT_TRUE(engine_.SetLocalMonitor(true));
1955   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1956   EXPECT_TRUE(channel_->SetPlayout(true));
1957   EXPECT_TRUE(voe_.GetRecordingMicrophone());
1958   EXPECT_TRUE(voe_.GetSend(channel_num));
1959   EXPECT_TRUE(voe_.GetPlayout(channel_num));
1960
1961   EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1962
1963   EXPECT_TRUE(voe_.GetRecordingMicrophone());
1964   EXPECT_TRUE(voe_.GetSend(channel_num));
1965   EXPECT_TRUE(voe_.GetPlayout(channel_num));
1966
1967   // Test that failure to open newly selected devices does not prevent opening
1968   // ones after that.
1969   voe_.set_fail_start_recording_microphone(true);
1970   voe_.set_playout_fail_channel(channel_num);
1971   voe_.set_send_fail_channel(channel_num);
1972
1973   EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
1974
1975   EXPECT_FALSE(voe_.GetRecordingMicrophone());
1976   EXPECT_FALSE(voe_.GetSend(channel_num));
1977   EXPECT_FALSE(voe_.GetPlayout(channel_num));
1978
1979   voe_.set_fail_start_recording_microphone(false);
1980   voe_.set_playout_fail_channel(-1);
1981   voe_.set_send_fail_channel(-1);
1982
1983   EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
1984
1985   EXPECT_TRUE(voe_.GetRecordingMicrophone());
1986   EXPECT_TRUE(voe_.GetSend(channel_num));
1987   EXPECT_TRUE(voe_.GetPlayout(channel_num));
1988 }
1989
1990 // Test that we can set the devices to use even if we failed to
1991 // open the initial ones.
1992 TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
1993   EXPECT_TRUE(SetupEngine());
1994   int channel_num = voe_.GetLastChannel();
1995   std::vector<cricket::AudioCodec> codecs;
1996   codecs.push_back(kPcmuCodec);
1997   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1998
1999   cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
2000                               cricket::kFakeDefaultDeviceId);
2001   cricket::Device dev(cricket::kFakeDeviceName,
2002                       cricket::kFakeDeviceId);
2003
2004   // Test that failure to open devices selected before starting
2005   // send/play does not prevent opening newly selected ones after that.
2006   voe_.set_fail_start_recording_microphone(true);
2007   voe_.set_playout_fail_channel(channel_num);
2008   voe_.set_send_fail_channel(channel_num);
2009
2010   EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
2011
2012   EXPECT_FALSE(engine_.SetLocalMonitor(true));
2013   EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
2014   EXPECT_FALSE(channel_->SetPlayout(true));
2015   EXPECT_FALSE(voe_.GetRecordingMicrophone());
2016   EXPECT_FALSE(voe_.GetSend(channel_num));
2017   EXPECT_FALSE(voe_.GetPlayout(channel_num));
2018
2019   voe_.set_fail_start_recording_microphone(false);
2020   voe_.set_playout_fail_channel(-1);
2021   voe_.set_send_fail_channel(-1);
2022
2023   EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
2024
2025   EXPECT_TRUE(voe_.GetRecordingMicrophone());
2026   EXPECT_TRUE(voe_.GetSend(channel_num));
2027   EXPECT_TRUE(voe_.GetPlayout(channel_num));
2028 }
2029
2030 // Test that we can create a channel configured for multi-point conferences,
2031 // and start sending/playing out on it.
2032 TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
2033   EXPECT_TRUE(SetupEngine());
2034   int channel_num = voe_.GetLastChannel();
2035   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2036   std::vector<cricket::AudioCodec> codecs;
2037   codecs.push_back(kPcmuCodec);
2038   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2039   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2040   EXPECT_TRUE(voe_.GetSend(channel_num));
2041 }
2042
2043 // Test that we can create a channel configured for Codian bridges,
2044 // and start sending/playing out on it.
2045 TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
2046   EXPECT_TRUE(SetupEngine());
2047   int channel_num = voe_.GetLastChannel();
2048   webrtc::AgcConfig agc_config;
2049   EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2050   EXPECT_EQ(0, agc_config.targetLeveldBOv);
2051   EXPECT_TRUE(channel_->SetOptions(options_adjust_agc_));
2052   std::vector<cricket::AudioCodec> codecs;
2053   codecs.push_back(kPcmuCodec);
2054   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2055   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2056   EXPECT_TRUE(voe_.GetSend(channel_num));
2057   EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2058   EXPECT_EQ(agc_config.targetLeveldBOv, 10);  // level was attenuated
2059   EXPECT_TRUE(channel_->SetPlayout(true));
2060   EXPECT_TRUE(voe_.GetPlayout(channel_num));
2061   EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2062   EXPECT_FALSE(voe_.GetSend(channel_num));
2063   EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2064   EXPECT_EQ(0, agc_config.targetLeveldBOv);  // level was restored
2065   EXPECT_TRUE(channel_->SetPlayout(false));
2066   EXPECT_FALSE(voe_.GetPlayout(channel_num));
2067 }
2068
2069 TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2070   EXPECT_TRUE(SetupEngine());
2071   webrtc::AgcConfig agc_config;
2072   EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2073   EXPECT_EQ(0, agc_config.targetLeveldBOv);
2074
2075   cricket::AudioOptions options;
2076   options.tx_agc_target_dbov.Set(3);
2077   options.tx_agc_digital_compression_gain.Set(9);
2078   options.tx_agc_limiter.Set(true);
2079   options.auto_gain_control.Set(true);
2080   EXPECT_TRUE(engine_.SetOptions(options));
2081
2082   EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2083   EXPECT_EQ(3, agc_config.targetLeveldBOv);
2084   EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2085   EXPECT_TRUE(agc_config.limiterEnable);
2086
2087   // Check interaction with adjust_agc_delta. Both should be respected, for
2088   // backwards compatibility.
2089   options.adjust_agc_delta.Set(-10);
2090   EXPECT_TRUE(engine_.SetOptions(options));
2091
2092   EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2093   EXPECT_EQ(13, agc_config.targetLeveldBOv);
2094 }
2095
2096 TEST_F(WebRtcVoiceEngineTestFake, RxAgcConfigViaOptions) {
2097   EXPECT_TRUE(SetupEngine());
2098   int channel_num = voe_.GetLastChannel();
2099   cricket::AudioOptions options;
2100   options.rx_agc_target_dbov.Set(6);
2101   options.rx_agc_digital_compression_gain.Set(0);
2102   options.rx_agc_limiter.Set(true);
2103   options.rx_auto_gain_control.Set(true);
2104   EXPECT_TRUE(channel_->SetOptions(options));
2105
2106   webrtc::AgcConfig agc_config;
2107   EXPECT_EQ(0, engine_.voe()->processing()->GetRxAgcConfig(
2108       channel_num, agc_config));
2109   EXPECT_EQ(6, agc_config.targetLeveldBOv);
2110   EXPECT_EQ(0, agc_config.digitalCompressionGaindB);
2111   EXPECT_TRUE(agc_config.limiterEnable);
2112 }
2113
2114 TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2115   EXPECT_TRUE(SetupEngine());
2116   cricket::AudioOptions options;
2117   options.recording_sample_rate.Set(48000u);
2118   options.playout_sample_rate.Set(44100u);
2119   EXPECT_TRUE(engine_.SetOptions(options));
2120
2121   unsigned int recording_sample_rate, playout_sample_rate;
2122   EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2123   EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2124   EXPECT_EQ(48000u, recording_sample_rate);
2125   EXPECT_EQ(44100u, playout_sample_rate);
2126 }
2127
2128 TEST_F(WebRtcVoiceEngineTestFake, TraceFilterViaTraceOptions) {
2129   EXPECT_TRUE(SetupEngine());
2130   engine_.SetLogging(rtc::LS_INFO, "");
2131   EXPECT_EQ(
2132       // Info:
2133       webrtc::kTraceStateInfo | webrtc::kTraceInfo |
2134       // Warning:
2135       webrtc::kTraceTerseInfo | webrtc::kTraceWarning |
2136       // Error:
2137       webrtc::kTraceError | webrtc::kTraceCritical,
2138       static_cast<int>(trace_wrapper_->filter_));
2139   // Now set it explicitly
2140   std::string filter =
2141       "tracefilter " + rtc::ToString(webrtc::kTraceDefault);
2142   engine_.SetLogging(rtc::LS_VERBOSE, filter.c_str());
2143   EXPECT_EQ(static_cast<unsigned int>(webrtc::kTraceDefault),
2144             trace_wrapper_->filter_);
2145 }
2146
2147 // Test that we can set the outgoing SSRC properly.
2148 // SSRC is set in SetupEngine by calling AddSendStream.
2149 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2150   EXPECT_TRUE(SetupEngine());
2151   int channel_num = voe_.GetLastChannel();
2152   unsigned int send_ssrc;
2153   EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2154   EXPECT_NE(0U, send_ssrc);
2155   EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
2156   EXPECT_EQ(kSsrc1, send_ssrc);
2157 }
2158
2159 TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2160   // Setup. We need send codec to be set to get all stats.
2161   EXPECT_TRUE(SetupEngine());
2162   // SetupEngine adds a send stream with kSsrc1, so the receive stream has to
2163   // use a different SSRC.
2164   EXPECT_TRUE(channel_->AddRecvStream(
2165       cricket::StreamParams::CreateLegacy(kSsrc2)));
2166   std::vector<cricket::AudioCodec> codecs;
2167   codecs.push_back(kPcmuCodec);
2168   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2169   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2170
2171   cricket::VoiceMediaInfo info;
2172   EXPECT_EQ(true, channel_->GetStats(&info));
2173   EXPECT_EQ(1u, info.senders.size());
2174   EXPECT_EQ(kSsrc1, info.senders[0].ssrc());
2175   EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2176   EXPECT_EQ(cricket::kIntStatValue, info.senders[0].bytes_sent);
2177   EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_sent);
2178   EXPECT_EQ(cricket::kIntStatValue, info.senders[0].packets_lost);
2179   EXPECT_EQ(cricket::kFractionLostStatValue, info.senders[0].fraction_lost);
2180   EXPECT_EQ(cricket::kIntStatValue, info.senders[0].ext_seqnum);
2181   EXPECT_EQ(cricket::kIntStatValue, info.senders[0].rtt_ms);
2182   EXPECT_EQ(cricket::kIntStatValue, info.senders[0].jitter_ms);
2183   EXPECT_EQ(kPcmuCodec.name, info.senders[0].codec_name);
2184   // TODO(sriniv): Add testing for more fields. These are not populated
2185   // in FakeWebrtcVoiceEngine yet.
2186   // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].audio_level);
2187   // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_median_ms);
2188   // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_delay_std_ms);
2189   // EXPECT_EQ(cricket::kIntStatValue, info.senders[0].echo_return_loss);
2190   // EXPECT_EQ(cricket::kIntStatValue,
2191   //           info.senders[0].echo_return_loss_enhancement);
2192
2193   EXPECT_EQ(0u, info.receivers.size());
2194   DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2195   EXPECT_EQ(true, channel_->GetStats(&info));
2196   EXPECT_EQ(1u, info.receivers.size());
2197
2198   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].bytes_rcvd);
2199   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_rcvd);
2200   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].packets_lost);
2201   EXPECT_EQ(cricket::kIntStatValue, info.receivers[0].ext_seqnum);
2202   EXPECT_EQ(kPcmuCodec.name, info.receivers[0].codec_name);
2203   // TODO(sriniv): Add testing for more receiver fields.
2204 }
2205
2206 // Test that we can set the outgoing SSRC properly with multiple streams.
2207 // SSRC is set in SetupEngine by calling AddSendStream.
2208 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2209   EXPECT_TRUE(SetupEngine());
2210   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2211   int channel_num1 = voe_.GetLastChannel();
2212   unsigned int send_ssrc;
2213   EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
2214   EXPECT_EQ(kSsrc1, send_ssrc);
2215
2216   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2217   int channel_num2 = voe_.GetLastChannel();
2218   EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
2219   EXPECT_EQ(kSsrc1, send_ssrc);
2220 }
2221
2222 // Test that the local SSRC is the same on sending and receiving channels if the
2223 // receive channel is created before the send channel.
2224 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2225   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2226   channel_ = engine_.CreateChannel();
2227   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2228
2229   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2230   int receive_channel_num = voe_.GetLastChannel();
2231   EXPECT_TRUE(channel_->AddSendStream(
2232       cricket::StreamParams::CreateLegacy(1234)));
2233   int send_channel_num = voe_.GetLastChannel();
2234
2235   unsigned int ssrc = 0;
2236   EXPECT_EQ(0, voe_.GetLocalSSRC(send_channel_num, ssrc));
2237   EXPECT_EQ(1234U, ssrc);
2238   ssrc = 0;
2239   EXPECT_EQ(0, voe_.GetLocalSSRC(receive_channel_num, ssrc));
2240   EXPECT_EQ(1234U, ssrc);
2241 }
2242
2243 // Test that we can properly receive packets.
2244 TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2245   EXPECT_TRUE(SetupEngine());
2246   int channel_num = voe_.GetLastChannel();
2247   DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2248   EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
2249                                sizeof(kPcmuFrame)));
2250 }
2251
2252 // Test that we can properly receive packets on multiple streams.
2253 TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2254   EXPECT_TRUE(SetupEngine());
2255   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2256   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2257   int channel_num1 = voe_.GetLastChannel();
2258   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2259   int channel_num2 = voe_.GetLastChannel();
2260   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2261   int channel_num3 = voe_.GetLastChannel();
2262   // Create packets with the right SSRCs.
2263   char packets[4][sizeof(kPcmuFrame)];
2264   for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
2265     memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2266     rtc::SetBE32(packets[i] + 8, static_cast<uint32>(i));
2267   }
2268   EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2269   EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2270   EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2271   DeliverPacket(packets[0], sizeof(packets[0]));
2272   EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2273   EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2274   EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2275   DeliverPacket(packets[1], sizeof(packets[1]));
2276   EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
2277                                sizeof(packets[1])));
2278   EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2279   EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2280   DeliverPacket(packets[2], sizeof(packets[2]));
2281   EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2282   EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
2283                                sizeof(packets[2])));
2284   EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2285   DeliverPacket(packets[3], sizeof(packets[3]));
2286   EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2287   EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2288   EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
2289                                sizeof(packets[3])));
2290   EXPECT_TRUE(channel_->RemoveRecvStream(3));
2291   EXPECT_TRUE(channel_->RemoveRecvStream(2));
2292   EXPECT_TRUE(channel_->RemoveRecvStream(1));
2293 }
2294
2295 // Test that we properly handle failures to add a stream.
2296 TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
2297   EXPECT_TRUE(SetupEngine());
2298   voe_.set_fail_create_channel(true);
2299   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2300   EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2301
2302   // In 1:1 call, we should not try to create a new channel.
2303   cricket::AudioOptions options_no_conference_;
2304   options_no_conference_.conference_mode.Set(false);
2305   EXPECT_TRUE(channel_->SetOptions(options_no_conference_));
2306   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2307 }
2308
2309 // Test that AddRecvStream doesn't create new channel for 1:1 call.
2310 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream1On1) {
2311   EXPECT_TRUE(SetupEngine());
2312   int channel_num = voe_.GetLastChannel();
2313   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2314   EXPECT_EQ(channel_num, voe_.GetLastChannel());
2315 }
2316
2317 // Test that after adding a recv stream, we do not decode more codecs than
2318 // those previously passed into SetRecvCodecs.
2319 TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2320   EXPECT_TRUE(SetupEngine());
2321   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2322   std::vector<cricket::AudioCodec> codecs;
2323   codecs.push_back(kIsacCodec);
2324   codecs.push_back(kPcmuCodec);
2325   EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2326   EXPECT_TRUE(channel_->AddRecvStream(
2327       cricket::StreamParams::CreateLegacy(kSsrc1)));
2328   int channel_num2 = voe_.GetLastChannel();
2329   webrtc::CodecInst gcodec;
2330   rtc::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "CELT");
2331   gcodec.plfreq = 32000;
2332   gcodec.channels = 2;
2333   EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2334 }
2335
2336 // Test that we properly clean up any streams that were added, even if
2337 // not explicitly removed.
2338 TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2339   EXPECT_TRUE(SetupEngine());
2340   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2341   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2342   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2343   EXPECT_EQ(3, voe_.GetNumChannels());  // default channel + 2 added
2344   delete channel_;
2345   channel_ = NULL;
2346   EXPECT_EQ(0, voe_.GetNumChannels());
2347 }
2348
2349 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2350   EXPECT_TRUE(SetupEngine());
2351   EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2352 }
2353
2354 TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2355   EXPECT_TRUE(SetupEngine());
2356   // Stream 1 reuses default channel.
2357   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2358   // Manually delete default channel to simulate a failure.
2359   int default_channel = voe_.GetLastChannel();
2360   EXPECT_EQ(0, voe_.DeleteChannel(default_channel));
2361   // Add recv stream 2 should fail because default channel is gone.
2362   EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2363   int new_channel = voe_.GetLastChannel();
2364   EXPECT_NE(default_channel, new_channel);
2365   // The last created channel should have already been deleted.
2366   EXPECT_EQ(-1, voe_.DeleteChannel(new_channel));
2367 }
2368
2369 // Test the InsertDtmf on default send stream as caller.
2370 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2371   TestInsertDtmf(0, true);
2372 }
2373
2374 // Test the InsertDtmf on default send stream as callee
2375 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2376   TestInsertDtmf(0, false);
2377 }
2378
2379 // Test the InsertDtmf on specified send stream as caller.
2380 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2381   TestInsertDtmf(kSsrc1, true);
2382 }
2383
2384 // Test the InsertDtmf on specified send stream as callee.
2385 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2386   TestInsertDtmf(kSsrc1, false);
2387 }
2388
2389 // Test that we can play a ringback tone properly in a single-stream call.
2390 TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
2391   EXPECT_TRUE(SetupEngine());
2392   int channel_num = voe_.GetLastChannel();
2393   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2394   // Check we fail if no ringback tone specified.
2395   EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
2396   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2397   // Check we can set and play a ringback tone.
2398   EXPECT_TRUE(channel_->SetRingbackTone(
2399                   kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
2400   EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2401   EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2402   // Check we can stop the tone manually.
2403   EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
2404   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2405   // Check we stop the tone if a packet arrives.
2406   EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
2407   EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2408   DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2409   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2410 }
2411
2412 // Test that we can play a ringback tone properly in a multi-stream call.
2413 TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
2414   EXPECT_TRUE(SetupEngine());
2415   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2416   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2417   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2418   int channel_num = voe_.GetLastChannel();
2419   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2420   // Check we fail if no ringback tone specified.
2421   EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
2422   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2423   // Check we can set and play a ringback tone on the correct ssrc.
2424   EXPECT_TRUE(channel_->SetRingbackTone(
2425                   kRingbackTone, static_cast<int>(strlen(kRingbackTone))));
2426   EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
2427   EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2428   EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2429   // Check we can stop the tone manually.
2430   EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
2431   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2432   // Check we stop the tone if a packet arrives, but only with the right SSRC.
2433   EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
2434   EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2435   // Send a packet with SSRC 1; the tone should not stop.
2436   DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2437   EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
2438   // Send a packet with SSRC 2; the tone should stop.
2439   char packet[sizeof(kPcmuFrame)];
2440   memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2441   rtc::SetBE32(packet + 8, 2);
2442   DeliverPacket(packet, sizeof(packet));
2443   EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
2444 }
2445
2446 // Tests creating soundclips, and make sure they come from the right engine.
2447 TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
2448   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2449   EXPECT_FALSE(voe_sc_.IsInited());
2450   soundclip_ = engine_.CreateSoundclip();
2451   EXPECT_TRUE(voe_sc_.IsInited());
2452   ASSERT_TRUE(soundclip_ != NULL);
2453   EXPECT_EQ(0, voe_.GetNumChannels());
2454   EXPECT_EQ(1, voe_sc_.GetNumChannels());
2455   int channel_num = voe_sc_.GetLastChannel();
2456   EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
2457   delete soundclip_;
2458   soundclip_ = NULL;
2459   EXPECT_EQ(0, voe_sc_.GetNumChannels());
2460   // Make sure the soundclip engine is uninitialized on shutdown, now that
2461   // we've initialized it by creating a soundclip.
2462   engine_.Terminate();
2463   EXPECT_FALSE(voe_sc_.IsInited());
2464 }
2465
2466 // Tests playing out a fake sound.
2467 TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
2468   static const char kZeroes[16000] = {};
2469   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2470   soundclip_ = engine_.CreateSoundclip();
2471   ASSERT_TRUE(soundclip_ != NULL);
2472   EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
2473 }
2474
2475 TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
2476   rtc::scoped_ptr<ChannelErrorListener> listener;
2477   cricket::WebRtcVoiceMediaChannel* media_channel;
2478   unsigned int ssrc = 0;
2479
2480   EXPECT_TRUE(SetupEngine());
2481   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2482   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2483
2484   media_channel = static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2485   listener.reset(new ChannelErrorListener(channel_));
2486
2487   // Test on WebRtc VoE channel.
2488   voe_.TriggerCallbackOnError(media_channel->voe_channel(),
2489                               VE_SATURATION_WARNING);
2490   EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2491             listener->error());
2492   EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
2493   EXPECT_EQ(ssrc, listener->ssrc());
2494
2495   listener->Reset();
2496   voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
2497   EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
2498             listener->error());
2499   EXPECT_EQ(0U, listener->ssrc());
2500
2501   // Add another stream and test on that.
2502   ++ssrc;
2503   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(
2504       ssrc)));
2505   listener->Reset();
2506   voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
2507                               VE_SATURATION_WARNING);
2508   EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
2509             listener->error());
2510   EXPECT_EQ(ssrc, listener->ssrc());
2511
2512   // Testing a non-existing channel.
2513   listener->Reset();
2514   voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
2515                               VE_SATURATION_WARNING);
2516   EXPECT_EQ(0, listener->error());
2517 }
2518
2519 TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2520   EXPECT_TRUE(SetupEngine());
2521   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2522   std::vector<cricket::AudioCodec> codecs;
2523   codecs.push_back(kPcmuCodec);
2524   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2525   EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2526   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2527   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2528   EXPECT_TRUE(channel_->SetPlayout(true));
2529   voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2530   EXPECT_TRUE(channel_->SetPlayout(false));
2531   EXPECT_FALSE(channel_->SetPlayout(true));
2532 }
2533
2534 // Test that the Registering/Unregistering with the
2535 // webrtcvoiceengine works as expected
2536 TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
2537   EXPECT_TRUE(SetupEngine());
2538   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2539   EXPECT_TRUE(channel_->AddRecvStream(
2540       cricket::StreamParams::CreateLegacy(kSsrc2)));
2541   cricket::FakeMediaProcessor vp_1;
2542   cricket::FakeMediaProcessor vp_2;
2543
2544   EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_TX));
2545   EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2546   EXPECT_TRUE(engine_.RegisterProcessor(kSsrc2, &vp_2, cricket::MPD_RX));
2547   voe_.TriggerProcessPacket(cricket::MPD_RX);
2548   voe_.TriggerProcessPacket(cricket::MPD_TX);
2549
2550   EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2551   EXPECT_EQ(1, vp_1.voice_frame_count());
2552   EXPECT_EQ(1, vp_2.voice_frame_count());
2553
2554   EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2555                                           &vp_2,
2556                                           cricket::MPD_RX));
2557   voe_.TriggerProcessPacket(cricket::MPD_RX);
2558   EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2559   EXPECT_EQ(1, vp_2.voice_frame_count());
2560   EXPECT_EQ(2, vp_1.voice_frame_count());
2561
2562   EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc2,
2563                                           &vp_1,
2564                                           cricket::MPD_RX));
2565   voe_.TriggerProcessPacket(cricket::MPD_RX);
2566   EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2567   EXPECT_EQ(2, vp_1.voice_frame_count());
2568
2569   EXPECT_FALSE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_RX));
2570   EXPECT_TRUE(engine_.RegisterProcessor(kSsrc1, &vp_1, cricket::MPD_TX));
2571   voe_.TriggerProcessPacket(cricket::MPD_RX);
2572   voe_.TriggerProcessPacket(cricket::MPD_TX);
2573   EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2574   EXPECT_EQ(3, vp_1.voice_frame_count());
2575
2576   EXPECT_TRUE(engine_.UnregisterProcessor(kSsrc1,
2577                                           &vp_1,
2578                                           cricket::MPD_RX_AND_TX));
2579   voe_.TriggerProcessPacket(cricket::MPD_TX);
2580   EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2581   EXPECT_EQ(3, vp_1.voice_frame_count());
2582   EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2583   EXPECT_FALSE(engine_.RegisterProcessor(kSsrc2, &vp_1, cricket::MPD_RX));
2584   EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
2585
2586   // Test that we can register a processor on the receive channel on SSRC 0.
2587   // This tests the 1:1 case when the receive SSRC is unknown.
2588   EXPECT_TRUE(engine_.RegisterProcessor(0, &vp_1, cricket::MPD_RX));
2589   voe_.TriggerProcessPacket(cricket::MPD_RX);
2590   EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
2591   EXPECT_EQ(4, vp_1.voice_frame_count());
2592   EXPECT_TRUE(engine_.UnregisterProcessor(0,
2593                                           &vp_1,
2594                                           cricket::MPD_RX));
2595
2596   // The following tests test that FindChannelNumFromSsrc is doing
2597   // what we expect.
2598   // pick an invalid ssrc and make sure we can't register
2599   EXPECT_FALSE(engine_.RegisterProcessor(99,
2600                                          &vp_1,
2601                                          cricket::MPD_RX));
2602   EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2603   EXPECT_TRUE(engine_.RegisterProcessor(1,
2604                                         &vp_1,
2605                                         cricket::MPD_RX));
2606   EXPECT_TRUE(engine_.UnregisterProcessor(1,
2607                                           &vp_1,
2608                                           cricket::MPD_RX));
2609   EXPECT_FALSE(engine_.RegisterProcessor(1,
2610                                          &vp_1,
2611                                          cricket::MPD_TX));
2612   EXPECT_TRUE(channel_->RemoveRecvStream(1));
2613 }
2614
2615 TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2616   EXPECT_TRUE(SetupEngine());
2617
2618   bool ec_enabled;
2619   webrtc::EcModes ec_mode;
2620   bool ec_metrics_enabled;
2621   webrtc::AecmModes aecm_mode;
2622   bool cng_enabled;
2623   bool agc_enabled;
2624   webrtc::AgcModes agc_mode;
2625   webrtc::AgcConfig agc_config;
2626   bool ns_enabled;
2627   webrtc::NsModes ns_mode;
2628   bool highpass_filter_enabled;
2629   bool stereo_swapping_enabled;
2630   bool typing_detection_enabled;
2631   voe_.GetEcStatus(ec_enabled, ec_mode);
2632   voe_.GetEcMetricsStatus(ec_metrics_enabled);
2633   voe_.GetAecmMode(aecm_mode, cng_enabled);
2634   voe_.GetAgcStatus(agc_enabled, agc_mode);
2635   voe_.GetAgcConfig(agc_config);
2636   voe_.GetNsStatus(ns_enabled, ns_mode);
2637   highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2638   stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2639   voe_.GetTypingDetectionStatus(typing_detection_enabled);
2640   EXPECT_TRUE(ec_enabled);
2641   EXPECT_TRUE(ec_metrics_enabled);
2642   EXPECT_FALSE(cng_enabled);
2643   EXPECT_TRUE(agc_enabled);
2644   EXPECT_EQ(0, agc_config.targetLeveldBOv);
2645   EXPECT_TRUE(ns_enabled);
2646   EXPECT_TRUE(highpass_filter_enabled);
2647   EXPECT_FALSE(stereo_swapping_enabled);
2648   EXPECT_TRUE(typing_detection_enabled);
2649   EXPECT_EQ(ec_mode, webrtc::kEcConference);
2650   EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2651
2652   // Nothing set, so all ignored.
2653   cricket::AudioOptions options;
2654   ASSERT_TRUE(engine_.SetOptions(options));
2655   voe_.GetEcStatus(ec_enabled, ec_mode);
2656   voe_.GetEcMetricsStatus(ec_metrics_enabled);
2657   voe_.GetAecmMode(aecm_mode, cng_enabled);
2658   voe_.GetAgcStatus(agc_enabled, agc_mode);
2659   voe_.GetAgcConfig(agc_config);
2660   voe_.GetNsStatus(ns_enabled, ns_mode);
2661   highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2662   stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2663   voe_.GetTypingDetectionStatus(typing_detection_enabled);
2664   EXPECT_TRUE(ec_enabled);
2665   EXPECT_TRUE(ec_metrics_enabled);
2666   EXPECT_FALSE(cng_enabled);
2667   EXPECT_TRUE(agc_enabled);
2668   EXPECT_EQ(0, agc_config.targetLeveldBOv);
2669   EXPECT_TRUE(ns_enabled);
2670   EXPECT_TRUE(highpass_filter_enabled);
2671   EXPECT_FALSE(stereo_swapping_enabled);
2672   EXPECT_TRUE(typing_detection_enabled);
2673   EXPECT_EQ(ec_mode, webrtc::kEcConference);
2674   EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2675
2676   // Turn echo cancellation off
2677   options.echo_cancellation.Set(false);
2678   ASSERT_TRUE(engine_.SetOptions(options));
2679   voe_.GetEcStatus(ec_enabled, ec_mode);
2680   EXPECT_FALSE(ec_enabled);
2681
2682   // Turn echo cancellation back on, with settings, and make sure
2683   // nothing else changed.
2684   options.echo_cancellation.Set(true);
2685   ASSERT_TRUE(engine_.SetOptions(options));
2686   voe_.GetEcStatus(ec_enabled, ec_mode);
2687   voe_.GetEcMetricsStatus(ec_metrics_enabled);
2688   voe_.GetAecmMode(aecm_mode, cng_enabled);
2689   voe_.GetAgcStatus(agc_enabled, agc_mode);
2690   voe_.GetAgcConfig(agc_config);
2691   voe_.GetNsStatus(ns_enabled, ns_mode);
2692   highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2693   stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2694   voe_.GetTypingDetectionStatus(typing_detection_enabled);
2695   EXPECT_TRUE(ec_enabled);
2696   EXPECT_TRUE(ec_metrics_enabled);
2697   EXPECT_TRUE(agc_enabled);
2698   EXPECT_EQ(0, agc_config.targetLeveldBOv);
2699   EXPECT_TRUE(ns_enabled);
2700   EXPECT_TRUE(highpass_filter_enabled);
2701   EXPECT_FALSE(stereo_swapping_enabled);
2702   EXPECT_TRUE(typing_detection_enabled);
2703   EXPECT_EQ(ec_mode, webrtc::kEcConference);
2704   EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2705
2706   // Turn off AGC
2707   options.auto_gain_control.Set(false);
2708   ASSERT_TRUE(engine_.SetOptions(options));
2709   voe_.GetAgcStatus(agc_enabled, agc_mode);
2710   EXPECT_FALSE(agc_enabled);
2711
2712   // Turn AGC back on
2713   options.auto_gain_control.Set(true);
2714   options.adjust_agc_delta.Clear();
2715   ASSERT_TRUE(engine_.SetOptions(options));
2716   voe_.GetAgcStatus(agc_enabled, agc_mode);
2717   EXPECT_TRUE(agc_enabled);
2718   voe_.GetAgcConfig(agc_config);
2719   EXPECT_EQ(0, agc_config.targetLeveldBOv);
2720
2721   // Turn off other options (and stereo swapping on).
2722   options.noise_suppression.Set(false);
2723   options.highpass_filter.Set(false);
2724   options.typing_detection.Set(false);
2725   options.stereo_swapping.Set(true);
2726   ASSERT_TRUE(engine_.SetOptions(options));
2727   voe_.GetNsStatus(ns_enabled, ns_mode);
2728   highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2729   stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2730   voe_.GetTypingDetectionStatus(typing_detection_enabled);
2731   EXPECT_FALSE(ns_enabled);
2732   EXPECT_FALSE(highpass_filter_enabled);
2733   EXPECT_FALSE(typing_detection_enabled);
2734   EXPECT_TRUE(stereo_swapping_enabled);
2735
2736   // Turn on "conference mode" to ensure it has no impact.
2737   options.conference_mode.Set(true);
2738   ASSERT_TRUE(engine_.SetOptions(options));
2739   voe_.GetEcStatus(ec_enabled, ec_mode);
2740   voe_.GetNsStatus(ns_enabled, ns_mode);
2741   EXPECT_TRUE(ec_enabled);
2742   EXPECT_EQ(webrtc::kEcConference, ec_mode);
2743   EXPECT_FALSE(ns_enabled);
2744   EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2745 }
2746
2747 TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
2748   EXPECT_TRUE(SetupEngine());
2749
2750   bool ec_enabled;
2751   webrtc::EcModes ec_mode;
2752   bool ec_metrics_enabled;
2753   bool agc_enabled;
2754   webrtc::AgcModes agc_mode;
2755   bool ns_enabled;
2756   webrtc::NsModes ns_mode;
2757   bool highpass_filter_enabled;
2758   bool stereo_swapping_enabled;
2759   bool typing_detection_enabled;
2760
2761   voe_.GetEcStatus(ec_enabled, ec_mode);
2762   voe_.GetEcMetricsStatus(ec_metrics_enabled);
2763   voe_.GetAgcStatus(agc_enabled, agc_mode);
2764   voe_.GetNsStatus(ns_enabled, ns_mode);
2765   highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2766   stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2767   voe_.GetTypingDetectionStatus(typing_detection_enabled);
2768   EXPECT_TRUE(ec_enabled);
2769   EXPECT_TRUE(agc_enabled);
2770   EXPECT_TRUE(ns_enabled);
2771   EXPECT_TRUE(highpass_filter_enabled);
2772   EXPECT_TRUE(typing_detection_enabled);
2773   EXPECT_FALSE(stereo_swapping_enabled);
2774 }
2775
2776 TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2777   webrtc::AgcConfig set_config = {0};
2778   set_config.targetLeveldBOv = 3;
2779   set_config.digitalCompressionGaindB = 9;
2780   set_config.limiterEnable = true;
2781   EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2782   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2783
2784   webrtc::AgcConfig config = {0};
2785   EXPECT_EQ(0, voe_.GetAgcConfig(config));
2786   EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2787   EXPECT_EQ(set_config.digitalCompressionGaindB,
2788             config.digitalCompressionGaindB);
2789   EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2790 }
2791
2792 TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2793   EXPECT_TRUE(SetupEngine());
2794   rtc::scoped_ptr<cricket::VoiceMediaChannel> channel1(
2795       engine_.CreateChannel());
2796   rtc::scoped_ptr<cricket::VoiceMediaChannel> channel2(
2797       engine_.CreateChannel());
2798
2799   // Have to add a stream to make SetSend work.
2800   cricket::StreamParams stream1;
2801   stream1.ssrcs.push_back(1);
2802   channel1->AddSendStream(stream1);
2803   cricket::StreamParams stream2;
2804   stream2.ssrcs.push_back(2);
2805   channel2->AddSendStream(stream2);
2806
2807   // AEC and AGC and NS
2808   cricket::AudioOptions options_all;
2809   options_all.echo_cancellation.Set(true);
2810   options_all.auto_gain_control.Set(true);
2811   options_all.noise_suppression.Set(true);
2812
2813   ASSERT_TRUE(channel1->SetOptions(options_all));
2814   cricket::AudioOptions expected_options = options_all;
2815   cricket::AudioOptions actual_options;
2816   ASSERT_TRUE(channel1->GetOptions(&actual_options));
2817   EXPECT_EQ(expected_options, actual_options);
2818   ASSERT_TRUE(channel2->SetOptions(options_all));
2819   ASSERT_TRUE(channel2->GetOptions(&actual_options));
2820   EXPECT_EQ(expected_options, actual_options);
2821
2822   // unset NS
2823   cricket::AudioOptions options_no_ns;
2824   options_no_ns.noise_suppression.Set(false);
2825   ASSERT_TRUE(channel1->SetOptions(options_no_ns));
2826
2827   expected_options.echo_cancellation.Set(true);
2828   expected_options.auto_gain_control.Set(true);
2829   expected_options.noise_suppression.Set(false);
2830   ASSERT_TRUE(channel1->GetOptions(&actual_options));
2831   EXPECT_EQ(expected_options, actual_options);
2832
2833   // unset AGC
2834   cricket::AudioOptions options_no_agc;
2835   options_no_agc.auto_gain_control.Set(false);
2836   ASSERT_TRUE(channel2->SetOptions(options_no_agc));
2837
2838   expected_options.echo_cancellation.Set(true);
2839   expected_options.auto_gain_control.Set(false);
2840   expected_options.noise_suppression.Set(true);
2841   ASSERT_TRUE(channel2->GetOptions(&actual_options));
2842   EXPECT_EQ(expected_options, actual_options);
2843
2844   ASSERT_TRUE(engine_.SetOptions(options_all));
2845   bool ec_enabled;
2846   webrtc::EcModes ec_mode;
2847   bool agc_enabled;
2848   webrtc::AgcModes agc_mode;
2849   bool ns_enabled;
2850   webrtc::NsModes ns_mode;
2851   voe_.GetEcStatus(ec_enabled, ec_mode);
2852   voe_.GetAgcStatus(agc_enabled, agc_mode);
2853   voe_.GetNsStatus(ns_enabled, ns_mode);
2854   EXPECT_TRUE(ec_enabled);
2855   EXPECT_TRUE(agc_enabled);
2856   EXPECT_TRUE(ns_enabled);
2857
2858   channel1->SetSend(cricket::SEND_MICROPHONE);
2859   voe_.GetEcStatus(ec_enabled, ec_mode);
2860   voe_.GetAgcStatus(agc_enabled, agc_mode);
2861   voe_.GetNsStatus(ns_enabled, ns_mode);
2862   EXPECT_TRUE(ec_enabled);
2863   EXPECT_TRUE(agc_enabled);
2864   EXPECT_FALSE(ns_enabled);
2865
2866   channel1->SetSend(cricket::SEND_NOTHING);
2867   voe_.GetEcStatus(ec_enabled, ec_mode);
2868   voe_.GetAgcStatus(agc_enabled, agc_mode);
2869   voe_.GetNsStatus(ns_enabled, ns_mode);
2870   EXPECT_TRUE(ec_enabled);
2871   EXPECT_TRUE(agc_enabled);
2872   EXPECT_TRUE(ns_enabled);
2873
2874   channel2->SetSend(cricket::SEND_MICROPHONE);
2875   voe_.GetEcStatus(ec_enabled, ec_mode);
2876   voe_.GetAgcStatus(agc_enabled, agc_mode);
2877   voe_.GetNsStatus(ns_enabled, ns_mode);
2878   EXPECT_TRUE(ec_enabled);
2879   EXPECT_FALSE(agc_enabled);
2880   EXPECT_TRUE(ns_enabled);
2881
2882   channel2->SetSend(cricket::SEND_NOTHING);
2883   voe_.GetEcStatus(ec_enabled, ec_mode);
2884   voe_.GetAgcStatus(agc_enabled, agc_mode);
2885   voe_.GetNsStatus(ns_enabled, ns_mode);
2886   EXPECT_TRUE(ec_enabled);
2887   EXPECT_TRUE(agc_enabled);
2888   EXPECT_TRUE(ns_enabled);
2889
2890   // Make sure settings take effect while we are sending.
2891   ASSERT_TRUE(engine_.SetOptions(options_all));
2892   cricket::AudioOptions options_no_agc_nor_ns;
2893   options_no_agc_nor_ns.auto_gain_control.Set(false);
2894   options_no_agc_nor_ns.noise_suppression.Set(false);
2895   channel2->SetSend(cricket::SEND_MICROPHONE);
2896   channel2->SetOptions(options_no_agc_nor_ns);
2897
2898   expected_options.echo_cancellation.Set(true);
2899   expected_options.auto_gain_control.Set(false);
2900   expected_options.noise_suppression.Set(false);
2901   ASSERT_TRUE(channel2->GetOptions(&actual_options));
2902   EXPECT_EQ(expected_options, actual_options);
2903   voe_.GetEcStatus(ec_enabled, ec_mode);
2904   voe_.GetAgcStatus(agc_enabled, agc_mode);
2905   voe_.GetNsStatus(ns_enabled, ns_mode);
2906   EXPECT_TRUE(ec_enabled);
2907   EXPECT_FALSE(agc_enabled);
2908   EXPECT_FALSE(ns_enabled);
2909 }
2910
2911 // This test verifies DSCP settings are properly applied on voice media channel.
2912 TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2913   EXPECT_TRUE(SetupEngine());
2914   rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
2915       engine_.CreateChannel());
2916   rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2917       new cricket::FakeNetworkInterface);
2918   channel->SetInterface(network_interface.get());
2919   cricket::AudioOptions options;
2920   options.dscp.Set(true);
2921   EXPECT_TRUE(channel->SetOptions(options));
2922   EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2923   // Verify previous value is not modified if dscp option is not set.
2924   cricket::AudioOptions options1;
2925   EXPECT_TRUE(channel->SetOptions(options1));
2926   EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2927   options.dscp.Set(false);
2928   EXPECT_TRUE(channel->SetOptions(options));
2929   EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2930 }
2931
2932 TEST(WebRtcVoiceEngineTest, TestDefaultOptionsBeforeInit) {
2933   cricket::WebRtcVoiceEngine engine;
2934   cricket::AudioOptions options = engine.GetOptions();
2935   // The default options should have at least a few things set. We purposefully
2936   // don't check the option values here, though.
2937   EXPECT_TRUE(options.echo_cancellation.IsSet());
2938   EXPECT_TRUE(options.auto_gain_control.IsSet());
2939   EXPECT_TRUE(options.noise_suppression.IsSet());
2940 }
2941
2942 // Test that GetReceiveChannelNum returns the default channel for the first
2943 // recv stream in 1-1 calls.
2944 TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelNumIn1To1Calls) {
2945   EXPECT_TRUE(SetupEngine());
2946   cricket::WebRtcVoiceMediaChannel* media_channel =
2947         static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2948   // Test that GetChannelNum returns the default channel if the SSRC is unknown.
2949   EXPECT_EQ(media_channel->voe_channel(),
2950             media_channel->GetReceiveChannelNum(0));
2951   cricket::StreamParams stream;
2952   stream.ssrcs.push_back(kSsrc2);
2953   EXPECT_TRUE(channel_->AddRecvStream(stream));
2954   EXPECT_EQ(media_channel->voe_channel(),
2955             media_channel->GetReceiveChannelNum(kSsrc2));
2956 }
2957
2958 // Test that GetReceiveChannelNum doesn't return the default channel for the
2959 // first recv stream in conference calls.
2960 TEST_F(WebRtcVoiceEngineTestFake, TestGetChannelNumInConferenceCalls) {
2961   EXPECT_TRUE(SetupEngine());
2962   EXPECT_TRUE(channel_->SetOptions(options_conference_));
2963   cricket::StreamParams stream;
2964   stream.ssrcs.push_back(kSsrc2);
2965   EXPECT_TRUE(channel_->AddRecvStream(stream));
2966   cricket::WebRtcVoiceMediaChannel* media_channel =
2967       static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2968   EXPECT_LT(media_channel->voe_channel(),
2969             media_channel->GetReceiveChannelNum(kSsrc2));
2970 }
2971
2972 TEST_F(WebRtcVoiceEngineTestFake, SetOutputScaling) {
2973   EXPECT_TRUE(SetupEngine());
2974   double left, right;
2975   EXPECT_TRUE(channel_->SetOutputScaling(0, 1, 2));
2976   EXPECT_TRUE(channel_->GetOutputScaling(0, &left, &right));
2977   EXPECT_DOUBLE_EQ(1, left);
2978   EXPECT_DOUBLE_EQ(2, right);
2979
2980   EXPECT_FALSE(channel_->SetOutputScaling(kSsrc2, 1, 2));
2981   cricket::StreamParams stream;
2982   stream.ssrcs.push_back(kSsrc2);
2983   EXPECT_TRUE(channel_->AddRecvStream(stream));
2984
2985   EXPECT_TRUE(channel_->SetOutputScaling(kSsrc2, 2, 1));
2986   EXPECT_TRUE(channel_->GetOutputScaling(kSsrc2, &left, &right));
2987   EXPECT_DOUBLE_EQ(2, left);
2988   EXPECT_DOUBLE_EQ(1, right);
2989 }
2990
2991 // Tests for the actual WebRtc VoE library.
2992
2993 // Tests that the library initializes and shuts down properly.
2994 TEST(WebRtcVoiceEngineTest, StartupShutdown) {
2995   cricket::WebRtcVoiceEngine engine;
2996   EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
2997   cricket::VoiceMediaChannel* channel = engine.CreateChannel();
2998   EXPECT_TRUE(channel != NULL);
2999   delete channel;
3000   engine.Terminate();
3001
3002   // Reinit to catch regression where VoiceEngineObserver reference is lost
3003   EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3004   engine.Terminate();
3005 }
3006
3007 // Tests that the logging from the library is cleartext.
3008 TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
3009   cricket::WebRtcVoiceEngine engine;
3010   rtc::scoped_ptr<rtc::MemoryStream> stream(
3011       new rtc::MemoryStream);
3012   size_t size = 0;
3013   bool cleartext = true;
3014   rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3015   engine.SetLogging(rtc::LS_VERBOSE, "");
3016   EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3017   EXPECT_TRUE(stream->GetSize(&size));
3018   EXPECT_GT(size, 0U);
3019   engine.Terminate();
3020   rtc::LogMessage::RemoveLogToStream(stream.get());
3021   const char* buf = stream->GetBuffer();
3022   for (size_t i = 0; i < size && cleartext; ++i) {
3023     int ch = static_cast<int>(buf[i]);
3024     ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
3025                      << std::hex << ch;
3026     cleartext = (isprint(ch) || isspace(ch));
3027   }
3028   EXPECT_TRUE(cleartext);
3029 }
3030
3031 // Tests we do not see any references to a monitor thread being spun up
3032 // when initiating the engine.
3033 TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
3034   cricket::WebRtcVoiceEngine engine;
3035   rtc::scoped_ptr<rtc::MemoryStream> stream(
3036       new rtc::MemoryStream);
3037   rtc::LogMessage::AddLogToStream(stream.get(), rtc::LS_VERBOSE);
3038   engine.SetLogging(rtc::LS_VERBOSE, "");
3039   EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3040   engine.Terminate();
3041   rtc::LogMessage::RemoveLogToStream(stream.get());
3042
3043   size_t size = 0;
3044   EXPECT_TRUE(stream->GetSize(&size));
3045   EXPECT_GT(size, 0U);
3046   const std::string logs(stream->GetBuffer(), size);
3047   EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
3048 }
3049
3050 // Tests that the library is configured with the codecs we want.
3051 TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3052   cricket::WebRtcVoiceEngine engine;
3053   // Check codecs by name.
3054   EXPECT_TRUE(engine.FindCodec(
3055       cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0)));
3056   EXPECT_TRUE(engine.FindCodec(
3057       cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
3058   EXPECT_TRUE(engine.FindCodec(
3059       cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
3060   // Check that name matching is case-insensitive.
3061   EXPECT_TRUE(engine.FindCodec(
3062       cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
3063   EXPECT_TRUE(engine.FindCodec(
3064       cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
3065   EXPECT_TRUE(engine.FindCodec(
3066       cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
3067   EXPECT_TRUE(engine.FindCodec(
3068       cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
3069   EXPECT_TRUE(engine.FindCodec(
3070       cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
3071   EXPECT_TRUE(engine.FindCodec(
3072       cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
3073   EXPECT_TRUE(engine.FindCodec(
3074       cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
3075   EXPECT_TRUE(engine.FindCodec(
3076       cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
3077   EXPECT_TRUE(engine.FindCodec(
3078       cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
3079   EXPECT_TRUE(engine.FindCodec(
3080       cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
3081   // Check codecs with an id by id.
3082   EXPECT_TRUE(engine.FindCodec(
3083       cricket::AudioCodec(0, "", 8000, 0, 1, 0)));   // PCMU
3084   EXPECT_TRUE(engine.FindCodec(
3085       cricket::AudioCodec(8, "", 8000, 0, 1, 0)));   // PCMA
3086   EXPECT_TRUE(engine.FindCodec(
3087       cricket::AudioCodec(9, "", 16000, 0, 1, 0)));  // G722
3088   EXPECT_TRUE(engine.FindCodec(
3089       cricket::AudioCodec(13, "", 8000, 0, 1, 0)));  // CN
3090   // Check sample/bitrate matching.
3091   EXPECT_TRUE(engine.FindCodec(
3092       cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
3093   // Check that bad codecs fail.
3094   EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
3095   EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
3096   EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
3097   EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
3098   EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
3099   // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3100   for (std::vector<cricket::AudioCodec>::const_iterator it =
3101       engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3102     if (it->name == "CN" && it->clockrate == 16000) {
3103       EXPECT_EQ(105, it->id);
3104     } else if (it->name == "CN" && it->clockrate == 32000) {
3105       EXPECT_EQ(106, it->id);
3106     } else if (it->name == "ISAC" && it->clockrate == 16000) {
3107       EXPECT_EQ(103, it->id);
3108     } else if (it->name == "ISAC" && it->clockrate == 32000) {
3109       EXPECT_EQ(104, it->id);
3110     } else if (it->name == "G722" && it->clockrate == 16000) {
3111       EXPECT_EQ(9, it->id);
3112     } else if (it->name == "telephone-event") {
3113       EXPECT_EQ(126, it->id);
3114     } else if (it->name == "red") {
3115       EXPECT_EQ(127, it->id);
3116     } else if (it->name == "opus") {
3117       EXPECT_EQ(111, it->id);
3118       ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3119       EXPECT_EQ("10", it->params.find("minptime")->second);
3120       ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3121       EXPECT_EQ("60", it->params.find("maxptime")->second);
3122     }
3123   }
3124
3125   engine.Terminate();
3126 }
3127
3128 // Tests that VoE supports at least 32 channels
3129 TEST(WebRtcVoiceEngineTest, Has32Channels) {
3130   cricket::WebRtcVoiceEngine engine;
3131   EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3132
3133   cricket::VoiceMediaChannel* channels[32];
3134   int num_channels = 0;
3135
3136   while (num_channels < ARRAY_SIZE(channels)) {
3137     cricket::VoiceMediaChannel* channel = engine.CreateChannel();
3138     if (!channel)
3139       break;
3140
3141     channels[num_channels++] = channel;
3142   }
3143
3144   int expected = ARRAY_SIZE(channels);
3145   EXPECT_EQ(expected, num_channels);
3146
3147   while (num_channels > 0) {
3148     delete channels[--num_channels];
3149   }
3150
3151   engine.Terminate();
3152 }
3153
3154 // Test that we set our preferred codecs properly.
3155 TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3156   cricket::WebRtcVoiceEngine engine;
3157   EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3158   cricket::WebRtcVoiceMediaChannel channel(&engine);
3159   EXPECT_TRUE(channel.SetRecvCodecs(engine.codecs()));
3160 }
3161
3162 #ifdef WIN32
3163 // Test our workarounds to WebRtc VoE' munging of the coinit count
3164 TEST(WebRtcVoiceEngineTest, CoInitialize) {
3165   cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
3166
3167   // Initial refcount should be 0.
3168   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3169
3170   // Engine should start even with COM already inited.
3171   EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
3172   engine->Terminate();
3173   EXPECT_TRUE(engine->Init(rtc::Thread::Current()));
3174   engine->Terminate();
3175
3176   // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
3177   EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3178   // Decrement refcount to (hopefully) 0.
3179   CoUninitialize();
3180   CoUninitialize();
3181   delete engine;
3182
3183   // Ensure refcount is 0.
3184   EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
3185   CoUninitialize();
3186 }
3187 #endif