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