/*
 * 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.
 */

// shhhhh{
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// shhhhh}

#ifdef HAVE_GIPS

#include "talk/session/phone/gipsmediaengine.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"

#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 void GipsLogMultiline(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;
  }
}

// GipsVoiceEngine
const GipsVoiceEngine::CodecPref GipsVoiceEngine::kCodecPrefs[] = {
  { "ISAC",   16000 },
  { "ISAC",   32000 },
  { "ISACLC", 16000 },
  { "speex",  16000 },
  { "IPCMWB", 16000 },
  { "G722",   16000 },
  { "iLBC",   8000 },
  { "speex",  8000 },
  { "GSM",    8000 },
  { "EG711U", 8000 },
  { "EG711A", 8000 },
  { "PCMU",   8000 },
  { "PCMA",   8000 },
  { "CN",     32000 },
  { "CN",     16000 },
  { "CN",     8000 },
  { "red",    8000 },
  { "telephone-event", 8000 },
};

class GipsSoundclipMedia : public SoundclipMedia {
 public:
  explicit GipsSoundclipMedia(GipsVoiceEngine *engine)
      : engine_(engine), gips_channel_(-1) {
    engine_->RegisterSoundclip(this);
  }

  virtual ~GipsSoundclipMedia() {
    engine_->UnregisterSoundclip(this);
    if (gips_channel_ != -1) {
      if (engine_->gips_sc()->base()->GIPSVE_DeleteChannel(gips_channel_)
          == -1) {
        LOG_GIPSERR1(DeleteChannel, gips_channel_);
      }
    }
  }

  bool Init() {
    gips_channel_ = engine_->gips_sc()->base()->GIPSVE_CreateChannel();
    if (gips_channel_ == -1) {
      LOG_GIPSERR0(CreateChannel);
      return false;
    }
    return true;
  }

  bool Enable() {
    if (engine_->gips_sc()->base()->GIPSVE_StartPlayout(gips_channel_) == -1) {
      LOG_GIPSERR1(StartPlayout, gips_channel_);
      return false;
    }
    return true;
  }

  bool Disable() {
    if (engine_->gips_sc()->base()->GIPSVE_StopPlayout(gips_channel_) == -1) {
      LOG_GIPSERR1(StopPlayout, gips_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_->gips_sc()->file()->GIPSVE_StopPlayingFileLocally(gips_channel_)
        == -1) {
      LOG_GIPSERR1(StopPlayingFileLocally, gips_channel_);
      return false;
    }

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

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

  int GetLastGipsError() { return engine_->gips_sc()->error(); }

 private:
  GipsVoiceEngine *engine_;
  int gips_channel_;
  talk_base::scoped_ptr<GipsSoundclipStream> stream_;
};

GipsVoiceEngine::GipsVoiceEngine()
    : gips_(new GipsWrapper()),
      gips_sc_(new GipsWrapper()),
      tracing_(new GipsTraceWrapper()),
      log_level_(kDefaultLogSeverity),
      is_dumping_aec_(false),
      desired_local_monitor_enable_(false) {
  Construct();
}

GipsVoiceEngine::GipsVoiceEngine(
    GipsWrapper* gips, GipsWrapper* gips_sc, GipsTraceWrapper* tracing)
    : gips_(gips),
      gips_sc_(gips_sc),
      tracing_(tracing),
      log_level_(kDefaultLogSeverity),
      is_dumping_aec_(false),
      desired_local_monitor_enable_(false) {
  Construct();
}

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

  // Load our audio codec list
  LOG(LS_INFO) << "GIPS VoiceEngine codecs:";
  int ncodecs = gips_->codec()->GIPSVE_NumOfCodecs();
  for (int i = 0; i < ncodecs; ++i) {
    GIPS_CodecInst gcodec;
    if (gips_->codec()->GIPSVE_GetCodec(i, gcodec) >= 0) {
      int pref = GetCodecPreference(gcodec.plname, gcodec.plfreq);
      if (pref != -1) {
        if (gcodec.rate == -1) gcodec.rate = 0;
        AudioCodec codec(gcodec.pltype, gcodec.plname, gcodec.plfreq,
                         gcodec.rate, gcodec.channels, pref);
        LOG(LS_INFO) << gcodec.plname << "/" << gcodec.plfreq << "/"
                     << gcodec.channels << " " << gcodec.pltype;
        codecs_.push_back(codec);
      }
    }
  }
  // Make sure they are in local preference order
  std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable);
}

GipsVoiceEngine::~GipsVoiceEngine() {
  LOG(LS_VERBOSE) << "GipsVoiceEngine::~GipsVoiceEngine";
  if (gips_->base()->GIPSVE_DeRegisterVoiceEngineObserver() == -1) {
    LOG_GIPSERR0(DeRegisterVoiceEngineObserver);
  }
  tracing_->SetTraceCallback(NULL);
}

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

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

#if defined(LINUX) && !defined(HAVE_LIBPULSE)
  gips_->hw()->GIPSVE_SetAudioDeviceLayer(GIPS_AUDIO_LINUX_ALSA);
#endif
#ifdef WIN32
  // NOTE(fbarchard): Enable this to test WAVE on Windows 7
  // gips_->hw()->GIPSVE_SetAudioDeviceLayer(GIPS_AUDIO_WINDOWS_WAVE);
