/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "audio_coding_module_impl.h"

#include <assert.h>
#include <stdlib.h>
#ifdef ACM_QA_TEST
#   include <stdio.h>
#endif

#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_dtmf_detection.h"
#include "acm_generic_codec.h"
#include "acm_resampler.h"
#include "critical_section_wrapper.h"
#include "engine_configurations.h"
#include "rw_lock_wrapper.h"
#include "trace.h"

namespace webrtc {

enum {
  kACMToneEnd = 999
};

// Maximum number of bytes in one packet (PCM16B, 20 ms packets, stereo).
enum {
  kMaxPacketSize = 2560
};

AudioCodingModuleImpl::AudioCodingModuleImpl(const WebRtc_Word32 id)
    : _packetizationCallback(NULL),
      _id(id),
      _lastTimestamp(0),
      _lastInTimestamp(0),
      _cng_nb_pltype(255),
      _cng_wb_pltype(255),
      _cng_swb_pltype(255),
      _cng_fb_pltype(255),
      _red_pltype(255),
      _vadEnabled(false),
      _dtxEnabled(false),
      _vadMode(VADNormal),
      _stereoReceiveRegistered(false),
      _stereoSend(false),
      _prev_received_channel(0),
      _expected_channels(1),
      _currentSendCodecIdx(-1),
      _current_receive_codec_idx(-1),
      _sendCodecRegistered(false),
      _acmCritSect(CriticalSectionWrapper::CreateCriticalSection()),
      _vadCallback(NULL),
      _lastRecvAudioCodecPlType(255),
      _isFirstRED(true),
      _fecEnabled(false),
      _fragmentation(NULL),
      _lastFECTimestamp(0),
      _receiveREDPayloadType(255),
      _previousPayloadType(255),
      _dummyRTPHeader(NULL),
      _recvPlFrameSizeSmpls(0),
      _receiverInitialized(false),
      _dtmfDetector(NULL),
      _dtmfCallback(NULL),
      _lastDetectedTone(kACMToneEnd),
      _callbackCritSect(CriticalSectionWrapper::CreateCriticalSection()) {
  _lastTimestamp = 0xD87F3F9F;
  _lastInTimestamp = 0xD87F3F9F;

  // Nullify send codec memory, set payload type and set codec name to
  // invalid values.
  memset(&_sendCodecInst, 0, sizeof(CodecInst));
  strncpy(_sendCodecInst.plname, "noCodecRegistered", 31);
  _sendCodecInst.pltype = -1;

  for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
    _codecs[i] = NULL;
    _registeredPlTypes[i] = -1;
    _stereoReceive[i] = false;
    _slaveCodecs[i] = NULL;
    _mirrorCodecIdx[i] = -1;
  }

  _netEq.SetUniqueId(_id);

  // Allocate memory for RED.
  _redBuffer = new WebRtc_UWord8[MAX_PAYLOAD_SIZE_BYTE];
  _fragmentation = new RTPFragmentationHeader;
  _fragmentation->fragmentationVectorSize = 2;
  _fragmentation->fragmentationOffset = new WebRtc_UWord32[2];
  _fragmentation->fragmentationLength = new WebRtc_UWord32[2];
  _fragmentation->fragmentationTimeDiff = new WebRtc_UWord16[2];
  _fragmentation->fragmentationPlType = new WebRtc_UWord8[2];

  // Register the default payload type for RED and for CNG for the three
  // frequencies 8, 16 and 32 kHz.
  for (int i = (ACMCodecDB::kNumCodecs - 1); i >= 0; i--) {
    if (IsCodecRED(i)) {
      _red_pltype = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
    } else if (IsCodecCN(i)) {
      if (ACMCodecDB::database_[i].plfreq == 8000) {
        _cng_nb_pltype = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
      } else if (ACMCodecDB::database_[i].plfreq == 16000) {
        _cng_wb_pltype = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
      } else if (ACMCodecDB::database_[i].plfreq == 32000) {
        _cng_swb_pltype = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
      } else if (ACMCodecDB::database_[i].plfreq == 48000) {
        _cng_fb_pltype = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
      }
    }
  }

  if (InitializeReceiverSafe() < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Cannot initialize reciever");
  }
#ifdef ACM_QA_TEST
  char file_name[500];
  sprintf(file_name, "ACM_QA_incomingPL_%03d_%d%d%d%d%d%d.dat", _id,
          rand() % 10, rand() % 10, rand() % 10, rand() % 10, rand() % 10,
          rand() % 10);
  _incomingPL = fopen(file_name, "wb");
  sprintf(file_name, "ACM_QA_outgoingPL_%03d_%d%d%d%d%d%d.dat", _id,
          rand() % 10, rand() % 10, rand() % 10, rand() % 10, rand() % 10,
          rand() % 10);
  _outgoingPL = fopen(file_name, "wb");
#endif

  WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceAudioCoding, id, "Created");
}

AudioCodingModuleImpl::~AudioCodingModuleImpl() {
  {
    CriticalSectionScoped lock(_acmCritSect);
    _currentSendCodecIdx = -1;

    for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
      if (_codecs[i] != NULL) {
        // True stereo codecs share the same memory for master and
        // slave, so slave codec need to be nullified here, since the
        // memory will be deleted.
        if (_slaveCodecs[i] == _codecs[i]) {
          _slaveCodecs[i] = NULL;
        }

        // Mirror index holds the address of the codec memory.
        assert(_mirrorCodecIdx[i] > -1);
        if (_codecs[_mirrorCodecIdx[i]] != NULL) {
          delete _codecs[_mirrorCodecIdx[i]];
          _codecs[_mirrorCodecIdx[i]] = NULL;
        }

        _codecs[i] = NULL;
      }

      if (_slaveCodecs[i] != NULL) {
        // Delete memory for stereo usage of mono codecs.
        assert(_mirrorCodecIdx[i] > -1);
        if (_slaveCodecs[_mirrorCodecIdx[i]] != NULL) {
          delete _slaveCodecs[_mirrorCodecIdx[i]];
          _slaveCodecs[_mirrorCodecIdx[i]] = NULL;
        }
        _slaveCodecs[i] = NULL;
      }
    }

    if (_dtmfDetector != NULL) {
      delete _dtmfDetector;
      _dtmfDetector = NULL;
    }
    if (_dummyRTPHeader != NULL) {
      delete _dummyRTPHeader;
      _dummyRTPHeader = NULL;
    }
    if (_redBuffer != NULL) {
      delete[] _redBuffer;
      _redBuffer = NULL;
    }
    if (_fragmentation != NULL) {
      // Only need to delete fragmentation header, it will clean
      // up it's own memory.
      delete _fragmentation;
      _fragmentation = NULL;
    }
  }

#ifdef ACM_QA_TEST
  if(_incomingPL != NULL) {
    fclose(_incomingPL);
  }

  if(_outgoingPL != NULL) {
    fclose(_outgoingPL);
  }
#endif

  delete _callbackCritSect;
  _callbackCritSect = NULL;

  delete _acmCritSect;
  _acmCritSect = NULL;
  WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceAudioCoding, _id,
               "Destroyed");
}

WebRtc_Word32 AudioCodingModuleImpl::ChangeUniqueId(const WebRtc_Word32 id) {
  {
    CriticalSectionScoped lock(_acmCritSect);
    _id = id;

#ifdef ACM_QA_TEST
    if (_incomingPL != NULL) {
      fclose (_incomingPL);
    }
    if (_outgoingPL != NULL) {
      fclose (_outgoingPL);
    }
    char fileName[500];
    sprintf(fileName, "ACM_QA_incomingPL_%03d_%d%d%d%d%d%d.dat", _id,
            rand() % 10, rand() % 10, rand() % 10, rand() % 10, rand() % 10,
            rand() % 10);
    _incomingPL = fopen(fileName, "wb");
    sprintf(fileName, "ACM_QA_outgoingPL_%03d_%d%d%d%d%d%d.dat", _id,
            rand() % 10, rand() % 10, rand() % 10, rand() % 10, rand() % 10,
            rand() % 10);
    _outgoingPL = fopen(fileName, "wb");
#endif

    for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
      if (_codecs[i] != NULL) {
        _codecs[i]->SetUniqueID(id);
      }
    }
  }

  _netEq.SetUniqueId(_id);
  return 0;
}

// Returns the number of milliseconds until the module want a
// worker thread to call Process.
WebRtc_Word32 AudioCodingModuleImpl::TimeUntilNextProcess() {
  CriticalSectionScoped lock(_acmCritSect);

  if (!HaveValidEncoder("TimeUntilNextProcess")) {
    return -1;
  }
  return _codecs[_currentSendCodecIdx]->SamplesLeftToEncode() /
      (_sendCodecInst.plfreq / 1000);
}

