/*
 * 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) {
    return WEBRTC_VIDEO_CODEC_OK;
  }

  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_);
};

// 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_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_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(SetRotateCapturedFrames, (const int,
      const webrtc::RotateCapturedFrame));
  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::RotateCapturedFrame&));
  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&));
  virtual bool SetBandwidthEstimationConfig(int, const webrtc::Config&) {
    return true;
  }

  // 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_STUB(MirrorRenderStream, (const int, const bool, const bool,
      const bool));
  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(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 int 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_
