/*
 * libjingle
 * Copyright 2010 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.
 */

#ifndef TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
#define TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_

#include <map>
#include <set>
#include <vector>

#include "talk/media/base/codec.h"
#include "talk/media/webrtc/fakewebrtccommon.h"
#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
#include "talk/media/webrtc/webrtcvie.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/thread_annotations.h"

namespace cricket {

#define WEBRTC_CHECK_CAPTURER(capturer) \
  if (capturers_.find(capturer) == capturers_.end()) return -1;

#define WEBRTC_ASSERT_CAPTURER(capturer) \
  ASSERT(capturers_.find(capturer) != capturers_.end());

static const int kMinVideoBitrate = 100;
static const int kStartVideoBitrate = 300;
static const int kMaxVideoBitrate = 1000;

// WebRtc channel id and capture id share the same number space.
// This is how AddRenderer(renderId, ...) is able to tell if it is adding a
// renderer for a channel or it is adding a renderer for a capturer.
static const int kViEChannelIdBase = 0;
static const int kViEChannelIdMax = 1000;
static const int kViECaptureIdBase = 10000;  // Make sure there is a gap.
static const int kViECaptureIdMax = 11000;

// Fake class for mocking out webrtc::VideoDecoder
class FakeWebRtcVideoDecoder : public webrtc::VideoDecoder {
 public:
  FakeWebRtcVideoDecoder()
      : num_frames_received_(0) {
  }