// Process any pending tasks such as timeouts.
WebRtc_Word32 AudioCodingModuleImpl::Process() {
  // Make room for 1 RED payload.
  WebRtc_UWord8 stream[2 * MAX_PAYLOAD_SIZE_BYTE];
  WebRtc_Word16 length_bytes = 2 * MAX_PAYLOAD_SIZE_BYTE;
  WebRtc_Word16 red_length_bytes = length_bytes;
  WebRtc_UWord32 rtp_timestamp;
  WebRtc_Word16 status;
  WebRtcACMEncodingType encoding_type;
  FrameType frame_type = kAudioFrameSpeech;
  WebRtc_UWord8 current_payload_type = 0;
  bool has_data_to_send = false;
  bool fec_active = false;

  // Keep the scope of the ACM critical section limited.
  {
    CriticalSectionScoped lock(_acmCritSect);
    if (!HaveValidEncoder("Process")) {
      return -1;
    }

    status = _codecs[_currentSendCodecIdx]->Encode(stream, &length_bytes,
                                                   &rtp_timestamp,
                                                   &encoding_type);
    if (status < 0) {
      // Encode failed.
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Process(): Encoding Failed");
      length_bytes = 0;
      return -1;
    } else if (status == 0) {
      // Not enough data.
      return 0;
    } else {
      switch (encoding_type) {
        case kNoEncoding: {
          current_payload_type = _previousPayloadType;
          frame_type = kFrameEmpty;
          length_bytes = 0;
          break;
        }
        case kActiveNormalEncoded:
        case kPassiveNormalEncoded: {
          current_payload_type = (WebRtc_UWord8) _sendCodecInst.pltype;
          frame_type = kAudioFrameSpeech;
          break;
        }
        case kPassiveDTXNB: {
          current_payload_type = _cng_nb_pltype;
          frame_type = kAudioFrameCN;
          _isFirstRED = true;
          break;
        }
        case kPassiveDTXWB: {
          current_payload_type = _cng_wb_pltype;
          frame_type = kAudioFrameCN;
          _isFirstRED = true;
          break;
        }
        case kPassiveDTXSWB: {
          current_payload_type = _cng_swb_pltype;
          frame_type = kAudioFrameCN;
          _isFirstRED = true;
          break;
        }
        case kPassiveDTXFB: {
          current_payload_type = _cng_fb_pltype;
          frame_type = kAudioFrameCN;
          _isFirstRED = true;
          break;
        }
      }
      has_data_to_send = true;
      _previousPayloadType = current_payload_type;

      // Redundancy encode is done here. The two bitstreams packetized into
      // one RTP packet and the fragmentation points are set.
      // Only apply RED on speech data.
      if ((_fecEnabled) &&
          ((encoding_type == kActiveNormalEncoded) ||
              (encoding_type == kPassiveNormalEncoded))) {
        // FEC is enabled within this scope.
        //
        // Note that, a special solution exists for iSAC since it is the only
        // codec for which getRedPayload has a non-empty implementation.
        //
        // Summary of the FEC scheme below (use iSAC as example):
        //
        //  1st (_firstRED is true) encoded iSAC frame (primary #1) =>
        //      - call getRedPayload() and store redundancy for packet #1 in
        //        second fragment of RED buffer (old data)
        //      - drop the primary iSAC frame
        //      - don't call SendData
        //  2nd (_firstRED is false) encoded iSAC frame (primary #2) =>
        //      - store primary #2 in 1st fragment of RED buffer and send the
        //        combined packet
        //      - the transmitted packet contains primary #2 (new) and
        //        reduncancy for packet #1 (old)
        //      - call getRedPayload() and store redundancy for packet #2 in
        //        second fragment of RED buffer
        //
        //  ...
        //
        //  Nth encoded iSAC frame (primary #N) =>
        //      - store primary #N in 1st fragment of RED buffer and send the
        //        combined packet
        //      - the transmitted packet contains primary #N (new) and
        //        reduncancy for packet #(N-1) (old)
        //      - call getRedPayload() and store redundancy for packet #N in
        //        second fragment of RED buffer
        //
        //  For all other codecs, getRedPayload does nothing and returns -1 =>
        //  redundant data is only a copy.
        //
        //  First combined packet contains : #2 (new) and #1 (old)
        //  Second combined packet contains: #3 (new) and #2 (old)
        //  Third combined packet contains : #4 (new) and #3 (old)
        //
        //  Hence, even if every second packet is dropped, perfect
        //  reconstruction is possible.
        fec_active = true;

        has_data_to_send = false;
        // Skip the following part for the first packet in a RED session.
        if (!_isFirstRED) {
          // Rearrange stream such that FEC packets are included.
          // Replace stream now that we have stored current stream.
          memcpy(stream + _fragmentation->fragmentationOffset[1], _redBuffer,
                 _fragmentation->fragmentationLength[1]);
          // Update the fragmentation time difference vector, in number of
          // timestamps.
          WebRtc_UWord16 time_since_last = WebRtc_UWord16(
              rtp_timestamp - _lastFECTimestamp);

          // Update fragmentation vectors.
          _fragmentation->fragmentationPlType[1] = _fragmentation
              ->fragmentationPlType[0];
          _fragmentation->fragmentationTimeDiff[1] = time_since_last;
          has_data_to_send = true;
        }

        // Insert new packet length.
        _fragmentation->fragmentationLength[0] = length_bytes;

        // Insert new packet payload type.
        _fragmentation->fragmentationPlType[0] = current_payload_type;
        _lastFECTimestamp = rtp_timestamp;

        // Can be modified by the GetRedPayload() call if iSAC is utilized.
        red_length_bytes = length_bytes;

        // A fragmentation header is provided => packetization according to
        // RFC 2198 (RTP Payload for Redundant Audio Data) will be used.
        // First fragment is the current data (new).
        // Second fragment is the previous data (old).
        length_bytes = static_cast<WebRtc_Word16>(
            _fragmentation->fragmentationLength[0] +
            _fragmentation->fragmentationLength[1]);

        // Get, and store, redundant data from the encoder based on the recently
        // encoded frame.
        // NOTE - only iSAC contains an implementation; all other codecs does
        // nothing and returns -1.
        if (_codecs[_currentSendCodecIdx]->GetRedPayload(
            _redBuffer,
            &red_length_bytes) == -1) {
          // The codec was not iSAC => use current encoder output as redundant
          // data instead (trivial FEC scheme).
          memcpy(_redBuffer, stream, red_length_bytes);
        }

        _isFirstRED = false;
        // Update payload type with RED payload type.
        current_payload_type = _red_pltype;
      }
    }
  }

  if (has_data_to_send) {
    CriticalSectionScoped lock(_callbackCritSect);
#ifdef ACM_QA_TEST
    if(_outgoingPL != NULL) {
      if (fwrite(&rtp_timestamp, sizeof(WebRtc_UWord32), 1, _outgoingPL) != 1) {
        return -1;
      }
      if (fwrite(&current_payload_type, sizeof(WebRtc_UWord8),
                 1, _outgoingPL) != 1) {
        return -1;
      }
      if (fwrite(&length_bytes, sizeof(WebRtc_Word16), 1, _outgoingPL) != 1) {
        return -1;
      }
    }
#endif

    if (_packetizationCallback != NULL) {
      if (fec_active) {
        // Callback with payload data, including redundant data (FEC/RED).
        _packetizationCallback->SendData(frame_type, current_payload_type,
                                         rtp_timestamp, stream, length_bytes,
                                         _fragmentation);
      } else {
        // Callback with payload data.
        _packetizationCallback->SendData(frame_type, current_payload_type,
                                         rtp_timestamp, stream, length_bytes,
                                         NULL);
      }
    }

    if (_vadCallback != NULL) {
      // Callback with VAD decision.
      _vadCallback->InFrameType(((WebRtc_Word16) encoding_type));
    }
  }
  if (fec_active) {
    // Store RED length in bytes.
    _fragmentation->fragmentationLength[1] = red_length_bytes;
  }
  return length_bytes;
}

/////////////////////////////////////////
//   Sender
//

// Initialize send codec.
WebRtc_Word32 AudioCodingModuleImpl::InitializeSender() {
  CriticalSectionScoped lock(_acmCritSect);

  // Start with invalid values.
  _sendCodecRegistered = false;
  _currentSendCodecIdx = -1;
  _sendCodecInst.plname[0] = '\0';

  // Delete all encoders to start fresh.
  for (int id = 0; id < ACMCodecDB::kMaxNumCodecs; id++) {
    if (_codecs[id] != NULL) {
      _codecs[id]->DestructEncoder();
    }
  }

  // Initialize FEC/RED.
  _isFirstRED = true;
  if (_fecEnabled) {
    if (_redBuffer != NULL) {
      memset(_redBuffer, 0, MAX_PAYLOAD_SIZE_BYTE);
    }
    if (_fragmentation != NULL) {
      _fragmentation->fragmentationVectorSize = 2;
      _fragmentation->fragmentationOffset[0] = 0;
      _fragmentation->fragmentationOffset[0] = MAX_PAYLOAD_SIZE_BYTE;
      memset(_fragmentation->fragmentationLength, 0,
             sizeof(WebRtc_UWord32) * 2);
      memset(_fragmentation->fragmentationTimeDiff, 0,
             sizeof(WebRtc_UWord16) * 2);
      memset(_fragmentation->fragmentationPlType, 0, sizeof(WebRtc_UWord8) * 2);
    }
  }

  return 0;
}

WebRtc_Word32 AudioCodingModuleImpl::ResetEncoder() {
  CriticalSectionScoped lock(_acmCritSect);
  if (!HaveValidEncoder("ResetEncoder")) {
    return -1;
  }
  return _codecs[_currentSendCodecIdx]->ResetEncoder();
}

void AudioCodingModuleImpl::UnregisterSendCodec() {
  CriticalSectionScoped lock(_acmCritSect);
  _sendCodecRegistered = false;
  _currentSendCodecIdx = -1;
  return;
}

ACMGenericCodec* AudioCodingModuleImpl::CreateCodec(const CodecInst& codec) {
  ACMGenericCodec* my_codec = NULL;

  my_codec = ACMCodecDB::CreateCodecInstance(&codec);
  if (my_codec == NULL) {
    // Error, could not create the codec.
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "ACMCodecDB::CreateCodecInstance() failed in CreateCodec()");
    return my_codec;
  }
  my_codec->SetUniqueID(_id);
  my_codec->SetNetEqDecodeLock(_netEq.DecodeLock());

  return my_codec;
}

