/*
 * libjingle
 * Copyright 2004--2011, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef HAVE_WEBRTC_VOICE

#include "talk/session/phone/webrtcvoiceengine.h"

#include <algorithm>
#include <cstdio>
#include <string>
#include <vector>

#include "talk/base/base64.h"
#include "talk/base/byteorder.h"
#include "talk/base/common.h"
#include "talk/base/helpers.h"
#include "talk/base/logging.h"
#include "talk/base/stringencode.h"
#include "talk/base/stringutils.h"
#include "talk/session/phone/streamparams.h"
#include "talk/session/phone/voiceprocessor.h"
#include "talk/session/phone/webrtcvoe.h"

#ifdef WIN32
#include <objbase.h>  // NOLINT
#endif

namespace cricket {

// For Linux/Mac, using the default device is done by specifying index 0 for
// VoE 4.0 and not -1 (which was the case for VoE 3.5).
//
// On Windows Vista and newer, Microsoft introduced the concept of "Default
// Communications Device". This means that there are two types of default
// devices (old Wave Audio style default and Default Communications Device).
//
// On Windows systems which only support Wave Audio style default, uses either
// -1 or 0 to select the default device.
//
// On Windows systems which support both "Default Communication Device" and
// old Wave Audio style default, use -1 for Default Communications Device and
// -2 for Wave Audio style default, which is what we want to use for clips.
// It's not clear yet whether the -2 index is handled properly on other OSes.

#ifdef WIN32
static const int kDefaultAudioDeviceId = -1;
static const int kDefaultSoundclipDeviceId = -2;
#else
static const int kDefaultAudioDeviceId = 0;
#endif

// extension header for audio levels, as defined in
// http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
static const char kRtpAudioLevelHeaderExtension[] =
    "urn:ietf:params:rtp-hdrext:ssrc-audio-level";

static const char kIsacCodecName[] = "ISAC";
static const char kL16CodecName[] = "L16";

// Dumps an AudioCodec in RFC 2327-ish format.
static std::string ToString(const AudioCodec& codec) {
  std::stringstream ss;
  ss << codec.name << "/" << codec.clockrate << "/" << codec.channels
     << " (" << codec.id << ")";
  return ss.str();
}
static std::string ToString(const webrtc::CodecInst& codec) {
  std::stringstream ss;
  ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels
     << " (" << codec.pltype << ")";
  return ss.str();
}

static void LogMultiline(talk_base::LoggingSeverity sev, char* text) {
  const char* delim = "\r\n";
  for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) {
    LOG_V(sev) << tok;
  }
}

// WebRtcVoiceEngine
const WebRtcVoiceEngine::CodecPref WebRtcVoiceEngine::kCodecPrefs[] = {
  { "ISAC",   16000,  103 },
  { "ISAC",   32000,  104 },
  { "speex",  16000,  107 },
  { "G722",   16000,  9 },
  { "ILBC",   8000,   102 },
  { "speex",  8000,   108 },
  { "PCMU",   8000,   0 },
  { "PCMA",   8000,   8 },
  { "CN",     32000,  106 },
  { "CN",     16000,  105 },
  { "CN",     8000,   13 },
  { "red",    8000,   127 },
  { "telephone-event", 8000, 126 },
};

class WebRtcSoundclipMedia : public SoundclipMedia {
 public:
  explicit WebRtcSoundclipMedia(WebRtcVoiceEngine *engine)
      : engine_(engine), webrtc_channel_(-1) {
    engine_->RegisterSoundclip(this);
  }

  virtual ~WebRtcSoundclipMedia() {
    engine_->UnregisterSoundclip(this);
    if (webrtc_channel_ != -1) {
      // We shouldn't have to call Disable() here. DeleteChannel() should call
      // StopPlayout() while deleting the channel.  We should fix the bug
      // inside WebRTC and remove the Disable() call bellow.  This work is
      // tracked by bug http://b/issue?id=5382855.
      PlaySound(NULL, 0, 0);
      Disable();
      if (engine_->voe_sc()->base()->DeleteChannel(webrtc_channel_)
          == -1) {
        LOG_RTCERR1(DeleteChannel, webrtc_channel_);
      }
    }
  }

  bool Init() {
    webrtc_channel_ = engine_->voe_sc()->base()->CreateChannel();
    if (webrtc_channel_ == -1) {
      LOG_RTCERR0(CreateChannel);
      return false;
    }
    return true;
  }

  bool Enable() {
    if (engine_->voe_sc()->base()->StartPlayout(webrtc_channel_) == -1) {
      LOG_RTCERR1(StartPlayout, webrtc_channel_);
      return false;
    }
    return true;
  }

  bool Disable() {
    if (engine_->voe_sc()->base()->StopPlayout(webrtc_channel_) == -1) {
      LOG_RTCERR1(StopPlayout, webrtc_channel_);
      return false;
    }
    return true;
  }

  virtual bool PlaySound(const char *buf, int len, int flags) {
    // Must stop playing the current sound (if any), because we are about to
    // modify the stream.
    if (engine_->voe_sc()->file()->StopPlayingFileLocally(webrtc_channel_)
        == -1) {
      LOG_RTCERR1(StopPlayingFileLocally, webrtc_channel_);
      return false;
    }

    if (buf) {
      stream_.reset(new WebRtcSoundclipStream(buf, len));
      stream_->set_loop((flags & SF_LOOP) != 0);
      stream_->Rewind();

      // Play it.
      if (engine_->voe_sc()->file()->StartPlayingFileLocally(
          webrtc_channel_, stream_.get()) == -1) {
        LOG_RTCERR2(StartPlayingFileLocally, webrtc_channel_, stream_.get());
        LOG(LS_ERROR) << "Unable to start soundclip";
        return false;
      }
    } else {
      stream_.reset();
    }
    return true;
  }

  int GetLastEngineError() const { return engine_->voe_sc()->error(); }

 private:
  WebRtcVoiceEngine *engine_;
  int webrtc_channel_;
  talk_base::scoped_ptr<WebRtcSoundclipStream> stream_;
};

WebRtcVoiceEngine::WebRtcVoiceEngine()
    : voe_wrapper_(new VoEWrapper()),
      voe_wrapper_sc_(new VoEWrapper()),
      tracing_(new VoETraceWrapper()),
      adm_(NULL),
      adm_sc_(NULL),
      log_level_(kDefaultLogSeverity),
      is_dumping_aec_(false),
      desired_local_monitor_enable_(false) {
  Construct();
}

WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
                                     VoEWrapper* voe_wrapper_sc,
                                     VoETraceWrapper* tracing)
    : voe_wrapper_(voe_wrapper),
      voe_wrapper_sc_(voe_wrapper_sc),
      tracing_(tracing),
      adm_(NULL),
      adm_sc_(NULL),
      log_level_(kDefaultLogSeverity),
      is_dumping_aec_(false),
      desired_local_monitor_enable_(false) {
  Construct();
}

void WebRtcVoiceEngine::Construct() {
  initialized_ = false;
  LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
  ApplyLogging("");
  if (tracing_->SetTraceCallback(this) == -1) {
    LOG_RTCERR0(SetTraceCallback);
  }
  if (voe_wrapper_->base()->RegisterVoiceEngineObserver(*this) == -1) {
    LOG_RTCERR0(RegisterVoiceEngineObserver);
  }
  // Clear the default agc state.
  memset(&default_agc_config_, 0, sizeof(default_agc_config_));

  // Load our audio codec list.
  ConstructCodecs();
}

void WebRtcVoiceEngine::ConstructCodecs() {
  LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
  int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
  for (int i = 0; i < ncodecs; ++i) {
    webrtc::CodecInst voe_codec;
    if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) {
      // Skip uncompressed formats.
      if (_stricmp(voe_codec.plname, kL16CodecName) == 0) {
        continue;
      }

      const CodecPref* pref = NULL;
      for (size_t j = 0; j < ARRAY_SIZE(kCodecPrefs); ++j) {
        if (_stricmp(kCodecPrefs[j].name, voe_codec.plname) == 0 &&
            kCodecPrefs[j].clockrate == voe_codec.plfreq) {
          pref = &kCodecPrefs[j];
          break;
        }
      }

      if (pref) {
        // Use the payload type that we've configured in our pref table;
        // use the offset in our pref table to determine the sort order.
        AudioCodec codec(pref->payload_type, voe_codec.plname, voe_codec.plfreq,
                         voe_codec.rate, voe_codec.channels,
                         ARRAY_SIZE(kCodecPrefs) - (pref - kCodecPrefs));
        LOG(LS_INFO) << ToString(codec);
        // For ISAC, use 0 to indicate auto bandwidth in our signaling.
        if (_stricmp(codec.name.c_str(), kIsacCodecName) == 0) {
          codec.bitrate = 0;
        }
        codecs_.push_back(codec);
      } else {
        LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec);
      }
    }
  }
  // Make sure they are in local preference order.
  std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable);
}

WebRtcVoiceEngine::~WebRtcVoiceEngine() {
  LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine";
  if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) {
    LOG_RTCERR0(DeRegisterVoiceEngineObserver);
  }
  if (adm_) {
    voe_wrapper_.reset();
    adm_->Release();
    adm_ = NULL;
  }
  if (adm_sc_) {
    voe_wrapper_sc_.reset();
    adm_sc_->Release();
    adm_sc_ = NULL;
  }

  // Test to see if the media processor was deregistered properly
  ASSERT(SignalRxMediaFrame.is_empty());
  ASSERT(SignalTxMediaFrame.is_empty());

  tracing_->SetTraceCallback(NULL);
}

bool WebRtcVoiceEngine::Init() {
  LOG(LS_INFO) << "WebRtcVoiceEngine::Init";
  bool res = InitInternal();
  if (res) {
    LOG(LS_INFO) << "WebRtcVoiceEngine::Init Done!";
  } else {
    LOG(LS_ERROR) << "WebRtcVoiceEngine::Init failed";
    Terminate();
  }
  return res;
}

bool WebRtcVoiceEngine::InitInternal() {
  // Temporarily turn logging level up for the Init call
  int old_level = log_level_;
  log_level_ = talk_base::_min(log_level_,
                               static_cast<int>(talk_base::LS_INFO));
  ApplyLogging("");

  // Init WebRtc VoiceEngine, enabling AEC logging if specified in SetLogging.
  if (voe_wrapper_->base()->Init(adm_) == -1) {
    LOG_RTCERR0_EX(Init, voe_wrapper_->error());
    return false;
  }

  // Restore the previous log level and apply the log filter.
  log_level_ = old_level;
  ApplyLogging(log_filter_);

  // Log the VoiceEngine version info
  char buffer[1024] = "";
  voe_wrapper_->base()->GetVersion(buffer);
  LOG(LS_INFO) << "WebRtc VoiceEngine Version:";
  LogMultiline(talk_base::LS_INFO, buffer);

  // Turn on AEC and AGC by default.
  if (!SetOptions(
      MediaEngineInterface::ECHO_CANCELLATION |
      MediaEngineInterface::AUTO_GAIN_CONTROL)) {
    return false;
  }

  // Save the default AGC configuration settings.
  if (voe_wrapper_->processing()->SetAgcConfig(default_agc_config_) == -1) {
    LOG_RTCERR0(GetAGCConfig);
    return false;
  }

  // Print our codec list again for the call diagnostic log
  LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
  for (std::vector<AudioCodec>::const_iterator it = codecs_.begin();
      it != codecs_.end(); ++it) {
    LOG(LS_INFO) << ToString(*it);
  }

#if defined(LINUX) && !defined(HAVE_LIBPULSE)
  voe_wrapper_sc_->hw()->SetAudioDeviceLayer(webrtc::kAudioLinuxAlsa);
#endif

  // Initialize the VoiceEngine instance that we'll use to play out sound clips.
  if (voe_wrapper_sc_->base()->Init(adm_sc_) == -1) {
    LOG_RTCERR0_EX(Init, voe_wrapper_sc_->error());
    return false;
  }

  // On Windows, tell it to use the default sound (not communication) devices.
  // First check whether there is a valid sound device for playback.
  // TODO: Clean this up when we support setting the soundclip device.
#ifdef WIN32
  // The SetPlayoutDevice may not be implemented in the case of external ADM.
  // TODO: We should only check the adm_sc_ here, but current
  // PeerConnection interface never set the adm_sc_, so need to check both
  // in order to determine if the external adm is used.
  if (!adm_ && !adm_sc_) {
    int num_of_devices = 0;
    if (voe_wrapper_sc_->hw()->GetNumOfPlayoutDevices(num_of_devices) != -1 &&
        num_of_devices > 0) {
      if (voe_wrapper_sc_->hw()->SetPlayoutDevice(kDefaultSoundclipDeviceId)
          == -1) {
        LOG_RTCERR1_EX(SetPlayoutDevice, kDefaultSoundclipDeviceId,
                       voe_wrapper_sc_->error());
        return false;
      }
    } else {
      LOG(LS_WARNING) << "No valid sound playout device found.";
    }
  }
#endif

  initialized_ = true;
  return true;
}

void WebRtcVoiceEngine::Terminate() {
  LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate";
  initialized_ = false;

  if (is_dumping_aec_) {
    if (voe_wrapper_->processing()->StopDebugRecording() == -1) {
      LOG_RTCERR0(StopDebugRecording);
    }
    is_dumping_aec_ = false;
  }

  voe_wrapper_sc_->base()->Terminate();
  voe_wrapper_->base()->Terminate();
  desired_local_monitor_enable_ = false;
}

int WebRtcVoiceEngine::GetCapabilities() {
  return AUDIO_SEND | AUDIO_RECV;
}

VoiceMediaChannel *WebRtcVoiceEngine::CreateChannel() {
  WebRtcVoiceMediaChannel* ch = new WebRtcVoiceMediaChannel(this);
  if (!ch->valid()) {
    delete ch;
    ch = NULL;
  }
  return ch;
}

SoundclipMedia *WebRtcVoiceEngine::CreateSoundclip() {
  WebRtcSoundclipMedia *soundclip = new WebRtcSoundclipMedia(this);
  if (!soundclip->Init() || !soundclip->Enable()) {
    delete soundclip;
    return NULL;
  }
  return soundclip;
}

bool WebRtcVoiceEngine::SetOptions(int options) {
  // NS and typing detection are always on, if supported.
  bool aec = (options & MediaEngineInterface::ECHO_CANCELLATION) ? true : false;
  bool agc = (options & MediaEngineInterface::AUTO_GAIN_CONTROL) ? true : false;
#if !defined(IOS) && !defined(ANDROID)
  if (voe_wrapper_->processing()->SetEcStatus(aec) == -1) {
    LOG_RTCERR1(SetEcStatus, aec);
    return false;
  }
  if (aec) {
    if (voe_wrapper_->processing()->SetEcMetricsStatus(true) == -1) {
      LOG_RTCERR1(SetEcMetricsStatus, true);
      return false;
    }
  }

  if (voe_wrapper_->processing()->SetAgcStatus(agc) == -1) {
    LOG_RTCERR1(SetAgcStatus, agc);
    return false;
  }

  if (voe_wrapper_->processing()->SetNsStatus(true) == -1) {
    LOG_RTCERR1(SetNsStatus, true);
    return false;
  }

  if (voe_wrapper_->processing()->SetTypingDetectionStatus(true) == -1) {
    // In case of error, log the info and continue
    LOG_RTCERR1(SetTypingDetectionStatus, true);
  }
#else
  if (voe_wrapper_->processing()->SetEcStatus(aec, kEcAecm) == -1) {
    LOG_RTCERR2(SetEcStatus, aec, kEcAecm);
    return false;
  }

  if (aec) {
    // Use speakerphone mode with comfort noise generation for mobile.
    if (voe_wrapper_->processing()->SetAecmMode(kAecmSpeakerphone, true) != 0) {
      LOG_RTCERR2(SetAecmMode, kAecmSpeakerphone, true);
    }
  }

  // On mobile, GIPS recommends fixed AGC (not adaptive)
  if (voe_wrapper_->processing()->SetAgcStatus(agc, kAgcFixedDigital) == -1) {
    LOG_RTCERR2(SetAgcStatus, agc, kAgcFixedDigital);
    return false;
  }

  // On mobile, GIPS recommends moderate aggressiveness.
  if (voe_wrapper_->processing()->SetNsStatus(true,
      kNsModerateSuppression) == -1) {
    LOG_RTCERR2(SetNsStatus, ns, kNsModerateSuppression);
    return false;
  }

  // No typing detection support on iOS or Android.
#endif  // !IOS && !ANDROID

  return true;
}

struct ResumeEntry {
  ResumeEntry(WebRtcVoiceMediaChannel *c, bool p, SendFlags s)
      : channel(c),
        playout(p),
        send(s) {
  }

  WebRtcVoiceMediaChannel *channel;
  bool playout;
  SendFlags send;
};

// TODO: Refactor this so that the core logic can be used to set the
// soundclip device. At that time, reinstate the soundclip pause/resume code.
bool WebRtcVoiceEngine::SetDevices(const Device* in_device,
                                   const Device* out_device) {
#if !defined(IOS) && !defined(ANDROID)
  int in_id = in_device ? talk_base::FromString<int>(in_device->id) :
      kDefaultAudioDeviceId;
  int out_id = out_device ? talk_base::FromString<int>(out_device->id) :
      kDefaultAudioDeviceId;
  // The device manager uses -1 as the default device, which was the case for
  // VoE 3.5. VoE 4.0, however, uses 0 as the default in Linux and Mac.
#ifndef WIN32
  if (-1 == in_id) {
    in_id = kDefaultAudioDeviceId;
  }
  if (-1 == out_id) {
    out_id = kDefaultAudioDeviceId;
  }
#endif

  std::string in_name = (in_id != kDefaultAudioDeviceId) ?
      in_device->name : "Default device";
  std::string out_name = (out_id != kDefaultAudioDeviceId) ?
      out_device->name : "Default device";
  LOG(LS_INFO) << "Setting microphone to (id=" << in_id << ", name=" << in_name
            << ") and speaker to (id=" << out_id << ", name=" << out_name
            << ")";

  // If we're running the local monitor, we need to stop it first.
  bool ret = true;
  if (!PauseLocalMonitor()) {
    LOG(LS_WARNING) << "Failed to pause local monitor";
    ret = false;
  }

  // Must also pause all audio playback and capture.
  for (ChannelList::const_iterator i = channels_.begin();
       i != channels_.end(); ++i) {
    WebRtcVoiceMediaChannel *channel = *i;
    if (!channel->PausePlayout()) {
      LOG(LS_WARNING) << "Failed to pause playout";
      ret = false;
    }
    if (!channel->PauseSend()) {
      LOG(LS_WARNING) << "Failed to pause send";
      ret = false;
    }
  }

  // Find the recording device id in VoiceEngine and set recording device.
  if (!FindWebRtcAudioDeviceId(true, in_name, in_id, &in_id)) {
    ret = false;
  }
  if (ret) {
    if (voe_wrapper_->hw()->SetRecordingDevice(in_id) == -1) {
      LOG_RTCERR2(SetRecordingDevice, in_device->name, in_id);
      ret = false;
    }
  }

  // Find the playout device id in VoiceEngine and set playout device.
  if (!FindWebRtcAudioDeviceId(false, out_name, out_id, &out_id)) {
    LOG(LS_WARNING) << "Failed to find VoiceEngine device id for " << out_name;
    ret = false;
  }
  if (ret) {
    if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) {
      LOG_RTCERR2(SetPlayoutDevice, out_device->name, out_id);
      ret = false;
    }
  }

  // Resume all audio playback and capture.
  for (ChannelList::const_iterator i = channels_.begin();
       i != channels_.end(); ++i) {
    WebRtcVoiceMediaChannel *channel = *i;
    if (!channel->ResumePlayout()) {
      LOG(LS_WARNING) << "Failed to resume playout";
      ret = false;
    }
    if (!channel->ResumeSend()) {
      LOG(LS_WARNING) << "Failed to resume send";
      ret = false;
    }
  }

  // Resume local monitor.
  if (!ResumeLocalMonitor()) {
    LOG(LS_WARNING) << "Failed to resume local monitor";
    ret = false;
  }

  if (ret) {
    LOG(LS_INFO) << "Set microphone to (id=" << in_id <<" name=" << in_name
                 << ") and speaker to (id="<< out_id << " name=" << out_name
                 << ")";
  }

  return ret;
#else
  return true;
#endif  // !IOS && !ANDROID
}

bool WebRtcVoiceEngine::FindWebRtcAudioDeviceId(
  bool is_input, const std::string& dev_name, int dev_id, int* rtc_id) {
  // In Linux, VoiceEngine uses the same device dev_id as the device manager.
#ifdef LINUX
  *rtc_id = dev_id;
  return true;
#else
  // In Windows and Mac, we need to find the VoiceEngine device id by name
  // unless the input dev_id is the default device id.
  if (kDefaultAudioDeviceId == dev_id) {
    *rtc_id = dev_id;
    return true;
  }

  // Get the number of VoiceEngine audio devices.
  int count = 0;
  if (is_input) {
    if (-1 == voe_wrapper_->hw()->GetNumOfRecordingDevices(count)) {
      LOG_RTCERR0(GetNumOfRecordingDevices);
      return false;
    }
  } else {
    if (-1 == voe_wrapper_->hw()->GetNumOfPlayoutDevices(count)) {
      LOG_RTCERR0(GetNumOfPlayoutDevices);
      return false;
    }
  }

  for (int i = 0; i < count; ++i) {
    char name[128];
    char guid[128];
    if (is_input) {
      voe_wrapper_->hw()->GetRecordingDeviceName(i, name, guid);
      LOG(LS_VERBOSE) << "VoiceEngine microphone " << i << ": " << name;
    } else {
      voe_wrapper_->hw()->GetPlayoutDeviceName(i, name, guid);
      LOG(LS_VERBOSE) << "VoiceEngine speaker " << i << ": " << name;
    }

    std::string webrtc_name(name);
    if (dev_name.compare(0, webrtc_name.size(), webrtc_name) == 0) {
      *rtc_id = i;
      return true;
    }
  }
  LOG(LS_WARNING) << "VoiceEngine cannot find device: " << dev_name;
  return false;
#endif
}

bool WebRtcVoiceEngine::GetOutputVolume(int* level) {
  unsigned int ulevel;
  if (voe_wrapper_->volume()->GetSpeakerVolume(ulevel) == -1) {
    LOG_RTCERR1(GetSpeakerVolume, level);
    return false;
  }
  *level = ulevel;
  return true;
}

bool WebRtcVoiceEngine::SetOutputVolume(int level) {
  ASSERT(level >= 0 && level <= 255);
  if (voe_wrapper_->volume()->SetSpeakerVolume(level) == -1) {
    LOG_RTCERR1(SetSpeakerVolume, level);
    return false;
  }
  return true;
}

int WebRtcVoiceEngine::GetInputLevel() {
  unsigned int ulevel;
  return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ?
      static_cast<int>(ulevel) : -1;
}

bool WebRtcVoiceEngine::SetLocalMonitor(bool enable) {
  desired_local_monitor_enable_ = enable;
  return ChangeLocalMonitor(desired_local_monitor_enable_);
}

bool WebRtcVoiceEngine::ChangeLocalMonitor(bool enable) {
  if (enable && !monitor_.get()) {
    monitor_.reset(new WebRtcMonitorStream);
    if (voe_wrapper_->file()->StartRecordingMicrophone(monitor_.get()) == -1) {
      LOG_RTCERR1(StartRecordingMicrophone, monitor_.get());
      // Must call Stop() because there are some cases where Start will report
      // failure but still change the state, and if we leave VE in the on state
      // then it could crash later when trying to invoke methods on our monitor.
      voe_wrapper_->file()->StopRecordingMicrophone();
      monitor_.reset();
      return false;
    }
  } else if (!enable && monitor_.get()) {
    voe_wrapper_->file()->StopRecordingMicrophone();
    monitor_.reset();
  }
  return true;
}

bool WebRtcVoiceEngine::PauseLocalMonitor() {
  return ChangeLocalMonitor(false);
}

bool WebRtcVoiceEngine::ResumeLocalMonitor() {
  return ChangeLocalMonitor(desired_local_monitor_enable_);
}

const std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() {
  return codecs_;
}

bool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) {
  return FindWebRtcCodec(in, NULL);
}

// Get the VoiceEngine codec that matches |in|, with the supplied settings.
bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in,
                                        webrtc::CodecInst* out) {
  int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
  for (int i = 0; i < ncodecs; ++i) {
    webrtc::CodecInst voe_codec;
    if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) {
      AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
                       voe_codec.rate, voe_codec.channels, 0);
      // Allow arbitrary rates for ISAC to be specified.
      if (_stricmp(codec.name.c_str(), kIsacCodecName) == 0) {
        codec.bitrate = 0;
      }
      if (codec.Matches(in)) {
        if (out) {
          // Fixup the payload type.
          voe_codec.pltype = in.id;
          // If ISAC is being used, and an explicit bitrate is not specified,
          // enable auto bandwidth adjustment.
          if (_stricmp(codec.name.c_str(), kIsacCodecName) == 0) {
            voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1;
          }
          *out = voe_codec;
        }
        return true;
      }
    }
  }
  return false;
}

void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) {
  // if min_sev == -1, we keep the current log level.
  if (min_sev >= 0) {
    log_level_ = min_sev;
  }
  log_filter_ = filter;
  ApplyLogging(initialized_ ? log_filter_ : "");
}

int WebRtcVoiceEngine::GetLastEngineError() {
  return voe_wrapper_->error();
}

// We suppport three different logging settings for VoiceEngine:
// 1. Observer callback that goes into talk diagnostic logfile.
//    Use --logfile and --loglevel
//
// 2. Encrypted VoiceEngine log for debugging VoiceEngine.
//    Use --voice_loglevel --voice_logfilter "tracefile file_name"
//
// 3. EC log and dump for debugging QualityEngine.
//    Use --voice_loglevel --voice_logfilter "recordEC file_name"
//
// For more details see: "https://sites.google.com/a/google.com/wavelet/Home/
//    Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters"
void WebRtcVoiceEngine::ApplyLogging(const std::string& log_filter) {
  // Set log level.
  int filter = 0;
  switch (log_level_) {
    case talk_base::LS_VERBOSE:
      filter |= webrtc::kTraceAll;      // fall through
    case talk_base::LS_INFO:
      filter |= webrtc::kTraceStateInfo;  // fall through
    case talk_base::LS_WARNING:
      filter |= (webrtc::kTraceInfo | webrtc::kTraceWarning);  // fall through
    case talk_base::LS_ERROR:
      filter |= (webrtc::kTraceError | webrtc::kTraceCritical);
  }
  tracing_->SetTraceFilter(filter);

  // Set encrypted trace file.
  std::vector<std::string> opts;
  talk_base::tokenize(log_filter, ' ', '"', '"', &opts);
  std::vector<std::string>::iterator tracefile =
      std::find(opts.begin(), opts.end(), "tracefile");
  if (tracefile != opts.end() && ++tracefile != opts.end()) {
    // Write encrypted debug output (at same loglevel) to file
    // EncryptedTraceFile no longer supported.
    if (tracing_->SetTraceFile(tracefile->c_str()) == -1) {
      LOG_RTCERR1(SetTraceFile, *tracefile);
    }
  }

  // Set AEC dump file
  std::vector<std::string>::iterator recordEC =
      std::find(opts.begin(), opts.end(), "recordEC");
  if (recordEC != opts.end()) {
    ++recordEC;
    if (recordEC != opts.end() && !is_dumping_aec_) {
      // Start dumping AEC when we are not dumping and recordEC has a filename.
      if (voe_wrapper_->processing()->StartDebugRecording(
          recordEC->c_str()) == -1) {
        LOG_RTCERR0(StartDebugRecording);
      } else {
        is_dumping_aec_ = true;
      }
    } else if (recordEC == opts.end() && is_dumping_aec_) {
      // Stop dumping EC when we are dumping and recordEC has no filename.
      if (voe_wrapper_->processing()->StopDebugRecording() == -1) {
        LOG_RTCERR0(StopDebugRecording);
      }
      is_dumping_aec_ = false;
    }
  }
}

// Ignore spammy trace messages, mostly from the stats API when we haven't
// gotten RTCP info yet from the remote side.
bool WebRtcVoiceEngine::ShouldIgnoreTrace(const std::string& trace) {
  static const char* kTracesToIgnore[] = {
    "\tfailed to GetReportBlockInformation",
    "GetRecCodec() failed to get received codec",
    "GetReceivedRtcpStatistics: Could not get received RTP statistics",
    "GetRemoteRTCPData() failed to measure statistics due to lack of received RTP and/or RTCP packets",  // NOLINT
    "GetRemoteRTCPData() failed to retrieve sender info for remote side",
    "GetRTPStatistics() failed to measure RTT since no RTP packets have been received yet",  // NOLINT
    "GetRTPStatistics() failed to read RTP statistics from the RTP/RTCP module",
    "GetRTPStatistics() failed to retrieve RTT from the RTP/RTCP module",
    "SenderInfoReceived No received SR",
    "StatisticsRTP() no statisitics availble",
    NULL
  };
  for (const char* const* p = kTracesToIgnore; *p; ++p) {
    if (trace.find(*p) == 0) {
      return true;
    }
  }
  return false;
}

void WebRtcVoiceEngine::Print(const webrtc::TraceLevel level,
                              const char* trace, const int length) {
  talk_base::LoggingSeverity sev = talk_base::LS_VERBOSE;
  if (level == webrtc::kTraceError || level == webrtc::kTraceCritical)
    sev = talk_base::LS_ERROR;
  else if (level == webrtc::kTraceWarning)
    sev = talk_base::LS_WARNING;
  else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo)
    sev = talk_base::LS_INFO;

  if (sev >= log_level_) {
    // Skip past boilerplate prefix text
    if (length < 72) {
      std::string msg(trace, length);
      LOG(LS_ERROR) << "Malformed webrtc log message: ";
      LOG_V(sev) << msg;
    } else {
      std::string msg(trace + 71, length - 72);
      if (!ShouldIgnoreTrace(msg)) {
        LOG_V(sev) << "WebRtc:" << msg;
      }
    }
  }
}

void WebRtcVoiceEngine::CallbackOnError(const int channel_num,
                                        const int err_code) {
  talk_base::CritScope lock(&channels_cs_);
  WebRtcVoiceMediaChannel* channel = NULL;
  uint32 ssrc = 0;
  LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel "
                  << channel_num << ".";
  if (FindChannelAndSsrc(channel_num, &channel, &ssrc)) {
    ASSERT(channel != NULL);
    channel->OnError(ssrc, err_code);
  } else {
    LOG(LS_ERROR) << "VoiceEngine channel " << channel_num
                  << " could not be found in channel list when error reported.";
  }
}

bool WebRtcVoiceEngine::FindChannelAndSsrc(
    int channel_num, WebRtcVoiceMediaChannel** channel, uint32* ssrc) const {
  ASSERT(channel != NULL && ssrc != NULL);

  *channel = NULL;
  *ssrc = 0;
  // Find corresponding channel and ssrc
  for (ChannelList::const_iterator it = channels_.begin();
      it != channels_.end(); ++it) {
    ASSERT(*it != NULL);
    if ((*it)->FindSsrc(channel_num, ssrc)) {
      *channel = *it;
      return true;
    }
  }

  return false;
}

// This method will search through the WebRtcVoiceMediaChannels and
// obtain the voice engine's channel number.
bool WebRtcVoiceEngine::FindChannelNumFromSsrc(
    uint32 ssrc, MediaProcessorDirection direction, int* channel_num) {
  ASSERT(channel_num != NULL);

  *channel_num = -1;
  // Find corresponding channel for ssrc.
  for (ChannelList::const_iterator it = channels_.begin();
      it != channels_.end(); ++it) {
    ASSERT(*it != NULL);
    uint32 local_ssrc;
    if ((direction & MPD_RX) != 0) {
      *channel_num = (*it)->GetChannelNum(ssrc);
    } else {
      if (voe()->rtp()->GetLocalSSRC((*it)->voe_channel(), local_ssrc) != -1) {
        if (ssrc == local_ssrc) {
          *channel_num = (*it)->voe_channel();
        }
      }
    }
    if (*channel_num != -1) {
      return true;
    }
  }
  LOG(LS_WARNING) << "FindChannelFromSsrc. No Channel Found for Ssrc: " << ssrc;
  return false;
}

void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel *channel) {
  talk_base::CritScope lock(&channels_cs_);
  channels_.push_back(channel);
}

void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel *channel) {
  talk_base::CritScope lock(&channels_cs_);
  ChannelList::iterator i = std::find(channels_.begin(),
                                      channels_.end(),
                                      channel);
  if (i != channels_.end()) {
    channels_.erase(i);
  }
}

void WebRtcVoiceEngine::RegisterSoundclip(WebRtcSoundclipMedia *soundclip) {
  soundclips_.push_back(soundclip);
}

void WebRtcVoiceEngine::UnregisterSoundclip(WebRtcSoundclipMedia *soundclip) {
  SoundclipList::iterator i = std::find(soundclips_.begin(),
                                        soundclips_.end(),
                                        soundclip);
  if (i != soundclips_.end()) {
    soundclips_.erase(i);
  }
}

// Adjusts the default AGC target level by the specified delta.
// NB: If we start messing with other config fields, we'll want
// to save the current webrtc::AgcConfig as well.
bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) {
  webrtc::AgcConfig config = default_agc_config_;
  config.targetLeveldBOv += delta;

  LOG(LS_INFO) << "Adjusting AGC level from default -"
               << default_agc_config_.targetLeveldBOv << "dB to -"
               << config.targetLeveldBOv << "dB";

  if (voe_wrapper_->processing()->SetAgcConfig(config) == -1) {
    LOG_RTCERR1(SetAgcConfig, config.targetLeveldBOv);
    return false;
  }
  return true;
}

// Configures echo cancellation and noise suppression modes according to
// whether or not we are in a multi-point conference.
bool WebRtcVoiceEngine::SetConferenceMode(bool enable) {
// Only use EC_AECM for mobile.
#if defined(IOS) || defined(ANDROID)
  return true;
#endif

  LOG(LS_INFO) << (enable ? "Enabling" : "Disabling")
               << " Conference Mode noise reduction";

  // We always configure noise suppression on, so just toggle the mode.
  const webrtc::NsModes ns_mode = enable ? webrtc::kNsConference
                                         : webrtc::kNsDefault;
  if (voe_wrapper_->processing()->SetNsStatus(true, ns_mode) == -1) {
    LOG_RTCERR2(SetNsStatus, true, ns_mode);
    return false;
  }

  // Echo-cancellation is a user-option, so preserve the enable state and
  // just toggle the mode.
  bool aec;
  webrtc::EcModes ec_mode;
  if (voe_wrapper_->processing()->GetEcStatus(aec, ec_mode) == -1) {
    LOG_RTCERR0(GetEcStatus);
    return false;
  }
  ec_mode = enable ? webrtc::kEcConference : webrtc::kEcDefault;
  if (voe_wrapper_->processing()->SetEcStatus(aec, ec_mode) == -1) {
    LOG_RTCERR2(SetEcStatus, aec, ec_mode);
    return false;
  }
  return true;
}

bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
    webrtc::AudioDeviceModule* adm_sc) {
  if (initialized_) {
    LOG(LS_WARNING) << "SetAudioDeviceModule can not be called after Init.";
    return false;
  }
  if (adm_) {
    adm_->Release();
    adm_ = NULL;
  }
  if (adm) {
    adm_ = adm;
    adm_->AddRef();
  }

  if (adm_sc_) {
    adm_sc_->Release();
    adm_sc_ = NULL;
  }
  if (adm_sc) {
    adm_sc_ = adm_sc;
    adm_sc_->AddRef();
  }
  return true;
}

bool WebRtcVoiceEngine::RegisterProcessor(
    uint32 ssrc,
    VoiceProcessor* voice_processor,
    MediaProcessorDirection direction) {
  bool register_with_webrtc = false;
  int channel_id = -1;
  bool success = false;
  bool found_channel = FindChannelNumFromSsrc(ssrc, direction, &channel_id);
  if (voice_processor == NULL || !found_channel) {
    LOG(LS_WARNING) << "Media Processing Registration Failed. ssrc: " << ssrc
        << " foundChannel: " << found_channel;
    return false;
  }
  talk_base::CritScope cs(&signal_media_critical_);
  webrtc::ProcessingTypes processing_type;
  if (direction == MPD_RX) {
    processing_type = webrtc::kPlaybackPerChannel;
    if (SignalRxMediaFrame.is_empty()) {
      register_with_webrtc = true;
    }
    SignalRxMediaFrame.connect(voice_processor,
                               &VoiceProcessor::OnFrame);
  } else {
    processing_type = webrtc::kRecordingPerChannel;
    if (SignalTxMediaFrame.is_empty()) {
      register_with_webrtc = true;
    }
    SignalTxMediaFrame.connect(voice_processor,
                               &VoiceProcessor::OnFrame);
  }
  if (register_with_webrtc) {
    if (voe()->media()->
        RegisterExternalMediaProcessing(channel_id,
                                        processing_type,
                                        *this) == -1) {
      LOG_RTCERR2(RegisterExternalMediaProcessing,
                  channel_id,
                  processing_type);
      success = false;
    } else {
      LOG(LS_INFO) << "Media Processing Registration Succeeded. channel:"
                   << channel_id;
      success = true;
    }
  } else {
    // If we don't have to register with the engine, we just needed to
    // connect a new processor, set success to true;
    success = true;
  }
  return success;
}

bool WebRtcVoiceEngine::UnregisterProcessor(
    uint32 ssrc,
    VoiceProcessor* voice_processor,
    MediaProcessorDirection direction) {
  int channel_id = -1;
  bool found_channel = FindChannelNumFromSsrc(ssrc, direction, &channel_id);
  bool success = true;
  if (voice_processor == NULL || !found_channel) {
    LOG(LS_WARNING) << "Media Processing Deregistration Failed. ssrc: "
                    << ssrc
                    << " foundChannel: "
                    << found_channel;
    return false;
  }
  talk_base::CritScope cs(&signal_media_critical_);
  if ((direction & MPD_RX) != 0) {
    SignalRxMediaFrame.disconnect(voice_processor);
    if (SignalRxMediaFrame.is_empty()) {
      if (voe()->media()->DeRegisterExternalMediaProcessing(channel_id,
          webrtc::kPlaybackPerChannel) != -1) {
        LOG(LS_INFO) << "Media Processing DeRegistration Succeeded. channel:"
                     << channel_id;
      } else {
        LOG_RTCERR2(DeRegisterExternalMediaProcessing,
                    channel_id,
                    webrtc::kPlaybackPerChannel);
        success = false;
      }
    }
  }
  if ((direction & MPD_TX) != 0) {
    SignalTxMediaFrame.disconnect(voice_processor);
    if (SignalTxMediaFrame.is_empty()) {
      if (voe()->media()->DeRegisterExternalMediaProcessing(channel_id,
          webrtc::kRecordingPerChannel) != -1) {
        LOG(LS_INFO) << "Media Processing DeRegistration Succeeded. channel:"
                     << channel_id;
      } else {
        LOG_RTCERR2(DeRegisterExternalMediaProcessing,
                    channel_id,
                    webrtc::kRecordingPerChannel);
        success = false;
      }
    }
  }
  return success;
}

// Implementing method from WebRtc VoEMediaProcess interface
void WebRtcVoiceEngine::Process(const int channel,
                                const webrtc::ProcessingTypes type,
                                WebRtc_Word16 audio10ms[],
                                const int length,
                                const int sampling_freq,
                                const bool is_stereo) {
  uint32 ssrc;
  WebRtcVoiceMediaChannel* media_channel;

  if (FindChannelAndSsrc(channel, &media_channel, &ssrc)) {
    talk_base::CritScope cs(&signal_media_critical_);
    AudioFrame frame(audio10ms, length, sampling_freq, is_stereo);
    if (type == webrtc::kPlaybackPerChannel) {
      SignalRxMediaFrame(ssrc, &frame);
    } else if (type == webrtc::kRecordingPerChannel) {
      SignalTxMediaFrame(ssrc, &frame);
    }
  } else {
    LOG(LS_WARNING) << "MediaProcess Callback invoked with unexpected channel: "
                    << channel;
  }
}

// WebRtcVoiceMediaChannel
WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine *engine)
    : WebRtcMediaChannel<VoiceMediaChannel, WebRtcVoiceEngine>(
          engine,
          engine->voe()->base()->CreateChannel()),
      recv_codecs_set_(false),
      channel_options_(0),
      agc_adjusted_(false),
      dtmf_allowed_(false),
      desired_playout_(false),
      playout_(false),
      desired_send_(SEND_NOTHING),
      send_(SEND_NOTHING),
      local_ssrc_(0) {
  engine->RegisterChannel(this);
  LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel "
                  << voe_channel();

  // Register external transport
  if (engine->voe()->network()->RegisterExternalTransport(
      voe_channel(), *static_cast<Transport*>(this)) == -1) {
    LOG_RTCERR2(RegisterExternalTransport, voe_channel(), this);
  }

  // Enable RTCP (for quality stats and feedback messages)
  EnableRtcp(voe_channel());

  // Reset all recv codecs; they will be enabled via SetRecvCodecs.
  ResetRecvCodecs(voe_channel());
}

WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() {
  LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel "
                  << voe_channel();

  // DeRegister external transport
  if (engine()->voe()->network()->DeRegisterExternalTransport(
      voe_channel()) == -1) {
    LOG_RTCERR1(DeRegisterExternalTransport, voe_channel());
  }

  // Unregister ourselves from the engine.
  engine()->UnregisterChannel(this);
  // Remove any remaining streams.
  while (!mux_channels_.empty()) {
    RemoveRecvStream(mux_channels_.begin()->first);
  }

  // Delete the primary channel.
  if (engine()->voe()->base()->DeleteChannel(voe_channel()) == -1) {
    LOG_RTCERR1(DeleteChannel, voe_channel());
  }
}

bool WebRtcVoiceMediaChannel::SetOptions(int flags) {
  // Always accept flags that are unchanged.
  if (channel_options_ == flags) {
    return true;
  }

  // Reject new options if we're already sending.
  if (send_ != SEND_NOTHING) {
    return false;
  }

  // Save the options, to be interpreted where appropriate.
  channel_options_ = flags;
  return true;
}

bool WebRtcVoiceMediaChannel::SetRecvCodecs(
    const std::vector<AudioCodec>& codecs) {
  // Set the payload types to be used for incoming media.
  bool ret = true;
  LOG(LS_INFO) << "Setting receive voice codecs:";
  for (std::vector<AudioCodec>::const_iterator it = codecs.begin();
       it != codecs.end() && ret; ++it) {
    webrtc::CodecInst voe_codec;
    if (engine()->FindWebRtcCodec(*it, &voe_codec)) {
      LOG(LS_INFO) << ToString(*it);
      voe_codec.pltype = it->id;
      if (engine()->voe()->codec()->SetRecPayloadType(
          voe_channel(), voe_codec) == -1) {
        LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec));
        ret = false;
      }
      // Set the receive codecs on all receiving channels.
      for (ChannelMap::iterator it = mux_channels_.begin();
           it != mux_channels_.end() && ret; ++it) {
        if (engine()->voe()->codec()->SetRecPayloadType(
            it->second, voe_codec) == -1) {
          LOG_RTCERR2(SetRecPayloadType, it->second, ToString(voe_codec));
          ret = false;
        }
      }
    } else {
      LOG(LS_WARNING) << "Unknown codec " << ToString(*it);
      ret = false;
    }
  }
  recv_codecs_set_ = ret;
  return ret;
}

bool WebRtcVoiceMediaChannel::SetSendCodecs(
    const std::vector<AudioCodec>& codecs) {
  // Disable DTMF, VAD, and FEC unless we know the other side wants them.
  dtmf_allowed_ = false;
  engine()->voe()->codec()->SetVADStatus(voe_channel(), false);
  engine()->voe()->rtp()->SetFECStatus(voe_channel(), false);

  // Scan through the list to figure out the codec to use for sending, along
  // with the proper configuration for VAD and DTMF.
  bool first = true;
  webrtc::CodecInst send_codec;
  memset(&send_codec, 0, sizeof(send_codec));

  for (std::vector<AudioCodec>::const_iterator it = codecs.begin();
       it != codecs.end(); ++it) {
    // Ignore codecs we don't know about. The negotiation step should prevent
    // this, but double-check to be sure.
    webrtc::CodecInst voe_codec;
    if (!engine()->FindWebRtcCodec(*it, &voe_codec)) {
      LOG(LS_WARNING) << "Unknown codec " << ToString(voe_codec);
      continue;
    }

    // Find the DTMF telephone event "codec" and tell VoiceEngine about it.
    if (_stricmp(it->name.c_str(), "telephone-event") == 0 ||
        _stricmp(it->name.c_str(), "audio/telephone-event") == 0) {
      engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType(
          voe_channel(), it->id);
      dtmf_allowed_ = true;
    }

    // Turn voice activity detection/comfort noise on if supported.
    // Set the wideband CN payload type appropriately.
    // (narrowband always uses the static payload type 13).
    if (_stricmp(it->name.c_str(), "CN") == 0) {
      webrtc::PayloadFrequencies cn_freq;
      switch (it->clockrate) {
        case 8000:
          cn_freq = webrtc::kFreq8000Hz;
          break;
        case 16000:
          cn_freq = webrtc::kFreq16000Hz;
          break;
        case 32000:
          cn_freq = webrtc::kFreq32000Hz;
          break;
        default:
          LOG(LS_WARNING) << "CN frequency " << it->clockrate
                          << " not supported.";
          continue;
      }
      engine()->voe()->codec()->SetVADStatus(voe_channel(), true);
      if (cn_freq != webrtc::kFreq8000Hz) {
        engine()->voe()->codec()->SetSendCNPayloadType(voe_channel(),
                                                       it->id, cn_freq);
      }
    }

    // We'll use the first codec in the list to actually send audio data.
    // Be sure to use the payload type requested by the remote side.
    // "red", for FEC audio, is a special case where the actual codec to be
    // used is specified in params.
    if (first) {
      if (_stricmp(it->name.c_str(), "red") == 0) {
        // Parse out the RED parameters. If we fail, just ignore RED;
        // we don't support all possible params/usage scenarios.
        if (!GetRedSendCodec(*it, codecs, &send_codec)) {
          continue;
        }

        // Enable redundant encoding of the specified codec. Treat any
        // failure as a fatal internal error.
        LOG(LS_INFO) << "Enabling FEC";
        if (engine()->voe()->rtp()->SetFECStatus(voe_channel(),
                                                 true, it->id) == -1) {
          LOG_RTCERR3(SetFECStatus, voe_channel(), true, it->id);
          return false;
        }
      } else {
        send_codec = voe_codec;
      }
      first = false;
    }
  }

  // If we're being asked to set an empty list of codecs, due to a buggy client,
  // choose the most common format: PCMU
  if (first) {
    LOG(LS_WARNING) << "Received empty list of codecs; using PCMU/8000";
    AudioCodec codec(0, "PCMU", 8000, 0, 1, 0);
    engine()->FindWebRtcCodec(codec, &send_codec);
  }

  // Set the codec.
  LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec)
               << ", bitrate=" << send_codec.rate;
  if (engine()->voe()->codec()->SetSendCodec(voe_channel(),
                                             send_codec) == -1) {
    LOG_RTCERR2(SetSendCodec, voe_channel(), ToString(send_codec));
    return false;
  }

  send_codec_.reset(new webrtc::CodecInst(send_codec));
  return true;
}

bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions(
    const std::vector<RtpHeaderExtension>& extensions) {
  // We don't support any incoming extensions headers right now.
  return true;
}

bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions(
    const std::vector<RtpHeaderExtension>& extensions) {
  // Enable the audio level extension header if requested.
  std::vector<RtpHeaderExtension>::const_iterator it;
  for (it = extensions.begin(); it != extensions.end(); ++it) {
    if (it->uri == kRtpAudioLevelHeaderExtension) {
      break;
    }
  }

  bool enable = (it != extensions.end());
  int id = 0;

  if (enable) {
    id = it->id;
    if (id < kMinRtpHeaderExtensionId ||
        id > kMaxRtpHeaderExtensionId) {
      LOG(LS_WARNING) << "Invalid RTP header extension id " << id;
      return false;
    }
  }

// This api call is not available in iOS version of VoiceEngine currently.
#if !defined(IOS) && !defined(ANDROID)
  if (engine()->voe()->rtp()->SetRTPAudioLevelIndicationStatus(
      voe_channel(), enable, id) == -1) {
    LOG_RTCERR3(SetRTPAudioLevelIndicationStatus, voe_channel(), enable, id);
    return false;
  }
#endif

  return true;
}

bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) {
  desired_playout_ = playout;
  return ChangePlayout(desired_playout_);
}

bool WebRtcVoiceMediaChannel::PausePlayout() {
  return ChangePlayout(false);
}

bool WebRtcVoiceMediaChannel::ResumePlayout() {
  return ChangePlayout(desired_playout_);
}

bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) {
  if (playout_ == playout) {
    return true;
  }

  bool result = true;
  if (mux_channels_.empty()) {
    // Only toggle the default channel if we don't have any other channels.
    result = SetPlayout(voe_channel(), playout);
  }
  for (ChannelMap::iterator it = mux_channels_.begin();
       it != mux_channels_.end() && result; ++it) {
    if (!SetPlayout(it->second, playout)) {
      LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " << it->second
                    << " failed";
      result = false;
    }
  }

  if (result) {
    playout_ = playout;
  }
  return result;
}

bool WebRtcVoiceMediaChannel::SetSend(SendFlags send) {
  desired_send_ = send;
  if (local_ssrc_ != 0)
    return ChangeSend(desired_send_);
  return true;
}

bool WebRtcVoiceMediaChannel::PauseSend() {
  return ChangeSend(SEND_NOTHING);
}

bool WebRtcVoiceMediaChannel::ResumeSend() {
  return ChangeSend(desired_send_);
}

bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) {
  if (send_ == send) {
    return true;
  }

  if (send == SEND_MICROPHONE) {
#ifdef CHROMEOS
    // Conference mode doesn't work well on ChromeOS.
    if (!engine()->SetConferenceMode(false)) {
      LOG_RTCERR1(SetConferenceMode, voe_channel());
      return false;
    }
#else
    // Multi-point conferences use conference-mode noise filtering.
    if (!engine()->SetConferenceMode(
        0 != (channel_options_ & OPT_CONFERENCE))) {
      LOG_RTCERR1(SetConferenceMode, voe_channel());
      return false;
    }
#endif  // CHROMEOS

    if ((channel_options_ & OPT_AGC_MINUS_10DB) && !agc_adjusted_) {
      if (engine()->AdjustAgcLevel(kMinus10DbAdjustment)) {
        agc_adjusted_ = true;
      }
    }

    // VoiceEngine resets sequence number when StopSend is called. This
    // sometimes causes libSRTP to complain about packets being
    // replayed. To get around this we store the last sent sequence
    // number and initializes the channel with the next to continue on
    // the same sequence.
    if (sequence_number() != -1) {
      LOG(LS_INFO) << "WebRtcVoiceMediaChannel restores seqnum="
                   << sequence_number() + 1;
      if (engine()->voe()->sync()->SetInitSequenceNumber(
              voe_channel(), sequence_number() + 1) == -1) {
        LOG_RTCERR2(SetInitSequenceNumber, voe_channel(),
                    sequence_number() + 1);
      }
    }
    if (engine()->voe()->base()->StartSend(voe_channel()) == -1) {
      LOG_RTCERR1(StartSend, voe_channel());
      return false;
    }
    if (engine()->voe()->file()->StopPlayingFileAsMicrophone(
        voe_channel()) == -1) {
      LOG_RTCERR1(StopPlayingFileAsMicrophone, voe_channel());
      return false;
    }
  } else if (send == SEND_RINGBACKTONE) {
    ASSERT(ringback_tone_.get() != NULL);
    if (!ringback_tone_.get()) {
      return false;
    }
    if (engine()->voe()->file()->StartPlayingFileAsMicrophone(
        voe_channel(), ringback_tone_.get(), false) == -1) {
      LOG_RTCERR3(StartPlayingFileAsMicrophone, voe_channel(),
                  ringback_tone_.get(), false);
      return false;
    }
    // VoiceEngine resets sequence number when StopSend is called. This
    // sometimes causes libSRTP to complain about packets being
    // replayed. To get around this we store the last sent sequence
    // number and initializes the channel with the next to continue on
    // the same sequence.
    if (sequence_number() != -1) {
      LOG(LS_INFO) << "WebRtcVoiceMediaChannel restores seqnum="
                   << sequence_number() + 1;
      if (engine()->voe()->sync()->SetInitSequenceNumber(
              voe_channel(), sequence_number() + 1) == -1) {
        LOG_RTCERR2(SetInitSequenceNumber, voe_channel(),
                    sequence_number() + 1);
      }
    }
    if (engine()->voe()->base()->StartSend(voe_channel()) == -1) {
      LOG_RTCERR1(StartSend, voe_channel());
      return false;
    }
  } else {  // SEND_NOTHING
    if (engine()->voe()->base()->StopSend(voe_channel()) == -1) {
      LOG_RTCERR1(StopSend, voe_channel());
    }

    // Reset the AGC level, if it was set.
    if (agc_adjusted_) {
      if (engine()->AdjustAgcLevel(0)) {
        agc_adjusted_ = false;
      }
    }

    // Disable conference-mode noise filtering.
    if (!engine()->SetConferenceMode(false)) {
      LOG_RTCERR1(SetConferenceMode, voe_channel());
    }
  }
  send_ = send;
  return true;
}

bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
  if (local_ssrc_ != 0) {
    LOG(LS_ERROR) << "WebRtcVoiceMediaChannel supports one sending channel.";
    return false;
  }

  if (engine()->voe()->rtp()->SetLocalSSRC(voe_channel(), sp.first_ssrc())
        == -1) {
    LOG_RTCERR2(SetSendSSRC, voe_channel(), sp.first_ssrc());
    return false;
  }

  if (engine()->voe()->rtp()->SetRTCP_CNAME(voe_channel(),
                                            sp.cname.c_str()) == -1) {
     LOG_RTCERR2(SetRTCP_CNAME, voe_channel(), sp.cname);
     return false;
  }

  local_ssrc_ = sp.first_ssrc();
  if (desired_send_ != send_)
    return ChangeSend(desired_send_);
  return true;
}

bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32 ssrc) {
  if (ssrc != local_ssrc_) {
    return false;
  }
  local_ssrc_ = 0;
  ChangeSend(SEND_NOTHING);
  return true;
}

bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {
  talk_base::CritScope lock(&mux_channels_cs_);

  if (!VERIFY(sp.ssrcs.size() == 1))
    return false;
  uint32 ssrc = sp.first_ssrc();

  if (mux_channels_.find(ssrc) != mux_channels_.end()) {
    return false;
  }

  // Create a new channel for receiving audio data.
  int channel = engine()->voe()->base()->CreateChannel();
  if (channel == -1) {
    LOG_RTCERR0(CreateChannel);
    return false;
  }

  // Configure to use external transport, like our default channel.
  if (engine()->voe()->network()->RegisterExternalTransport(
          channel, *this) == -1) {
    LOG_RTCERR2(SetExternalTransport, channel, this);
    return false;
  }

  // Use the same SSRC as our default channel (so the RTCP reports are correct).
  unsigned int send_ssrc;
  webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp();
  if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) {
    LOG_RTCERR2(GetSendSSRC, channel, send_ssrc);
    return false;
  }
  if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) {
    LOG_RTCERR2(SetSendSSRC, channel, send_ssrc);
    return false;
  }

  // Use the same recv payload types as our default channel.
  ResetRecvCodecs(channel);
  if (recv_codecs_set_) {
    int ncodecs = engine()->voe()->codec()->NumOfCodecs();
    for (int i = 0; i < ncodecs; ++i) {
      webrtc::CodecInst voe_codec;
      if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
        voe_codec.rate = 0;  // Needed to make GetRecPayloadType work for ISAC
        if (engine()->voe()->codec()->GetRecPayloadType(
            voe_channel(), voe_codec) != -1) {
          if (engine()->voe()->codec()->SetRecPayloadType(
              channel, voe_codec) == -1) {
            LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
            return false;
          }
        }
      }
    }
  }

  if (mux_channels_.empty() && playout_) {
    // This is the first stream in a multi user meeting. We can now
    // disable playback of the default stream. This since the default
    // stream will probably have received some initial packets before
    // the new stream was added. This will mean that the CN state from
    // the default channel will be mixed in with the other streams
    // throughout the whole meeting, which might be disturbing.
    LOG(LS_INFO) << "Disabling playback on the default voice channel";
    SetPlayout(voe_channel(), false);
  }

  mux_channels_[ssrc] = channel;

  // TODO: We should rollback the add if SetPlayout fails.
  LOG(LS_INFO) << "New audio stream " << ssrc
            << " registered to VoiceEngine channel #"
            << channel << ".";
  return SetPlayout(channel, playout_);
}

bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) {
  talk_base::CritScope lock(&mux_channels_cs_);
  ChannelMap::iterator it = mux_channels_.find(ssrc);

  if (it != mux_channels_.end()) {
    if (engine()->voe()->network()->DeRegisterExternalTransport(
        it->second) == -1) {
      LOG_RTCERR1(DeRegisterExternalTransport, it->second);
    }

    LOG(LS_INFO) << "Removing audio stream " << ssrc
              << " with VoiceEngine channel #"
              << it->second << ".";
    if (engine()->voe()->base()->DeleteChannel(it->second) == -1) {
      LOG_RTCERR1(DeleteChannel, voe_channel());
      return false;
    }

    mux_channels_.erase(it);
    if (mux_channels_.empty() && playout_) {
      // The last stream was removed. We can now enable the default
      // channel for new channels to be played out immediately without
      // waiting for AddStream messages.
      // TODO: Does the default channel still have it's CN state?
      LOG(LS_INFO) << "Enabling playback on the default voice channel";
      SetPlayout(voe_channel(), true);
    }
  }
  return true;
}

bool WebRtcVoiceMediaChannel::GetActiveStreams(
    AudioInfo::StreamList* actives) {
  actives->clear();
  for (ChannelMap::iterator it = mux_channels_.begin();
       it != mux_channels_.end(); ++it) {
    int level = GetOutputLevel(it->second);
    if (level > 0) {
      actives->push_back(std::make_pair(it->first, level));
    }
  }
  return true;
}

int WebRtcVoiceMediaChannel::GetOutputLevel() {
  // return the highest output level of all streams
  int highest = GetOutputLevel(voe_channel());
  for (ChannelMap::iterator it = mux_channels_.begin();
       it != mux_channels_.end(); ++it) {
    int level = GetOutputLevel(it->second);
    highest = talk_base::_max(level, highest);
  }
  return highest;
}


bool WebRtcVoiceMediaChannel::SetOutputScaling(
    uint32 ssrc, double left, double right) {
  talk_base::CritScope lock(&mux_channels_cs_);
  // Collect the channels to scale the output volume.
  std::vector<int> channels;
  if (0 == ssrc) {  // Collect all channels, including the default one.
    channels.push_back(voe_channel());
    for (ChannelMap::const_iterator it = mux_channels_.begin();
        it != mux_channels_.end(); ++it) {
      channels.push_back(it->second);
    }
  } else {  // Collect only the channel of the specified ssrc.
    int channel = GetChannelNum(ssrc);
    if (-1 == channel) {
      LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
      return false;
    }
    channels.push_back(channel);
  }

  // Scale the output volume for the collected channels. We first normalize to
  // scale the volume and then set the left and right pan.
  float scale = static_cast<float>(talk_base::_max(left, right));
  if (scale > 0.0001f) {
    left /= scale;
    right /= scale;
  }
  for (std::vector<int>::const_iterator it = channels.begin();
      it != channels.end(); ++it) {
    if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling(
        *it, scale)) {
      LOG_RTCERR2(SetChannelOutputVolumeScaling, *it, scale);
      return false;
    }
    if (-1 == engine()->voe()->volume()->SetOutputVolumePan(
        *it, static_cast<float>(left), static_cast<float>(right))) {
      LOG_RTCERR3(SetOutputVolumePan, *it, left, right);
      // Do not return if fails. SetOutputVolumePan is not available for all
      // pltforms.
    }
    LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale
                 << " right=" << right * scale
                 << " for channel " << *it << " and ssrc " << ssrc;
  }
  return true;
}

bool WebRtcVoiceMediaChannel::GetOutputScaling(
    uint32 ssrc, double* left, double* right) {
  if (!left || !right) return false;

  talk_base::CritScope lock(&mux_channels_cs_);
  // Determine which channel based on ssrc.
  int channel = (0 == ssrc) ? voe_channel() : GetChannelNum(ssrc);
  if (channel == -1) {
    LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
    return false;
  }

  float scaling;
  if (-1 == engine()->voe()->volume()->GetChannelOutputVolumeScaling(
      channel, scaling)) {
    LOG_RTCERR2(GetChannelOutputVolumeScaling, channel, scaling);
    return false;
  }

  float left_pan;
  float right_pan;
  if (-1 == engine()->voe()->volume()->GetOutputVolumePan(
      channel, left_pan, right_pan)) {
    LOG_RTCERR3(GetOutputVolumePan, channel, left_pan, right_pan);
    // If GetOutputVolumePan fails, we use the default left and right pan.
    left_pan = 1.0f;
    right_pan = 1.0f;
  }

  *left = scaling * left_pan;
  *right = scaling * right_pan;
  return true;
}

bool WebRtcVoiceMediaChannel::SetRingbackTone(const char *buf, int len) {
  ringback_tone_.reset(new WebRtcSoundclipStream(buf, len));
  return true;
}

bool WebRtcVoiceMediaChannel::PlayRingbackTone(uint32 ssrc,
                                             bool play, bool loop) {
  if (!ringback_tone_.get()) {
    return false;
  }

  // Determine which VoiceEngine channel to play on.
  int channel = (ssrc == 0) ? voe_channel() : GetChannelNum(ssrc);
  if (channel == -1) {
    return false;
  }

  // Make sure the ringtone is cued properly, and play it out.
  if (play) {
    ringback_tone_->set_loop(loop);
    ringback_tone_->Rewind();
    if (engine()->voe()->file()->StartPlayingFileLocally(channel,
        ringback_tone_.get()) == -1) {
      LOG_RTCERR2(StartPlayingFileLocally, channel, ringback_tone_.get());
      LOG(LS_ERROR) << "Unable to start ringback tone";
      return false;
    }
    ringback_channels_.insert(channel);
    LOG(LS_INFO) << "Started ringback on channel " << channel;
  } else {
    if (engine()->voe()->file()->IsPlayingFileLocally(channel) == 1 &&
        engine()->voe()->file()->StopPlayingFileLocally(channel) == -1) {
      LOG_RTCERR1(StopPlayingFileLocally, channel);
      return false;
    }
    LOG(LS_INFO) << "Stopped ringback on channel " << channel;
    ringback_channels_.erase(channel);
  }

  return true;
}

bool WebRtcVoiceMediaChannel::PressDTMF(int event, bool playout) {
  if (!dtmf_allowed_) {
    return false;
  }

  // Enable or disable DTMF playout of this tone as requested. This will linger
  // until the next call to this method, but that's OK.
  if (engine()->voe()->dtmf()->SetDtmfFeedbackStatus(playout) == -1) {
    LOG_RTCERR2(SendDTMF, voe_channel(), playout);
    return false;
  }

  // Send DTMF using out-of-band DTMF. ("true", as 3rd arg)
  if (engine()->voe()->dtmf()->SendTelephoneEvent(voe_channel(), event,
      true) == -1) {
    LOG_RTCERR3(SendDTMF, voe_channel(), event, true);
    return false;
  }

  return true;
}

void WebRtcVoiceMediaChannel::OnPacketReceived(talk_base::Buffer* packet) {
  // Pick which channel to send this packet to. If this packet doesn't match
  // any multiplexed streams, just send it to the default channel. Otherwise,
  // send it to the specific decoder instance for that stream.
  int which_channel = GetChannelNum(
      ParseSsrc(packet->data(), packet->length(), false));
  if (which_channel == -1) {
    which_channel = voe_channel();
  }

  // Stop any ringback that might be playing on the channel.
  // It's possible the ringback has already stopped, ih which case we'll just
  // use the opportunity to remove the channel from ringback_channels_.
  const std::set<int>::iterator it = ringback_channels_.find(which_channel);
  if (it != ringback_channels_.end()) {
    if (engine()->voe()->file()->IsPlayingFileLocally(
        which_channel) == 1) {
      engine()->voe()->file()->StopPlayingFileLocally(which_channel);
      LOG(LS_INFO) << "Stopped ringback on channel " << which_channel
                   << " due to incoming media";
    }
    ringback_channels_.erase(which_channel);
  }

  // Pass it off to the decoder.
  engine()->voe()->network()->ReceivedRTPPacket(which_channel,
                                                   packet->data(),
                                                   packet->length());
}

void WebRtcVoiceMediaChannel::OnRtcpReceived(talk_base::Buffer* packet) {
  // See above.
  int which_channel = GetChannelNum(
      ParseSsrc(packet->data(), packet->length(), true));
  if (which_channel == -1) {
    which_channel = voe_channel();
  }

  engine()->voe()->network()->ReceivedRTCPPacket(which_channel,
                                                    packet->data(),
                                                    packet->length());
}

bool WebRtcVoiceMediaChannel::Mute(bool muted) {
  if (engine()->voe()->volume()->SetInputMute(voe_channel(),
      muted) == -1) {
    LOG_RTCERR2(SetInputMute, voe_channel(), muted);
    return false;
  }
  return true;
}

bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
  // In VoiceEngine 3.5, GetRTCPStatistics will return 0 even when it fails,
  // causing the stats to contain garbage information. To prevent this, we
  // zero the stats structure before calling this API.
  // TODO: Remove this workaround.
  webrtc::CallStatistics cs;
  unsigned int ssrc;
  webrtc::CodecInst codec;
  unsigned int level;

  // Fill in the sender info, based on what we know, and what the
  // remote side told us it got from its RTCP report.
  VoiceSenderInfo sinfo;

  // Data we obtain locally.
  memset(&cs, 0, sizeof(cs));
  if (engine()->voe()->rtp()->GetRTCPStatistics(voe_channel(), cs) == -1 ||
      engine()->voe()->rtp()->GetLocalSSRC(voe_channel(), ssrc) == -1) {
    return false;
  }

  sinfo.ssrc = ssrc;
  sinfo.codec_name = send_codec_.get() ? send_codec_->plname : "";
  sinfo.bytes_sent = cs.bytesSent;
  sinfo.packets_sent = cs.packetsSent;
  // RTT isn't known until a RTCP report is received. Until then, VoiceEngine
  // returns 0 to indicate an error value.
  sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1;

  // Data from the last remote RTCP report.
  unsigned int ntp_high, ntp_low, timestamp, ptimestamp, jitter;
  unsigned short loss;  // NOLINT
  if (engine()->voe()->rtp()->GetRemoteRTCPData(voe_channel(),
          ntp_high, ntp_low, timestamp, ptimestamp, &jitter, &loss) != -1 &&
      engine()->voe()->codec()->GetSendCodec(voe_channel(),
          codec) != -1) {
    // Convert Q8 to floating point.
    sinfo.fraction_lost = static_cast<float>(loss) / (1 << 8);
    // Convert samples to milliseconds.
    if (codec.plfreq / 1000 > 0) {
      sinfo.jitter_ms = jitter / (codec.plfreq / 1000);
    }
  } else {
    sinfo.fraction_lost = -1;
    sinfo.jitter_ms = -1;
  }
  // TODO: Figure out how to get remote packets_lost, ext_seqnum
  sinfo.packets_lost = -1;
  sinfo.ext_seqnum = -1;

  // Local speech level.
  sinfo.audio_level = (engine()->voe()->volume()->
      GetSpeechInputLevelFullRange(level) != -1) ? level : -1;

  bool echo_metrics_on = false;
  // These can take on valid negative values, so use the lowest possible level
  // as default rather than -1.
  sinfo.echo_return_loss = -100;
  sinfo.echo_return_loss_enhancement = -100;
  // These can also be negative, but in practice -1 is only used to signal
  // insufficient data, since the resolution is limited to multiples of 4 ms.
  sinfo.echo_delay_median_ms = -1;
  sinfo.echo_delay_std_ms = -1;
  if (engine()->voe()->processing()->GetEcMetricsStatus(echo_metrics_on) !=
      -1 && echo_metrics_on) {
    // TODO: we may want to use VoECallReport::GetEchoMetricsSummary
    // here, but it appears to be unsuitable currently. Revisit after this is
    // investigated: http://b/issue?id=5666755
    int erl, erle, rerl, anlp;
    if (engine()->voe()->processing()->GetEchoMetrics(erl, erle, rerl, anlp) !=
        -1) {
      sinfo.echo_return_loss = erl;
      sinfo.echo_return_loss_enhancement = erle;
    }

    int median, std;
    if (engine()->voe()->processing()->GetEcDelayMetrics(median, std) != -1) {
      sinfo.echo_delay_median_ms = median;
      sinfo.echo_delay_std_ms = std;
    }
  }

  info->senders.push_back(sinfo);

  // Build the list of receivers, one for each mux channel, or 1 in a 1:1 call.
  std::vector<int> channels;
  for (ChannelMap::const_iterator it = mux_channels_.begin();
       it != mux_channels_.end(); ++it) {
    channels.push_back(it->second);
  }
  if (channels.empty()) {
    channels.push_back(voe_channel());
  }

  // Get the SSRC and stats for each receiver, based on our own calculations.
  for (std::vector<int>::const_iterator it = channels.begin();
       it != channels.end(); ++it) {
    memset(&cs, 0, sizeof(cs));
    if (engine()->voe()->rtp()->GetRemoteSSRC(*it, ssrc) != -1 &&
        engine()->voe()->rtp()->GetRTCPStatistics(*it, cs) != -1 &&
        engine()->voe()->codec()->GetRecCodec(*it, codec) != -1) {
      VoiceReceiverInfo rinfo;
      rinfo.ssrc = ssrc;
      rinfo.bytes_rcvd = cs.bytesReceived;
      rinfo.packets_rcvd = cs.packetsReceived;
      // The next four fields are from the most recently sent RTCP report.
      // Convert Q8 to floating point.
      rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8);
      rinfo.packets_lost = cs.cumulativeLost;
      rinfo.ext_seqnum = cs.extendedMax;
      // Convert samples to milliseconds.
      if (codec.plfreq / 1000 > 0) {
        rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000);
      }

      // Get jitter buffer and total delay (alg + jitter + playout) stats.
      webrtc::NetworkStatistics ns;
      if (engine()->voe()->neteq() &&
          engine()->voe()->neteq()->GetNetworkStatistics(
              *it, ns) != -1) {
        rinfo.jitter_buffer_ms = ns.currentBufferSize;
        rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize;
      }
      if (engine()->voe()->sync()) {
        engine()->voe()->sync()->GetDelayEstimate(*it,
            rinfo.delay_estimate_ms);
      }

      // Get speech level.
      rinfo.audio_level = (engine()->voe()->volume()->
          GetSpeechOutputLevelFullRange(*it, level) != -1) ? level : -1;
      info->receivers.push_back(rinfo);
    }
  }

  return true;
}

void WebRtcVoiceMediaChannel::GetLastMediaError(
    uint32* ssrc, VoiceMediaChannel::Error* error) {
  ASSERT(ssrc != NULL);
  ASSERT(error != NULL);
  FindSsrc(voe_channel(), ssrc);
  *error = WebRtcErrorToChannelError(GetLastEngineError());
}

bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) {
  talk_base::CritScope lock(&mux_channels_cs_);
  ASSERT(ssrc != NULL);
  if (channel_num == voe_channel()) {
    unsigned local_ssrc = 0;
    // This is a sending channel.
    if (engine()->voe()->rtp()->GetLocalSSRC(
        channel_num, local_ssrc) != -1) {
      *ssrc = local_ssrc;
    }
    return true;
  } else if (channel_num == -1 && send_ != SEND_NOTHING) {
    // Sometimes the VoiceEngine core will throw error with channel_num = -1.
    // This means the error is not limited to a specific channel.  Signal the
    // message using ssrc=0.  If the current channel is sending, use this
    // channel for sending the message.
    *ssrc = 0;
    return true;
  } else {
    // Check whether this is a receiving channel.
    for (ChannelMap::const_iterator it = mux_channels_.begin();
        it != mux_channels_.end(); ++it) {
      if (it->second == channel_num) {
        *ssrc = it->first;
        return true;
      }
    }
  }
  return false;
}

void WebRtcVoiceMediaChannel::OnError(uint32 ssrc, int error) {
  SignalMediaError(ssrc, WebRtcErrorToChannelError(error));
}

int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) {
  unsigned int ulevel;
  int ret =
      engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel);
  return (ret == 0) ? static_cast<int>(ulevel) : -1;
}

int WebRtcVoiceMediaChannel::GetChannelNum(uint32 ssrc) {
  ChannelMap::iterator it = mux_channels_.find(ssrc);
  return (it != mux_channels_.end()) ? it->second : -1;
}

bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
    const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) {
  // Get the RED encodings from the parameter with no name. This may
  // change based on what is discussed on the Jingle list.
  // The encoding parameter is of the form "a/b"; we only support where
  // a == b. Verify this and parse out the value into red_pt.
  // If the parameter value is absent (as it will be until we wire up the
  // signaling of this message), use the second codec specified (i.e. the
  // one after "red") as the encoding parameter.
  int red_pt = -1;
  std::string red_params;
  CodecParameterMap::const_iterator it = red_codec.params.find("");
  if (it != red_codec.params.end()) {
    red_params = it->second;
    std::vector<std::string> red_pts;
    if (talk_base::split(red_params, '/', &red_pts) != 2 ||
        red_pts[0] != red_pts[1] ||
        !talk_base::FromString(red_pts[0], &red_pt)) {
      LOG(LS_WARNING) << "RED params " << red_params << " not supported.";
      return false;
    }
  } else if (red_codec.params.empty()) {
    LOG(LS_WARNING) << "RED params not present, using defaults";
    if (all_codecs.size() > 1) {
      red_pt = all_codecs[1].id;
    }
  }

  // Try to find red_pt in |codecs|.
  std::vector<AudioCodec>::const_iterator codec;
  for (codec = all_codecs.begin(); codec != all_codecs.end(); ++codec) {
    if (codec->id == red_pt)
      break;
  }

  // If we find the right codec, that will be the codec we pass to
  // SetSendCodec, with the desired payload type.
  if (codec != all_codecs.end() &&
    engine()->FindWebRtcCodec(*codec, send_codec)) {
  } else {
    LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
    return false;
  }

  return true;
}

bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) {
  if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) {
    LOG_RTCERR2(SetRTCPStatus, voe_channel(), 1);
    return false;
  }
  // TODO: Enable VQMon and RTCP XR reports, once we know what
  // what we want to do with them.
  // engine()->voe().EnableVQMon(voe_channel(), true);
  // engine()->voe().EnableRTCP_XR(voe_channel(), true);
  return true;
}

bool WebRtcVoiceMediaChannel::ResetRecvCodecs(int channel) {
  int ncodecs = engine()->voe()->codec()->NumOfCodecs();
  for (int i = 0; i < ncodecs; ++i) {
    webrtc::CodecInst voe_codec;
    if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
      voe_codec.pltype = -1;
      if (engine()->voe()->codec()->SetRecPayloadType(
          channel, voe_codec) == -1) {
        LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
        return false;
      }
    }
  }
  return true;
}

bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) {
  if (playout) {
    LOG(LS_INFO) << "Starting playout for channel #" << channel;
    if (engine()->voe()->base()->StartPlayout(channel) == -1) {
      LOG_RTCERR1(StartPlayout, channel);
      return false;
    }
  } else {
    LOG(LS_INFO) << "Stopping playout for channel #" << channel;
    engine()->voe()->base()->StopPlayout(channel);
  }
  return true;
}

uint32 WebRtcVoiceMediaChannel::ParseSsrc(const void* data, size_t len,
                                        bool rtcp) {
  size_t ssrc_pos = (!rtcp) ? 8 : 4;
  uint32 ssrc = 0;
  if (len >= (ssrc_pos + sizeof(ssrc))) {
    ssrc = talk_base::GetBE32(static_cast<const char*>(data) + ssrc_pos);
  }
  return ssrc;
}

// Convert VoiceEngine error code into VoiceMediaChannel::Error enum.
VoiceMediaChannel::Error
    WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) {
  switch (err_code) {
    case 0:
      return ERROR_NONE;
    case VE_CANNOT_START_RECORDING:
    case VE_MIC_VOL_ERROR:
    case VE_GET_MIC_VOL_ERROR:
    case VE_CANNOT_ACCESS_MIC_VOL:
      return ERROR_REC_DEVICE_OPEN_FAILED;
    case VE_SATURATION_WARNING:
      return ERROR_REC_DEVICE_SATURATION;
    case VE_REC_DEVICE_REMOVED:
      return ERROR_REC_DEVICE_REMOVED;
    case VE_RUNTIME_REC_WARNING:
    case VE_RUNTIME_REC_ERROR:
      return ERROR_REC_RUNTIME_ERROR;
    case VE_CANNOT_START_PLAYOUT:
    case VE_SPEAKER_VOL_ERROR:
    case VE_GET_SPEAKER_VOL_ERROR:
    case VE_CANNOT_ACCESS_SPEAKER_VOL:
      return ERROR_PLAY_DEVICE_OPEN_FAILED;
    case VE_RUNTIME_PLAY_WARNING:
    case VE_RUNTIME_PLAY_ERROR:
      return ERROR_PLAY_RUNTIME_ERROR;
    case VE_TYPING_NOISE_WARNING:
      return ERROR_REC_TYPING_NOISE_DETECTED;
    default:
      return VoiceMediaChannel::ERROR_OTHER;
  }
}

int WebRtcSoundclipStream::Read(void *buf, int len) {
  size_t res = 0;
  mem_.Read(buf, len, &res, NULL);
  return res;
}

int WebRtcSoundclipStream::Rewind() {
  mem_.Rewind();
  // Return -1 to keep VoiceEngine from looping.
  return (loop_) ? 0 : -1;
}

}  // namespace cricket

#endif  // HAVE_WEBRTC_VOICE
