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