// Can be called multiple times for Codec, CNG, RED.
WebRtc_Word32 AudioCodingModuleImpl::RegisterSendCodec(
    const CodecInst& send_codec) {
  if ((send_codec.channels != 1) && (send_codec.channels != 2)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Registering Send codec failed due to wrong number of "
                 "channels, %d. Only mono codecs are supported, i.e. "
                 "channels=1.", send_codec.channels);
    return -1;
  }

  char error_message[500];
  int mirror_id;
  int codec_id = ACMCodecDB::CodecNumber(&send_codec, &mirror_id, error_message,
                                        sizeof(error_message));
  CriticalSectionScoped lock(_acmCritSect);

  // Check for reported errors from function CodecNumber().
  if (codec_id < 0) {
    if (!_sendCodecRegistered) {
      // This values has to be NULL if there is no codec registered.
      _currentSendCodecIdx = -1;
    }
    // Failed to register Send Codec.
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 error_message);
    return -1;
  }

  // Telephone-event cannot be a send codec.
  if (!STR_CASE_CMP(send_codec.plname, "telephone-event")) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "telephone-event cannot be registered as send codec");
    return -1;
  }

  // RED can be registered with other payload type. If not registered a default
  // payload type is used.
  if (IsCodecRED(&send_codec)) {
    // TODO(tlegrand): Remove this check. Already taken care of in
    // ACMCodecDB::CodecNumber().
    // Check if the payload-type is valid
    if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Invalid payload-type %d for %s.", send_codec.pltype,
                   send_codec.plname);
      return -1;
    }
    // Set RED payload type.
    _red_pltype = static_cast<uint8_t>(send_codec.pltype);
    return 0;
  }

  // CNG can be registered with other payload type. If not registered the
  // default payload types from codec database will be used.
  if (IsCodecCN(&send_codec)) {
    // CNG is registered.
    switch (send_codec.plfreq) {
      case 8000: {
        _cng_nb_pltype = static_cast<uint8_t>(send_codec.pltype);
        break;
      }
      case 16000: {
        _cng_wb_pltype = static_cast<uint8_t>(send_codec.pltype);
        break;
      }
      case 32000: {
        _cng_swb_pltype = static_cast<uint8_t>(send_codec.pltype);
        break;
      }
      case 48000: {
        _cng_fb_pltype = static_cast<uint8_t>(send_codec.pltype);
        break;
      }
      default: {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "RegisterSendCodec() failed, invalid frequency for CNG "
                     "registration");
        return -1;
      }
    }

    return 0;
  }

  // TODO(tlegrand): Remove this check. Already taken care of in
  // ACMCodecDB::CodecNumber().
  // Check if the payload-type is valid
  if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Invalid payload-type %d for %s.", send_codec.pltype,
                 send_codec.plname);
    return -1;
  }

  // Check if codec supports the number of channels.
  if (ACMCodecDB::codec_settings_[codec_id].channel_support
      < send_codec.channels) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "%d number of channels not supportedn for %s.",
                 send_codec.channels, send_codec.plname);
    return -1;
  }

  // Set Stereo, and make sure VAD and DTX is turned off.
  if (send_codec.channels == 2) {
    _stereoSend = true;
    if (_vadEnabled || _dtxEnabled) {
      WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, _id,
                   "VAD/DTX is turned off, not supported when sending stereo.");
    }
    _vadEnabled = false;
    _dtxEnabled = false;
  } else {
    _stereoSend = false;
  }

  // Check if the codec is already registered as send codec.
  bool is_send_codec;
  if (_sendCodecRegistered) {
    int send_codec_mirror_id;
    int send_codec_id = ACMCodecDB::CodecNumber(&_sendCodecInst,
                                              &send_codec_mirror_id);
    assert(send_codec_id >= 0);
    is_send_codec = (send_codec_id == codec_id) ||
        (mirror_id == send_codec_mirror_id);
  } else {
    is_send_codec = false;
  }

  // If new codec, or new settings, register.
  if (!is_send_codec) {
    if (_codecs[mirror_id] == NULL) {

      _codecs[mirror_id] = CreateCodec(send_codec);
      if (_codecs[mirror_id] == NULL) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Cannot Create the codec");
        return -1;
      }
      _mirrorCodecIdx[mirror_id] = mirror_id;
    }

    if (mirror_id != codec_id) {
      _codecs[codec_id] = _codecs[mirror_id];
      _mirrorCodecIdx[codec_id] = mirror_id;
    }

    ACMGenericCodec* codec_ptr = _codecs[codec_id];
    WebRtc_Word16 status;
    WebRtcACMCodecParams codec_params;

    memcpy(&(codec_params.codecInstant), &send_codec, sizeof(CodecInst));
    codec_params.enableVAD = _vadEnabled;
    codec_params.enableDTX = _dtxEnabled;
    codec_params.vadMode = _vadMode;
    // Force initialization.
    status = codec_ptr->InitEncoder(&codec_params, true);

    // Check if VAD was turned on, or if error is reported.
    if (status == 1) {
      _vadEnabled = true;
    } else if (status < 0) {
      // Could not initialize the encoder.

      // Check if already have a registered codec.
      // Depending on that different messages are logged.
      if (!_sendCodecRegistered) {
        _currentSendCodecIdx = -1;
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Cannot Initialize the encoder No Encoder is registered");
      } else {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Cannot Initialize the encoder, continue encoding with "
                     "the previously registered codec");
      }
      return -1;
    }

    // Everything is fine so we can replace the previous codec with this one.
    if (_sendCodecRegistered) {
      // If we change codec we start fresh with FEC.
      // This is not strictly required by the standard.
      _isFirstRED = true;

      if (codec_ptr->SetVAD(_dtxEnabled, _vadEnabled, _vadMode) < 0) {
        // SetVAD failed.
        _vadEnabled = false;
        _dtxEnabled = false;
      }
    }

    _currentSendCodecIdx = codec_id;
    _sendCodecRegistered = true;
    memcpy(&_sendCodecInst, &send_codec, sizeof(CodecInst));
    _previousPayloadType = _sendCodecInst.pltype;
    return 0;
  } else {
    // If codec is the same as already registered check if any parameters
    // has changed compared to the current values.
    // If any parameter is valid then apply it and record.
    bool force_init = false;

    if (mirror_id != codec_id) {
      _codecs[codec_id] = _codecs[mirror_id];
      _mirrorCodecIdx[codec_id] = mirror_id;
    }

    // Check the payload type.
    if (send_codec.pltype != _sendCodecInst.pltype) {
      // At this point check if the given payload type is valid.
      // Record it later when the sampling frequency is changed
      // successfully.
      if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Out of range payload type");
        return -1;
      }
    }

    // If there is a codec that ONE instance of codec supports multiple
    // sampling frequencies, then we need to take care of it here.
    // one such a codec is iSAC. Both WB and SWB are encoded and decoded
    // with one iSAC instance. Therefore, we need to update the encoder
    // frequency if required.
    if (_sendCodecInst.plfreq != send_codec.plfreq) {
      force_init = true;

      // If sampling frequency is changed we have to start fresh with RED.
      _isFirstRED = true;
    }

    // If packet size or number of channels has changed, we need to
    // re-initialize the encoder.
    if (_sendCodecInst.pacsize != send_codec.pacsize) {
      force_init = true;
    }
    if (_sendCodecInst.channels != send_codec.channels) {
      force_init = true;
    }

    if (force_init) {
      WebRtcACMCodecParams codec_params;

      memcpy(&(codec_params.codecInstant), &send_codec, sizeof(CodecInst));
      codec_params.enableVAD = _vadEnabled;
      codec_params.enableDTX = _dtxEnabled;
      codec_params.vadMode = _vadMode;

      // Force initialization.
      if (_codecs[_currentSendCodecIdx]->InitEncoder(&codec_params, true) < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Could not change the codec packet-size.");
        return -1;
      }

      _sendCodecInst.plfreq = send_codec.plfreq;
      _sendCodecInst.pacsize = send_codec.pacsize;
      _sendCodecInst.channels = send_codec.channels;
    }

    // If the change of sampling frequency has been successful then
    // we store the payload-type.
    _sendCodecInst.pltype = send_codec.pltype;

    // Check if a change in Rate is required.
    if (send_codec.rate != _sendCodecInst.rate) {
      if (_codecs[codec_id]->SetBitRate(send_codec.rate) < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Could not change the codec rate.");
        return -1;
      }
      _sendCodecInst.rate = send_codec.rate;
    }
    _previousPayloadType = _sendCodecInst.pltype;

    return 0;
  }
}

// Get current send codec.
WebRtc_Word32 AudioCodingModuleImpl::SendCodec(
    CodecInst& current_codec) const {
  WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
               "SendCodec()");
  CriticalSectionScoped lock(_acmCritSect);

  if (!_sendCodecRegistered) {
    WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
                 "SendCodec Failed, no codec is registered");

    return -1;
  }
  WebRtcACMCodecParams encoder_param;
  _codecs[_currentSendCodecIdx]->EncoderParams(&encoder_param);
  encoder_param.codecInstant.pltype = _sendCodecInst.pltype;
  memcpy(&current_codec, &(encoder_param.codecInstant), sizeof(CodecInst));

  return 0;
}

// Get current send frequency.
WebRtc_Word32 AudioCodingModuleImpl::SendFrequency() const {
  WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
               "SendFrequency()");
  CriticalSectionScoped lock(_acmCritSect);

  if (!_sendCodecRegistered) {
    WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
                 "SendFrequency Failed, no codec is registered");

    return -1;
  }

  return _sendCodecInst.plfreq;
}

// Get encode bitrate.
// Adaptive rate codecs return their current encode target rate, while other
// codecs return there longterm avarage or their fixed rate.
WebRtc_Word32 AudioCodingModuleImpl::SendBitrate() const {
  CriticalSectionScoped lock(_acmCritSect);

  if (!_sendCodecRegistered) {
    WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
                 "SendBitrate Failed, no codec is registered");

    return -1;
  }

  WebRtcACMCodecParams encoder_param;
  _codecs[_currentSendCodecIdx]->EncoderParams(&encoder_param);

  return encoder_param.codecInstant.rate;
}

// Set available bandwidth, inform the encoder about the estimated bandwidth
// received from the remote party.
WebRtc_Word32 AudioCodingModuleImpl::SetReceivedEstimatedBandwidth(
    const WebRtc_Word32 bw) {
  return _codecs[_currentSendCodecIdx]->SetEstimatedBandwidth(bw);
}

// Register a transport callback which will be called to deliver
// the encoded buffers.
WebRtc_Word32 AudioCodingModuleImpl::RegisterTransportCallback(
    AudioPacketizationCallback* transport) {
  CriticalSectionScoped lock(_callbackCritSect);
  _packetizationCallback = transport;
  return 0;
}

