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