  virtual int32 InitDecode(const webrtc::VideoCodec*, int32) {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 Decode(
      const webrtc::EncodedImage&, bool, const webrtc::RTPFragmentationHeader*,
      const webrtc::CodecSpecificInfo*, int64_t) {
    num_frames_received_++;
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 RegisterDecodeCompleteCallback(
      webrtc::DecodedImageCallback*) {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 Release() {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 Reset() {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  int GetNumFramesReceived() const {
    return num_frames_received_;
  }

 private:
  int num_frames_received_;
};

// Fake class for mocking out WebRtcVideoDecoderFactory.
class FakeWebRtcVideoDecoderFactory : public WebRtcVideoDecoderFactory {
 public:
  FakeWebRtcVideoDecoderFactory()
      : num_created_decoders_(0) {
  }

  virtual webrtc::VideoDecoder* CreateVideoDecoder(
      webrtc::VideoCodecType type) {
    if (supported_codec_types_.count(type) == 0) {
      return NULL;
    }
    FakeWebRtcVideoDecoder* decoder = new FakeWebRtcVideoDecoder();
    decoders_.push_back(decoder);
    num_created_decoders_++;
    return decoder;
  }

  virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) {
    decoders_.erase(
        std::remove(decoders_.begin(), decoders_.end(), decoder),
        decoders_.end());
    delete decoder;
  }

  void AddSupportedVideoCodecType(webrtc::VideoCodecType type) {
    supported_codec_types_.insert(type);
  }

  int GetNumCreatedDecoders() {
    return num_created_decoders_;
  }

  const std::vector<FakeWebRtcVideoDecoder*>& decoders() {
    return decoders_;
  }

 private:
  std::set<webrtc::VideoCodecType> supported_codec_types_;
  std::vector<FakeWebRtcVideoDecoder*> decoders_;
  int num_created_decoders_;
};

// Fake class for mocking out webrtc::VideoEnoder
class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder {
 public:
  FakeWebRtcVideoEncoder() : num_frames_encoded_(0) {}

  virtual int32 InitEncode(const webrtc::VideoCodec* codecSettings,
                           int32 numberOfCores,
                           size_t maxPayloadSize) {
    rtc::CritScope lock(&crit_);
    codec_settings_ = *codecSettings;
    return WEBRTC_VIDEO_CODEC_OK;
  }

  webrtc::VideoCodec GetCodecSettings() {
    rtc::CritScope lock(&crit_);
    return codec_settings_;
  }

  virtual int32 Encode(
      const webrtc::I420VideoFrame& inputImage,
            const webrtc::CodecSpecificInfo* codecSpecificInfo,
            const std::vector<webrtc::VideoFrameType>* frame_types) {
    rtc::CritScope lock(&crit_);
    ++num_frames_encoded_;
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 RegisterEncodeCompleteCallback(
      webrtc::EncodedImageCallback* callback) {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 Release() {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 SetChannelParameters(uint32 packetLoss,
                                     int64_t rtt) {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  virtual int32 SetRates(uint32 newBitRate,
                         uint32 frameRate) {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  int GetNumEncodedFrames() {
    rtc::CritScope lock(&crit_);
    return num_frames_encoded_;
  }

 private:
  rtc::CriticalSection crit_;
  int num_frames_encoded_ GUARDED_BY(crit_);
  webrtc::VideoCodec codec_settings_ GUARDED_BY(crit_);
};

// Fake class for mocking out WebRtcVideoEncoderFactory.
class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory {
 public:
  FakeWebRtcVideoEncoderFactory()
      : num_created_encoders_(0) {
  }

  virtual webrtc::VideoEncoder* CreateVideoEncoder(
      webrtc::VideoCodecType type) {
    if (supported_codec_types_.count(type) == 0) {
      return NULL;
    }
    FakeWebRtcVideoEncoder* encoder = new FakeWebRtcVideoEncoder();
    encoders_.push_back(encoder);
    num_created_encoders_++;
    return encoder;
  }

  virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) {
    encoders_.erase(
        std::remove(encoders_.begin(), encoders_.end(), encoder),
        encoders_.end());
    delete encoder;
  }

  virtual const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs()
      const {
    return codecs_;
  }

  void AddSupportedVideoCodecType(webrtc::VideoCodecType type,
                                  const std::string& name) {
    supported_codec_types_.insert(type);
    codecs_.push_back(
        WebRtcVideoEncoderFactory::VideoCodec(type, name, 1280, 720, 30));
  }

  int GetNumCreatedEncoders() {
    return num_created_encoders_;
  }

  const std::vector<FakeWebRtcVideoEncoder*>& encoders() {
    return encoders_;
  }

 private:
  std::set<webrtc::VideoCodecType> supported_codec_types_;
  std::vector<WebRtcVideoEncoderFactory::VideoCodec> codecs_;
  std::vector<FakeWebRtcVideoEncoder*> encoders_;
  int num_created_encoders_;
};

class FakeWebRtcVideoEngine
    : public webrtc::ViEBase,
      public webrtc::ViECodec,
      public webrtc::ViECapture,
      public webrtc::ViENetwork,
      public webrtc::ViERender,
      public webrtc::ViERTP_RTCP,
      public webrtc::ViEImageProcess,
      public webrtc::ViEExternalCodec {
 public:
  struct Channel {
    Channel()
        : capture_id_(-1),
          original_channel_id_(-1),
          has_renderer_(false),
          render_started_(false),
          send(false),
          receive_(false),
          can_transmit_(true),
          remote_rtx_ssrc_(-1),
          rtx_send_payload_type(-1),
          rtx_recv_payload_type(-1),
          rtcp_status_(webrtc::kRtcpNone),
          key_frame_request_method_(webrtc::kViEKeyFrameRequestNone),
          tmmbr_(false),
          remb_contribute_(false),
          remb_bw_partition_(false),
          rtp_offset_send_id_(-1),
          rtp_offset_receive_id_(-1),
          rtp_absolute_send_time_send_id_(-1),
          rtp_absolute_send_time_receive_id_(-1),
          sender_target_delay_(0),
          receiver_target_delay_(0),
          transmission_smoothing_(false),
          nack_(false),
          hybrid_nack_fec_(false),
          send_video_bitrate_(0),
          send_fec_bitrate_(0),
          send_nack_bitrate_(0),
          send_bandwidth_(0),
          receive_bandwidth_(0),
          reserved_transmit_bitrate_bps_(0),
          suspend_below_min_bitrate_(false),
          overuse_observer_(NULL),
          last_recvd_payload_type_(-1) {
      ssrcs_[0] = 0;  // default ssrc.
      memset(&send_codec, 0, sizeof(send_codec));
      memset(&overuse_options_, 0, sizeof(overuse_options_));
    }
    int capture_id_;
    int original_channel_id_;
    bool has_renderer_;
    bool render_started_;
    bool send;
    bool receive_;
    bool can_transmit_;
    std::map<int, int> ssrcs_;
    std::map<int, int> rtx_ssrcs_;
    int remote_rtx_ssrc_;
    int rtx_send_payload_type;
    int rtx_recv_payload_type;
    std::string cname_;
    webrtc::ViERTCPMode rtcp_status_;
    webrtc::ViEKeyFrameRequestMethod key_frame_request_method_;
    bool tmmbr_;
    bool remb_contribute_;   // This channel contributes to the remb report.
    bool remb_bw_partition_; // This channel is allocated part of total bw.
    int rtp_offset_send_id_;
    int rtp_offset_receive_id_;
    int rtp_absolute_send_time_send_id_;
    int rtp_absolute_send_time_receive_id_;
    int sender_target_delay_;
    int receiver_target_delay_;
    bool transmission_smoothing_;
    bool nack_;
    bool hybrid_nack_fec_;
    std::vector<webrtc::VideoCodec> recv_codecs;
    std::set<unsigned int> ext_decoder_pl_types_;
    std::set<unsigned int> ext_encoder_pl_types_;
    webrtc::VideoCodec send_codec;
    unsigned int send_video_bitrate_;
    unsigned int send_fec_bitrate_;
    unsigned int send_nack_bitrate_;
    unsigned int send_bandwidth_;
    unsigned int receive_bandwidth_;
    // Bandwidth to deduct from estimated uplink capacity.
    unsigned int reserved_transmit_bitrate_bps_;
    bool suspend_below_min_bitrate_;
    webrtc::CpuOveruseObserver* overuse_observer_;
    webrtc::CpuOveruseOptions overuse_options_;
    int last_recvd_payload_type_;
  };
  class Capturer : public webrtc::ViEExternalCapture {
   public:
    Capturer() : channel_id_(-1), denoising_(false),
                 last_capture_time_(0), incoming_frame_num_(0) { }
    int channel_id() const { return channel_id_; }
    void set_channel_id(int channel_id) { channel_id_ = channel_id; }
    bool denoising() const { return denoising_; }
    void set_denoising(bool denoising) { denoising_ = denoising; }
    int64 last_capture_time() const { return last_capture_time_; }
    int incoming_frame_num() const { return incoming_frame_num_; }

    // From ViEExternalCapture
    virtual int IncomingFrame(unsigned char* videoFrame,
                              size_t videoFrameLength,
                              unsigned short width,
                              unsigned short height,
                              webrtc::RawVideoType videoType,
                              unsigned long long captureTime) {
      return 0;
    }
    virtual int IncomingFrameI420(
        const webrtc::ViEVideoFrameI420& video_frame,
        unsigned long long captureTime) {
      last_capture_time_ = captureTime;
      ++incoming_frame_num_;
      return 0;
    }

   private:
    int channel_id_;
    bool denoising_;
    int64 last_capture_time_;
    int incoming_frame_num_;
  };

  FakeWebRtcVideoEngine(const cricket::VideoCodec* const* codecs,
                        int num_codecs)
      : inited_(false),
        last_channel_(kViEChannelIdBase - 1),
        fail_create_channel_(false),
        last_capturer_(kViECaptureIdBase - 1),
        fail_alloc_capturer_(false),
        codecs_(codecs),
        num_codecs_(num_codecs),
        num_set_send_codecs_(0) {
  }

  ~FakeWebRtcVideoEngine() {
    ASSERT(0 == channels_.size());
    ASSERT(0 == capturers_.size());
  }
  bool IsInited() const { return inited_; }

  int GetLastChannel() const { return last_channel_; }
  int GetChannelFromLocalSsrc(int local_ssrc) const {
    // ssrcs_[0] is the default local ssrc.
    for (std::map<int, Channel*>::const_iterator iter = channels_.begin();
         iter != channels_.end(); ++iter) {
      if (local_ssrc == iter->second->ssrcs_[0]) {
        return iter->first;
      }
    }
    return -1;
  }

  int GetNumChannels() const { return static_cast<int>(channels_.size()); }
  bool IsChannel(int channel) const {
    return (channels_.find(channel) != channels_.end());
  }
  void set_fail_create_channel(bool fail_create_channel) {
    fail_create_channel_ = fail_create_channel;
  }

  int GetLastCapturer() const { return last_capturer_; }
  int GetNumCapturers() const { return static_cast<int>(capturers_.size()); }
  int GetIncomingFrameNum(int channel_id) const {
    for (std::map<int, Capturer*>::const_iterator iter = capturers_.begin();
         iter != capturers_.end(); ++iter) {
      Capturer* capturer = iter->second;
      if (capturer->channel_id() == channel_id) {
        return capturer->incoming_frame_num();
      }
    }
    return -1;
  }
  void set_fail_alloc_capturer(bool fail_alloc_capturer) {
    fail_alloc_capturer_ = fail_alloc_capturer;
  }
  int GetNumSetSendCodecs() const { return num_set_send_codecs_; }

  int GetCaptureId(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->capture_id_;
  }
  int GetOriginalChannelId(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->original_channel_id_;
  }
  bool GetHasRenderer(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->has_renderer_;
  }
  bool GetRenderStarted(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->render_started_;
  }
  bool GetSend(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->send;
  }
  bool GetReceive(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->receive_;
  }
  int GetCaptureChannelId(int capture_id) const {
    WEBRTC_ASSERT_CAPTURER(capture_id);
    return capturers_.find(capture_id)->second->channel_id();
  }
  bool GetCaptureDenoising(int capture_id) const {
    WEBRTC_ASSERT_CAPTURER(capture_id);
    return capturers_.find(capture_id)->second->denoising();
  }
  int64 GetCaptureLastTimestamp(int capture_id) const {
    WEBRTC_ASSERT_CAPTURER(capture_id);
    return capturers_.find(capture_id)->second->last_capture_time();
  }
  webrtc::ViERTCPMode GetRtcpStatus(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->rtcp_status_;
  }
  webrtc::ViEKeyFrameRequestMethod GetKeyFrameRequestMethod(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->key_frame_request_method_;
  }
  bool GetTmmbrStatus(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->tmmbr_;
  }
  bool GetRembStatusBwPartition(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->remb_bw_partition_;
  }
  bool GetRembStatusContribute(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->remb_contribute_;
  }
  int GetSendRtpExtensionId(int channel, const std::string& extension) {
    WEBRTC_ASSERT_CHANNEL(channel);
    if (extension == kRtpTimestampOffsetHeaderExtension) {
      return channels_.find(channel)->second->rtp_offset_send_id_;
    } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
      return channels_.find(channel)->second->rtp_absolute_send_time_send_id_;
    }
    return -1;
  }
  int GetReceiveRtpExtensionId(int channel, const std::string& extension) {
    WEBRTC_ASSERT_CHANNEL(channel);
    if (extension == kRtpTimestampOffsetHeaderExtension) {
      return channels_.find(channel)->second->rtp_offset_receive_id_;
    } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
      return
          channels_.find(channel)->second->rtp_absolute_send_time_receive_id_;
    }
    return -1;
  }
  bool GetTransmissionSmoothingStatus(int channel) {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->transmission_smoothing_;
  }
  int GetSenderTargetDelay(int channel) {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->sender_target_delay_;
  }
  int GetReceiverTargetDelay(int channel) {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->receiver_target_delay_;
  }
  bool GetNackStatus(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->nack_;
  }
  bool GetHybridNackFecStatus(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->hybrid_nack_fec_;
  }
  int GetNumSsrcs(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return static_cast<int>(
        channels_.find(channel)->second->ssrcs_.size());
  }
  int GetNumRtxSsrcs(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return static_cast<int>(
        channels_.find(channel)->second->rtx_ssrcs_.size());
  }
  bool GetIsTransmitting(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->can_transmit_;
  }
  webrtc::CpuOveruseObserver* GetCpuOveruseObserver(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->overuse_observer_;
  }
  webrtc::CpuOveruseOptions GetCpuOveruseOptions(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->overuse_options_;
  }
  int GetSsrc(int channel, int idx) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    if (channels_.find(channel)->second->ssrcs_.find(idx) ==
        channels_.find(channel)->second->ssrcs_.end()) {
      return -1;
    }
    return channels_.find(channel)->second->ssrcs_[idx];
  }
  int GetRtxSsrc(int channel, int idx) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    if (channels_.find(channel)->second->rtx_ssrcs_.find(idx) ==
        channels_.find(channel)->second->rtx_ssrcs_.end()) {
      return -1;
    }
    return channels_.find(channel)->second->rtx_ssrcs_[idx];
  }
  bool ReceiveCodecRegistered(int channel,
                              const webrtc::VideoCodec& codec) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    const std::vector<webrtc::VideoCodec>& codecs =
      channels_.find(channel)->second->recv_codecs;
    return std::find(codecs.begin(), codecs.end(), codec) != codecs.end();
  };
  bool ExternalDecoderRegistered(int channel,
                                 unsigned int pl_type) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->
        ext_decoder_pl_types_.count(pl_type) != 0;
  };
  int GetNumExternalDecoderRegistered(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return static_cast<int>(
        channels_.find(channel)->second->ext_decoder_pl_types_.size());
  };
  bool ExternalEncoderRegistered(int channel,
                                 unsigned int pl_type) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->
        ext_encoder_pl_types_.count(pl_type) != 0;
  };
  int GetNumExternalEncoderRegistered(int channel) const {
    WEBRTC_ASSERT_CHANNEL(channel);
    return static_cast<int>(
        channels_.find(channel)->second->ext_encoder_pl_types_.size());
  };
  int GetTotalNumExternalEncoderRegistered() const {
    std::map<int, Channel*>::const_iterator it;
    int total_num_registered = 0;
    for (it = channels_.begin(); it != channels_.end(); ++it)
      total_num_registered +=
          static_cast<int>(it->second->ext_encoder_pl_types_.size());
    return total_num_registered;
  }
  void SetSendBitrates(int channel, unsigned int video_bitrate,
                       unsigned int fec_bitrate, unsigned int nack_bitrate) {
    WEBRTC_ASSERT_CHANNEL(channel);
    channels_[channel]->send_video_bitrate_ = video_bitrate;
    channels_[channel]->send_fec_bitrate_ = fec_bitrate;
    channels_[channel]->send_nack_bitrate_ = nack_bitrate;
  }
  void SetSendBandwidthEstimate(int channel, unsigned int send_bandwidth) {
    WEBRTC_ASSERT_CHANNEL(channel);
    channels_[GetOriginalChannelId(channel)]->send_bandwidth_ = send_bandwidth;
  }
  void SetReceiveBandwidthEstimate(int channel,
                                   unsigned int receive_bandwidth) {
    WEBRTC_ASSERT_CHANNEL(channel);
    channels_[GetOriginalChannelId(channel)]->receive_bandwidth_ =
        receive_bandwidth;
  };
  int GetRtxSendPayloadType(int channel) {
    WEBRTC_CHECK_CHANNEL(channel);
    return channels_[channel]->rtx_send_payload_type;
  }
  int GetRtxRecvPayloadType(int channel) {
    WEBRTC_CHECK_CHANNEL(channel);
    return channels_[channel]->rtx_recv_payload_type;
  }
  int GetRemoteRtxSsrc(int channel) {
    WEBRTC_CHECK_CHANNEL(channel);
    return channels_.find(channel)->second->remote_rtx_ssrc_;
  }
  bool GetSuspendBelowMinBitrateStatus(int channel) {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->suspend_below_min_bitrate_;
  }
  int GetLastRecvdPayloadType(int channel) const {
    WEBRTC_CHECK_CHANNEL(channel);
    return channels_.find(channel)->second->last_recvd_payload_type_;
  }
  unsigned int GetReservedTransmitBitrate(int channel) {
    WEBRTC_ASSERT_CHANNEL(channel);
    return channels_.find(channel)->second->reserved_transmit_bitrate_bps_;
  }

  WEBRTC_STUB(Release, ());

  // webrtc::ViEBase
  WEBRTC_FUNC(Init, ()) {
    inited_ = true;
    return 0;
  };
  WEBRTC_STUB(SetVoiceEngine, (webrtc::VoiceEngine*));
  WEBRTC_FUNC(CreateChannel, (int& channel)) {  // NOLINT
    if (fail_create_channel_) {
      return -1;
    }
    if (kViEChannelIdMax == last_channel_) {
      return -1;
    }
    Channel* ch = new Channel();
    ++last_channel_;
    // The original channel of the first channel in a group refers to itself
    // for code simplicity.
    ch->original_channel_id_ = last_channel_;
    channels_[last_channel_] = ch;
    channel = last_channel_;
    return 0;
  };
  WEBRTC_FUNC(CreateChannel, (int& channel, int original_channel)) {
    WEBRTC_CHECK_CHANNEL(original_channel);
    if (CreateChannel(channel) != 0) {
      return -1;
    }
    channels_[channel]->original_channel_id_ = original_channel;
    return 0;
  }
  WEBRTC_STUB(CreateChannelWithoutDefaultEncoder, (int&, int original_channel));
  WEBRTC_FUNC(CreateReceiveChannel, (int& channel, int original_channel)) {
    return CreateChannel(channel, original_channel);
  }
  WEBRTC_FUNC(DeleteChannel, (const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    // Make sure we deregister all the decoders before deleting a channel.
    EXPECT_EQ(0, GetNumExternalDecoderRegistered(channel));
    delete channels_[channel];
    channels_.erase(channel);
    return 0;
  }
  WEBRTC_FUNC(RegisterCpuOveruseObserver,
      (int channel, webrtc::CpuOveruseObserver* observer)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->overuse_observer_ = observer;
    return 0;
  }
  WEBRTC_STUB(GetCpuOveruseMetrics, (int, webrtc::CpuOveruseMetrics*));
  WEBRTC_VOID_STUB(RegisterCpuOveruseMetricsObserver,
                   (int, webrtc::CpuOveruseMetricsObserver*));
  WEBRTC_FUNC(SetCpuOveruseOptions,
      (int channel, const webrtc::CpuOveruseOptions& options)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->overuse_options_ = options;
    return 0;
  }
  WEBRTC_STUB(ConnectAudioChannel, (const int, const int));
  WEBRTC_STUB(DisconnectAudioChannel, (const int));
  WEBRTC_FUNC(StartSend, (const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->send = true;
    return 0;
  }
  WEBRTC_FUNC(StopSend, (const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->send = false;
    return 0;
  }
  WEBRTC_FUNC(StartReceive, (const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->receive_ = true;
    return 0;
  }
  WEBRTC_FUNC(StopReceive, (const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->receive_ = false;
    return 0;
  }
  WEBRTC_STUB(GetVersion, (char version[1024]));
  WEBRTC_STUB(LastError, ());
  WEBRTC_VOID_STUB(RegisterSendStatisticsProxy,
                   (int, webrtc::SendStatisticsProxy*));

  WEBRTC_VOID_STUB(RegisterReceiveStatisticsProxy,
                   (int, webrtc::ReceiveStatisticsProxy*));

  // webrtc::ViECodec
  WEBRTC_FUNC_CONST(NumberOfCodecs, ()) {
    return num_codecs_;
  };
  WEBRTC_FUNC_CONST(GetCodec, (const unsigned char list_number,
                               webrtc::VideoCodec& out_codec)) {
    if (list_number >= NumberOfCodecs()) {
      return -1;
    }
    memset(&out_codec, 0, sizeof(out_codec));
    const cricket::VideoCodec& c(*codecs_[list_number]);
    if ("I420" == c.name) {
      out_codec.codecType = webrtc::kVideoCodecI420;
    } else if ("VP8" == c.name) {
      out_codec.codecType = webrtc::kVideoCodecVP8;
    } else if ("red" == c.name) {
      out_codec.codecType = webrtc::kVideoCodecRED;
    } else if ("ulpfec" == c.name) {
      out_codec.codecType = webrtc::kVideoCodecULPFEC;
    } else {
      out_codec.codecType = webrtc::kVideoCodecUnknown;
    }
    rtc::strcpyn(out_codec.plName, sizeof(out_codec.plName),
                       c.name.c_str());
    out_codec.plType = c.id;
    out_codec.width = c.width;
    out_codec.height = c.height;
    out_codec.startBitrate = kStartVideoBitrate;
    out_codec.maxBitrate = kMaxVideoBitrate;
    out_codec.minBitrate = kMinVideoBitrate;
    out_codec.maxFramerate = c.framerate;
    return 0;
  };
  WEBRTC_FUNC(SetSendCodec, (const int channel,
                             const webrtc::VideoCodec& codec)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->send_codec = codec;
    ++num_set_send_codecs_;
    return 0;
  };
  WEBRTC_FUNC_CONST(GetSendCodec, (const int channel,
                                   webrtc::VideoCodec& codec)) {  // NOLINT
    WEBRTC_CHECK_CHANNEL(channel);
    codec = channels_.find(channel)->second->send_codec;
    return 0;
  };
  WEBRTC_FUNC(SetReceiveCodec, (const int channel,
                                const webrtc::VideoCodec& codec)) {  // NOLINT
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->recv_codecs.push_back(codec);
    return 0;
  };
  WEBRTC_STUB_CONST(GetReceiveCodec, (const int, webrtc::VideoCodec&));
  WEBRTC_STUB_CONST(GetCodecConfigParameters, (const int,
      unsigned char*, unsigned char&));
  WEBRTC_STUB(SetImageScaleStatus, (const int, const bool));
  WEBRTC_STUB_CONST(GetSendCodecStastistics, (const int,
      unsigned int&, unsigned int&));
  WEBRTC_STUB_CONST(GetReceiveCodecStastistics, (const int,
      unsigned int&, unsigned int&));
  WEBRTC_STUB_CONST(GetReceiveSideDelay, (const int video_channel,
                                          int* delay_ms));
  WEBRTC_FUNC_CONST(GetCodecTargetBitrate, (const int channel,
      unsigned int* codec_target_bitrate)) {
    WEBRTC_CHECK_CHANNEL(channel);

    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
    if (it->second->send) {
      // Assume the encoder produces the expected rate.
      *codec_target_bitrate = it->second->send_video_bitrate_;
    } else {
      *codec_target_bitrate = 0;
    }
    return 0;
  }
  virtual unsigned int GetDiscardedPackets(const int channel) const {
    return 0;
  }

  WEBRTC_STUB(SetKeyFrameRequestCallbackStatus, (const int, const bool));
  WEBRTC_STUB(SetSignalKeyPacketLossStatus, (const int, const bool,
      const bool));
  WEBRTC_STUB(RegisterEncoderObserver, (const int,
      webrtc::ViEEncoderObserver&));
  WEBRTC_STUB(DeregisterEncoderObserver, (const int));
  WEBRTC_STUB(RegisterDecoderObserver, (const int,
      webrtc::ViEDecoderObserver&));
  WEBRTC_STUB(DeregisterDecoderObserver, (const int));
  WEBRTC_STUB(SendKeyFrame, (const int));
  WEBRTC_STUB(WaitForFirstKeyFrame, (const int, const bool));
  WEBRTC_STUB(StartDebugRecording, (int, const char*));
  WEBRTC_STUB(StopDebugRecording, (int));
  WEBRTC_VOID_FUNC(SuspendBelowMinBitrate, (int channel)) {
    WEBRTC_ASSERT_CHANNEL(channel);
    channels_[channel]->suspend_below_min_bitrate_ = true;
  }

  // webrtc::ViECapture
  WEBRTC_STUB(NumberOfCaptureDevices, ());
  WEBRTC_STUB(GetCaptureDevice, (unsigned int, char*,
      const unsigned int, char*, const unsigned int));
  WEBRTC_STUB(AllocateCaptureDevice, (const char*, const unsigned int, int&));
  WEBRTC_FUNC(AllocateExternalCaptureDevice,
              (int& capture_id, webrtc::ViEExternalCapture*& capture)) {
    if (fail_alloc_capturer_) {
      return -1;
    }
    if (kViECaptureIdMax == last_capturer_) {
      return -1;
    }
    Capturer* cap = new Capturer();
    capturers_[++last_capturer_] = cap;
    capture_id = last_capturer_;
    capture = cap;
    return 0;
  }
  WEBRTC_STUB(AllocateCaptureDevice, (webrtc::VideoCaptureModule&, int&));
  WEBRTC_FUNC(ReleaseCaptureDevice, (const int capture_id)) {
    WEBRTC_CHECK_CAPTURER(capture_id);
    delete capturers_[capture_id];
    capturers_.erase(capture_id);
    return 0;
  }
  WEBRTC_FUNC(ConnectCaptureDevice, (const int capture_id,
                                     const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    WEBRTC_CHECK_CAPTURER(capture_id);
    channels_[channel]->capture_id_ = capture_id;
    capturers_[capture_id]->set_channel_id(channel);
    return 0;
  }
  WEBRTC_FUNC(DisconnectCaptureDevice, (const int channel)) {
    WEBRTC_CHECK_CHANNEL(channel);
    int capture_id = channels_[channel]->capture_id_;
    WEBRTC_CHECK_CAPTURER(capture_id);
    channels_[channel]->capture_id_ = -1;
    capturers_[capture_id]->set_channel_id(-1);
    return 0;
  }
  WEBRTC_STUB(StartCapture, (const int, const webrtc::CaptureCapability&));
  WEBRTC_STUB(StopCapture, (const int));
  WEBRTC_STUB(SetVideoRotation, (const int, const webrtc::VideoRotation));
  WEBRTC_STUB(SetCaptureDelay, (const int, const unsigned int));
  WEBRTC_STUB(NumberOfCapabilities, (const char*, const unsigned int));
  WEBRTC_STUB(GetCaptureCapability, (const char*, const unsigned int,
      const unsigned int, webrtc::CaptureCapability&));
  WEBRTC_STUB(ShowCaptureSettingsDialogBox, (const char*, const unsigned int,
      const char*, void*, const unsigned int, const unsigned int));
  WEBRTC_STUB(GetOrientation, (const char*, webrtc::VideoRotation&));
  WEBRTC_STUB(EnableBrightnessAlarm, (const int, const bool));
  WEBRTC_STUB(RegisterObserver, (const int, webrtc::ViECaptureObserver&));
  WEBRTC_STUB(DeregisterObserver, (const int));

  // webrtc::ViENetwork
  WEBRTC_VOID_FUNC(SetNetworkTransmissionState, (const int channel,
                                                 const bool is_transmitting)) {
    WEBRTC_ASSERT_CHANNEL(channel);
    channels_[channel]->can_transmit_ = is_transmitting;
  }
  WEBRTC_STUB(RegisterSendTransport, (const int, webrtc::Transport&));
  WEBRTC_STUB(DeregisterSendTransport, (const int));

  WEBRTC_FUNC(ReceivedRTPPacket, (const int channel,
                                  const void* packet,
                                  const size_t length,
                                  const webrtc::PacketTime& packet_time)) {
    WEBRTC_ASSERT_CHANNEL(channel);
    ASSERT(length > 1);
    uint8_t payload_type = static_cast<const uint8_t*>(packet)[1] & 0x7F;
    channels_[channel]->last_recvd_payload_type_ = payload_type;
    return 0;
  }

  WEBRTC_STUB(ReceivedRTCPPacket, (const int, const void*, const size_t));
  // Not using WEBRTC_STUB due to bool return value
  virtual bool IsIPv6Enabled(int channel) { return true; }
  WEBRTC_STUB(SetMTU, (int, unsigned int));
  WEBRTC_STUB(ReceivedBWEPacket, (const int, int64_t, size_t,
      const webrtc::RTPHeader&));

  // webrtc::ViERender
  WEBRTC_STUB(RegisterVideoRenderModule, (webrtc::VideoRender&));
  WEBRTC_STUB(DeRegisterVideoRenderModule, (webrtc::VideoRender&));
  WEBRTC_STUB(AddRenderer, (const int, void*, const unsigned int, const float,
      const float, const float, const float));
  WEBRTC_FUNC(RemoveRenderer, (const int render_id)) {
    if (IsCapturerId(render_id)) {
      WEBRTC_CHECK_CAPTURER(render_id);
      return 0;
    } else if (IsChannelId(render_id)) {
      WEBRTC_CHECK_CHANNEL(render_id);
      channels_[render_id]->has_renderer_ = false;
      return 0;
    }
    return -1;
  }
  WEBRTC_FUNC(StartRender, (const int render_id)) {
    if (IsCapturerId(render_id)) {
      WEBRTC_CHECK_CAPTURER(render_id);
      return 0;
    } else if (IsChannelId(render_id)) {
      WEBRTC_CHECK_CHANNEL(render_id);
      channels_[render_id]->render_started_ = true;
      return 0;
    }
    return -1;
  }
  WEBRTC_FUNC(StopRender, (const int render_id)) {
    if (IsCapturerId(render_id)) {
      WEBRTC_CHECK_CAPTURER(render_id);
      return 0;
    } else if (IsChannelId(render_id)) {
      WEBRTC_CHECK_CHANNEL(render_id);
      channels_[render_id]->render_started_ = false;
      return 0;
    }
    return -1;
  }
  WEBRTC_STUB(SetExpectedRenderDelay, (int render_id, int render_delay));
  WEBRTC_STUB(ConfigureRender, (int, const unsigned int, const float,
      const float, const float, const float));
  WEBRTC_FUNC(AddRenderer, (const int render_id,
                            webrtc::RawVideoType video_type,
                            webrtc::ExternalRenderer* renderer)) {
    if (IsCapturerId(render_id)) {
      WEBRTC_CHECK_CAPTURER(render_id);
      return 0;
    } else if (IsChannelId(render_id)) {
      WEBRTC_CHECK_CHANNEL(render_id);
      channels_[render_id]->has_renderer_ = true;
      return 0;
    }
    return -1;
  }

  // webrtc::ViERTP_RTCP
  WEBRTC_FUNC(SetLocalSSRC, (const int channel,
                             const unsigned int ssrc,
                             const webrtc::StreamType usage,
                             const unsigned char idx)) {
    WEBRTC_CHECK_CHANNEL(channel);
    switch (usage) {
      case webrtc::kViEStreamTypeNormal:
        channels_[channel]->ssrcs_[idx] = ssrc;
        break;
      case webrtc::kViEStreamTypeRtx:
        channels_[channel]->rtx_ssrcs_[idx] = ssrc;
        break;
      default:
        return -1;
    }
    return 0;
  }

  WEBRTC_FUNC_CONST(SetRemoteSSRCType, (const int channel,
        const webrtc::StreamType usage, const unsigned int ssrc)) {
    WEBRTC_CHECK_CHANNEL(channel);
    if (usage == webrtc::kViEStreamTypeRtx) {
      channels_.find(channel)->second->remote_rtx_ssrc_ = ssrc;
      return 0;
    }
    return -1;
  }

  WEBRTC_FUNC_CONST(GetLocalSSRC, (const int channel,
                                   unsigned int& ssrc)) {
    // ssrcs_[0] is the default local ssrc.
    WEBRTC_CHECK_CHANNEL(channel);
    ssrc = channels_.find(channel)->second->ssrcs_[0];
    return 0;
  }
  WEBRTC_STUB_CONST(GetRemoteSSRC, (const int, unsigned int&));
  WEBRTC_STUB_CONST(GetRemoteCSRCs, (const int, unsigned int*));

  WEBRTC_FUNC(SetRtxSendPayloadType, (const int channel,
                                      const uint8 payload_type)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtx_send_payload_type = payload_type;
    return 0;
  }

  WEBRTC_FUNC(SetRtxReceivePayloadType, (const int channel,
                                         const uint8 payload_type)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtx_recv_payload_type = payload_type;
    return 0;
  }

  WEBRTC_STUB(SetStartSequenceNumber, (const int, unsigned short));
  WEBRTC_FUNC(SetRTCPStatus,
              (const int channel, const webrtc::ViERTCPMode mode)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtcp_status_ = mode;
    return 0;
  }
  WEBRTC_STUB_CONST(GetRTCPStatus, (const int, webrtc::ViERTCPMode&));
  WEBRTC_FUNC(SetRTCPCName, (const int channel,
                             const char rtcp_cname[KMaxRTCPCNameLength])) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->cname_.assign(rtcp_cname);
    return 0;
  }
  WEBRTC_FUNC_CONST(GetRTCPCName, (const int channel,
                                   char rtcp_cname[KMaxRTCPCNameLength])) {
    WEBRTC_CHECK_CHANNEL(channel);
    rtc::strcpyn(rtcp_cname, KMaxRTCPCNameLength,
                       channels_.find(channel)->second->cname_.c_str());
    return 0;
  }
  WEBRTC_STUB_CONST(GetRemoteRTCPCName, (const int, char*));
  WEBRTC_STUB(SendApplicationDefinedRTCPPacket, (const int, const unsigned char,
      unsigned int, const char*, unsigned short));
  WEBRTC_FUNC(SetNACKStatus, (const int channel, const bool enable)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->nack_ = enable;
    channels_[channel]->hybrid_nack_fec_ = false;
    return 0;
  }
  WEBRTC_STUB(SetFECStatus, (const int, const bool, const unsigned char,
      const unsigned char));
  WEBRTC_FUNC(SetHybridNACKFECStatus, (const int channel, const bool enable,
      const unsigned char red_type, const unsigned char fec_type)) {
    WEBRTC_CHECK_CHANNEL(channel);
    if (red_type == fec_type ||
        red_type == channels_[channel]->send_codec.plType ||
        fec_type == channels_[channel]->send_codec.plType) {
      return -1;
    }
    channels_[channel]->nack_ = false;
    channels_[channel]->hybrid_nack_fec_ = enable;
    return 0;
  }
  WEBRTC_FUNC(SetKeyFrameRequestMethod,
              (const int channel,
               const webrtc::ViEKeyFrameRequestMethod method)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->key_frame_request_method_ = method;
    return 0;
  }
  WEBRTC_FUNC(SetSenderBufferingMode, (int channel, int target_delay)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->sender_target_delay_ = target_delay;
    return 0;
  }
  WEBRTC_FUNC(SetReceiverBufferingMode, (int channel, int target_delay)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->receiver_target_delay_ = target_delay;
    return 0;
  }
  // |Send| and |receive| are stored locally in variables that more clearly
  // explain what they mean.
  WEBRTC_FUNC(SetRembStatus, (int channel, bool send, bool receive)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->remb_contribute_ = receive;
    channels_[channel]->remb_bw_partition_ = send;
    return 0;
  }
  WEBRTC_FUNC(SetTMMBRStatus, (const int channel, const bool enable)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->tmmbr_ = enable;
    return 0;
  }
  WEBRTC_FUNC(SetSendTimestampOffsetStatus, (int channel, bool enable,
      int id)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtp_offset_send_id_ = (enable) ? id : -1;
    return 0;
  }
  WEBRTC_FUNC(SetReceiveTimestampOffsetStatus, (int channel, bool enable,
      int id)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtp_offset_receive_id_ = (enable) ? id : -1;
    return 0;
  }
  WEBRTC_FUNC(SetSendAbsoluteSendTimeStatus, (int channel, bool enable,
      int id)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtp_absolute_send_time_send_id_ = (enable) ? id : -1;
    return 0;
  }
  WEBRTC_FUNC(SetReceiveAbsoluteSendTimeStatus, (int channel, bool enable,
      int id)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->rtp_absolute_send_time_receive_id_ = (enable) ? id : -1;
    return 0;
  }
  WEBRTC_STUB(SetRtcpXrRrtrStatus, (int, bool));
  WEBRTC_FUNC(SetTransmissionSmoothingStatus, (int channel, bool enable)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->transmission_smoothing_ = enable;
    return 0;
  }
  WEBRTC_FUNC(SetReservedTransmitBitrate, (int channel,
      unsigned int reserved_transmit_bitrate_bps)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->reserved_transmit_bitrate_bps_ =
        reserved_transmit_bitrate_bps;
    return 0;
  }
  WEBRTC_STUB_CONST(GetRtcpPacketTypeCounters, (int,
      webrtc::RtcpPacketTypeCounter*, webrtc::RtcpPacketTypeCounter*));
  WEBRTC_STUB_CONST(GetReceivedRTCPStatistics, (const int, unsigned short&,
      unsigned int&, unsigned int&, unsigned int&, int64_t&));
  WEBRTC_STUB_CONST(GetSentRTCPStatistics, (const int, unsigned short&,
      unsigned int&, unsigned int&, unsigned int&, int64_t&));
  WEBRTC_STUB_CONST(GetRTPStatistics, (const int, size_t&, unsigned int&,
      size_t&, unsigned int&));
  WEBRTC_STUB_CONST(GetReceiveChannelRtcpStatistics, (const int,
      webrtc::RtcpStatistics&, int64_t&));
  WEBRTC_STUB_CONST(GetSendChannelRtcpStatistics, (const int,
      webrtc::RtcpStatistics&, int64_t&));
  WEBRTC_STUB_CONST(GetRtpStatistics, (const int, webrtc::StreamDataCounters&,
      webrtc::StreamDataCounters&));
  WEBRTC_FUNC_CONST(GetBandwidthUsage, (const int channel,
      unsigned int& total_bitrate, unsigned int& video_bitrate,
      unsigned int& fec_bitrate, unsigned int& nack_bitrate)) {
    WEBRTC_CHECK_CHANNEL(channel);
    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
    if (it->second->send) {
      video_bitrate = it->second->send_video_bitrate_;
      fec_bitrate = it->second->send_fec_bitrate_;
      nack_bitrate = it->second->send_nack_bitrate_;
      total_bitrate = video_bitrate + fec_bitrate + nack_bitrate;
    } else {
      total_bitrate = 0;
      video_bitrate = 0;
      fec_bitrate = 0;
      nack_bitrate = 0;
    }
    return 0;
  }
  WEBRTC_FUNC_CONST(GetEstimatedSendBandwidth, (const int channel,
      unsigned int* send_bandwidth_estimate)) {
    WEBRTC_CHECK_CHANNEL(channel);
    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
    // Assume the current video, fec and nack bitrate sums up to our estimate.
    if (it->second->send) {
      it = channels_.find(GetOriginalChannelId(channel));
      *send_bandwidth_estimate = it->second->send_bandwidth_;
    } else {
      *send_bandwidth_estimate = 0;
    }
    return 0;
  }
  WEBRTC_FUNC_CONST(GetEstimatedReceiveBandwidth, (const int channel,
      unsigned int* receive_bandwidth_estimate)) {
    WEBRTC_CHECK_CHANNEL(channel);
    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
    if (it->second->receive_) {
      it = channels_.find(GetOriginalChannelId(channel));
      *receive_bandwidth_estimate = it->second->receive_bandwidth_;
    } else {
      *receive_bandwidth_estimate = 0;
    }
    return 0;
  }
  WEBRTC_STUB(RegisterSendChannelRtcpStatisticsCallback,
                    (int, webrtc::RtcpStatisticsCallback*));
  WEBRTC_STUB(DeregisterSendChannelRtcpStatisticsCallback,
                    (int, webrtc::RtcpStatisticsCallback*));
  WEBRTC_STUB(RegisterReceiveChannelRtcpStatisticsCallback,
                    (int, webrtc::RtcpStatisticsCallback*));
  WEBRTC_STUB(DeregisterReceiveChannelRtcpStatisticsCallback,
                    (int, webrtc::RtcpStatisticsCallback*));
  WEBRTC_STUB(RegisterSendChannelRtpStatisticsCallback,
                    (int, webrtc::StreamDataCountersCallback*));
  WEBRTC_STUB(DeregisterSendChannelRtpStatisticsCallback,
                    (int, webrtc::StreamDataCountersCallback*));
  WEBRTC_STUB(RegisterReceiveChannelRtpStatisticsCallback,
                    (int, webrtc::StreamDataCountersCallback*));
  WEBRTC_STUB(DeregisterReceiveChannelRtpStatisticsCallback,
                    (int, webrtc::StreamDataCountersCallback*));
  WEBRTC_STUB(RegisterSendBitrateObserver,
                    (int, webrtc::BitrateStatisticsObserver*));
  WEBRTC_STUB(DeregisterSendBitrateObserver,
                    (int, webrtc::BitrateStatisticsObserver*));
  WEBRTC_STUB(RegisterSendFrameCountObserver,
                    (int, webrtc::FrameCountObserver*));
  WEBRTC_STUB(DeregisterSendFrameCountObserver,
                    (int, webrtc::FrameCountObserver*));
  WEBRTC_STUB(RegisterRtcpPacketTypeCounterObserver,
                    (int, webrtc::RtcpPacketTypeCounterObserver*));

  WEBRTC_STUB(StartRTPDump, (const int, const char*, webrtc::RTPDirections));
  WEBRTC_STUB(StopRTPDump, (const int, webrtc::RTPDirections));
  WEBRTC_STUB(RegisterRTPObserver, (const int, webrtc::ViERTPObserver&));
  WEBRTC_STUB(DeregisterRTPObserver, (const int));

  // webrtc::ViEImageProcess
  WEBRTC_STUB(RegisterCaptureEffectFilter, (const int,
      webrtc::ViEEffectFilter&));
  WEBRTC_STUB(DeregisterCaptureEffectFilter, (const int));
  WEBRTC_STUB(RegisterSendEffectFilter, (const int,
      webrtc::ViEEffectFilter&));
  WEBRTC_STUB(DeregisterSendEffectFilter, (const int));
  WEBRTC_STUB(RegisterRenderEffectFilter, (const int,
      webrtc::ViEEffectFilter&));
  WEBRTC_STUB(DeregisterRenderEffectFilter, (const int));
  WEBRTC_STUB(EnableDeflickering, (const int, const bool));
  WEBRTC_FUNC(EnableDenoising, (const int capture_id, const bool denoising)) {
    WEBRTC_CHECK_CAPTURER(capture_id);
    capturers_[capture_id]->set_denoising(denoising);
    return 0;
  }
  WEBRTC_STUB(EnableColorEnhancement, (const int, const bool));
  WEBRTC_VOID_STUB(RegisterPreEncodeCallback,
                   (int, webrtc::I420FrameCallback*));
  WEBRTC_VOID_STUB(DeRegisterPreEncodeCallback, (int));
  WEBRTC_VOID_STUB(RegisterPreRenderCallback,
                   (int, webrtc::I420FrameCallback*));
  WEBRTC_VOID_STUB(DeRegisterPreRenderCallback, (int));
  // webrtc::ViEExternalCodec
  WEBRTC_FUNC(RegisterExternalSendCodec,
      (const int channel, const unsigned char pl_type, webrtc::VideoEncoder*,
          bool)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->ext_encoder_pl_types_.insert(pl_type);
    return 0;
  }
  WEBRTC_FUNC(DeRegisterExternalSendCodec,
      (const int channel, const unsigned char pl_type)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->ext_encoder_pl_types_.erase(pl_type);
    return 0;
  }
  WEBRTC_FUNC(RegisterExternalReceiveCodec,
      (const int channel, const unsigned char pl_type, webrtc::VideoDecoder*,
       bool, int)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->ext_decoder_pl_types_.insert(pl_type);
    return 0;
  }
  WEBRTC_FUNC(DeRegisterExternalReceiveCodec,
      (const int channel, const unsigned char pl_type)) {
    WEBRTC_CHECK_CHANNEL(channel);
    channels_[channel]->ext_decoder_pl_types_.erase(pl_type);
    return 0;
  }

 private:
  bool IsChannelId(int id) const {
    return (id >= kViEChannelIdBase && id <= kViEChannelIdMax);
  }
  bool IsCapturerId(int id) const {
    return (id >= kViECaptureIdBase && id <= kViECaptureIdMax);
  }

  bool inited_;
  int last_channel_;
  std::map<int, Channel*> channels_;
  bool fail_create_channel_;
  int last_capturer_;
  std::map<int, Capturer*> capturers_;
  bool fail_alloc_capturer_;
  const cricket::VideoCodec* const* codecs_;
  int num_codecs_;
  int num_set_send_codecs_;  // how many times we call SetSendCodec().
};

}  // namespace cricket

#endif  // TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