// Used by the module to deliver messages to the codec module/application
// AVT(DTMF).
WebRtc_Word32 AudioCodingModuleImpl::RegisterIncomingMessagesCallback(
#ifndef WEBRTC_DTMF_DETECTION
    AudioCodingFeedback* /* incoming_message */,
    const ACMCountries /* cpt */) {
  return -1;
#else
    AudioCodingFeedback* incoming_message,
    const ACMCountries cpt) {
  WebRtc_Word16 status = 0;

  // Enter the critical section for callback.
  {
    CriticalSectionScoped lock(_callbackCritSect);
    _dtmfCallback = incoming_message;
  }
  // Enter the ACM critical section to set up the DTMF class.
  {
    CriticalSectionScoped lock(_acmCritSect);
    // Check if the call is to disable or enable the callback.
    if (incoming_message == NULL) {
      // Callback is disabled, delete DTMF-detector class.
      if (_dtmfDetector != NULL) {
        delete _dtmfDetector;
        _dtmfDetector = NULL;
      }
      status = 0;
    } else {
      status = 0;
      if (_dtmfDetector == NULL) {
        _dtmfDetector = new (ACMDTMFDetection);
        if (_dtmfDetector == NULL) {
          status = -1;
        }
      }
      if (status >= 0) {
        status = _dtmfDetector->Enable(cpt);
        if (status < 0) {
          // Failed to initialize if DTMF-detection was not enabled before,
          // delete the class, and set the callback to NULL and return -1.
          delete _dtmfDetector;
          _dtmfDetector = NULL;
        }
      }
    }
  }
  // Check if we failed in setting up the DTMF-detector class.
  if ((status < 0)) {
    // We failed, we cannot have the callback.
    CriticalSectionScoped lock(_callbackCritSect);
    _dtmfCallback = NULL;
  }

  return status;
#endif
}

// Add 10MS of raw (PCM) audio data to the encoder.
WebRtc_Word32 AudioCodingModuleImpl::Add10MsData(
    const AudioFrame& audio_frame) {
  // Do we have a codec registered?
  CriticalSectionScoped lock(_acmCritSect);
  if (!HaveValidEncoder("Add10MsData")) {
    return -1;
  }

  if (audio_frame.samples_per_channel_ == 0) {
    assert(false);
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Cannot Add 10 ms audio, payload length is zero");
    return -1;
  }
  // Allow for 8, 16, 32 and 48kHz input audio.
  if ((audio_frame.sample_rate_hz_ != 8000)
      && (audio_frame.sample_rate_hz_ != 16000)
      && (audio_frame.sample_rate_hz_ != 32000)
      && (audio_frame.sample_rate_hz_ != 48000)) {
    assert(false);
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Cannot Add 10 ms audio, input frequency not valid");
    return -1;
  }

  // If the length and frequency matches. We currently just support raw PCM.
  if ((audio_frame.sample_rate_hz_ / 100)
      != audio_frame.samples_per_channel_) {
    WEBRTC_TRACE(
        webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
        "Cannot Add 10 ms audio, input frequency and length doesn't match");
    return -1;
  }

  // Calculate the timestamp that should be pushed to codec.
  // This might be different from the timestamp of the frame
  // due to re-sampling.
  bool resample = ((WebRtc_Word32) audio_frame.sample_rate_hz_
      != _sendCodecInst.plfreq);

  // If number of channels in audio doesn't match codec mode, we need
  // either mono-to-stereo or stereo-to-mono conversion.
  WebRtc_Word16 audio[WEBRTC_10MS_PCM_AUDIO];
  int audio_channels = _sendCodecInst.channels;
  // TODO(andrew): reuse RemixAndResample here? The upmixing should be done
  // after resampling. (Would require moving it somewhere common).
  if (audio_frame.num_channels_ != audio_channels) {
    if (audio_channels == 2) {
      // Do mono-to-stereo conversion by copying each sample.
      for (int k = 0; k < audio_frame.samples_per_channel_; k++) {
        audio[k * 2] = audio_frame.data_[k];
        audio[(k * 2) + 1] = audio_frame.data_[k];
      }
    } else if (audio_channels == 1) {
      // Do stereo-to-mono conversion by creating the average of the stereo
      // samples.
      for (int k = 0; k < audio_frame.samples_per_channel_; k++) {
        audio[k] = (audio_frame.data_[k * 2]
            + audio_frame.data_[(k * 2) + 1]) >> 1;
      }
    }
  } else {
    // Copy payload data for future use.
    size_t length = static_cast<size_t>(audio_frame.samples_per_channel_
        * audio_channels);
    memcpy(audio, audio_frame.data_, length * sizeof(WebRtc_UWord16));
  }

  WebRtc_UWord32 current_timestamp;
  WebRtc_Word32 status;
  // If it is required, we have to do a resampling.
  if (resample) {
    WebRtc_Word16 resampled_audio[WEBRTC_10MS_PCM_AUDIO];
    WebRtc_Word32 send_freq = _sendCodecInst.plfreq;
    WebRtc_UWord32 timestamp_diff;
    WebRtc_Word16 new_length;

    // Calculate the timestamp of this frame.
    if (_lastInTimestamp > audio_frame.timestamp_) {
      // A wrap around has happened.
      timestamp_diff = ((WebRtc_UWord32) 0xFFFFFFFF - _lastInTimestamp)
          + audio_frame.timestamp_;
    } else {
      timestamp_diff = audio_frame.timestamp_ - _lastInTimestamp;
    }
    current_timestamp = _lastTimestamp + (WebRtc_UWord32)(timestamp_diff *
        ((double) _sendCodecInst.plfreq / (double) audio_frame.sample_rate_hz_));

    new_length = _inputResampler.Resample10Msec(audio,
                                                audio_frame.sample_rate_hz_,
                                                resampled_audio, send_freq,
                                                audio_channels);

    if (new_length < 0) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Cannot add 10 ms audio, resmapling failed");
      return -1;
    }
    status = _codecs[_currentSendCodecIdx]->Add10MsData(current_timestamp,
                                                        resampled_audio,
                                                        new_length,
                                                        audio_channels);
  } else {
    current_timestamp = audio_frame.timestamp_;

    status = _codecs[_currentSendCodecIdx]->Add10MsData(
        current_timestamp, audio, audio_frame.samples_per_channel_,
        audio_channels);
  }
  _lastInTimestamp = audio_frame.timestamp_;
  _lastTimestamp = current_timestamp;
  return status;
}

/////////////////////////////////////////
//   (FEC) Forward Error Correction
//

bool AudioCodingModuleImpl::FECStatus() const {
  CriticalSectionScoped lock(_acmCritSect);
  return _fecEnabled;
}

// Configure FEC status i.e on/off.
WebRtc_Word32
AudioCodingModuleImpl::SetFECStatus(
#ifdef WEBRTC_CODEC_RED
    const bool enable_fec) {
  CriticalSectionScoped lock(_acmCritSect);

  if (_fecEnabled != enable_fec) {
    // Reset the RED buffer.
    memset(_redBuffer, 0, MAX_PAYLOAD_SIZE_BYTE);

    // Reset fragmentation buffers.
    _fragmentation->fragmentationVectorSize = 2;
    _fragmentation->fragmentationOffset[0] = 0;
    _fragmentation->fragmentationOffset[1] = MAX_PAYLOAD_SIZE_BYTE;
    memset(_fragmentation->fragmentationLength, 0, sizeof(WebRtc_UWord32) * 2);
    memset(_fragmentation->fragmentationTimeDiff, 0,
           sizeof(WebRtc_UWord16) * 2);
    memset(_fragmentation->fragmentationPlType, 0, sizeof(WebRtc_UWord8) * 2);

    // Set _fecEnabled.
    _fecEnabled = enable_fec;
  }
  _isFirstRED = true;  // Make sure we restart FEC.
  return 0;
#else
    const bool /* enable_fec */) {
  _fecEnabled = false;
  WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, _id,
               "  WEBRTC_CODEC_RED is undefined => _fecEnabled = %d",
               _fecEnabled);
  return -1;
#endif
}

/////////////////////////////////////////
//   (VAD) Voice Activity Detection
//

WebRtc_Word32 AudioCodingModuleImpl::SetVAD(const bool enable_dtx,
                                            const bool enable_vad,
                                            const ACMVADMode mode) {
  CriticalSectionScoped lock(_acmCritSect);

  // Sanity check of the mode.
  if ((mode != VADNormal) && (mode != VADLowBitrate)
      && (mode != VADAggr) && (mode != VADVeryAggr)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Invalid VAD Mode %d, no change is made to VAD/DTX status",
                 (int) mode);
    return -1;
  }

  // Check that the send codec is mono. We don't support VAD/DTX for stereo
  // sending.
  if ((enable_dtx || enable_vad) && _stereoSend) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "VAD/DTX not supported for stereo sending");
    return -1;
  }

  // If a send codec is registered, set VAD/DTX for the codec.
  if (HaveValidEncoder("SetVAD")) {
    WebRtc_Word16 status = _codecs[_currentSendCodecIdx]->SetVAD(enable_dtx,
                                                                 enable_vad,
                                                                 mode);
    if (status == 1) {
      // Vad was enabled.
      _vadEnabled = true;
      _dtxEnabled = enable_dtx;
      _vadMode = mode;

      return 0;
    } else if (status < 0) {
      // SetVAD failed.
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "SetVAD failed");

      _vadEnabled = false;
      _dtxEnabled = false;

      return -1;
    }
  }

  _vadEnabled = enable_vad;
  _dtxEnabled = enable_dtx;
  _vadMode = mode;

  return 0;
}

// Get VAD/DTX settings.
WebRtc_Word32 AudioCodingModuleImpl::VAD(bool& dtx_enabled, bool& vad_enabled,
                                         ACMVADMode& mode) const {
  CriticalSectionScoped lock(_acmCritSect);

  dtx_enabled = _dtxEnabled;
  vad_enabled = _vadEnabled;
  mode = _vadMode;

  return 0;
}

/////////////////////////////////////////
//   Receiver
//

WebRtc_Word32 AudioCodingModuleImpl::InitializeReceiver() {
  CriticalSectionScoped lock(_acmCritSect);
  return InitializeReceiverSafe();
}

