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