#endif
// shhhhh{
#ifdef ANDROID
  const char AUTH_KEY[] =
      "====YUtFWRAAAAADBtIHgAAAAAEAAAAcAAAAAQBHU0dsb2J"
      "hbCBJUCBTb3VuZAACAAAADgAAAGdvb2dsZQAAAABGAAAAEkxO38dEtVtksyvvIn"
      "eiDc8yJtfB038G6bZQ4zNByUrAnpd9znXNRIe9k4Tjrjn0q7ztOMs2Ge6pqMEYq"
      "aAEANWCYjZ1kKXkBNJqfZq6TGn894PUJXYKirNVozxjT1E+GzB9xCEDVuTowZIJ"
      "T7qFBDr2TSCBhg2rA5JTT7Y/+l01DHxOzvOtdvdQucVyp3QbNZlwdFLJEuevKre"
      "ZnfH+ChYvHXrPDWyJPNvnl9382VFbk/5ZVbdoCaHi4ISDWn9C=6wIv";

  if (gips_->base()->GIPSVE_Authenticate(AUTH_KEY, strlen(AUTH_KEY)) != 0) {
    LOG_GIPSERR0(Authenticate);
    return false;
  }
#endif
// shhhhh}

  // Init GIPS VoiceEngine, enabling AEC logging if specified in SetLogging.
  if (gips_->base()->GIPSVE_Init() == -1) {
    LOG_GIPSERR0_EX(Init, gips_->error());
    return false;
  }

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

  // Log the GIPS version info
  char buffer[1024] = "";
  gips_->base()->GIPSVE_GetVersion(buffer);
  LOG(LS_INFO) << "GIPS VoiceEngine Version:";
  GipsLogMultiline(talk_base::LS_INFO, buffer);

  // Turn on AEC, AGC, NS and typing detection by default.
  int options = MediaEngineInterface::ECHO_CANCELLATION
      | MediaEngineInterface::AUTO_GAIN_CONTROL
      | MediaEngineInterface::NOISE_SUPPRESSION
#if !defined(IOS) && !defined(ANDROID)
      | MediaEngineInterface::TYPING_DETECTION
#endif
      ;
  if (!SetOptions(options)) {
    return false;
  }

  // Save the default AGC configuration settings.
  if (gips_->vqe()->GIPSVE_GetAGCConfig(default_agc_config_) == -1) {
    LOG_GIPSERR0(GetAGCConfig);
    return false;
  }

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

#if defined(LINUX) && !defined(HAVE_LIBPULSE)
  gips_sc_->hw()->GIPSVE_SetAudioDeviceLayer(GIPS_AUDIO_LINUX_ALSA);
#endif

// shhhhh{
#ifdef ANDROID
  if (gips_sc_->base()->GIPSVE_Authenticate(AUTH_KEY, strlen(AUTH_KEY)) != 0) {
    LOG_GIPSERR0(Authenticate);
    return false;
  }
#endif
// shhhhh}

  // Initialize the GIPS instance that we'll use to play out sound clips.
  if (gips_sc_->base()->GIPSVE_Init() == -1) {
    LOG_GIPSERR0_EX(Init, gips_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(juberti): Clean this up when we support setting the soundclip device.
#ifdef WIN32
  int num_of_devices = 0;
  if (gips_sc_->hw()->GIPSVE_GetNumOfPlayoutDevices(num_of_devices) != -1 &&
      num_of_devices > 0) {
    if (gips_sc_->hw()->GIPSVE_SetPlayoutDevice(kDefaultSoundclipDeviceId)
        == -1) {
      LOG_GIPSERR1_EX(SetPlayoutDevice, kDefaultSoundclipDeviceId,
                      gips_sc_->error());
      return false;
    }
  } else {
    LOG(LS_WARNING) << "No valid sound playout device found.";
  }
#endif

  initialized_ = true;
  return true;
}

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

  if (is_dumping_aec_) {
    if (gips_->vqe()->GIPSVE_StopDebugRecording() == -1) {
      LOG_GIPSERR0(StopDebugRecording);
    }
    is_dumping_aec_ = false;
  }

  gips_sc_->base()->GIPSVE_Terminate();
  gips_->base()->GIPSVE_Terminate();
  desired_local_monitor_enable_ = false;
}

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

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

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