// Initialize receiver, resets codec database etc.
WebRtc_Word32 AudioCodingModuleImpl::InitializeReceiverSafe() {
  // If the receiver is already initialized then we want to destroy any
  // existing decoders. After a call to this function, we should have a clean
  // start-up.
  if (_receiverInitialized) {
    for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
      if (UnregisterReceiveCodecSafe(i) < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "InitializeReceiver() failed, Could not unregister codec");
        return -1;
      }
    }
  }
  if (_netEq.Init() != 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "InitializeReceiver() failed, Could not initialize NetEQ");
    return -1;
  }
  _netEq.SetUniqueId(_id);
  if (_netEq.AllocatePacketBuffer(ACMCodecDB::NetEQDecoders(),
                                  ACMCodecDB::kNumCodecs) != 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "NetEQ cannot allocatePacket Buffer");
    return -1;
  }

  // Register RED and CN.
  for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
    if (IsCodecRED(i) || IsCodecCN(i)) {
      if (RegisterRecCodecMSSafe(ACMCodecDB::database_[i], i, i,
                                 ACMNetEQ::masterJB) < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Cannot register master codec.");
        return -1;
      }
      _registeredPlTypes[i] = ACMCodecDB::database_[i].pltype;
    }
  }

  _receiverInitialized = true;
  return 0;
}

// Reset the decoder state.
WebRtc_Word32 AudioCodingModuleImpl::ResetDecoder() {
  CriticalSectionScoped lock(_acmCritSect);

  for (int id = 0; id < ACMCodecDB::kMaxNumCodecs; id++) {
    if ((_codecs[id] != NULL) && (_registeredPlTypes[id] != -1)) {
      if (_codecs[id]->ResetDecoder(_registeredPlTypes[id]) < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "ResetDecoder failed:");
        return -1;
      }
    }
  }
  return _netEq.FlushBuffers();
}

// Get current receive frequency.
WebRtc_Word32 AudioCodingModuleImpl::ReceiveFrequency() const {
  WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
               "ReceiveFrequency()");
  WebRtcACMCodecParams codec_params;

  CriticalSectionScoped lock(_acmCritSect);
  if (DecoderParamByPlType(_lastRecvAudioCodecPlType, codec_params) < 0) {
    return _netEq.CurrentSampFreqHz();
  } else if (codec_params.codecInstant.plfreq == 48000) {
    // TODO(tlegrand): Remove this option when we have full 48 kHz support.
    return 32000;
  } else {
    return codec_params.codecInstant.plfreq;
  }
}

// Get current playout frequency.
WebRtc_Word32 AudioCodingModuleImpl::PlayoutFrequency() const {
  WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
               "PlayoutFrequency()");

  CriticalSectionScoped lock(_acmCritSect);

  return _netEq.CurrentSampFreqHz();
}

// Register possible reveive codecs, can be called multiple times,
// for codecs, CNG (NB, WB and SWB), DTMF, RED.
WebRtc_Word32 AudioCodingModuleImpl::RegisterReceiveCodec(
    const CodecInst& receive_codec) {
  CriticalSectionScoped lock(_acmCritSect);

  if (receive_codec.channels > 2) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "More than 2 audio channel is not supported.");
    return -1;
  }

  int mirror_id;
  int codec_id = ACMCodecDB::ReceiverCodecNumber(&receive_codec, &mirror_id);

  if (codec_id < 0 || codec_id >= ACMCodecDB::kNumCodecs) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Wrong codec params to be registered as receive codec");
    return -1;
  }
  // Check if the payload-type is valid.
  if (!ACMCodecDB::ValidPayloadType(receive_codec.pltype)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Invalid payload-type %d for %s.", receive_codec.pltype,
                 receive_codec.plname);
    return -1;
  }

  if (!_receiverInitialized) {
    if (InitializeReceiverSafe() < 0) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Cannot initialize reciver, so failed registering a codec.");
      return -1;
    }
  }

  // If codec already registered, unregister. Except for CN where we only
  // unregister if payload type is changing.
  if ((_registeredPlTypes[codec_id] == receive_codec.pltype)
      && IsCodecCN(&receive_codec)) {
    // Codec already registered as receiver with this payload type. Nothing
    // to be done.
    return 0;
  } else if (_registeredPlTypes[codec_id] != -1) {
    if (UnregisterReceiveCodecSafe(codec_id) < 0) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Cannot register master codec.");
      return -1;
    }
  }

  if (RegisterRecCodecMSSafe(receive_codec, codec_id, mirror_id,
                             ACMNetEQ::masterJB) < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Cannot register master codec.");
    return -1;
  }

  // TODO(andrew): Refactor how the slave is initialized. Can we instead
  // always start up a slave and pre-register CN and RED? We should be able
  // to get rid of _stereoReceiveRegistered.
  // http://code.google.com/p/webrtc/issues/detail?id=453

  // Register stereo codecs with the slave, or, if we've had already seen a
  // stereo codec, register CN or RED as a special case.
  if (receive_codec.channels == 2 ||
      (_stereoReceiveRegistered && (IsCodecCN(&receive_codec) ||
          IsCodecRED(&receive_codec)))) {
    // TODO(andrew): refactor this block to combine with InitStereoSlave().

    if (!_stereoReceiveRegistered) {
      // This is the first time a stereo codec has been registered. Make
      // some stereo preparations.

      // Add a stereo slave.
      assert(_netEq.NumSlaves() == 0);
      if (_netEq.AddSlave(ACMCodecDB::NetEQDecoders(),
                          ACMCodecDB::kNumCodecs) < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Cannot add slave jitter buffer to NetEQ.");
        return -1;
      }

      // Register any existing CN or RED codecs with the slave and as stereo.
      for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
        if (_registeredPlTypes[i] != -1 && (IsCodecRED(i) || IsCodecCN(i))) {
          _stereoReceive[i] = true;

          CodecInst codec;
          memcpy(&codec, &ACMCodecDB::database_[i], sizeof(CodecInst));
          codec.pltype = _registeredPlTypes[i];
          if (RegisterRecCodecMSSafe(codec, i, i, ACMNetEQ::slaveJB) < 0) {
            WEBRTC_TRACE(kTraceError, kTraceAudioCoding, _id,
                         "Cannot register slave codec.");
            return -1;
          }
        }
      }
    }

    if (RegisterRecCodecMSSafe(receive_codec, codec_id, mirror_id,
                               ACMNetEQ::slaveJB) < 0) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Cannot register slave codec.");
      return -1;
    }

    if (!_stereoReceive[codec_id]
        && (_lastRecvAudioCodecPlType == receive_codec.pltype)) {
      // The last received payload type is the same as the current one, but
      // was marked as mono. Reset to avoid problems.
      _lastRecvAudioCodecPlType = -1;
    }

    _stereoReceive[codec_id] = true;
    _stereoReceiveRegistered = true;
  } else {
    _stereoReceive[codec_id] = false;
  }

  _registeredPlTypes[codec_id] = receive_codec.pltype;

  if (IsCodecRED(&receive_codec)) {
    _receiveREDPayloadType = receive_codec.pltype;
  }
  return 0;
}

WebRtc_Word32 AudioCodingModuleImpl::RegisterRecCodecMSSafe(
    const CodecInst& receive_codec, WebRtc_Word16 codec_id,
    WebRtc_Word16 mirror_id, ACMNetEQ::JB jitter_buffer) {
  ACMGenericCodec** codecs;
  if (jitter_buffer == ACMNetEQ::masterJB) {
    codecs = &_codecs[0];
  } else if (jitter_buffer == ACMNetEQ::slaveJB) {
    codecs = &_slaveCodecs[0];
    if (_codecs[codec_id]->IsTrueStereoCodec()) {
      // True stereo codecs need to use the same codec memory
      // for both master and slave.
      _slaveCodecs[mirror_id] = _codecs[mirror_id];
      _mirrorCodecIdx[mirror_id] = mirror_id;
    }
  } else {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "RegisterReceiveCodecMSSafe failed, jitter_buffer is neither "
                 "master or slave ");
    return -1;
  }

  if (codecs[mirror_id] == NULL) {
    codecs[mirror_id] = CreateCodec(receive_codec);
    if (codecs[mirror_id] == NULL) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "Cannot create codec to register as receive codec");
      return -1;
    }
    _mirrorCodecIdx[mirror_id] = mirror_id;
  }
  if (mirror_id != codec_id) {
    codecs[codec_id] = codecs[mirror_id];
    _mirrorCodecIdx[codec_id] = mirror_id;
  }

  codecs[codec_id]->SetIsMaster(jitter_buffer == ACMNetEQ::masterJB);

  WebRtc_Word16 status = 0;
  WebRtcACMCodecParams codec_params;
  memcpy(&(codec_params.codecInstant), &receive_codec, sizeof(CodecInst));
  codec_params.enableVAD = false;
  codec_params.enableDTX = false;
  codec_params.vadMode = VADNormal;
  if (!codecs[codec_id]->DecoderInitialized()) {
    // Force initialization.
    status = codecs[codec_id]->InitDecoder(&codec_params, true);
    if (status < 0) {
      // Could not initialize the decoder, we don't want to
      // continue if we could not initialize properly.
      WEBRTC_TRACE(
          webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
          "could not initialize the receive codec, codec not registered");

      return -1;
    }
  } else if (mirror_id != codec_id) {
    // Currently this only happens for iSAC.
    // We have to store the decoder parameters.
    codecs[codec_id]->SaveDecoderParam(&codec_params);
  }

  if (codecs[codec_id]->RegisterInNetEq(&_netEq, receive_codec) != 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Receive codec could not be registered in NetEQ");
      return -1;
  }
  // Guarantee that the same payload-type that is
  // registered in NetEQ is stored in the codec.
  codecs[codec_id]->SaveDecoderParam(&codec_params);

  return status;
}

