Home | History | Annotate | Download | only in webrtc
      1 /*
      2  * libjingle
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifndef TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
     29 #define TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
     30 
     31 #include <list>
     32 #include <map>
     33 #include <vector>
     34 
     35 #include "talk/media/base/codec.h"
     36 #include "talk/media/base/rtputils.h"
     37 #include "talk/media/base/voiceprocessor.h"
     38 #include "talk/media/webrtc/fakewebrtccommon.h"
     39 #include "talk/media/webrtc/webrtcvoe.h"
     40 #include "webrtc/base/basictypes.h"
     41 #include "webrtc/base/gunit.h"
     42 #include "webrtc/base/stringutils.h"
     43 #ifdef USE_WEBRTC_DEV_BRANCH
     44 #include "webrtc/modules/audio_processing/include/audio_processing.h"
     45 #endif
     46 #include "webrtc/video_engine/include/vie_network.h"
     47 
     48 namespace cricket {
     49 
     50 // Function returning stats will return these values
     51 // for all values based on type.
     52 const int kIntStatValue = 123;
     53 const float kFractionLostStatValue = 0.5;
     54 
     55 static const char kFakeDefaultDeviceName[] = "Fake Default";
     56 static const int kFakeDefaultDeviceId = -1;
     57 static const char kFakeDeviceName[] = "Fake Device";
     58 #ifdef WIN32
     59 static const int kFakeDeviceId = 0;
     60 #else
     61 static const int kFakeDeviceId = 1;
     62 #endif
     63 
     64 static const int kOpusBandwidthNb = 4000;
     65 static const int kOpusBandwidthMb = 6000;
     66 static const int kOpusBandwidthWb = 8000;
     67 static const int kOpusBandwidthSwb = 12000;
     68 static const int kOpusBandwidthFb = 20000;
     69 
     70 // Verify the header extension ID, if enabled, is within the bounds specified in
     71 // [RFC5285]: 1-14 inclusive.
     72 #define WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id) \
     73   do { \
     74     if (enable && (id < 1 || id > 14)) { \
     75       return -1; \
     76     } \
     77   } while (0);
     78 
     79 #ifdef USE_WEBRTC_DEV_BRANCH
     80 class FakeAudioProcessing : public webrtc::AudioProcessing {
     81  public:
     82   FakeAudioProcessing() : experimental_ns_enabled_(false) {}
     83 
     84   WEBRTC_STUB(Initialize, ())
     85   WEBRTC_STUB(Initialize, (
     86       int input_sample_rate_hz,
     87       int output_sample_rate_hz,
     88       int reverse_sample_rate_hz,
     89       webrtc::AudioProcessing::ChannelLayout input_layout,
     90       webrtc::AudioProcessing::ChannelLayout output_layout,
     91       webrtc::AudioProcessing::ChannelLayout reverse_layout));
     92 
     93   WEBRTC_VOID_FUNC(SetExtraOptions, (const webrtc::Config& config)) {
     94     experimental_ns_enabled_ = config.Get<webrtc::ExperimentalNs>().enabled;
     95   }
     96 
     97   WEBRTC_STUB(set_sample_rate_hz, (int rate));
     98   WEBRTC_STUB_CONST(input_sample_rate_hz, ());
     99   WEBRTC_STUB_CONST(sample_rate_hz, ());
    100   WEBRTC_STUB_CONST(proc_sample_rate_hz, ());
    101   WEBRTC_STUB_CONST(proc_split_sample_rate_hz, ());
    102   WEBRTC_STUB_CONST(num_input_channels, ());
    103   WEBRTC_STUB_CONST(num_output_channels, ());
    104   WEBRTC_STUB_CONST(num_reverse_channels, ());
    105   WEBRTC_VOID_STUB(set_output_will_be_muted, (bool muted));
    106   WEBRTC_BOOL_STUB_CONST(output_will_be_muted, ());
    107   WEBRTC_STUB(ProcessStream, (webrtc::AudioFrame* frame));
    108   WEBRTC_STUB(ProcessStream, (
    109       const float* const* src,
    110       int samples_per_channel,
    111       int input_sample_rate_hz,
    112       webrtc::AudioProcessing::ChannelLayout input_layout,
    113       int output_sample_rate_hz,
    114       webrtc::AudioProcessing::ChannelLayout output_layout,
    115       float* const* dest));
    116   WEBRTC_STUB(AnalyzeReverseStream, (webrtc::AudioFrame* frame));
    117   WEBRTC_STUB(AnalyzeReverseStream, (
    118       const float* const* data,
    119       int samples_per_channel,
    120       int sample_rate_hz,
    121       webrtc::AudioProcessing::ChannelLayout layout));
    122   WEBRTC_STUB(set_stream_delay_ms, (int delay));
    123   WEBRTC_STUB_CONST(stream_delay_ms, ());
    124   WEBRTC_BOOL_STUB_CONST(was_stream_delay_set, ());
    125   WEBRTC_VOID_STUB(set_stream_key_pressed, (bool key_pressed));
    126   WEBRTC_BOOL_STUB_CONST(stream_key_pressed, ());
    127   WEBRTC_VOID_STUB(set_delay_offset_ms, (int offset));
    128   WEBRTC_STUB_CONST(delay_offset_ms, ());
    129   WEBRTC_STUB(StartDebugRecording, (const char filename[kMaxFilenameSize]));
    130   WEBRTC_STUB(StartDebugRecording, (FILE* handle));
    131   WEBRTC_STUB(StopDebugRecording, ());
    132   virtual webrtc::EchoCancellation* echo_cancellation() const OVERRIDE {
    133     return NULL;
    134   }
    135   virtual webrtc::EchoControlMobile* echo_control_mobile() const OVERRIDE {
    136     return NULL;
    137   }
    138   virtual webrtc::GainControl* gain_control() const OVERRIDE { return NULL; }
    139   virtual webrtc::HighPassFilter* high_pass_filter() const OVERRIDE {
    140     return NULL;
    141   }
    142   virtual webrtc::LevelEstimator* level_estimator() const OVERRIDE {
    143     return NULL;
    144   }
    145   virtual webrtc::NoiseSuppression* noise_suppression() const OVERRIDE {
    146     return NULL;
    147   }
    148   virtual webrtc::VoiceDetection* voice_detection() const OVERRIDE {
    149     return NULL;
    150   }
    151 
    152   bool experimental_ns_enabled() {
    153     return experimental_ns_enabled_;
    154   }
    155 
    156  private:
    157   bool experimental_ns_enabled_;
    158 };
    159 #endif
    160 
    161 class FakeWebRtcVoiceEngine
    162     : public webrtc::VoEAudioProcessing,
    163       public webrtc::VoEBase, public webrtc::VoECodec, public webrtc::VoEDtmf,
    164       public webrtc::VoEFile, public webrtc::VoEHardware,
    165       public webrtc::VoEExternalMedia, public webrtc::VoENetEqStats,
    166       public webrtc::VoENetwork, public webrtc::VoERTP_RTCP,
    167       public webrtc::VoEVideoSync, public webrtc::VoEVolumeControl {
    168  public:
    169   struct DtmfInfo {
    170     DtmfInfo()
    171       : dtmf_event_code(-1),
    172         dtmf_out_of_band(false),
    173         dtmf_length_ms(-1) {}
    174     int dtmf_event_code;
    175     bool dtmf_out_of_band;
    176     int dtmf_length_ms;
    177   };
    178   struct Channel {
    179     explicit Channel()
    180         : external_transport(false),
    181           send(false),
    182           playout(false),
    183           volume_scale(1.0),
    184           volume_pan_left(1.0),
    185           volume_pan_right(1.0),
    186           file(false),
    187           vad(false),
    188           codec_fec(false),
    189           max_encoding_bandwidth(0),
    190           red(false),
    191           nack(false),
    192           media_processor_registered(false),
    193           rx_agc_enabled(false),
    194           rx_agc_mode(webrtc::kAgcDefault),
    195           cn8_type(13),
    196           cn16_type(105),
    197           dtmf_type(106),
    198           red_type(117),
    199           nack_max_packets(0),
    200           vie_network(NULL),
    201           video_channel(-1),
    202           send_ssrc(0),
    203           send_audio_level_ext_(-1),
    204           receive_audio_level_ext_(-1),
    205           send_absolute_sender_time_ext_(-1),
    206           receive_absolute_sender_time_ext_(-1) {
    207       memset(&send_codec, 0, sizeof(send_codec));
    208       memset(&rx_agc_config, 0, sizeof(rx_agc_config));
    209     }
    210     bool external_transport;
    211     bool send;
    212     bool playout;
    213     float volume_scale;
    214     float volume_pan_left;
    215     float volume_pan_right;
    216     bool file;
    217     bool vad;
    218     bool codec_fec;
    219     int max_encoding_bandwidth;
    220     bool red;
    221     bool nack;
    222     bool media_processor_registered;
    223     bool rx_agc_enabled;
    224     webrtc::AgcModes rx_agc_mode;
    225     webrtc::AgcConfig rx_agc_config;
    226     int cn8_type;
    227     int cn16_type;
    228     int dtmf_type;
    229     int red_type;
    230     int nack_max_packets;
    231     webrtc::ViENetwork* vie_network;
    232     int video_channel;
    233     uint32 send_ssrc;
    234     int send_audio_level_ext_;
    235     int receive_audio_level_ext_;
    236     int send_absolute_sender_time_ext_;
    237     int receive_absolute_sender_time_ext_;
    238     DtmfInfo dtmf_info;
    239     std::vector<webrtc::CodecInst> recv_codecs;
    240     webrtc::CodecInst send_codec;
    241     webrtc::PacketTime last_rtp_packet_time;
    242     std::list<std::string> packets;
    243   };
    244 
    245   FakeWebRtcVoiceEngine(const cricket::AudioCodec* const* codecs,
    246                         int num_codecs)
    247       : inited_(false),
    248         last_channel_(-1),
    249         fail_create_channel_(false),
    250         codecs_(codecs),
    251         num_codecs_(num_codecs),
    252         num_set_send_codecs_(0),
    253         ec_enabled_(false),
    254         ec_metrics_enabled_(false),
    255         cng_enabled_(false),
    256         ns_enabled_(false),
    257         agc_enabled_(false),
    258         highpass_filter_enabled_(false),
    259         stereo_swapping_enabled_(false),
    260         typing_detection_enabled_(false),
    261         ec_mode_(webrtc::kEcDefault),
    262         aecm_mode_(webrtc::kAecmSpeakerphone),
    263         ns_mode_(webrtc::kNsDefault),
    264         agc_mode_(webrtc::kAgcDefault),
    265         observer_(NULL),
    266         playout_fail_channel_(-1),
    267         send_fail_channel_(-1),
    268         fail_start_recording_microphone_(false),
    269         recording_microphone_(false),
    270         recording_sample_rate_(-1),
    271         playout_sample_rate_(-1),
    272         media_processor_(NULL) {
    273     memset(&agc_config_, 0, sizeof(agc_config_));
    274   }
    275   ~FakeWebRtcVoiceEngine() {
    276     // Ought to have all been deleted by the WebRtcVoiceMediaChannel
    277     // destructors, but just in case ...
    278     for (std::map<int, Channel*>::const_iterator i = channels_.begin();
    279          i != channels_.end(); ++i) {
    280       delete i->second;
    281     }
    282   }
    283 
    284   bool IsExternalMediaProcessorRegistered() const {
    285     return media_processor_ != NULL;
    286   }
    287   bool IsInited() const { return inited_; }
    288   int GetLastChannel() const { return last_channel_; }
    289   int GetChannelFromLocalSsrc(uint32 local_ssrc) const {
    290     for (std::map<int, Channel*>::const_iterator iter = channels_.begin();
    291          iter != channels_.end(); ++iter) {
    292       if (local_ssrc == iter->second->send_ssrc)
    293         return iter->first;
    294     }
    295     return -1;
    296   }
    297   int GetNumChannels() const { return static_cast<int>(channels_.size()); }
    298   bool GetPlayout(int channel) {
    299     return channels_[channel]->playout;
    300   }
    301   bool GetSend(int channel) {
    302     return channels_[channel]->send;
    303   }
    304   bool GetRecordingMicrophone() {
    305     return recording_microphone_;
    306   }
    307   bool GetVAD(int channel) {
    308     return channels_[channel]->vad;
    309   }
    310   bool GetRED(int channel) {
    311     return channels_[channel]->red;
    312   }
    313   bool GetCodecFEC(int channel) {
    314     return channels_[channel]->codec_fec;
    315   }
    316   int GetMaxEncodingBandwidth(int channel) {
    317     return channels_[channel]->max_encoding_bandwidth;
    318   }
    319   bool GetNACK(int channel) {
    320     return channels_[channel]->nack;
    321   }
    322   int GetNACKMaxPackets(int channel) {
    323     return channels_[channel]->nack_max_packets;
    324   }
    325   webrtc::ViENetwork* GetViENetwork(int channel) {
    326     WEBRTC_ASSERT_CHANNEL(channel);
    327     // WARNING: This pointer is for verification purposes only. Calling
    328     // functions on it may result in undefined behavior!
    329     return channels_[channel]->vie_network;
    330   }
    331   int GetVideoChannel(int channel) {
    332     WEBRTC_ASSERT_CHANNEL(channel);
    333     return channels_[channel]->video_channel;
    334   }
    335   const webrtc::PacketTime& GetLastRtpPacketTime(int channel) {
    336     WEBRTC_ASSERT_CHANNEL(channel);
    337     return channels_[channel]->last_rtp_packet_time;
    338   }
    339   int GetSendCNPayloadType(int channel, bool wideband) {
    340     return (wideband) ?
    341         channels_[channel]->cn16_type :
    342         channels_[channel]->cn8_type;
    343   }
    344   int GetSendTelephoneEventPayloadType(int channel) {
    345     return channels_[channel]->dtmf_type;
    346   }
    347   int GetSendREDPayloadType(int channel) {
    348     return channels_[channel]->red_type;
    349   }
    350   bool CheckPacket(int channel, const void* data, size_t len) {
    351     bool result = !CheckNoPacket(channel);
    352     if (result) {
    353       std::string packet = channels_[channel]->packets.front();
    354       result = (packet == std::string(static_cast<const char*>(data), len));
    355       channels_[channel]->packets.pop_front();
    356     }
    357     return result;
    358   }
    359   bool CheckNoPacket(int channel) {
    360     return channels_[channel]->packets.empty();
    361   }
    362   void TriggerCallbackOnError(int channel_num, int err_code) {
    363     ASSERT(observer_ != NULL);
    364     observer_->CallbackOnError(channel_num, err_code);
    365   }
    366   void set_playout_fail_channel(int channel) {
    367     playout_fail_channel_ = channel;
    368   }
    369   void set_send_fail_channel(int channel) {
    370     send_fail_channel_ = channel;
    371   }
    372   void set_fail_start_recording_microphone(
    373       bool fail_start_recording_microphone) {
    374     fail_start_recording_microphone_ = fail_start_recording_microphone;
    375   }
    376   void set_fail_create_channel(bool fail_create_channel) {
    377     fail_create_channel_ = fail_create_channel;
    378   }
    379   void TriggerProcessPacket(MediaProcessorDirection direction) {
    380     webrtc::ProcessingTypes pt =
    381         (direction == cricket::MPD_TX) ?
    382             webrtc::kRecordingPerChannel : webrtc::kPlaybackAllChannelsMixed;
    383     if (media_processor_ != NULL) {
    384       media_processor_->Process(0,
    385                                 pt,
    386                                 NULL,
    387                                 0,
    388                                 0,
    389                                 true);
    390     }
    391   }
    392   int AddChannel() {
    393     if (fail_create_channel_) {
    394       return -1;
    395     }
    396     Channel* ch = new Channel();
    397     for (int i = 0; i < NumOfCodecs(); ++i) {
    398       webrtc::CodecInst codec;
    399       GetCodec(i, codec);
    400       ch->recv_codecs.push_back(codec);
    401     }
    402     channels_[++last_channel_] = ch;
    403     return last_channel_;
    404   }
    405   int GetSendRtpExtensionId(int channel, const std::string& extension) {
    406     WEBRTC_ASSERT_CHANNEL(channel);
    407     if (extension == kRtpAudioLevelHeaderExtension) {
    408       return channels_[channel]->send_audio_level_ext_;
    409     } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
    410       return channels_[channel]->send_absolute_sender_time_ext_;
    411     }
    412     return -1;
    413   }
    414   int GetReceiveRtpExtensionId(int channel, const std::string& extension) {
    415     WEBRTC_ASSERT_CHANNEL(channel);
    416     if (extension == kRtpAudioLevelHeaderExtension) {
    417       return channels_[channel]->receive_audio_level_ext_;
    418     } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
    419       return channels_[channel]->receive_absolute_sender_time_ext_;
    420     }
    421     return -1;
    422   }
    423 
    424   int GetNumSetSendCodecs() const { return num_set_send_codecs_; }
    425 
    426   WEBRTC_STUB(Release, ());
    427 
    428   // webrtc::VoEBase
    429   WEBRTC_FUNC(RegisterVoiceEngineObserver, (
    430       webrtc::VoiceEngineObserver& observer)) {
    431     observer_ = &observer;
    432     return 0;
    433   }
    434   WEBRTC_STUB(DeRegisterVoiceEngineObserver, ());
    435   WEBRTC_FUNC(Init, (webrtc::AudioDeviceModule* adm,
    436                      webrtc::AudioProcessing* audioproc)) {
    437     inited_ = true;
    438     return 0;
    439   }
    440   WEBRTC_FUNC(Terminate, ()) {
    441     inited_ = false;
    442     return 0;
    443   }
    444   virtual webrtc::AudioProcessing* audio_processing() OVERRIDE {
    445 #ifdef USE_WEBRTC_DEV_BRANCH
    446     return &audio_processing_;
    447 #else
    448     return NULL;
    449 #endif
    450   }
    451   WEBRTC_FUNC(CreateChannel, ()) {
    452     return AddChannel();
    453   }
    454   WEBRTC_FUNC(CreateChannel, (const webrtc::Config& /*config*/)) {
    455     return AddChannel();
    456   }
    457   WEBRTC_FUNC(DeleteChannel, (int channel)) {
    458     WEBRTC_CHECK_CHANNEL(channel);
    459     delete channels_[channel];
    460     channels_.erase(channel);
    461     return 0;
    462   }
    463   WEBRTC_STUB(StartReceive, (int channel));
    464   WEBRTC_FUNC(StartPlayout, (int channel)) {
    465     if (playout_fail_channel_ != channel) {
    466       WEBRTC_CHECK_CHANNEL(channel);
    467       channels_[channel]->playout = true;
    468       return 0;
    469     } else {
    470       // When playout_fail_channel_ == channel, fail the StartPlayout on this
    471       // channel.
    472       return -1;
    473     }
    474   }
    475   WEBRTC_FUNC(StartSend, (int channel)) {
    476     if (send_fail_channel_ != channel) {
    477       WEBRTC_CHECK_CHANNEL(channel);
    478       channels_[channel]->send = true;
    479       return 0;
    480     } else {
    481       // When send_fail_channel_ == channel, fail the StartSend on this
    482       // channel.
    483       return -1;
    484     }
    485   }
    486   WEBRTC_STUB(StopReceive, (int channel));
    487   WEBRTC_FUNC(StopPlayout, (int channel)) {
    488     WEBRTC_CHECK_CHANNEL(channel);
    489     channels_[channel]->playout = false;
    490     return 0;
    491   }
    492   WEBRTC_FUNC(StopSend, (int channel)) {
    493     WEBRTC_CHECK_CHANNEL(channel);
    494     channels_[channel]->send = false;
    495     return 0;
    496   }
    497   WEBRTC_STUB(GetVersion, (char version[1024]));
    498   WEBRTC_STUB(LastError, ());
    499   WEBRTC_STUB(SetOnHoldStatus, (int, bool, webrtc::OnHoldModes));
    500   WEBRTC_STUB(GetOnHoldStatus, (int, bool&, webrtc::OnHoldModes&));
    501 
    502   // webrtc::VoECodec
    503   WEBRTC_FUNC(NumOfCodecs, ()) {
    504     return num_codecs_;
    505   }
    506   WEBRTC_FUNC(GetCodec, (int index, webrtc::CodecInst& codec)) {
    507     if (index < 0 || index >= NumOfCodecs()) {
    508       return -1;
    509     }
    510     const cricket::AudioCodec& c(*codecs_[index]);
    511     codec.pltype = c.id;
    512     rtc::strcpyn(codec.plname, sizeof(codec.plname), c.name.c_str());
    513     codec.plfreq = c.clockrate;
    514     codec.pacsize = 0;
    515     codec.channels = c.channels;
    516     codec.rate = c.bitrate;
    517     return 0;
    518   }
    519   WEBRTC_FUNC(SetSendCodec, (int channel, const webrtc::CodecInst& codec)) {
    520     WEBRTC_CHECK_CHANNEL(channel);
    521     // To match the behavior of the real implementation.
    522     if (_stricmp(codec.plname, "telephone-event") == 0 ||
    523         _stricmp(codec.plname, "audio/telephone-event") == 0 ||
    524         _stricmp(codec.plname, "CN") == 0 ||
    525         _stricmp(codec.plname, "red") == 0 ) {
    526       return -1;
    527     }
    528     channels_[channel]->send_codec = codec;
    529     ++num_set_send_codecs_;
    530     return 0;
    531   }
    532   WEBRTC_FUNC(GetSendCodec, (int channel, webrtc::CodecInst& codec)) {
    533     WEBRTC_CHECK_CHANNEL(channel);
    534     codec = channels_[channel]->send_codec;
    535     return 0;
    536   }
    537   WEBRTC_STUB(SetSecondarySendCodec, (int channel,
    538                                       const webrtc::CodecInst& codec,
    539                                       int red_payload_type));
    540   WEBRTC_STUB(RemoveSecondarySendCodec, (int channel));
    541   WEBRTC_STUB(GetSecondarySendCodec, (int channel,
    542                                       webrtc::CodecInst& codec));
    543   WEBRTC_FUNC(GetRecCodec, (int channel, webrtc::CodecInst& codec)) {
    544     WEBRTC_CHECK_CHANNEL(channel);
    545     const Channel* c = channels_[channel];
    546     for (std::list<std::string>::const_iterator it_packet = c->packets.begin();
    547         it_packet != c->packets.end(); ++it_packet) {
    548       int pltype;
    549       if (!GetRtpPayloadType(it_packet->data(), it_packet->length(), &pltype)) {
    550         continue;
    551       }
    552       for (std::vector<webrtc::CodecInst>::const_iterator it_codec =
    553           c->recv_codecs.begin(); it_codec != c->recv_codecs.end();
    554           ++it_codec) {
    555         if (it_codec->pltype == pltype) {
    556           codec = *it_codec;
    557           return 0;
    558         }
    559       }
    560     }
    561     return -1;
    562   }
    563   WEBRTC_STUB(SetAMREncFormat, (int channel, webrtc::AmrMode mode));
    564   WEBRTC_STUB(SetAMRDecFormat, (int channel, webrtc::AmrMode mode));
    565   WEBRTC_STUB(SetAMRWbEncFormat, (int channel, webrtc::AmrMode mode));
    566   WEBRTC_STUB(SetAMRWbDecFormat, (int channel, webrtc::AmrMode mode));
    567   WEBRTC_STUB(SetISACInitTargetRate, (int channel, int rateBps,
    568                                       bool useFixedFrameSize));
    569   WEBRTC_STUB(SetISACMaxRate, (int channel, int rateBps));
    570   WEBRTC_STUB(SetISACMaxPayloadSize, (int channel, int sizeBytes));
    571   WEBRTC_FUNC(SetRecPayloadType, (int channel,
    572                                   const webrtc::CodecInst& codec)) {
    573     WEBRTC_CHECK_CHANNEL(channel);
    574     Channel* ch = channels_[channel];
    575     if (ch->playout)
    576       return -1;  // Channel is in use.
    577     // Check if something else already has this slot.
    578     if (codec.pltype != -1) {
    579       for (std::vector<webrtc::CodecInst>::iterator it =
    580           ch->recv_codecs.begin(); it != ch->recv_codecs.end(); ++it) {
    581         if (it->pltype == codec.pltype &&
    582             _stricmp(it->plname, codec.plname) != 0) {
    583           return -1;
    584         }
    585       }
    586     }
    587     // Otherwise try to find this codec and update its payload type.
    588     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
    589          it != ch->recv_codecs.end(); ++it) {
    590       if (strcmp(it->plname, codec.plname) == 0 &&
    591           it->plfreq == codec.plfreq) {
    592         it->pltype = codec.pltype;
    593         it->channels = codec.channels;
    594         return 0;
    595       }
    596     }
    597     return -1;  // not found
    598   }
    599   WEBRTC_FUNC(SetSendCNPayloadType, (int channel, int type,
    600                                      webrtc::PayloadFrequencies frequency)) {
    601     WEBRTC_CHECK_CHANNEL(channel);
    602     if (frequency == webrtc::kFreq8000Hz) {
    603       channels_[channel]->cn8_type = type;
    604     } else if (frequency == webrtc::kFreq16000Hz) {
    605       channels_[channel]->cn16_type = type;
    606     }
    607     return 0;
    608   }
    609   WEBRTC_FUNC(GetRecPayloadType, (int channel, webrtc::CodecInst& codec)) {
    610     WEBRTC_CHECK_CHANNEL(channel);
    611     Channel* ch = channels_[channel];
    612     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
    613          it != ch->recv_codecs.end(); ++it) {
    614       if (strcmp(it->plname, codec.plname) == 0 &&
    615           it->plfreq == codec.plfreq &&
    616           it->channels == codec.channels &&
    617           it->pltype != -1) {
    618         codec.pltype = it->pltype;
    619         return 0;
    620       }
    621     }
    622     return -1;  // not found
    623   }
    624   WEBRTC_FUNC(SetVADStatus, (int channel, bool enable, webrtc::VadModes mode,
    625                              bool disableDTX)) {
    626     WEBRTC_CHECK_CHANNEL(channel);
    627     if (channels_[channel]->send_codec.channels == 2) {
    628       // Replicating VoE behavior; VAD cannot be enabled for stereo.
    629       return -1;
    630     }
    631     channels_[channel]->vad = enable;
    632     return 0;
    633   }
    634   WEBRTC_STUB(GetVADStatus, (int channel, bool& enabled,
    635                              webrtc::VadModes& mode, bool& disabledDTX));
    636 
    637 #ifdef USE_WEBRTC_DEV_BRANCH
    638   WEBRTC_FUNC(SetFECStatus, (int channel, bool enable)) {
    639     WEBRTC_CHECK_CHANNEL(channel);
    640     if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
    641       // Return -1 if current send codec is not Opus.
    642       // TODO(minyue): Excludes other codecs if they support inband FEC.
    643       return -1;
    644     }
    645     channels_[channel]->codec_fec = enable;
    646     return 0;
    647   }
    648   WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable)) {
    649     WEBRTC_CHECK_CHANNEL(channel);
    650     enable = channels_[channel]->codec_fec;
    651     return 0;
    652   }
    653 
    654   WEBRTC_FUNC(SetOpusMaxPlaybackRate, (int channel, int frequency_hz)) {
    655     WEBRTC_CHECK_CHANNEL(channel);
    656     if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
    657       // Return -1 if current send codec is not Opus.
    658       return -1;
    659     }
    660     if (frequency_hz <= 8000)
    661       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthNb;
    662     else if (frequency_hz <= 12000)
    663       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthMb;
    664     else if (frequency_hz <= 16000)
    665       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthWb;
    666     else if (frequency_hz <= 24000)
    667       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthSwb;
    668     else
    669       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthFb;
    670     return 0;
    671   }
    672 #endif  // USE_WEBRTC_DEV_BRANCH
    673 
    674   // webrtc::VoEDtmf
    675   WEBRTC_FUNC(SendTelephoneEvent, (int channel, int event_code,
    676       bool out_of_band = true, int length_ms = 160, int attenuation_db = 10)) {
    677     channels_[channel]->dtmf_info.dtmf_event_code = event_code;
    678     channels_[channel]->dtmf_info.dtmf_out_of_band = out_of_band;
    679     channels_[channel]->dtmf_info.dtmf_length_ms = length_ms;
    680     return 0;
    681   }
    682 
    683   WEBRTC_FUNC(SetSendTelephoneEventPayloadType,
    684       (int channel, unsigned char type)) {
    685     channels_[channel]->dtmf_type = type;
    686     return 0;
    687   };
    688   WEBRTC_STUB(GetSendTelephoneEventPayloadType,
    689       (int channel, unsigned char& type));
    690 
    691   WEBRTC_STUB(SetDtmfFeedbackStatus, (bool enable, bool directFeedback));
    692   WEBRTC_STUB(GetDtmfFeedbackStatus, (bool& enabled, bool& directFeedback));
    693   WEBRTC_STUB(SetDtmfPlayoutStatus, (int channel, bool enable));
    694   WEBRTC_STUB(GetDtmfPlayoutStatus, (int channel, bool& enabled));
    695 
    696   WEBRTC_FUNC(PlayDtmfTone,
    697       (int event_code, int length_ms = 200, int attenuation_db = 10)) {
    698     dtmf_info_.dtmf_event_code = event_code;
    699     dtmf_info_.dtmf_length_ms = length_ms;
    700     return 0;
    701   }
    702   WEBRTC_STUB(StartPlayingDtmfTone,
    703       (int eventCode, int attenuationDb = 10));
    704   WEBRTC_STUB(StopPlayingDtmfTone, ());
    705 
    706   // webrtc::VoEFile
    707   WEBRTC_FUNC(StartPlayingFileLocally, (int channel, const char* fileNameUTF8,
    708                                         bool loop, webrtc::FileFormats format,
    709                                         float volumeScaling, int startPointMs,
    710                                         int stopPointMs)) {
    711     WEBRTC_CHECK_CHANNEL(channel);
    712     channels_[channel]->file = true;
    713     return 0;
    714   }
    715   WEBRTC_FUNC(StartPlayingFileLocally, (int channel, webrtc::InStream* stream,
    716                                         webrtc::FileFormats format,
    717                                         float volumeScaling, int startPointMs,
    718                                         int stopPointMs)) {
    719     WEBRTC_CHECK_CHANNEL(channel);
    720     channels_[channel]->file = true;
    721     return 0;
    722   }
    723   WEBRTC_FUNC(StopPlayingFileLocally, (int channel)) {
    724     WEBRTC_CHECK_CHANNEL(channel);
    725     channels_[channel]->file = false;
    726     return 0;
    727   }
    728   WEBRTC_FUNC(IsPlayingFileLocally, (int channel)) {
    729     WEBRTC_CHECK_CHANNEL(channel);
    730     return (channels_[channel]->file) ? 1 : 0;
    731   }
    732   WEBRTC_STUB(ScaleLocalFilePlayout, (int channel, float scale));
    733   WEBRTC_STUB(StartPlayingFileAsMicrophone, (int channel,
    734                                              const char* fileNameUTF8,
    735                                              bool loop,
    736                                              bool mixWithMicrophone,
    737                                              webrtc::FileFormats format,
    738                                              float volumeScaling));
    739   WEBRTC_STUB(StartPlayingFileAsMicrophone, (int channel,
    740                                              webrtc::InStream* stream,
    741                                              bool mixWithMicrophone,
    742                                              webrtc::FileFormats format,
    743                                              float volumeScaling));
    744   WEBRTC_STUB(StopPlayingFileAsMicrophone, (int channel));
    745   WEBRTC_STUB(IsPlayingFileAsMicrophone, (int channel));
    746   WEBRTC_STUB(ScaleFileAsMicrophonePlayout, (int channel, float scale));
    747   WEBRTC_STUB(StartRecordingPlayout, (int channel, const char* fileNameUTF8,
    748                                       webrtc::CodecInst* compression,
    749                                       int maxSizeBytes));
    750   WEBRTC_STUB(StartRecordingPlayout, (int channel, webrtc::OutStream* stream,
    751                                       webrtc::CodecInst* compression));
    752   WEBRTC_STUB(StopRecordingPlayout, (int channel));
    753   WEBRTC_FUNC(StartRecordingMicrophone, (const char* fileNameUTF8,
    754                                          webrtc::CodecInst* compression,
    755                                          int maxSizeBytes)) {
    756     if (fail_start_recording_microphone_) {
    757       return -1;
    758     }
    759     recording_microphone_ = true;
    760     return 0;
    761   }
    762   WEBRTC_FUNC(StartRecordingMicrophone, (webrtc::OutStream* stream,
    763                                          webrtc::CodecInst* compression)) {
    764     if (fail_start_recording_microphone_) {
    765       return -1;
    766     }
    767     recording_microphone_ = true;
    768     return 0;
    769   }
    770   WEBRTC_FUNC(StopRecordingMicrophone, ()) {
    771     if (!recording_microphone_) {
    772       return -1;
    773     }
    774     recording_microphone_ = false;
    775     return 0;
    776   }
    777   WEBRTC_STUB(ConvertPCMToWAV, (const char* fileNameInUTF8,
    778                                 const char* fileNameOutUTF8));
    779   WEBRTC_STUB(ConvertPCMToWAV, (webrtc::InStream* streamIn,
    780                                 webrtc::OutStream* streamOut));
    781   WEBRTC_STUB(ConvertWAVToPCM, (const char* fileNameInUTF8,
    782                                 const char* fileNameOutUTF8));
    783   WEBRTC_STUB(ConvertWAVToPCM, (webrtc::InStream* streamIn,
    784                                 webrtc::OutStream* streamOut));
    785   WEBRTC_STUB(ConvertPCMToCompressed, (const char* fileNameInUTF8,
    786                                        const char* fileNameOutUTF8,
    787                                        webrtc::CodecInst* compression));
    788   WEBRTC_STUB(ConvertPCMToCompressed, (webrtc::InStream* streamIn,
    789                                        webrtc::OutStream* streamOut,
    790                                        webrtc::CodecInst* compression));
    791   WEBRTC_STUB(ConvertCompressedToPCM, (const char* fileNameInUTF8,
    792                                      const char* fileNameOutUTF8));
    793   WEBRTC_STUB(ConvertCompressedToPCM, (webrtc::InStream* streamIn,
    794                                        webrtc::OutStream* streamOut));
    795   WEBRTC_STUB(GetFileDuration, (const char* fileNameUTF8, int& durationMs,
    796                                 webrtc::FileFormats format));
    797   WEBRTC_STUB(GetPlaybackPosition, (int channel, int& positionMs));
    798 
    799   // webrtc::VoEHardware
    800   WEBRTC_STUB(GetCPULoad, (int&));
    801   WEBRTC_FUNC(GetNumOfRecordingDevices, (int& num)) {
    802     return GetNumDevices(num);
    803   }
    804   WEBRTC_FUNC(GetNumOfPlayoutDevices, (int& num)) {
    805     return GetNumDevices(num);
    806   }
    807   WEBRTC_FUNC(GetRecordingDeviceName, (int i, char* name, char* guid)) {
    808     return GetDeviceName(i, name, guid);
    809   }
    810   WEBRTC_FUNC(GetPlayoutDeviceName, (int i, char* name, char* guid)) {
    811     return GetDeviceName(i, name, guid);
    812   }
    813   WEBRTC_STUB(SetRecordingDevice, (int, webrtc::StereoChannel));
    814   WEBRTC_STUB(SetPlayoutDevice, (int));
    815   WEBRTC_STUB(SetAudioDeviceLayer, (webrtc::AudioLayers));
    816   WEBRTC_STUB(GetAudioDeviceLayer, (webrtc::AudioLayers&));
    817   WEBRTC_STUB(GetPlayoutDeviceStatus, (bool&));
    818   WEBRTC_STUB(GetRecordingDeviceStatus, (bool&));
    819   WEBRTC_STUB(ResetAudioDevice, ());
    820   WEBRTC_STUB(AudioDeviceControl, (unsigned int, unsigned int, unsigned int));
    821   WEBRTC_STUB(SetLoudspeakerStatus, (bool enable));
    822   WEBRTC_STUB(GetLoudspeakerStatus, (bool& enabled));
    823   WEBRTC_FUNC(SetRecordingSampleRate, (unsigned int samples_per_sec)) {
    824     recording_sample_rate_ = samples_per_sec;
    825     return 0;
    826   }
    827   WEBRTC_FUNC_CONST(RecordingSampleRate, (unsigned int* samples_per_sec)) {
    828     *samples_per_sec = recording_sample_rate_;
    829     return 0;
    830   }
    831   WEBRTC_FUNC(SetPlayoutSampleRate, (unsigned int samples_per_sec)) {
    832     playout_sample_rate_ = samples_per_sec;
    833     return 0;
    834   }
    835   WEBRTC_FUNC_CONST(PlayoutSampleRate, (unsigned int* samples_per_sec)) {
    836     *samples_per_sec = playout_sample_rate_;
    837     return 0;
    838   }
    839   WEBRTC_STUB(EnableBuiltInAEC, (bool enable));
    840   virtual bool BuiltInAECIsEnabled() const { return true; }
    841 
    842   // webrtc::VoENetEqStats
    843   WEBRTC_STUB(GetNetworkStatistics, (int, webrtc::NetworkStatistics&));
    844   WEBRTC_FUNC_CONST(GetDecodingCallStatistics, (int channel,
    845       webrtc::AudioDecodingCallStats*)) {
    846     WEBRTC_CHECK_CHANNEL(channel);
    847     return 0;
    848   }
    849 
    850   // webrtc::VoENetwork
    851   WEBRTC_FUNC(RegisterExternalTransport, (int channel,
    852                                           webrtc::Transport& transport)) {
    853     WEBRTC_CHECK_CHANNEL(channel);
    854     channels_[channel]->external_transport = true;
    855     return 0;
    856   }
    857   WEBRTC_FUNC(DeRegisterExternalTransport, (int channel)) {
    858     WEBRTC_CHECK_CHANNEL(channel);
    859     channels_[channel]->external_transport = false;
    860     return 0;
    861   }
    862   WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
    863                                   unsigned int length)) {
    864     WEBRTC_CHECK_CHANNEL(channel);
    865     if (!channels_[channel]->external_transport) return -1;
    866     channels_[channel]->packets.push_back(
    867         std::string(static_cast<const char*>(data), length));
    868     return 0;
    869   }
    870   WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
    871                                   unsigned int length,
    872                                   const webrtc::PacketTime& packet_time)) {
    873     WEBRTC_CHECK_CHANNEL(channel);
    874     if (ReceivedRTPPacket(channel, data, length) == -1) {
    875       return -1;
    876     }
    877     channels_[channel]->last_rtp_packet_time = packet_time;
    878     return 0;
    879   }
    880 
    881   WEBRTC_STUB(ReceivedRTCPPacket, (int channel, const void* data,
    882                                    unsigned int length));
    883 
    884   // webrtc::VoERTP_RTCP
    885   WEBRTC_STUB(RegisterRTPObserver, (int channel,
    886                                     webrtc::VoERTPObserver& observer));
    887   WEBRTC_STUB(DeRegisterRTPObserver, (int channel));
    888   WEBRTC_STUB(RegisterRTCPObserver, (int channel,
    889                                      webrtc::VoERTCPObserver& observer));
    890   WEBRTC_STUB(DeRegisterRTCPObserver, (int channel));
    891   WEBRTC_FUNC(SetLocalSSRC, (int channel, unsigned int ssrc)) {
    892     WEBRTC_CHECK_CHANNEL(channel);
    893     channels_[channel]->send_ssrc = ssrc;
    894     return 0;
    895   }
    896   WEBRTC_FUNC(GetLocalSSRC, (int channel, unsigned int& ssrc)) {
    897     WEBRTC_CHECK_CHANNEL(channel);
    898     ssrc = channels_[channel]->send_ssrc;
    899     return 0;
    900   }
    901   WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc));
    902   WEBRTC_FUNC(SetSendAudioLevelIndicationStatus, (int channel, bool enable,
    903       unsigned char id)) {
    904     WEBRTC_CHECK_CHANNEL(channel);
    905     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    906     channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1;
    907     return 0;
    908   }
    909   WEBRTC_FUNC(SetReceiveAudioLevelIndicationStatus, (int channel, bool enable,
    910       unsigned char id)) {
    911     WEBRTC_CHECK_CHANNEL(channel);
    912     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    913     channels_[channel]->receive_audio_level_ext_ = (enable) ? id : -1;
    914    return 0;
    915   }
    916   WEBRTC_FUNC(SetSendAbsoluteSenderTimeStatus, (int channel, bool enable,
    917       unsigned char id)) {
    918     WEBRTC_CHECK_CHANNEL(channel);
    919     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    920     channels_[channel]->send_absolute_sender_time_ext_ = (enable) ? id : -1;
    921     return 0;
    922   }
    923   WEBRTC_FUNC(SetReceiveAbsoluteSenderTimeStatus, (int channel, bool enable,
    924       unsigned char id)) {
    925     WEBRTC_CHECK_CHANNEL(channel);
    926     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    927     channels_[channel]->receive_absolute_sender_time_ext_ = (enable) ? id : -1;
    928     return 0;
    929   }
    930 
    931   WEBRTC_STUB(GetRemoteCSRCs, (int channel, unsigned int arrCSRC[15]));
    932   WEBRTC_STUB(SetRTCPStatus, (int channel, bool enable));
    933   WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled));
    934   WEBRTC_STUB(SetRTCP_CNAME, (int channel, const char cname[256]));
    935   WEBRTC_STUB(GetRTCP_CNAME, (int channel, char cname[256]));
    936   WEBRTC_STUB(GetRemoteRTCP_CNAME, (int channel, char* cname));
    937   WEBRTC_STUB(GetRemoteRTCPData, (int channel, unsigned int& NTPHigh,
    938                                   unsigned int& NTPLow,
    939                                   unsigned int& timestamp,
    940                                   unsigned int& playoutTimestamp,
    941                                   unsigned int* jitter,
    942                                   unsigned short* fractionLost));
    943   WEBRTC_STUB(GetRemoteRTCPSenderInfo, (int channel,
    944                                         webrtc::SenderInfo* sender_info));
    945   WEBRTC_FUNC(GetRemoteRTCPReportBlocks,
    946               (int channel, std::vector<webrtc::ReportBlock>* receive_blocks)) {
    947     WEBRTC_CHECK_CHANNEL(channel);
    948     webrtc::ReportBlock block;
    949     block.source_SSRC = channels_[channel]->send_ssrc;
    950     webrtc::CodecInst send_codec = channels_[channel]->send_codec;
    951     if (send_codec.pltype >= 0) {
    952       block.fraction_lost = (unsigned char)(kFractionLostStatValue * 256);
    953       if (send_codec.plfreq / 1000 > 0) {
    954         block.interarrival_jitter = kIntStatValue * (send_codec.plfreq / 1000);
    955       }
    956       block.cumulative_num_packets_lost = kIntStatValue;
    957       block.extended_highest_sequence_number = kIntStatValue;
    958       receive_blocks->push_back(block);
    959     }
    960     return 0;
    961   }
    962   WEBRTC_STUB(SendApplicationDefinedRTCPPacket, (int channel,
    963                                                  unsigned char subType,
    964                                                  unsigned int name,
    965                                                  const char* data,
    966                                                  unsigned short dataLength));
    967   WEBRTC_STUB(GetRTPStatistics, (int channel, unsigned int& averageJitterMs,
    968                                  unsigned int& maxJitterMs,
    969                                  unsigned int& discardedPackets));
    970   WEBRTC_FUNC(GetRTCPStatistics, (int channel, webrtc::CallStatistics& stats)) {
    971     WEBRTC_CHECK_CHANNEL(channel);
    972     stats.fractionLost = static_cast<int16>(kIntStatValue);
    973     stats.cumulativeLost = kIntStatValue;
    974     stats.extendedMax = kIntStatValue;
    975     stats.jitterSamples = kIntStatValue;
    976     stats.rttMs = kIntStatValue;
    977     stats.bytesSent = kIntStatValue;
    978     stats.packetsSent = kIntStatValue;
    979     stats.bytesReceived = kIntStatValue;
    980     stats.packetsReceived = kIntStatValue;
    981     return 0;
    982   }
    983 #ifdef USE_WEBRTC_DEV_BRANCH
    984   WEBRTC_FUNC(SetREDStatus, (int channel, bool enable, int redPayloadtype)) {
    985     return SetFECStatus(channel, enable, redPayloadtype);
    986   }
    987 #endif
    988   // TODO(minyue): remove the below function when transition to SetREDStatus
    989   //               is finished.
    990   WEBRTC_FUNC(SetFECStatus, (int channel, bool enable, int redPayloadtype)) {
    991     WEBRTC_CHECK_CHANNEL(channel);
    992     channels_[channel]->red = enable;
    993     channels_[channel]->red_type = redPayloadtype;
    994     return 0;
    995   }
    996 #ifdef USE_WEBRTC_DEV_BRANCH
    997   WEBRTC_FUNC(GetREDStatus, (int channel, bool& enable, int& redPayloadtype)) {
    998     return GetFECStatus(channel, enable, redPayloadtype);
    999   }
   1000 #endif
   1001   // TODO(minyue): remove the below function when transition to GetREDStatus
   1002   //               is finished.
   1003   WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable, int& redPayloadtype)) {
   1004     WEBRTC_CHECK_CHANNEL(channel);
   1005     enable = channels_[channel]->red;
   1006     redPayloadtype = channels_[channel]->red_type;
   1007     return 0;
   1008   }
   1009   WEBRTC_FUNC(SetNACKStatus, (int channel, bool enable, int maxNoPackets)) {
   1010     WEBRTC_CHECK_CHANNEL(channel);
   1011     channels_[channel]->nack = enable;
   1012     channels_[channel]->nack_max_packets = maxNoPackets;
   1013     return 0;
   1014   }
   1015   WEBRTC_STUB(StartRTPDump, (int channel, const char* fileNameUTF8,
   1016                              webrtc::RTPDirections direction));
   1017   WEBRTC_STUB(StopRTPDump, (int channel, webrtc::RTPDirections direction));
   1018   WEBRTC_STUB(RTPDumpIsActive, (int channel, webrtc::RTPDirections direction));
   1019   WEBRTC_STUB(InsertExtraRTPPacket, (int channel, unsigned char payloadType,
   1020                                      bool markerBit, const char* payloadData,
   1021                                      unsigned short payloadSize));
   1022   WEBRTC_STUB(GetLastRemoteTimeStamp, (int channel,
   1023                                        uint32_t* lastRemoteTimeStamp));
   1024   WEBRTC_FUNC(SetVideoEngineBWETarget, (int channel,
   1025                                         webrtc::ViENetwork* vie_network,
   1026                                         int video_channel)) {
   1027     WEBRTC_CHECK_CHANNEL(channel);
   1028     channels_[channel]->vie_network = vie_network;
   1029     channels_[channel]->video_channel = video_channel;
   1030     if (vie_network) {
   1031       // The interface is released here to avoid leaks. A test should not
   1032       // attempt to call functions on the interface stored in the channel.
   1033       vie_network->Release();
   1034     }
   1035     return 0;
   1036   }
   1037 
   1038   // webrtc::VoEVideoSync
   1039   WEBRTC_STUB(GetPlayoutBufferSize, (int& bufferMs));
   1040   WEBRTC_STUB(GetPlayoutTimestamp, (int channel, unsigned int& timestamp));
   1041   WEBRTC_STUB(GetRtpRtcp, (int, webrtc::RtpRtcp**, webrtc::RtpReceiver**));
   1042   WEBRTC_STUB(SetInitTimestamp, (int channel, unsigned int timestamp));
   1043   WEBRTC_STUB(SetInitSequenceNumber, (int channel, short sequenceNumber));
   1044   WEBRTC_STUB(SetMinimumPlayoutDelay, (int channel, int delayMs));
   1045   WEBRTC_STUB(SetInitialPlayoutDelay, (int channel, int delay_ms));
   1046   WEBRTC_STUB(GetDelayEstimate, (int channel, int* jitter_buffer_delay_ms,
   1047                                  int* playout_buffer_delay_ms));
   1048   WEBRTC_STUB_CONST(GetLeastRequiredDelayMs, (int channel));
   1049 
   1050   // webrtc::VoEVolumeControl
   1051   WEBRTC_STUB(SetSpeakerVolume, (unsigned int));
   1052   WEBRTC_STUB(GetSpeakerVolume, (unsigned int&));
   1053   WEBRTC_STUB(SetSystemOutputMute, (bool));
   1054   WEBRTC_STUB(GetSystemOutputMute, (bool&));
   1055   WEBRTC_STUB(SetMicVolume, (unsigned int));
   1056   WEBRTC_STUB(GetMicVolume, (unsigned int&));
   1057   WEBRTC_STUB(SetInputMute, (int, bool));
   1058   WEBRTC_STUB(GetInputMute, (int, bool&));
   1059   WEBRTC_STUB(SetSystemInputMute, (bool));
   1060   WEBRTC_STUB(GetSystemInputMute, (bool&));
   1061   WEBRTC_STUB(GetSpeechInputLevel, (unsigned int&));
   1062   WEBRTC_STUB(GetSpeechOutputLevel, (int, unsigned int&));
   1063   WEBRTC_STUB(GetSpeechInputLevelFullRange, (unsigned int&));
   1064   WEBRTC_STUB(GetSpeechOutputLevelFullRange, (int, unsigned int&));
   1065   WEBRTC_FUNC(SetChannelOutputVolumeScaling, (int channel, float scale)) {
   1066     WEBRTC_CHECK_CHANNEL(channel);
   1067     channels_[channel]->volume_scale= scale;
   1068     return 0;
   1069   }
   1070   WEBRTC_FUNC(GetChannelOutputVolumeScaling, (int channel, float& scale)) {
   1071     WEBRTC_CHECK_CHANNEL(channel);
   1072     scale = channels_[channel]->volume_scale;
   1073     return 0;
   1074   }
   1075   WEBRTC_FUNC(SetOutputVolumePan, (int channel, float left, float right)) {
   1076     WEBRTC_CHECK_CHANNEL(channel);
   1077     channels_[channel]->volume_pan_left = left;
   1078     channels_[channel]->volume_pan_right = right;
   1079     return 0;
   1080   }
   1081   WEBRTC_FUNC(GetOutputVolumePan, (int channel, float& left, float& right)) {
   1082     WEBRTC_CHECK_CHANNEL(channel);
   1083     left = channels_[channel]->volume_pan_left;
   1084     right = channels_[channel]->volume_pan_right;
   1085     return 0;
   1086   }
   1087 
   1088   // webrtc::VoEAudioProcessing
   1089   WEBRTC_FUNC(SetNsStatus, (bool enable, webrtc::NsModes mode)) {
   1090     ns_enabled_ = enable;
   1091     ns_mode_ = mode;
   1092     return 0;
   1093   }
   1094   WEBRTC_FUNC(GetNsStatus, (bool& enabled, webrtc::NsModes& mode)) {
   1095     enabled = ns_enabled_;
   1096     mode = ns_mode_;
   1097     return 0;
   1098   }
   1099 
   1100   WEBRTC_FUNC(SetAgcStatus, (bool enable, webrtc::AgcModes mode)) {
   1101     agc_enabled_ = enable;
   1102     agc_mode_ = mode;
   1103     return 0;
   1104   }
   1105   WEBRTC_FUNC(GetAgcStatus, (bool& enabled, webrtc::AgcModes& mode)) {
   1106     enabled = agc_enabled_;
   1107     mode = agc_mode_;
   1108     return 0;
   1109   }
   1110 
   1111   WEBRTC_FUNC(SetAgcConfig, (webrtc::AgcConfig config)) {
   1112     agc_config_ = config;
   1113     return 0;
   1114   }
   1115   WEBRTC_FUNC(GetAgcConfig, (webrtc::AgcConfig& config)) {
   1116     config = agc_config_;
   1117     return 0;
   1118   }
   1119   WEBRTC_FUNC(SetEcStatus, (bool enable, webrtc::EcModes mode)) {
   1120     ec_enabled_ = enable;
   1121     ec_mode_ = mode;
   1122     return 0;
   1123   }
   1124   WEBRTC_FUNC(GetEcStatus, (bool& enabled, webrtc::EcModes& mode)) {
   1125     enabled = ec_enabled_;
   1126     mode = ec_mode_;
   1127     return 0;
   1128   }
   1129   WEBRTC_STUB(EnableDriftCompensation, (bool enable))
   1130   WEBRTC_BOOL_STUB(DriftCompensationEnabled, ())
   1131   WEBRTC_VOID_STUB(SetDelayOffsetMs, (int offset))
   1132   WEBRTC_STUB(DelayOffsetMs, ());
   1133   WEBRTC_FUNC(SetAecmMode, (webrtc::AecmModes mode, bool enableCNG)) {
   1134     aecm_mode_ = mode;
   1135     cng_enabled_ = enableCNG;
   1136     return 0;
   1137   }
   1138   WEBRTC_FUNC(GetAecmMode, (webrtc::AecmModes& mode, bool& enabledCNG)) {
   1139     mode = aecm_mode_;
   1140     enabledCNG = cng_enabled_;
   1141     return 0;
   1142   }
   1143   WEBRTC_STUB(SetRxNsStatus, (int channel, bool enable, webrtc::NsModes mode));
   1144   WEBRTC_STUB(GetRxNsStatus, (int channel, bool& enabled,
   1145                               webrtc::NsModes& mode));
   1146   WEBRTC_FUNC(SetRxAgcStatus, (int channel, bool enable,
   1147                                webrtc::AgcModes mode)) {
   1148     channels_[channel]->rx_agc_enabled = enable;
   1149     channels_[channel]->rx_agc_mode = mode;
   1150     return 0;
   1151   }
   1152   WEBRTC_FUNC(GetRxAgcStatus, (int channel, bool& enabled,
   1153                                webrtc::AgcModes& mode)) {
   1154     enabled = channels_[channel]->rx_agc_enabled;
   1155     mode = channels_[channel]->rx_agc_mode;
   1156     return 0;
   1157   }
   1158 
   1159   WEBRTC_FUNC(SetRxAgcConfig, (int channel, webrtc::AgcConfig config)) {
   1160     channels_[channel]->rx_agc_config = config;
   1161     return 0;
   1162   }
   1163   WEBRTC_FUNC(GetRxAgcConfig, (int channel, webrtc::AgcConfig& config)) {
   1164     config = channels_[channel]->rx_agc_config;
   1165     return 0;
   1166   }
   1167 
   1168   WEBRTC_STUB(RegisterRxVadObserver, (int, webrtc::VoERxVadCallback&));
   1169   WEBRTC_STUB(DeRegisterRxVadObserver, (int channel));
   1170   WEBRTC_STUB(VoiceActivityIndicator, (int channel));
   1171   WEBRTC_FUNC(SetEcMetricsStatus, (bool enable)) {
   1172     ec_metrics_enabled_ = enable;
   1173     return 0;
   1174   }
   1175   WEBRTC_FUNC(GetEcMetricsStatus, (bool& enabled)) {
   1176     enabled = ec_metrics_enabled_;
   1177     return 0;
   1178   }
   1179   WEBRTC_STUB(GetEchoMetrics, (int& ERL, int& ERLE, int& RERL, int& A_NLP));
   1180   WEBRTC_STUB(GetEcDelayMetrics, (int& delay_median, int& delay_std));
   1181 
   1182   WEBRTC_STUB(StartDebugRecording, (const char* fileNameUTF8));
   1183   WEBRTC_STUB(StartDebugRecording, (FILE* handle));
   1184   WEBRTC_STUB(StopDebugRecording, ());
   1185 
   1186   WEBRTC_FUNC(SetTypingDetectionStatus, (bool enable)) {
   1187     typing_detection_enabled_ = enable;
   1188     return 0;
   1189   }
   1190   WEBRTC_FUNC(GetTypingDetectionStatus, (bool& enabled)) {
   1191     enabled = typing_detection_enabled_;
   1192     return 0;
   1193   }
   1194 
   1195   WEBRTC_STUB(TimeSinceLastTyping, (int& seconds));
   1196   WEBRTC_STUB(SetTypingDetectionParameters, (int timeWindow,
   1197                                              int costPerTyping,
   1198                                              int reportingThreshold,
   1199                                              int penaltyDecay,
   1200                                              int typeEventDelay));
   1201   int EnableHighPassFilter(bool enable) {
   1202     highpass_filter_enabled_ = enable;
   1203     return 0;
   1204   }
   1205   bool IsHighPassFilterEnabled() {
   1206     return highpass_filter_enabled_;
   1207   }
   1208   bool IsStereoChannelSwappingEnabled() {
   1209     return stereo_swapping_enabled_;
   1210   }
   1211   void EnableStereoChannelSwapping(bool enable) {
   1212     stereo_swapping_enabled_ = enable;
   1213   }
   1214   bool WasSendTelephoneEventCalled(int channel, int event_code, int length_ms) {
   1215     return (channels_[channel]->dtmf_info.dtmf_event_code == event_code &&
   1216             channels_[channel]->dtmf_info.dtmf_out_of_band == true &&
   1217             channels_[channel]->dtmf_info.dtmf_length_ms == length_ms);
   1218   }
   1219   bool WasPlayDtmfToneCalled(int event_code, int length_ms) {
   1220     return (dtmf_info_.dtmf_event_code == event_code &&
   1221             dtmf_info_.dtmf_length_ms == length_ms);
   1222   }
   1223   // webrtc::VoEExternalMedia
   1224   WEBRTC_FUNC(RegisterExternalMediaProcessing,
   1225               (int channel, webrtc::ProcessingTypes type,
   1226                webrtc::VoEMediaProcess& processObject)) {
   1227     WEBRTC_CHECK_CHANNEL(channel);
   1228     if (channels_[channel]->media_processor_registered) {
   1229       return -1;
   1230     }
   1231     channels_[channel]->media_processor_registered = true;
   1232     media_processor_ = &processObject;
   1233     return 0;
   1234   }
   1235   WEBRTC_FUNC(DeRegisterExternalMediaProcessing,
   1236               (int channel, webrtc::ProcessingTypes type)) {
   1237     WEBRTC_CHECK_CHANNEL(channel);
   1238     if (!channels_[channel]->media_processor_registered) {
   1239       return -1;
   1240     }
   1241     channels_[channel]->media_processor_registered = false;
   1242     media_processor_ = NULL;
   1243     return 0;
   1244   }
   1245   WEBRTC_STUB(SetExternalRecordingStatus, (bool enable));
   1246   WEBRTC_STUB(SetExternalPlayoutStatus, (bool enable));
   1247   WEBRTC_STUB(ExternalRecordingInsertData,
   1248               (const int16_t speechData10ms[], int lengthSamples,
   1249                int samplingFreqHz, int current_delay_ms));
   1250   WEBRTC_STUB(ExternalPlayoutGetData,
   1251               (int16_t speechData10ms[], int samplingFreqHz,
   1252                int current_delay_ms, int& lengthSamples));
   1253   WEBRTC_STUB(GetAudioFrame, (int channel, int desired_sample_rate_hz,
   1254                               webrtc::AudioFrame* frame));
   1255   WEBRTC_STUB(SetExternalMixing, (int channel, bool enable));
   1256 
   1257  private:
   1258   int GetNumDevices(int& num) {
   1259 #ifdef WIN32
   1260     num = 1;
   1261 #else
   1262     // On non-Windows platforms VE adds a special entry for the default device,
   1263     // so if there is one physical device then there are two entries in the
   1264     // list.
   1265     num = 2;
   1266 #endif
   1267     return 0;
   1268   }
   1269 
   1270   int GetDeviceName(int i, char* name, char* guid) {
   1271     const char *s;
   1272 #ifdef WIN32
   1273     if (0 == i) {
   1274       s = kFakeDeviceName;
   1275     } else {
   1276       return -1;
   1277     }
   1278 #else
   1279     // See comment above.
   1280     if (0 == i) {
   1281       s = kFakeDefaultDeviceName;
   1282     } else if (1 == i) {
   1283       s = kFakeDeviceName;
   1284     } else {
   1285       return -1;
   1286     }
   1287 #endif
   1288     strcpy(name, s);
   1289     guid[0] = '\0';
   1290     return 0;
   1291   }
   1292 
   1293   bool inited_;
   1294   int last_channel_;
   1295   std::map<int, Channel*> channels_;
   1296   bool fail_create_channel_;
   1297   const cricket::AudioCodec* const* codecs_;
   1298   int num_codecs_;
   1299   int num_set_send_codecs_;  // how many times we call SetSendCodec().
   1300   bool ec_enabled_;
   1301   bool ec_metrics_enabled_;
   1302   bool cng_enabled_;
   1303   bool ns_enabled_;
   1304   bool agc_enabled_;
   1305   bool highpass_filter_enabled_;
   1306   bool stereo_swapping_enabled_;
   1307   bool typing_detection_enabled_;
   1308   webrtc::EcModes ec_mode_;
   1309   webrtc::AecmModes aecm_mode_;
   1310   webrtc::NsModes ns_mode_;
   1311   webrtc::AgcModes agc_mode_;
   1312   webrtc::AgcConfig agc_config_;
   1313   webrtc::VoiceEngineObserver* observer_;
   1314   int playout_fail_channel_;
   1315   int send_fail_channel_;
   1316   bool fail_start_recording_microphone_;
   1317   bool recording_microphone_;
   1318   int recording_sample_rate_;
   1319   int playout_sample_rate_;
   1320   DtmfInfo dtmf_info_;
   1321   webrtc::VoEMediaProcess* media_processor_;
   1322 #ifdef USE_WEBRTC_DEV_BRANCH
   1323   FakeAudioProcessing audio_processing_;
   1324 #endif
   1325 };
   1326 
   1327 #undef WEBRTC_CHECK_HEADER_EXTENSION_ID
   1328 
   1329 }  // namespace cricket
   1330 
   1331 #endif  // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
   1332