bool GipsVoiceEngine::SetOptions(int options) {
  // GIPS tells us that "auto" mode doesn't work too well, so we don't use it.
  bool aec = (options & MediaEngineInterface::ECHO_CANCELLATION) ? true : false;
  bool agc = (options & MediaEngineInterface::AUTO_GAIN_CONTROL) ? true : false;
  bool ns = (options & MediaEngineInterface::NOISE_SUPPRESSION) ? true : false;

#if !defined(IOS) && !defined(ANDROID)
  bool typing_detection =
      (options & MediaEngineInterface::TYPING_DETECTION) ? true : false;

  if (gips_->vqe()->GIPSVE_SetECStatus(aec) == -1) {
    LOG_GIPSERR1(SetECStatus, aec);
    return false;
  }

  if (gips_->vqe()->GIPSVE_SetAGCStatus(agc) == -1) {
    LOG_GIPSERR1(SetAGCStatus, agc);
    return false;
  }

  // TODO(pthatcher): The existing Talk Plugin's on-disk preference settings
  // won't include NOISE_SUPPRESSION or TYPING_DETECTION, so those flags won't
  // get passed in.  For desktop, we hard-code NS and typing detection to
  // true for now, until we can solve this.
  if (gips_->vqe()->GIPSVE_SetNSStatus(true) == -1) {
    LOG_GIPSERR1(SetNSStatus, ns);
    return false;
  }

  if (gips_->vqe()->GIPSVE_SetTypingDetectionStatus(true) == -1) {
    // In case of error, log the info and continue
    LOG_GIPSERR1(SetTypingDetectionStatus, typing_detection);
  }
#else
  if (gips_->vqe()->GIPSVE_SetECStatus(aec, GIPS_EC_AECM) == -1) {
    LOG_GIPSERR2(SetECStatus, aec, GIPS_EC_AECM);
    return false;
  }

  if (aec) {
    // Use speakerphone mode with comfort noise generation for mobile.
    if (gips_->vqe()->GIPSVE_SetAECMMode(GIPS_AECM_SPEAKERPHONE, true) != 0) {
      LOG_GIPSERR2(SetAECMMode, GIPS_AECM_SPEAKERPHONE, true);
    }
  }

  // On mobile, GIPS recommends fixed AGC (not adaptive)
  if (gips_->vqe()->GIPSVE_SetAGCStatus(agc, GIPS_AGC_FIXED_DIGITAL) == -1) {
    LOG_GIPSERR2(SetAGCStatus, agc, GIPS_AGC_FIXED_DIGITAL);
    return false;
  }

  // On mobile, GIPS recommends moderate aggressiveness.
  if (gips_->vqe()->GIPSVE_SetNSStatus(ns,
                                       GIPS_NS_MODERATE_SUPPRESSION) == -1) {
    LOG_GIPSERR2(SetNSStatus, ns, GIPS_NS_MODERATE_SUPPRESSION);
    return false;
  }

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

  return true;
}

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

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