// Get current received codec.
WebRtc_Word32 AudioCodingModuleImpl::ReceiveCodec(
    CodecInst& current_codec) const {
  WebRtcACMCodecParams decoderParam;
  CriticalSectionScoped lock(_acmCritSect);

  for (int id = 0; id < ACMCodecDB::kMaxNumCodecs; id++) {
    if (_codecs[id] != NULL) {
      if (_codecs[id]->DecoderInitialized()) {
        if (_codecs[id]->DecoderParams(&decoderParam,
                                       _lastRecvAudioCodecPlType)) {
          memcpy(&current_codec, &decoderParam.codecInstant, sizeof(CodecInst));
          return 0;
        }
      }
    }
  }

  // If we are here then we haven't found any codec. Set codec pltype to -1 to
  // indicate that the structure is invalid and return -1.
  current_codec.pltype = -1;
  return -1;
}

// Incoming packet from network parsed and ready for decode.
WebRtc_Word32 AudioCodingModuleImpl::IncomingPacket(
    const WebRtc_UWord8* incoming_payload,
    const WebRtc_Word32 payload_length,
    const WebRtcRTPHeader& rtp_info) {
  WebRtcRTPHeader rtp_header;

  memcpy(&rtp_header, &rtp_info, sizeof(WebRtcRTPHeader));

  if (payload_length < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "IncomingPacket() Error, payload-length cannot be negative");
    return -1;
  }
  {
    // Store the payload Type. This will be used to retrieve "received codec"
    // and "received frequency."
    CriticalSectionScoped lock(_acmCritSect);
#ifdef ACM_QA_TEST
    if(_incomingPL != NULL) {
      if (fwrite(&rtp_info.header.timestamp, sizeof(WebRtc_UWord32),
                 1, _incomingPL) != 1) {
        return -1;
      }
      if (fwrite(&rtp_info.header.payloadType, sizeof(WebRtc_UWord8),
                 1, _incomingPL) != 1) {
        return -1;
      }
      if (fwrite(&payload_length, sizeof(WebRtc_Word16),
                 1, _incomingPL) != 1) {
        return -1;
      }
    }
#endif

    WebRtc_UWord8 myPayloadType;

    // Check if this is an RED payload.
    if (rtp_info.header.payloadType == _receiveREDPayloadType) {
      // Get the primary payload-type.
      myPayloadType = incoming_payload[0] & 0x7F;
    } else {
      myPayloadType = rtp_info.header.payloadType;
    }

    // If payload is audio, check if received payload is different from
    // previous.
    if (!rtp_info.type.Audio.isCNG) {
      // This is Audio not CNG.

      if (myPayloadType != _lastRecvAudioCodecPlType) {
        // We detect a change in payload type. It is necessary for iSAC
        // we are going to use ONE iSAC instance for decoding both WB and
        // SWB payloads. If payload is changed there might be a need to reset
        // sampling rate of decoder. depending what we have received "now".
        for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
          if (_registeredPlTypes[i] == myPayloadType) {
            if (UpdateUponReceivingCodec(i) != 0)
              return -1;
            break;
          }
        }
      }
      _lastRecvAudioCodecPlType = myPayloadType;
    }
  }

  // Split the payload for stereo packets, so that first half of payload
  // vector holds left channel, and second half holds right channel.
  if (_expected_channels == 2) {
    if (!rtp_info.type.Audio.isCNG) {
      // Create a new vector for the payload, maximum payload size.
      WebRtc_Word32 length = payload_length;
      WebRtc_UWord8 payload[kMaxPacketSize];
      assert(payload_length <= kMaxPacketSize);
      memcpy(payload, incoming_payload, payload_length);
      _codecs[_current_receive_codec_idx]->SplitStereoPacket(payload, &length);
      rtp_header.type.Audio.channel = 2;
      // Insert packet into NetEQ.
      return _netEq.RecIn(payload, length, rtp_header);
    } else {
      // If we receive a CNG packet while expecting stereo, we ignore the packet
      // and continue. CNG is not supported for stereo.
      return 0;
    }
  } else {
    return _netEq.RecIn(incoming_payload, payload_length, rtp_header);
  }
}

int AudioCodingModuleImpl::UpdateUponReceivingCodec(int index) {
  if (_codecs[index] == NULL) {
    WEBRTC_TRACE(kTraceError, kTraceAudioCoding, _id,
        "IncomingPacket() error: payload type found but corresponding codec "
        "is NULL");
    return -1;
  }
  _codecs[index]->UpdateDecoderSampFreq(index);
  _netEq.SetReceivedStereo(_stereoReceive[index]);
  _current_receive_codec_idx = index;

  // If we have a change in the expected number of channels, flush packet
  // buffers in NetEQ.
  if ((_stereoReceive[index] && (_expected_channels == 1)) ||
      (!_stereoReceive[index] && (_expected_channels == 2))) {
    _netEq.FlushBuffers();
    _codecs[index]->ResetDecoder(_registeredPlTypes[index]);
  }

  if (_stereoReceive[index] && (_expected_channels == 1)) {
    // When switching from a mono to stereo codec reset the slave.
    if (InitStereoSlave() != 0)
      return -1;
  }

  // Store number of channels we expect to receive for the current payload type.
  if (_stereoReceive[index]) {
    _expected_channels = 2;
  } else {
    _expected_channels = 1;
  }

  // Reset previous received channel.
  _prev_received_channel = 0;
  return 0;
}

bool AudioCodingModuleImpl::IsCodecForSlave(int index) const {
  return (_registeredPlTypes[index] != -1 && _stereoReceive[index]);
}

bool AudioCodingModuleImpl::IsCodecRED(int index) const {
  return (IsCodecRED(&ACMCodecDB::database_[index]));
}

bool AudioCodingModuleImpl::IsCodecRED(const CodecInst* codec) const {
  return (STR_CASE_CMP(codec->plname, "RED") == 0);
}

bool AudioCodingModuleImpl::IsCodecCN(int index) const {
  return (IsCodecCN(&ACMCodecDB::database_[index]));
}

bool AudioCodingModuleImpl::IsCodecCN(const CodecInst* codec) const {
  return (STR_CASE_CMP(codec->plname, "CN") == 0);
}

int AudioCodingModuleImpl::InitStereoSlave() {
  _netEq.RemoveSlaves();

  if (_netEq.AddSlave(ACMCodecDB::NetEQDecoders(),
                      ACMCodecDB::kNumCodecs) < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Cannot add slave jitter buffer to NetEQ.");
    return -1;
  }

  // Register all needed codecs with slave.
  for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
    if (_codecs[i] != NULL && IsCodecForSlave(i)) {
      WebRtcACMCodecParams decoder_params;
      if (_codecs[i]->DecoderParams(&decoder_params, _registeredPlTypes[i])) {
        if (RegisterRecCodecMSSafe(decoder_params.codecInstant,
                                   i, ACMCodecDB::MirrorID(i),
                                   ACMNetEQ::slaveJB) < 0) {
            WEBRTC_TRACE(kTraceError, kTraceAudioCoding, _id,
                         "Cannot register slave codec.");
            return -1;
        }
      }
    }
  }
  return 0;
}

// Minimum playout delay (Used for lip-sync).
WebRtc_Word32 AudioCodingModuleImpl::SetMinimumPlayoutDelay(
    const WebRtc_Word32 time_ms) {
  if ((time_ms < 0) || (time_ms > 1000)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Delay must be in the range of 0-1000 milliseconds.");
    return -1;
  }
  return _netEq.SetExtraDelay(time_ms);
}

// Get Dtmf playout status.
bool AudioCodingModuleImpl::DtmfPlayoutStatus() const {
#ifndef WEBRTC_CODEC_AVT
  return false;
#else
  return _netEq.AVTPlayout();
#endif
}

// Configure Dtmf playout status i.e on/off playout the incoming outband
// Dtmf tone.
WebRtc_Word32 AudioCodingModuleImpl::SetDtmfPlayoutStatus(
#ifndef WEBRTC_CODEC_AVT
    const bool /* enable */) {
  WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, _id,
               "SetDtmfPlayoutStatus() failed: AVT is not supported.");
  return -1;
#else
    const bool enable) {
  return _netEq.SetAVTPlayout(enable);
#endif
}

// Estimate the Bandwidth based on the incoming stream, needed for one way
// audio where the RTCP send the BW estimate.
// This is also done in the RTP module.
WebRtc_Word32 AudioCodingModuleImpl::DecoderEstimatedBandwidth() const {
  CodecInst codec;
  WebRtc_Word16 codec_id = -1;
  int payloadtype_wb;
  int payloadtype_swb;

  // Get iSAC settings.
  for (int id = 0; id < ACMCodecDB::kNumCodecs; id++) {
    // Store codec settings for codec number "codeCntr" in the output struct.
    ACMCodecDB::Codec(id, &codec);

    if (!STR_CASE_CMP(codec.plname, "isac")) {
      codec_id = 1;
      payloadtype_wb = codec.pltype;

      ACMCodecDB::Codec(id + 1, &codec);
      payloadtype_swb = codec.pltype;

      break;
    }
  }

  if (codec_id < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "DecoderEstimatedBandwidth failed");
    return -1;
  }

  if ((_lastRecvAudioCodecPlType == payloadtype_wb) ||
      (_lastRecvAudioCodecPlType == payloadtype_swb)) {
    return _codecs[codec_id]->GetEstimatedBandwidth();
  } else {
    return -1;
  }
}

// Set playout mode for: voice, fax, or streaming.
WebRtc_Word32 AudioCodingModuleImpl::SetPlayoutMode(
    const AudioPlayoutMode mode) {
  if ((mode != voice) && (mode != fax) && (mode != streaming)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Invalid playout mode.");
    return -1;
  }
  return _netEq.SetPlayoutMode(mode);
}

// Get playout mode voice, fax.
AudioPlayoutMode AudioCodingModuleImpl::PlayoutMode() const {
  return _netEq.PlayoutMode();
}

// Get 10 milliseconds of raw audio data to play out.
// Automatic resample to the requested frequency.
WebRtc_Word32 AudioCodingModuleImpl::PlayoutData10Ms(
    const WebRtc_Word32 desired_freq_hz, AudioFrame& audio_frame) {
  bool stereo_mode;

  // RecOut always returns 10 ms.
  if (_netEq.RecOut(_audioFrame) != 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "PlayoutData failed, RecOut Failed");
    return -1;
  }

  audio_frame.num_channels_ = _audioFrame.num_channels_;
  audio_frame.vad_activity_ = _audioFrame.vad_activity_;
  audio_frame.speech_type_ = _audioFrame.speech_type_;

  stereo_mode = (_audioFrame.num_channels_ > 1);
  // For stereo playout:
  // Master and Slave samples are interleaved starting with Master.

  const WebRtc_UWord16 receive_freq =
      static_cast<WebRtc_UWord16>(_audioFrame.sample_rate_hz_);
  bool tone_detected = false;
  WebRtc_Word16 last_detected_tone;
  WebRtc_Word16 tone;

  // Limit the scope of ACM Critical section.
  {
    CriticalSectionScoped lock(_acmCritSect);

    if ((receive_freq != desired_freq_hz) && (desired_freq_hz != -1)) {
      // Resample payloadData.
      WebRtc_Word16 temp_len = _outputResampler.Resample10Msec(
          _audioFrame.data_, receive_freq, audio_frame.data_,
          desired_freq_hz, _audioFrame.num_channels_);

      if (temp_len < 0) {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "PlayoutData failed, resampler failed");
        return -1;
      }

      // Set the payload data length from the resampler.
      audio_frame.samples_per_channel_ = (WebRtc_UWord16) temp_len;
      // Set the sampling frequency.
      audio_frame.sample_rate_hz_ = desired_freq_hz;
    } else {
      memcpy(audio_frame.data_, _audioFrame.data_,
             _audioFrame.samples_per_channel_ * audio_frame.num_channels_
             * sizeof(WebRtc_Word16));
      // Set the payload length.
      audio_frame.samples_per_channel_ =
          _audioFrame.samples_per_channel_;
      // Set the sampling frequency.
      audio_frame.sample_rate_hz_ = receive_freq;
    }

    // Tone detection done for master channel.
    if (_dtmfDetector != NULL) {
      // Dtmf Detection.
      if (audio_frame.sample_rate_hz_ == 8000) {
        // Use audio_frame.data_ then Dtmf detector doesn't
        // need resampling.
        if (!stereo_mode) {
          _dtmfDetector->Detect(audio_frame.data_,
                                audio_frame.samples_per_channel_,
                                audio_frame.sample_rate_hz_, tone_detected,
                                tone);
        } else {
          // We are in 8 kHz so the master channel needs only 80 samples.
          WebRtc_Word16 master_channel[80];
          for (int n = 0; n < 80; n++) {
            master_channel[n] = audio_frame.data_[n << 1];
          }
          _dtmfDetector->Detect(master_channel,
                                audio_frame.samples_per_channel_,
                                audio_frame.sample_rate_hz_, tone_detected,
                                tone);
        }
      } else {
        // Do the detection on the audio that we got from NetEQ (_audioFrame).
        if (!stereo_mode) {
          _dtmfDetector->Detect(_audioFrame.data_,
                                _audioFrame.samples_per_channel_,
                                receive_freq, tone_detected, tone);
        } else {
          WebRtc_Word16 master_channel[WEBRTC_10MS_PCM_AUDIO];
          for (int n = 0; n < _audioFrame.samples_per_channel_; n++) {
            master_channel[n] = _audioFrame.data_[n << 1];
          }
          _dtmfDetector->Detect(master_channel,
                                _audioFrame.samples_per_channel_,
                                receive_freq, tone_detected, tone);
        }
      }
    }

    // We want to do this while we are in _acmCritSect.
    // (Doesn't really need to initialize the following
    // variable but Linux complains if we don't.)
    last_detected_tone = kACMToneEnd;
    if (tone_detected) {
      last_detected_tone = _lastDetectedTone;
      _lastDetectedTone = tone;
    }
  }

  if (tone_detected) {
    // We will deal with callback here, so enter callback critical section.
    CriticalSectionScoped lock(_callbackCritSect);

    if (_dtmfCallback != NULL) {
      if (tone != kACMToneEnd) {
        // just a tone
        _dtmfCallback->IncomingDtmf((WebRtc_UWord8) tone, false);
      } else if ((tone == kACMToneEnd) && (last_detected_tone != kACMToneEnd)) {
        // The tone is "END" and the previously detected tone is
        // not "END," so call fir an end.
        _dtmfCallback->IncomingDtmf((WebRtc_UWord8) last_detected_tone, true);
      }
    }
  }

  audio_frame.id_ = _id;
  audio_frame.energy_ = -1;
  audio_frame.timestamp_ = 0;

  return 0;
}

/////////////////////////////////////////
//   (CNG) Comfort Noise Generation
//   Generate comfort noise when receiving DTX packets
//

// Get VAD aggressiveness on the incoming stream
ACMVADMode AudioCodingModuleImpl::ReceiveVADMode() const {
  return _netEq.VADMode();
}

// Configure VAD aggressiveness on the incoming stream.
WebRtc_Word16 AudioCodingModuleImpl::SetReceiveVADMode(const ACMVADMode mode) {
  return _netEq.SetVADMode(mode);
}

/////////////////////////////////////////
//   Statistics
//

WebRtc_Word32 AudioCodingModuleImpl::NetworkStatistics(
    ACMNetworkStatistics& statistics) const {
  WebRtc_Word32 status;
  status = _netEq.NetworkStatistics(&statistics);
  return status;
}


void AudioCodingModuleImpl::DestructEncoderInst(void* inst) {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _id,
               "DestructEncoderInst()");
  if (!HaveValidEncoder("DestructEncoderInst")) {
    return;
  }

  _codecs[_currentSendCodecIdx]->DestructEncoderInst(inst);
}

WebRtc_Word16 AudioCodingModuleImpl::AudioBuffer(
    WebRtcACMAudioBuff& buffer) {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _id,
               "AudioBuffer()");
  if (!HaveValidEncoder("AudioBuffer")) {
    return -1;
  }
  buffer.lastInTimestamp = _lastInTimestamp;
  return _codecs[_currentSendCodecIdx]->AudioBuffer(buffer);
}

WebRtc_Word16 AudioCodingModuleImpl::SetAudioBuffer(
    WebRtcACMAudioBuff& buffer) {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _id,
               "SetAudioBuffer()");
  if (!HaveValidEncoder("SetAudioBuffer")) {
    return -1;
  }
  return _codecs[_currentSendCodecIdx]->SetAudioBuffer(buffer);
}

WebRtc_UWord32 AudioCodingModuleImpl::EarliestTimestamp() const {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _id,
               "EarliestTimestamp()");
  if (!HaveValidEncoder("EarliestTimestamp")) {
    return -1;
  }
  return _codecs[_currentSendCodecIdx]->EarliestTimestamp();
}

WebRtc_Word32 AudioCodingModuleImpl::RegisterVADCallback(
    ACMVADCallback* vad_callback) {
  WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _id,
               "RegisterVADCallback()");
  CriticalSectionScoped lock(_callbackCritSect);
  _vadCallback = vad_callback;
  return 0;
}

// TODO(tlegrand): Modify this function to work for stereo, and add tests.
WebRtc_Word32 AudioCodingModuleImpl::IncomingPayload(
    const WebRtc_UWord8* incoming_payload, const WebRtc_Word32 payload_length,
    const WebRtc_UWord8 payload_type, const WebRtc_UWord32 timestamp) {
  if (payload_length < 0) {
    // Log error in trace file.
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "IncomingPacket() Error, payload-length cannot be negative");
    return -1;
  }

  if (_dummyRTPHeader == NULL) {
    // This is the first time that we are using _dummyRTPHeader
    // so we have to create it.
    WebRtcACMCodecParams codec_params;
    _dummyRTPHeader = new WebRtcRTPHeader;
    if (_dummyRTPHeader == NULL) {
      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                   "IncomingPacket() Error, out of memory");
      return -1;
    }
    _dummyRTPHeader->header.payloadType = payload_type;
    // Don't matter in this case.
    _dummyRTPHeader->header.ssrc = 0;
    _dummyRTPHeader->header.markerBit = false;
    // Start with random numbers.
    _dummyRTPHeader->header.sequenceNumber = rand();
    _dummyRTPHeader->header.timestamp = (((WebRtc_UWord32) rand()) << 16)
        + (WebRtc_UWord32) rand();
    _dummyRTPHeader->type.Audio.channel = 1;

    if (DecoderParamByPlType(payload_type, codec_params) < 0) {
      // We didn't find a codec with the given payload.
      // Something is wrong we exit, but we delete _dummyRTPHeader
      // and set it to NULL to start clean next time.
      delete _dummyRTPHeader;
      _dummyRTPHeader = NULL;
      return -1;
    }
    _recvPlFrameSizeSmpls = codec_params.codecInstant.pacsize;
  }

  if (payload_type != _dummyRTPHeader->header.payloadType) {
    // Payload type has changed since the last time we might need to
    // update the frame-size.
    WebRtcACMCodecParams codec_params;
    if (DecoderParamByPlType(payload_type, codec_params) < 0) {
      // We didn't find a codec with the given payload.
      return -1;
    }
    _recvPlFrameSizeSmpls = codec_params.codecInstant.pacsize;
    _dummyRTPHeader->header.payloadType = payload_type;
  }

  if (timestamp > 0) {
    _dummyRTPHeader->header.timestamp = timestamp;
  }

  // Store the payload Type. this will be used to retrieve "received codec"
  // and "received frequency."
  _lastRecvAudioCodecPlType = payload_type;

  // Insert in NetEQ.
  if (_netEq.RecIn(incoming_payload, payload_length, (*_dummyRTPHeader)) < 0) {
    return -1;
  }

  // Get ready for the next payload.
  _dummyRTPHeader->header.sequenceNumber++;
  _dummyRTPHeader->header.timestamp += _recvPlFrameSizeSmpls;
  return 0;
}