// TODO(juberti): 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 GipsVoiceEngine::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) {
    GipsVoiceMediaChannel *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 GIPS and set recording device.
  if (!FindGipsAudioDeviceId(true, in_name, in_id, &in_id)) {
    ret = false;
  }
  if (ret) {
    if (gips_->hw()->GIPSVE_SetRecordingDevice(in_id) == -1) {
      LOG_GIPSERR2(SetRecordingDevice, in_device->name, in_id);
      ret = false;
    }
  }

  // Find the playout device id in GIPS and set playout device.
  if (!FindGipsAudioDeviceId(false, out_name, out_id, &out_id)) {
    LOG(LS_WARNING) << "Failed to find gips device id for " << out_name;
    ret = false;
  }
  if (ret) {
    if (gips_->hw()->GIPSVE_SetPlayoutDevice(out_id) == -1) {
      LOG_GIPSERR2(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) {
    GipsVoiceMediaChannel *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 GipsVoiceEngine::FindGipsAudioDeviceId(
    bool is_input, const std::string& dev_name, int dev_id, int* gips_id) {
  // In Linux, GIPS uses the same device dev_id as the device manager.
#ifdef LINUX
  *gips_id = dev_id;
  return true;
#else
  // In Windows and Mac, we need to find the GIPS device id by name unless the
  // input dev_id is the default device id.
  if (kDefaultAudioDeviceId == dev_id) {
    *gips_id = dev_id;
    return true;
  }

  // Get the number of GIPS audio devices.
  int count = 0;
  if (is_input) {
    if (-1 == gips_->hw()->GIPSVE_GetNumOfRecordingDevices(count)) {
      LOG_GIPSERR0(GetNumOfRecordingDevices);
      return false;
    }
  } else {
    if (-1 == gips_->hw()->GIPSVE_GetNumOfPlayoutDevices(count)) {
      LOG_GIPSERR0(GetNumOfPlayoutDevices);
      return false;
    }
  }

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

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

bool GipsVoiceEngine::GetOutputVolume(int* level) {
  unsigned int ulevel;
  if (gips_->volume()->GIPSVE_GetSpeakerVolume(ulevel) == -1) {
    LOG_GIPSERR1(GetSpeakerVolume, level);
    return false;
  }
  *level = ulevel;
  return true;
}

bool GipsVoiceEngine::SetOutputVolume(int level) {
  ASSERT(level >= 0 && level <= 255);
  if (gips_->volume()->GIPSVE_SetSpeakerVolume(level) == -1) {
    LOG_GIPSERR1(SetSpeakerVolume, level);
    return false;
  }
  return true;
}

int GipsVoiceEngine::GetInputLevel() {
  unsigned int ulevel;
  return (gips_->volume()->GIPSVE_GetSpeechInputLevel(ulevel) != -1) ?
      static_cast<int>(ulevel) : -1;
}

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

bool GipsVoiceEngine::ChangeLocalMonitor(bool enable) {
  if (enable && !monitor_.get()) {
    monitor_.reset(new GipsMonitorStream);
    if (gips_->file()->GIPSVE_StartRecordingMicrophone(monitor_.get()) == -1) {
      LOG_GIPSERR1(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.
      gips_->file()->GIPSVE_StopRecordingMicrophone();
      monitor_.reset();
      return false;
    }
  } else if (!enable && monitor_.get()) {
    gips_->file()->GIPSVE_StopRecordingMicrophone();
    monitor_.reset();
  }
  return true;
}

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

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

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

bool GipsVoiceEngine::FindCodec(const AudioCodec& in) {
  return FindGIPSCodec(in, NULL);
}

bool GipsVoiceEngine::FindGIPSCodec(const AudioCodec& in,
                                    GIPS_CodecInst* out) {
  int ncodecs = gips_->codec()->GIPSVE_NumOfCodecs();
  for (int i = 0; i < ncodecs; ++i) {
    GIPS_CodecInst gcodec;
    if (gips_->codec()->GIPSVE_GetCodec(i, gcodec) >= 0) {
      AudioCodec codec(gcodec.pltype, gcodec.plname,
                       gcodec.plfreq, gcodec.rate, gcodec.channels, 0);
      if (codec.Matches(in)) {
        if (out) {
          // If the codec is VBR and an explicit rate is specified, use it.
          if (in.bitrate != 0 && gcodec.rate == -1) {
            gcodec.rate = in.bitrate;
          }
          *out = gcodec;
        }
        return true;
      }
    }
  }
  return false;
}

void GipsVoiceEngine::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 GipsVoiceEngine::GetLastGipsError() {
  return gips_->error();
}

// We suppport three different logging settings for GIPS:
// 1. Observer callback that goes into talk diagnostic logfile.
//    Use --logfile and --loglevel
//
// 2. Encrypted GIPS 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 GipsVoiceEngine::ApplyLogging(const std::string& log_filter) {
  // Set log level.
  int filter = 0;
  switch (log_level_) {
    case talk_base::LS_VERBOSE:
      filter |= GIPS::TR_ALL;      // fall through
    case talk_base::LS_INFO:
      filter |= GIPS::TR_STATE_INFO;  // fall through
    case talk_base::LS_WARNING:
      filter |= (GIPS::TR_INFO | GIPS::TR_WARNING);  // fall through
    case talk_base::LS_ERROR:
      filter |= (GIPS::TR_ERROR | GIPS::TR_CRITICAL);
  }
  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
    if (tracing_->SetEncryptedTraceFile(tracefile->c_str()) == -1) {
      LOG_GIPSERR1(SetEncryptedTraceFileName, *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 (gips_->vqe()->GIPSVE_StartDebugRecording(recordEC->c_str()) == -1) {
        LOG_GIPSERR0(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 (gips_->vqe()->GIPSVE_StopDebugRecording() == -1) {
        LOG_GIPSERR0(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.
static bool ShouldIgnoreTrace(const std::string& trace) {
  static const char* kTracesToIgnore[] = {
    "\tfailed to GetReportBlockInformation",
    "GetRecCodec() failed to get received codec",
    "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",
    "RTCPReceiver::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 GipsVoiceEngine::Print(const GIPS::TraceLevel level,
                            const char* trace, const int length) {
  talk_base::LoggingSeverity sev = talk_base::LS_VERBOSE;
  if (level == GIPS::TR_ERROR || level == GIPS::TR_CRITICAL)
    sev = talk_base::LS_ERROR;
  else if (level == GIPS::TR_WARNING)
    sev = talk_base::LS_WARNING;
  else if (level == GIPS::TR_STATE_INFO || level == GIPS::TR_INFO)
    sev = talk_base::LS_INFO;

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

void GipsVoiceEngine::CallbackOnError(const int channel_num,
                                      const int err_code) {
  talk_base::CritScope lock(&channels_cs_);
  GipsVoiceMediaChannel* channel = NULL;
  uint32 ssrc = 0;
  LOG(LS_WARNING) << "GIPS 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) << "GIPS channel " << channel_num
        << " could not be found in the channel list when error reported.";
  }
}

int GipsVoiceEngine::GetCodecPreference(const char *name, int clockrate) {
  for (size_t i = 0; i < ARRAY_SIZE(kCodecPrefs); ++i) {
    if ((_stricmp(kCodecPrefs[i].name, name) == 0) &&
        (kCodecPrefs[i].clockrate == clockrate))
      return ARRAY_SIZE(kCodecPrefs) - i;
  }
  LOG(LS_WARNING) << "Unexpected codec \"" << name << "/" << clockrate << "\"";
  return -1;
}

bool GipsVoiceEngine::FindChannelAndSsrc(
    int channel_num, GipsVoiceMediaChannel** 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;
}

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

void GipsVoiceEngine::UnregisterChannel(GipsVoiceMediaChannel *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 GipsVoiceEngine::RegisterSoundclip(GipsSoundclipMedia *soundclip) {
  soundclips_.push_back(soundclip);
}

void GipsVoiceEngine::UnregisterSoundclip(GipsSoundclipMedia *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 GIPS_AGC_config as well.
bool GipsVoiceEngine::AdjustAgcLevel(int delta) {
  GIPS_AGC_config 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 (gips_->vqe()->GIPSVE_SetAGCConfig(config) == -1) {
    LOG_GIPSERR1(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 GipsVoiceEngine::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 GIPS_NSModes ns_mode = enable ? GIPS_NS_CONFERENCE : GIPS_NS_DEFAULT;
  if (gips_->vqe()->GIPSVE_SetNSStatus(true, ns_mode) == -1) {
    LOG_GIPSERR2(SetNSStatus, true, ns_mode);
    return false;
  }

  // Echo-cancellation is a user-option, so preserve the enable state and
  // just toggle the mode.
  bool aec;
  GIPS_ECModes ec_mode;
  GIPS_AESModes aes_mode;
  int aes_attn;
  if (gips_->vqe()->GIPSVE_GetECStatus(aec, ec_mode,
                                       aes_mode, aes_attn) == -1) {
    LOG_GIPSERR0(GetECStatus);
    return false;
  }
  ec_mode = enable ? GIPS_EC_CONFERENCE : GIPS_EC_DEFAULT;
  if (gips_->vqe()->GIPSVE_SetECStatus(aec, ec_mode) == -1) {
    LOG_GIPSERR2(GetECStatus, aec, ec_mode);
    return false;
  }
  return true;
}

// GipsVoiceMediaChannel
GipsVoiceMediaChannel::GipsVoiceMediaChannel(GipsVoiceEngine *engine)
    : GipsMediaChannel<VoiceMediaChannel, GipsVoiceEngine>(
          engine,
          engine->gips()->base()->GIPSVE_CreateChannel()),
      channel_options_(0),
      agc_adjusted_(false),
      dtmf_allowed_(false),
      desired_playout_(false),
      playout_(false),
      desired_send_(SEND_NOTHING),
      send_(SEND_NOTHING) {
  engine->RegisterChannel(this);
  LOG(LS_VERBOSE) << "GipsVoiceMediaChannel::GipsVoiceMediaChannel "
                  << gips_channel();

  // Register external transport
  if (engine->gips()->network()->GIPSVE_RegisterExternalTransport(
      gips_channel(), *static_cast<GIPS_transport*>(this)) == -1) {
    LOG_GIPSERR2(RegisterExternalTransport, gips_channel(), this);
  }

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

  // Create a random but nonzero send SSRC
  SetSendSsrc(talk_base::CreateRandomNonZeroId());

#if defined(IOS) || defined(ANDROID)
  // Turn on and configure receiving-end auto gain control
  if (engine->gips()->vqe()->GIPSVE_SetRxAGCStatus(
      gips_channel(), true, GIPS_AGC_FIXED_DIGITAL) != 0) {
    LOG(LS_ERROR) << "Failed to set Rx AGC status";
  }

  // These settings were found to work well on mobile.
  GIPS_AGC_config config;
  config.targetLeveldBOv = 6;
  config.digitalCompressionGaindB = 0;
  config.limiterEnable = true;

  if (engine->gips()->vqe()->GIPSVE_SetRxAGCConfig(gips_channel(),
                                                   config) != 0) {
    LOG(LS_ERROR) << "Failed to set Rx AGC config for channel "
                  << gips_channel();
  }
#endif  // IOS || ANDROID
}

GipsVoiceMediaChannel::~GipsVoiceMediaChannel() {
  LOG(LS_VERBOSE) << "GipsVoiceMediaChannel::~GipsVoiceMediaChannel "
                  << gips_channel();

  // DeRegister external transport
  if (engine()->gips()->network()->GIPSVE_DeRegisterExternalTransport(
      gips_channel()) == -1) {
    LOG_GIPSERR1(DeRegisterExternalTransport, gips_channel());
  }

  // Unregister ourselves from the engine.
  engine()->UnregisterChannel(this);
  // Remove any remaining streams.
  while (!mux_channels_.empty()) {
    RemoveStream(mux_channels_.begin()->first);
  }
  // Delete the primary channel.
  if (engine()->gips()->base()->GIPSVE_DeleteChannel(gips_channel()) == -1) {
    LOG_GIPSERR1(DeleteChannel, gips_channel());
  }
}

bool GipsVoiceMediaChannel::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 GipsVoiceMediaChannel::SetRecvCodecs(
    const std::vector<AudioCodec>& codecs) {
  // Update our receive payload types to match what we offered. This only is
  // an issue when a different entity (i.e. a server) is generating the offer
  // for us.
  bool ret = true;
  for (std::vector<AudioCodec>::const_iterator i = codecs.begin();
       i != codecs.end() && ret; ++i) {
    GIPS_CodecInst gcodec;
    if (engine()->FindGIPSCodec(*i, &gcodec)) {
      if (gcodec.pltype != i->id) {
        LOG(LS_INFO) << "Updating payload type for " << gcodec.plname
                     << " from " << gcodec.pltype << " to " << i->id;
        gcodec.pltype = i->id;
        if (engine()->gips()->codec()->GIPSVE_SetRecPayloadType(
            gips_channel(), gcodec) == -1) {
          LOG_GIPSERR1(SetRecPayloadType, gips_channel());
          ret = false;
        }
      }
    } else {
      LOG(LS_WARNING) << "Unknown codec " << i->name;
      ret = false;
    }
  }

  return ret;
}

bool GipsVoiceMediaChannel::SetSendCodecs(
    const std::vector<AudioCodec>& codecs) {
  // Disable DTMF, VAD, and FEC unless we know the other side wants them.
  dtmf_allowed_ = false;
  engine()->gips()->codec()->GIPSVE_SetVADStatus(gips_channel(), false);
  engine()->gips()->rtp()->GIPSVE_SetFECStatus(gips_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;
  GIPS_CodecInst send_codec;
  memset(&send_codec, 0, sizeof(send_codec));

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

    // Find the DTMF telephone event "codec" and tell gips about it.
    if (_stricmp(i->name.c_str(), "telephone-event") == 0 ||
        _stricmp(i->name.c_str(), "audio/telephone-event") == 0) {
      engine()->gips()->dtmf()->GIPSVE_SetSendTelephoneEventPayloadType(
          gips_channel(), i->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(i->name.c_str(), "CN") == 0) {
      GIPS_PayloadFrequencies cn_freq;
      switch (i->clockrate) {
        case 8000:
          cn_freq = GIPS_FREQ_8000_HZ;
          break;
        case 16000:
          cn_freq = GIPS_FREQ_16000_HZ;
          break;
        case 32000:
          cn_freq = GIPS_FREQ_32000_HZ;
          break;
        default:
          LOG(LS_WARNING) << "CN frequency " << i->clockrate
                          << " not supported.";
          continue;
      }
      engine()->gips()->codec()->GIPSVE_SetVADStatus(gips_channel(), true);
      if (cn_freq != GIPS_FREQ_8000_HZ) {
        engine()->gips()->codec()->GIPSVE_SetSendCNPayloadType(gips_channel(),
                                                               i->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(i->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(*i, codecs, &send_codec)) {
          continue;
        }

        // Enable redundant encoding of the specified codec. Treat any
        // failure as a fatal internal error.
        LOG(LS_INFO) << "Enabling RED";
        if (engine()->gips()->rtp()->GIPSVE_SetFECStatus(gips_channel(),
                                                         true, i->id) == -1) {
          LOG_GIPSERR3(SetFECStatus, gips_channel(), true, i->id);
          return false;
        }
      } else {
        send_codec = gcodec;
        send_codec.pltype = i->id;
      }
      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()->FindGIPSCodec(codec, &send_codec);
  }

  // Set the codec.
  LOG(LS_INFO) << "Selected voice codec " << send_codec.plname
               << "/" << send_codec.plfreq;
  if (engine()->gips()->codec()->GIPSVE_SetSendCodec(gips_channel(),
                                                     send_codec) == -1) {
    LOG_GIPSERR1(SetSendCodec, gips_channel());
    return false;
  }

  return true;
}

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

bool GipsVoiceMediaChannel::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 Bruno since GIPS VoE 3.0 upgrade
// (Change-Id: I26616ca99ccce8f63622c7b1b588886987067384)
//
// This api call is not available in iOS version of gips currently.
#if !defined(IOS) && !defined(ANDROID) && !defined(BRUNO)
  if (engine()->gips()->rtp()->GIPSVE_SetRTPAudioLevelIndicationStatus(
      gips_channel(), enable, id) == -1) {
    LOG_GIPSERR3(SetRTPAudioLevelIndicationStatus, gips_channel(), enable, id);
    return false;
  }
#endif

  return true;
}

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

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

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

bool GipsVoiceMediaChannel::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(gips_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 GipsVoiceMediaChannel::SetSend(SendFlags send) {
  desired_send_ = send;
  return ChangeSend(desired_send_);
}

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

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

bool GipsVoiceMediaChannel::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_GIPSERR1(SetConferenceMode, gips_channel());
      return false;
    }
#else
    // Multi-point conferences use conference-mode noise filtering.
    if (!engine()->SetConferenceMode(
        0 != (channel_options_ & OPT_CONFERENCE))) {
      LOG_GIPSERR1(SetConferenceMode, gips_channel());
      return false;
    }
#endif  // CHROMEOS

    // Tandberg-bridged conferences have an AGC target that is lower than
    // GTV-only levels.
    /* :BRUNO: disable this since this is built for tandberg */
#ifndef BRUNO
    if ((channel_options_ & OPT_AGC_TANDBERG_LEVELS) && !agc_adjusted_) {
      if (engine()->AdjustAgcLevel(kTandbergDbAdjustment)) {
        agc_adjusted_ = true;
      }
    }
#endif

    // GIPS 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) << "GipsVoiceMediaChannel restores seqnum="
                   << sequence_number() + 1;
      if (engine()->gips()->sync()->GIPSVE_SetInitSequenceNumber(
              gips_channel(), sequence_number() + 1) == -1) {
        LOG_GIPSERR2(SetInitSequenceNumber, gips_channel(),
                     sequence_number() + 1);
      }
    }
    if (engine()->gips()->base()->GIPSVE_StartSend(gips_channel()) == -1) {
      LOG_GIPSERR1(StartSend, gips_channel());
      return false;
    }
    if (engine()->gips()->file()->GIPSVE_StopPlayingFileAsMicrophone(
        gips_channel()) == -1) {
      LOG_GIPSERR1(StopPlayingFileAsMicrophone, gips_channel());
      return false;
    }
  } else if (send == SEND_RINGBACKTONE) {
    ASSERT(ringback_tone_.get() != NULL);
    if (!ringback_tone_.get()) {
      return false;
    }
    if (engine()->gips()->file()->GIPSVE_StartPlayingFileAsMicrophone(
        gips_channel(), ringback_tone_.get(), false) == -1) {
      LOG_GIPSERR3(StartPlayingFileAsMicrophone, gips_channel(),
                   ringback_tone_.get(), false);
      return false;
    }
    // GIPS 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) << "GipsVoiceMediaChannel restores seqnum="
                   << sequence_number() + 1;
      if (engine()->gips()->sync()->GIPSVE_SetInitSequenceNumber(
              gips_channel(), sequence_number() + 1) == -1) {
        LOG_GIPSERR2(SetInitSequenceNumber, gips_channel(),
                     sequence_number() + 1);
      }
    }
    if (engine()->gips()->base()->GIPSVE_StartSend(gips_channel()) == -1) {
      LOG_GIPSERR1(StartSend, gips_channel());
      return false;
    }
  } else {  // SEND_NOTHING
    if (engine()->gips()->base()->GIPSVE_StopSend(gips_channel()) == -1) {
      LOG_GIPSERR1(StopSend, gips_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_GIPSERR1(SetConferenceMode, gips_channel());
    }
  }
  send_ = send;
  return true;
}

bool GipsVoiceMediaChannel::AddStream(uint32 ssrc) {
  talk_base::CritScope lock(&mux_channels_cs_);

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

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

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

  // Use the same SSRC as our default channel (so the RTCP reports are correct).
  unsigned int send_ssrc;
  GIPSVERTP_RTCP* rtp = engine()->gips()->rtp();
  if (rtp->GIPSVE_GetLocalSSRC(gips_channel(), send_ssrc) == -1) {
    LOG_GIPSERR2(GetSendSSRC, channel, send_ssrc);
    return false;
  }
  if (rtp->GIPSVE_SetLocalSSRC(channel, send_ssrc) == -1) {
    LOG_GIPSERR2(SetSendSSRC, channel, send_ssrc);
    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(gips_channel(), false);
  }

  mux_channels_[ssrc] = channel;

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

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

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

    LOG(LS_INFO) << "Removing audio stream " << ssrc << " with channel "
                 << it->second << ".";
    if (engine()->gips()->base()->GIPSVE_DeleteChannel(it->second) == -1) {
      LOG_GIPSERR1(DeleteChannel, gips_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(oja): Does the default channel still have it's CN state?
      LOG(LS_INFO) << "Enabling playback on the default voice channel";
      SetPlayout(gips_channel(), true);
    }
  }
  return true;
}

bool GipsVoiceMediaChannel::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 GipsVoiceMediaChannel::GetOutputLevel() {
  // return the highest output level of all streams
  int highest = GetOutputLevel(gips_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 GipsVoiceMediaChannel::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(gips_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 = GetChannel(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 set the
  // scaling and then set the 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()->gips()->volume()->GIPSVE_SetChannelOutputVolumeScaling(
        *it, scale)) {
      LOG_GIPSERR2(SetChannelOutputVolumeScaling, *it, scale);
      return false;
    }
    if (-1 == engine()->gips()->volume()->GIPSVE_SetOutputVolumePan(
        *it, static_cast<float>(left), static_cast<float>(right))) {
      LOG_GIPSERR3(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 GipsVoiceMediaChannel::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) ? gips_channel() : GetChannel(ssrc);
  if (channel == -1) {
    LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
    return false;
  }

  float scaling;
  if (-1 == engine()->gips()->volume()->GIPSVE_GetChannelOutputVolumeScaling(
      channel, scaling)) {
    LOG_GIPSERR2(GetChannelOutputVolumeScaling, channel, scaling);
    return false;
  }

  float left_pan;
  float right_pan;
  if (-1 == engine()->gips()->volume()->GIPSVE_GetOutputVolumePan(
      channel, left_pan, right_pan)) {
    LOG_GIPSERR3(GIPSVE_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 GipsVoiceMediaChannel::SetRingbackTone(const char *buf, int len) {
  ringback_tone_.reset(new GipsSoundclipStream(buf, len));
  return true;
}

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

  // Determine which GIPS channel to play on.
  int channel = (ssrc == 0) ? gips_channel() : GetChannel(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()->gips()->file()->GIPSVE_StartPlayingFileLocally(channel,
        ringback_tone_.get()) == -1) {
      LOG_GIPSERR2(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()->gips()->file()->GIPSVE_StopPlayingFileLocally(channel)
        == -1) {
      LOG_GIPSERR1(StopPlayingFileLocally, channel);
      return false;
    }
    LOG(LS_INFO) << "Stopped ringback on channel " << channel;
    ringback_channels_.erase(channel);
  }

  return true;
}

bool GipsVoiceMediaChannel::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()->gips()->dtmf()->GIPSVE_SetDTMFFeedbackStatus(playout) == -1) {
    LOG_GIPSERR2(SendDTMF, gips_channel(), playout);
    return false;
  }

  // Send DTMF using out-of-band DTMF. ("true", as 3rd arg)
  if (engine()->gips()->dtmf()->GIPSVE_SendTelephoneEvent(gips_channel(), event,
      true) == -1) {
    LOG_GIPSERR3(SendDTMF, gips_channel(), event, true);
    return false;
  }

  return true;
}

void GipsVoiceMediaChannel::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 = GetChannel(
      ParseSsrc(packet->data(), packet->length(), false));
  if (which_channel == -1) {
    which_channel = gips_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()->gips()->file()->GIPSVE_IsPlayingFileLocally(
        which_channel) == 1) {
      engine()->gips()->file()->GIPSVE_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()->gips()->network()->GIPSVE_ReceivedRTPPacket(which_channel,
                                                        packet->data(),
                                                        packet->length());
}

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

  engine()->gips()->network()->GIPSVE_ReceivedRTCPPacket(which_channel,
                                                         packet->data(),
                                                         packet->length());
}

void GipsVoiceMediaChannel::SetSendSsrc(uint32 ssrc) {
  if (engine()->gips()->rtp()->GIPSVE_SetLocalSSRC(gips_channel(), ssrc)
      == -1) {
     LOG_GIPSERR2(SetSendSSRC, gips_channel(), ssrc);
  }
}

bool GipsVoiceMediaChannel::SetRtcpCName(const std::string& cname) {
  if (engine()->gips()->rtp()->GIPSVE_SetRTCP_CNAME(gips_channel(),
                                                    cname.c_str()) == -1) {
     LOG_GIPSERR2(SetRTCP_CNAME, gips_channel(), cname);
     return false;
  }
  return true;
}

bool GipsVoiceMediaChannel::Mute(bool muted) {
  if (engine()->gips()->volume()->GIPSVE_SetInputMute(gips_channel(),
      muted) == -1) {
    LOG_GIPSERR2(SetInputMute, gips_channel(), muted);
    return false;
  }
  return true;
}

bool GipsVoiceMediaChannel::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(juberti): Remove this workaround.
  GIPS_CallStatistics cs;
  unsigned int ssrc;
  GIPS_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()->gips()->rtp()->GIPSVE_GetRTCPStatistics(
          gips_channel(), cs) == -1 ||
      engine()->gips()->rtp()->GIPSVE_GetLocalSSRC(
          gips_channel(), ssrc) == -1) {
    return false;
  }

  sinfo.ssrc = ssrc;
  sinfo.bytes_sent = cs.bytesSent;
  sinfo.packets_sent = cs.packetsSent;
  // RTT isn't known until a RTCP report is received. Until then, GIPS
  // 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()->gips()->rtp()->GIPSVE_GetRemoteRTCPData(gips_channel(),
          ntp_high, ntp_low, timestamp, ptimestamp, &jitter, &loss) != -1 &&
      engine()->gips()->codec()->GIPSVE_GetSendCodec(gips_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(juberti): 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()->gips()->volume()->
      GIPSVE_GetSpeechInputLevelFullRange(level) != -1) ? level : -1;
  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(gips_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()->gips()->rtp()->GIPSVE_GetRemoteSSRC(*it, ssrc) != -1 &&
        engine()->gips()->rtp()->GIPSVE_GetRTCPStatistics(*it, cs) != -1 &&
        engine()->gips()->codec()->GIPSVE_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.
      GIPS_NetworkStatistics ns;
      if (engine()->gips()->neteq() &&
          engine()->gips()->neteq()->GIPSVE_GetNetworkStatistics(
              *it, ns) != -1) {
        rinfo.jitter_buffer_ms = ns.currentBufferSize;
        rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize;
      }
      if (engine()->gips()->sync()) {
        engine()->gips()->sync()->GIPSVE_GetDelayEstimate(*it,
            rinfo.delay_estimate_ms);
      }

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

  return true;
}

void GipsVoiceMediaChannel::GetLastMediaError(
    uint32* ssrc, VoiceMediaChannel::Error* error) {
  ASSERT(ssrc != NULL);
  ASSERT(error != NULL);
  FindSsrc(gips_channel(), ssrc);
  *error = GipsErrorToChannelError(GetLastGipsError());
}

bool GipsVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) {
  talk_base::CritScope lock(&mux_channels_cs_);
  ASSERT(ssrc != NULL);
  if (channel_num == gips_channel()) {
    unsigned local_ssrc = 0;
    // This is a sending channel.
    if (engine()->gips()->rtp()->GIPSVE_GetLocalSSRC(
        channel_num, local_ssrc) != -1) {
      *ssrc = local_ssrc;
    }
    return true;
  } else if (channel_num == -1 && send_ != SEND_NOTHING) {
    // Sometimes the GIPS 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 GipsVoiceMediaChannel::OnError(uint32 ssrc, int error) {
  SignalMediaError(ssrc, GipsErrorToChannelError(error));
}

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

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

bool GipsVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
    const std::vector<AudioCodec>& all_codecs, GIPS_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
  // GIPSVE_SetSendCodec, with the desired payload type.
  if (codec != all_codecs.end() &&
    engine()->FindGIPSCodec(*codec, send_codec)) {
    send_codec->pltype = red_pt;
  } else {
    LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
    return false;
  }

  return true;
}

bool GipsVoiceMediaChannel::EnableRtcp(int channel) {
  if (engine()->gips()->rtp()->GIPSVE_SetRTCPStatus(channel, true) == -1) {
    LOG_GIPSERR2(SetRTCPStatus, gips_channel(), 1);
    return false;
  }
  // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what
  // what we want to do with them.
  // engine()->gips().GIPSVE_EnableVQMon(gips_channel(), true);
  // engine()->gips().GIPSVE_EnableRTCP_XR(gips_channel(), true);
  return true;
}

bool GipsVoiceMediaChannel::SetPlayout(int channel, bool playout) {
  if (playout) {
    LOG(LS_INFO) << "Starting playout for channel " << channel;
    if (engine()->gips()->base()->GIPSVE_StartPlayout(channel) == -1) {
      LOG_GIPSERR1(StartPlayout, channel);
      return false;
    }
  } else {
    LOG(LS_INFO) << "Stopping playout for channel " << channel;
    engine()->gips()->base()->GIPSVE_StopPlayout(channel);
  }
  return true;
}

uint32 GipsVoiceMediaChannel::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 GIPS error code into VoiceMediaChannel::Error enum.
VoiceMediaChannel::Error GipsVoiceMediaChannel::GipsErrorToChannelError(
    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 GipsSoundclipStream::Read(void *buf, int len) {
  size_t res = 0;
  mem_.Read(buf, len, &res, NULL);
  return res;
}

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

}  // namespace cricket

#endif  // HAVE_GIPS

// shhhhh}