WebRtc_Word16 AudioCodingModuleImpl::DecoderParamByPlType(
    const WebRtc_UWord8 payload_type,
    WebRtcACMCodecParams& codec_params) const {
  CriticalSectionScoped lock(_acmCritSect);
  for (WebRtc_Word16 id = 0; id < ACMCodecDB::kMaxNumCodecs;
      id++) {
    if (_codecs[id] != NULL) {
      if (_codecs[id]->DecoderInitialized()) {
        if (_codecs[id]->DecoderParams(&codec_params, payload_type)) {
          return 0;
        }
      }
    }
  }
  // If we are here it means that we could not find a
  // codec with that payload type. reset the values to
  // not acceptable values and return -1.
  codec_params.codecInstant.plname[0] = '\0';
  codec_params.codecInstant.pacsize = 0;
  codec_params.codecInstant.rate = 0;
  codec_params.codecInstant.pltype = -1;
  return -1;
}

WebRtc_Word16 AudioCodingModuleImpl::DecoderListIDByPlName(
    const char* name, const WebRtc_UWord16 frequency) const {
  WebRtcACMCodecParams codec_params;
  CriticalSectionScoped lock(_acmCritSect);
  for (WebRtc_Word16 id = 0; id < ACMCodecDB::kMaxNumCodecs; id++) {
    if ((_codecs[id] != NULL)) {
      if (_codecs[id]->DecoderInitialized()) {
        assert(_registeredPlTypes[id] >= 0);
        assert(_registeredPlTypes[id] <= 255);
        _codecs[id]->DecoderParams(
            &codec_params, (WebRtc_UWord8) _registeredPlTypes[id]);
        if (!STR_CASE_CMP(codec_params.codecInstant.plname, name)) {
          // Check if the given sampling frequency matches.
          // A zero sampling frequency means we matching the names
          // is sufficient and we don't need to check for the
          // frequencies.
          // Currently it is only iSAC which has one name but two
          // sampling frequencies.
          if ((frequency == 0)||
              (codec_params.codecInstant.plfreq == frequency)) {
            return id;
          }
        }
      }
    }
  }
  // If we are here it means that we could not find a
  // codec with that payload type. return -1.
  return -1;
}

WebRtc_Word32 AudioCodingModuleImpl::LastEncodedTimestamp(
    WebRtc_UWord32& timestamp) const {
  CriticalSectionScoped lock(_acmCritSect);
  if (!HaveValidEncoder("LastEncodedTimestamp")) {
    return -1;
  }
  timestamp = _codecs[_currentSendCodecIdx]->LastEncodedTimestamp();
  return 0;
}

WebRtc_Word32 AudioCodingModuleImpl::ReplaceInternalDTXWithWebRtc(
    bool use_webrtc_dtx) {
  CriticalSectionScoped lock(_acmCritSect);

  if (!HaveValidEncoder("ReplaceInternalDTXWithWebRtc")) {
    WEBRTC_TRACE(
        webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
        "Cannot replace codec internal DTX when no send codec is registered.");
    return -1;
  }

  WebRtc_Word32 res = _codecs[_currentSendCodecIdx]->ReplaceInternalDTX(
      use_webrtc_dtx);
  // Check if VAD is turned on, or if there is any error.
  if (res == 1) {
    _vadEnabled = true;
  } else if (res < 0) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "Failed to set ReplaceInternalDTXWithWebRtc(%d)",
                 use_webrtc_dtx);
    return res;
  }

  return 0;
}

WebRtc_Word32 AudioCodingModuleImpl::IsInternalDTXReplacedWithWebRtc(
    bool& uses_webrtc_dtx) {
  CriticalSectionScoped lock(_acmCritSect);

  if (!HaveValidEncoder("IsInternalDTXReplacedWithWebRtc")) {
    return -1;
  }
  if (_codecs[_currentSendCodecIdx]->IsInternalDTXReplaced(&uses_webrtc_dtx)
      < 0) {
    return -1;
  }
  return 0;
}

WebRtc_Word32 AudioCodingModuleImpl::SetISACMaxRate(
    const WebRtc_UWord32 max_bit_per_sec) {
  CriticalSectionScoped lock(_acmCritSect);

  if (!HaveValidEncoder("SetISACMaxRate")) {
    return -1;
  }

  return _codecs[_currentSendCodecIdx]->SetISACMaxRate(max_bit_per_sec);
}

WebRtc_Word32 AudioCodingModuleImpl::SetISACMaxPayloadSize(
    const WebRtc_UWord16 max_size_bytes) {
  CriticalSectionScoped lock(_acmCritSect);

  if (!HaveValidEncoder("SetISACMaxPayloadSize")) {
    return -1;
  }

  return _codecs[_currentSendCodecIdx]->SetISACMaxPayloadSize(
      max_size_bytes);
}

WebRtc_Word32 AudioCodingModuleImpl::ConfigISACBandwidthEstimator(
    const WebRtc_UWord8 frame_size_ms,
    const WebRtc_UWord16 rate_bit_per_sec,
    const bool enforce_frame_size) {
  CriticalSectionScoped lock(_acmCritSect);

  if (!HaveValidEncoder("ConfigISACBandwidthEstimator")) {
    return -1;
  }

  return _codecs[_currentSendCodecIdx]->ConfigISACBandwidthEstimator(
      frame_size_ms, rate_bit_per_sec, enforce_frame_size);
}

WebRtc_Word32 AudioCodingModuleImpl::SetBackgroundNoiseMode(
    const ACMBackgroundNoiseMode mode) {
  if ((mode < On) || (mode > Off)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "The specified background noise is out of range.\n");
    return -1;
  }
  return _netEq.SetBackgroundNoiseMode(mode);
}

WebRtc_Word32 AudioCodingModuleImpl::BackgroundNoiseMode(
    ACMBackgroundNoiseMode& mode) {
  return _netEq.BackgroundNoiseMode(mode);
}

WebRtc_Word32 AudioCodingModuleImpl::PlayoutTimestamp(
    WebRtc_UWord32& timestamp) {
  WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, _id,
               "PlayoutTimestamp()");
  return _netEq.PlayoutTimestamp(timestamp);
}

bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const {
  if ((!_sendCodecRegistered) || (_currentSendCodecIdx < 0) ||
      (_currentSendCodecIdx >= ACMCodecDB::kNumCodecs)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "%s failed: No send codec is registered.", caller_name);
    return false;
  }
  if ((_currentSendCodecIdx < 0) ||
      (_currentSendCodecIdx >= ACMCodecDB::kNumCodecs)) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "%s failed: Send codec index out of range.", caller_name);
    return false;
  }
  if (_codecs[_currentSendCodecIdx] == NULL) {
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                 "%s failed: Send codec is NULL pointer.", caller_name);
    return false;
  }
  return true;
}

WebRtc_Word32 AudioCodingModuleImpl::UnregisterReceiveCodec(
    const WebRtc_Word16 payload_type) {
  CriticalSectionScoped lock(_acmCritSect);
  int id;

  // Search through the list of registered payload types.
  for (id = 0; id < ACMCodecDB::kMaxNumCodecs; id++) {
    if (_registeredPlTypes[id] == payload_type) {
      // We have found the id registered with the payload type.
      break;
    }
  }

  if (id >= ACMCodecDB::kNumCodecs) {
    // Payload type was not registered. No need to unregister.
    return 0;
  }

  // Unregister the codec with the given payload type.
  return UnregisterReceiveCodecSafe(id);
}

WebRtc_Word32 AudioCodingModuleImpl::UnregisterReceiveCodecSafe(
    const WebRtc_Word16 codec_id) {
  const WebRtcNetEQDecoder *neteq_decoder = ACMCodecDB::NetEQDecoders();
  WebRtc_Word16 mirror_id = ACMCodecDB::MirrorID(codec_id);
  bool stereo_receiver = false;

  if (_codecs[codec_id] != NULL) {
    if (_registeredPlTypes[codec_id] != -1) {
      // Store stereo information for future use.
      stereo_receiver = _stereoReceive[codec_id];

      // Before deleting the decoder instance unregister from NetEQ.
      if (_netEq.RemoveCodec(neteq_decoder[codec_id],
                             _stereoReceive[codec_id])  < 0) {
        CodecInst codec;
        ACMCodecDB::Codec(codec_id, &codec);
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _id,
                     "Unregistering %s-%d from NetEQ failed.", codec.plname,
                     codec.plfreq);
        return -1;
      }

      // CN is a special case for NetEQ, all three sampling frequencies
      // are unregistered if one is deleted.
      if (IsCodecCN(codec_id)) {
        for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
          if (IsCodecCN(i)) {
            _stereoReceive[i] = false;
            _registeredPlTypes[i] = -1;
          }
        }
      } else {
        if (codec_id == mirror_id) {
          _codecs[codec_id]->DestructDecoder();
          if (_stereoReceive[codec_id]) {
            _slaveCodecs[codec_id]->DestructDecoder();
            _stereoReceive[codec_id] = false;

          }
        }
      }

      // Check if this is the last registered stereo receive codec.
      if (stereo_receiver) {
        bool no_stereo = true;

        for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
          if (_stereoReceive[i]) {
            // We still have stereo codecs registered.
            no_stereo = false;
            break;
          }
        }

        // If we don't have any stereo codecs left, change status.
        if (no_stereo) {
          _netEq.RemoveSlaves();  // No longer need the slave.
          _stereoReceiveRegistered = false;
        }
      }
    }
  }

  if (_registeredPlTypes[codec_id] == _receiveREDPayloadType) {
    // RED is going to be unregistered, set to an invalid value.
    _receiveREDPayloadType = 255;
  }
  _registeredPlTypes[codec_id] = -1;

  return 0;
}

WebRtc_Word32 AudioCodingModuleImpl::REDPayloadISAC(
    const WebRtc_Word32 isac_rate, const WebRtc_Word16 isac_bw_estimate,
    WebRtc_UWord8* payload, WebRtc_Word16* length_bytes) {
  if (!HaveValidEncoder("EncodeData")) {
    return -1;
  }
  WebRtc_Word16 status;
  status = _codecs[_currentSendCodecIdx]->REDPayloadISAC(isac_rate,
                                                         isac_bw_estimate,
                                                         payload,
                                                         length_bytes);
  return status;
}

}  // namespace webrtc
