1/*
2 * libjingle
3 * Copyright 2010 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
29#define TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
30
31#include <map>
32#include <set>
33#include <vector>
34
35#include "talk/base/basictypes.h"
36#include "talk/base/stringutils.h"
37#include "talk/media/base/codec.h"
38#include "talk/media/webrtc/fakewebrtccommon.h"
39#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
40#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
41#include "talk/media/webrtc/webrtcvie.h"
42
43namespace webrtc {
44
45bool operator==(const webrtc::VideoCodec& c1, const webrtc::VideoCodec& c2) {
46  return memcmp(&c1, &c2, sizeof(c1)) == 0;
47}
48
49}
50
51namespace cricket {
52
53#define WEBRTC_CHECK_CAPTURER(capturer) \
54  if (capturers_.find(capturer) == capturers_.end()) return -1;
55
56#define WEBRTC_ASSERT_CAPTURER(capturer) \
57  ASSERT(capturers_.find(capturer) != capturers_.end());
58
59static const int kMinVideoBitrate = 100;
60static const int kStartVideoBitrate = 300;
61static const int kMaxVideoBitrate = 1000;
62
63// WebRtc channel id and capture id share the same number space.
64// This is how AddRenderer(renderId, ...) is able to tell if it is adding a
65// renderer for a channel or it is adding a renderer for a capturer.
66static const int kViEChannelIdBase = 0;
67static const int kViEChannelIdMax = 1000;
68static const int kViECaptureIdBase = 10000;  // Make sure there is a gap.
69static const int kViECaptureIdMax = 11000;
70
71// Fake class for mocking out webrtc::VideoDecoder
72class FakeWebRtcVideoDecoder : public webrtc::VideoDecoder {
73 public:
74  FakeWebRtcVideoDecoder()
75      : num_frames_received_(0) {
76  }
77
78  virtual int32 InitDecode(const webrtc::VideoCodec*, int32) {
79    return WEBRTC_VIDEO_CODEC_OK;
80  }
81
82  virtual int32 Decode(
83      const webrtc::EncodedImage&, bool, const webrtc::RTPFragmentationHeader*,
84      const webrtc::CodecSpecificInfo*, int64) {
85    num_frames_received_++;
86    return WEBRTC_VIDEO_CODEC_OK;
87  }
88
89  virtual int32 RegisterDecodeCompleteCallback(
90      webrtc::DecodedImageCallback*) {
91    return WEBRTC_VIDEO_CODEC_OK;
92  }
93
94  virtual int32 Release() {
95    return WEBRTC_VIDEO_CODEC_OK;
96  }
97
98  virtual int32 Reset() {
99    return WEBRTC_VIDEO_CODEC_OK;
100  }
101
102  int GetNumFramesReceived() const {
103    return num_frames_received_;
104  }
105
106 private:
107  int num_frames_received_;
108};
109
110// Fake class for mocking out WebRtcVideoDecoderFactory.
111class FakeWebRtcVideoDecoderFactory : public WebRtcVideoDecoderFactory {
112 public:
113  FakeWebRtcVideoDecoderFactory()
114      : num_created_decoders_(0) {
115  }
116
117  virtual webrtc::VideoDecoder* CreateVideoDecoder(
118      webrtc::VideoCodecType type) {
119    if (supported_codec_types_.count(type) == 0) {
120      return NULL;
121    }
122    FakeWebRtcVideoDecoder* decoder = new FakeWebRtcVideoDecoder();
123    decoders_.push_back(decoder);
124    num_created_decoders_++;
125    return decoder;
126  }
127
128  virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) {
129    decoders_.erase(
130        std::remove(decoders_.begin(), decoders_.end(), decoder),
131        decoders_.end());
132    delete decoder;
133  }
134
135  void AddSupportedVideoCodecType(webrtc::VideoCodecType type) {
136    supported_codec_types_.insert(type);
137  }
138
139  int GetNumCreatedDecoders() {
140    return num_created_decoders_;
141  }
142
143  const std::vector<FakeWebRtcVideoDecoder*>& decoders() {
144    return decoders_;
145  }
146
147 private:
148  std::set<webrtc::VideoCodecType> supported_codec_types_;
149  std::vector<FakeWebRtcVideoDecoder*> decoders_;
150  int num_created_decoders_;
151};
152
153// Fake class for mocking out webrtc::VideoEnoder
154class FakeWebRtcVideoEncoder : public webrtc::VideoEncoder {
155 public:
156  FakeWebRtcVideoEncoder() {}
157
158  virtual int32 InitEncode(const webrtc::VideoCodec* codecSettings,
159                           int32 numberOfCores,
160                           uint32 maxPayloadSize) {
161    return WEBRTC_VIDEO_CODEC_OK;
162  }
163
164  virtual int32 Encode(
165      const webrtc::I420VideoFrame& inputImage,
166            const webrtc::CodecSpecificInfo* codecSpecificInfo,
167            const std::vector<webrtc::VideoFrameType>* frame_types) {
168    return WEBRTC_VIDEO_CODEC_OK;
169  }
170
171  virtual int32 RegisterEncodeCompleteCallback(
172      webrtc::EncodedImageCallback* callback) {
173    return WEBRTC_VIDEO_CODEC_OK;
174  }
175
176  virtual int32 Release() {
177    return WEBRTC_VIDEO_CODEC_OK;
178  }
179
180  virtual int32 SetChannelParameters(uint32 packetLoss,
181                                     int rtt) {
182    return WEBRTC_VIDEO_CODEC_OK;
183  }
184
185  virtual int32 SetRates(uint32 newBitRate,
186                         uint32 frameRate) {
187    return WEBRTC_VIDEO_CODEC_OK;
188  }
189};
190
191// Fake class for mocking out WebRtcVideoEncoderFactory.
192class FakeWebRtcVideoEncoderFactory : public WebRtcVideoEncoderFactory {
193 public:
194  FakeWebRtcVideoEncoderFactory()
195      : num_created_encoders_(0) {
196  }
197
198  virtual webrtc::VideoEncoder* CreateVideoEncoder(
199      webrtc::VideoCodecType type) {
200    if (supported_codec_types_.count(type) == 0) {
201      return NULL;
202    }
203    FakeWebRtcVideoEncoder* encoder = new FakeWebRtcVideoEncoder();
204    encoders_.push_back(encoder);
205    num_created_encoders_++;
206    return encoder;
207  }
208
209  virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) {
210    encoders_.erase(
211        std::remove(encoders_.begin(), encoders_.end(), encoder),
212        encoders_.end());
213    delete encoder;
214  }
215
216  virtual void AddObserver(WebRtcVideoEncoderFactory::Observer* observer) {
217    bool inserted = observers_.insert(observer).second;
218    EXPECT_TRUE(inserted);
219  }
220
221  virtual void RemoveObserver(WebRtcVideoEncoderFactory::Observer* observer) {
222    size_t erased = observers_.erase(observer);
223    EXPECT_EQ(erased, 1UL);
224  }
225
226  virtual const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs()
227      const {
228    return codecs_;
229  }
230
231  void AddSupportedVideoCodecType(webrtc::VideoCodecType type,
232                                  const std::string& name) {
233    supported_codec_types_.insert(type);
234    codecs_.push_back(
235        WebRtcVideoEncoderFactory::VideoCodec(type, name, 1280, 720, 30));
236  }
237
238  void NotifyCodecsAvailable() {
239    std::set<WebRtcVideoEncoderFactory::Observer*>::iterator it;
240    for (it = observers_.begin(); it != observers_.end(); ++it)
241      (*it)->OnCodecsAvailable();
242  }
243
244  int GetNumCreatedEncoders() {
245    return num_created_encoders_;
246  }
247
248  const std::vector<FakeWebRtcVideoEncoder*>& encoders() {
249    return encoders_;
250  }
251
252 private:
253  std::set<webrtc::VideoCodecType> supported_codec_types_;
254  std::vector<WebRtcVideoEncoderFactory::VideoCodec> codecs_;
255  std::vector<FakeWebRtcVideoEncoder*> encoders_;
256  std::set<WebRtcVideoEncoderFactory::Observer*> observers_;
257  int num_created_encoders_;
258};
259
260class FakeWebRtcVideoEngine
261    : public webrtc::ViEBase,
262      public webrtc::ViECodec,
263      public webrtc::ViECapture,
264      public webrtc::ViENetwork,
265      public webrtc::ViERender,
266      public webrtc::ViERTP_RTCP,
267      public webrtc::ViEImageProcess,
268      public webrtc::ViEExternalCodec {
269 public:
270  struct Channel {
271    Channel()
272        : capture_id_(-1),
273          original_channel_id_(-1),
274          has_renderer_(false),
275          render_started_(false),
276          send(false),
277          receive_(false),
278          can_transmit_(true),
279          rtcp_status_(webrtc::kRtcpNone),
280          key_frame_request_method_(webrtc::kViEKeyFrameRequestNone),
281          tmmbr_(false),
282          remb_contribute_(false),
283          remb_bw_partition_(false),
284          rtp_offset_send_id_(0),
285          rtp_offset_receive_id_(0),
286          rtp_absolute_send_time_send_id_(0),
287          rtp_absolute_send_time_receive_id_(0),
288          sender_target_delay_(0),
289          receiver_target_delay_(0),
290          transmission_smoothing_(false),
291          nack_(false),
292          hybrid_nack_fec_(false),
293          send_video_bitrate_(0),
294          send_fec_bitrate_(0),
295          send_nack_bitrate_(0),
296          send_bandwidth_(0),
297          receive_bandwidth_(0) {
298      ssrcs_[0] = 0;  // default ssrc.
299      memset(&send_codec, 0, sizeof(send_codec));
300    }
301    int capture_id_;
302    int original_channel_id_;
303    bool has_renderer_;
304    bool render_started_;
305    bool send;
306    bool receive_;
307    bool can_transmit_;
308    std::map<int, int> ssrcs_;
309    std::string cname_;
310    webrtc::ViERTCPMode rtcp_status_;
311    webrtc::ViEKeyFrameRequestMethod key_frame_request_method_;
312    bool tmmbr_;
313    bool remb_contribute_;   // This channel contributes to the remb report.
314    bool remb_bw_partition_; // This channel is allocated part of total bw.
315    int rtp_offset_send_id_;
316    int rtp_offset_receive_id_;
317    int rtp_absolute_send_time_send_id_;
318    int rtp_absolute_send_time_receive_id_;
319    int sender_target_delay_;
320    int receiver_target_delay_;
321    bool transmission_smoothing_;
322    bool nack_;
323    bool hybrid_nack_fec_;
324    std::vector<webrtc::VideoCodec> recv_codecs;
325    std::set<unsigned int> ext_decoder_pl_types_;
326    std::set<unsigned int> ext_encoder_pl_types_;
327    webrtc::VideoCodec send_codec;
328    unsigned int send_video_bitrate_;
329    unsigned int send_fec_bitrate_;
330    unsigned int send_nack_bitrate_;
331    unsigned int send_bandwidth_;
332    unsigned int receive_bandwidth_;
333  };
334  class Capturer : public webrtc::ViEExternalCapture {
335   public:
336    Capturer() : channel_id_(-1), denoising_(false), last_capture_time_(0) { }
337    int channel_id() const { return channel_id_; }
338    void set_channel_id(int channel_id) { channel_id_ = channel_id; }
339    bool denoising() const { return denoising_; }
340    void set_denoising(bool denoising) { denoising_ = denoising; }
341    int64 last_capture_time() { return last_capture_time_; }
342
343    // From ViEExternalCapture
344    virtual int IncomingFrame(unsigned char* videoFrame,
345                              unsigned int videoFrameLength,
346                              unsigned short width,
347                              unsigned short height,
348                              webrtc::RawVideoType videoType,
349                              unsigned long long captureTime) {
350      return 0;
351    }
352    virtual int IncomingFrameI420(
353        const webrtc::ViEVideoFrameI420& video_frame,
354        unsigned long long captureTime) {
355      last_capture_time_ = captureTime;
356      return 0;
357    }
358
359   private:
360    int channel_id_;
361    bool denoising_;
362    int64 last_capture_time_;
363  };
364
365  FakeWebRtcVideoEngine(const cricket::VideoCodec* const* codecs,
366                        int num_codecs)
367      : inited_(false),
368        last_channel_(kViEChannelIdBase - 1),
369        fail_create_channel_(false),
370        last_capturer_(kViECaptureIdBase - 1),
371        fail_alloc_capturer_(false),
372        codecs_(codecs),
373        num_codecs_(num_codecs),
374        num_set_send_codecs_(0) {
375  }
376
377  ~FakeWebRtcVideoEngine() {
378    ASSERT(0 == channels_.size());
379    ASSERT(0 == capturers_.size());
380  }
381  bool IsInited() const { return inited_; }
382
383  int GetLastChannel() const { return last_channel_; }
384  int GetChannelFromLocalSsrc(int local_ssrc) const {
385    // ssrcs_[0] is the default local ssrc.
386    for (std::map<int, Channel*>::const_iterator iter = channels_.begin();
387         iter != channels_.end(); ++iter) {
388      if (local_ssrc == iter->second->ssrcs_[0]) {
389        return iter->first;
390      }
391    }
392    return -1;
393  }
394
395  int GetNumChannels() const { return static_cast<int>(channels_.size()); }
396  bool IsChannel(int channel) const {
397    return (channels_.find(channel) != channels_.end());
398  }
399  void set_fail_create_channel(bool fail_create_channel) {
400    fail_create_channel_ = fail_create_channel;
401  }
402
403  int GetLastCapturer() const { return last_capturer_; }
404  int GetNumCapturers() const { return static_cast<int>(capturers_.size()); }
405  void set_fail_alloc_capturer(bool fail_alloc_capturer) {
406    fail_alloc_capturer_ = fail_alloc_capturer;
407  }
408  int num_set_send_codecs() const { return num_set_send_codecs_; }
409
410  int GetCaptureId(int channel) const {
411    WEBRTC_ASSERT_CHANNEL(channel);
412    return channels_.find(channel)->second->capture_id_;
413  }
414  int GetOriginalChannelId(int channel) const {
415    WEBRTC_ASSERT_CHANNEL(channel);
416    return channels_.find(channel)->second->original_channel_id_;
417  }
418  bool GetHasRenderer(int channel) const {
419    WEBRTC_ASSERT_CHANNEL(channel);
420    return channels_.find(channel)->second->has_renderer_;
421  }
422  bool GetRenderStarted(int channel) const {
423    WEBRTC_ASSERT_CHANNEL(channel);
424    return channels_.find(channel)->second->render_started_;
425  }
426  bool GetSend(int channel) const {
427    WEBRTC_ASSERT_CHANNEL(channel);
428    return channels_.find(channel)->second->send;
429  }
430  int GetCaptureChannelId(int capture_id) const {
431    WEBRTC_ASSERT_CAPTURER(capture_id);
432    return capturers_.find(capture_id)->second->channel_id();
433  }
434  bool GetCaptureDenoising(int capture_id) const {
435    WEBRTC_ASSERT_CAPTURER(capture_id);
436    return capturers_.find(capture_id)->second->denoising();
437  }
438  int64 GetCaptureLastTimestamp(int capture_id) const {
439    WEBRTC_ASSERT_CAPTURER(capture_id);
440    return capturers_.find(capture_id)->second->last_capture_time();
441  }
442  webrtc::ViERTCPMode GetRtcpStatus(int channel) const {
443    WEBRTC_ASSERT_CHANNEL(channel);
444    return channels_.find(channel)->second->rtcp_status_;
445  }
446  webrtc::ViEKeyFrameRequestMethod GetKeyFrameRequestMethod(int channel) const {
447    WEBRTC_ASSERT_CHANNEL(channel);
448    return channels_.find(channel)->second->key_frame_request_method_;
449  }
450  bool GetTmmbrStatus(int channel) const {
451    WEBRTC_ASSERT_CHANNEL(channel);
452    return channels_.find(channel)->second->tmmbr_;
453  }
454  bool GetRembStatusBwPartition(int channel) const {
455    WEBRTC_ASSERT_CHANNEL(channel);
456    return channels_.find(channel)->second->remb_bw_partition_;
457  }
458  bool GetRembStatusContribute(int channel) const {
459    WEBRTC_ASSERT_CHANNEL(channel);
460    return channels_.find(channel)->second->remb_contribute_;
461  }
462  int GetSendRtpTimestampOffsetExtensionId(int channel) {
463    WEBRTC_ASSERT_CHANNEL(channel);
464    return channels_.find(channel)->second->rtp_offset_send_id_;
465  }
466  int GetReceiveRtpTimestampOffsetExtensionId(int channel) {
467    WEBRTC_ASSERT_CHANNEL(channel);
468    return channels_.find(channel)->second->rtp_offset_receive_id_;
469  }
470  int GetSendAbsoluteSendTimeExtensionId(int channel) {
471    WEBRTC_ASSERT_CHANNEL(channel);
472    return channels_.find(channel)->second->rtp_absolute_send_time_send_id_;
473  }
474  int GetReceiveAbsoluteSendTimeExtensionId(int channel) {
475    WEBRTC_ASSERT_CHANNEL(channel);
476    return channels_.find(channel)->second->rtp_absolute_send_time_receive_id_;
477  }
478  bool GetTransmissionSmoothingStatus(int channel) {
479    WEBRTC_ASSERT_CHANNEL(channel);
480    return channels_.find(channel)->second->transmission_smoothing_;
481  }
482  int GetSenderTargetDelay(int channel) {
483    WEBRTC_ASSERT_CHANNEL(channel);
484    return channels_.find(channel)->second->sender_target_delay_;
485  }
486  int GetReceiverTargetDelay(int channel) {
487    WEBRTC_ASSERT_CHANNEL(channel);
488    return channels_.find(channel)->second->receiver_target_delay_;
489  }
490  bool GetNackStatus(int channel) const {
491    WEBRTC_ASSERT_CHANNEL(channel);
492    return channels_.find(channel)->second->nack_;
493  }
494  bool GetHybridNackFecStatus(int channel) const {
495    WEBRTC_ASSERT_CHANNEL(channel);
496    return channels_.find(channel)->second->hybrid_nack_fec_;
497  }
498  int GetNumSsrcs(int channel) const {
499    WEBRTC_ASSERT_CHANNEL(channel);
500    return static_cast<int>(
501        channels_.find(channel)->second->ssrcs_.size());
502  }
503  bool GetIsTransmitting(int channel) const {
504    WEBRTC_ASSERT_CHANNEL(channel);
505    return channels_.find(channel)->second->can_transmit_;
506  }
507  bool ReceiveCodecRegistered(int channel,
508                              const webrtc::VideoCodec& codec) const {
509    WEBRTC_ASSERT_CHANNEL(channel);
510    const std::vector<webrtc::VideoCodec>& codecs =
511      channels_.find(channel)->second->recv_codecs;
512    return std::find(codecs.begin(), codecs.end(), codec) != codecs.end();
513  };
514  bool ExternalDecoderRegistered(int channel,
515                                 unsigned int pl_type) const {
516    WEBRTC_ASSERT_CHANNEL(channel);
517    return channels_.find(channel)->second->
518        ext_decoder_pl_types_.count(pl_type) != 0;
519  };
520  int GetNumExternalDecoderRegistered(int channel) const {
521    WEBRTC_ASSERT_CHANNEL(channel);
522    return static_cast<int>(
523        channels_.find(channel)->second->ext_decoder_pl_types_.size());
524  };
525  bool ExternalEncoderRegistered(int channel,
526                                 unsigned int pl_type) const {
527    WEBRTC_ASSERT_CHANNEL(channel);
528    return channels_.find(channel)->second->
529        ext_encoder_pl_types_.count(pl_type) != 0;
530  };
531  int GetNumExternalEncoderRegistered(int channel) const {
532    WEBRTC_ASSERT_CHANNEL(channel);
533    return static_cast<int>(
534        channels_.find(channel)->second->ext_encoder_pl_types_.size());
535  };
536  int GetTotalNumExternalEncoderRegistered() const {
537    std::map<int, Channel*>::const_iterator it;
538    int total_num_registered = 0;
539    for (it = channels_.begin(); it != channels_.end(); ++it)
540      total_num_registered +=
541          static_cast<int>(it->second->ext_encoder_pl_types_.size());
542    return total_num_registered;
543  }
544  void SetSendBitrates(int channel, unsigned int video_bitrate,
545                       unsigned int fec_bitrate, unsigned int nack_bitrate) {
546    WEBRTC_ASSERT_CHANNEL(channel);
547    channels_[channel]->send_video_bitrate_ = video_bitrate;
548    channels_[channel]->send_fec_bitrate_ = fec_bitrate;
549    channels_[channel]->send_nack_bitrate_ = nack_bitrate;
550  }
551  void SetSendBandwidthEstimate(int channel, unsigned int send_bandwidth) {
552    WEBRTC_ASSERT_CHANNEL(channel);
553    channels_[channel]->send_bandwidth_ = send_bandwidth;
554  }
555  void SetReceiveBandwidthEstimate(int channel,
556                                   unsigned int receive_bandwidth) {
557    WEBRTC_ASSERT_CHANNEL(channel);
558    channels_[channel]->receive_bandwidth_ = receive_bandwidth;
559  };
560
561  WEBRTC_STUB(Release, ());
562
563  // webrtc::ViEBase
564  WEBRTC_FUNC(Init, ()) {
565    inited_ = true;
566    return 0;
567  };
568  WEBRTC_STUB(SetVoiceEngine, (webrtc::VoiceEngine*));
569  WEBRTC_FUNC(CreateChannel, (int& channel)) {  // NOLINT
570    if (fail_create_channel_) {
571      return -1;
572    }
573    if (kViEChannelIdMax == last_channel_) {
574      return -1;
575    }
576    Channel* ch = new Channel();
577    channels_[++last_channel_] = ch;
578    channel = last_channel_;
579    return 0;
580  };
581  WEBRTC_FUNC(CreateChannel, (int& channel, int original_channel)) {
582    WEBRTC_CHECK_CHANNEL(original_channel);
583    if (CreateChannel(channel) != 0) {
584      return -1;
585    }
586    channels_[channel]->original_channel_id_ = original_channel;
587    return 0;
588  }
589  WEBRTC_FUNC(CreateReceiveChannel, (int& channel, int original_channel)) {
590    return CreateChannel(channel, original_channel);
591  }
592  WEBRTC_FUNC(DeleteChannel, (const int channel)) {
593    WEBRTC_CHECK_CHANNEL(channel);
594    // Make sure we deregister all the decoders before deleting a channel.
595    EXPECT_EQ(0, GetNumExternalDecoderRegistered(channel));
596    delete channels_[channel];
597    channels_.erase(channel);
598    return 0;
599  }
600  WEBRTC_STUB(RegisterCpuOveruseObserver,
601      (int channel, webrtc::CpuOveruseObserver* observer));
602  WEBRTC_STUB(ConnectAudioChannel, (const int, const int));
603  WEBRTC_STUB(DisconnectAudioChannel, (const int));
604  WEBRTC_FUNC(StartSend, (const int channel)) {
605    WEBRTC_CHECK_CHANNEL(channel);
606    channels_[channel]->send = true;
607    return 0;
608  }
609  WEBRTC_FUNC(StopSend, (const int channel)) {
610    WEBRTC_CHECK_CHANNEL(channel);
611    channels_[channel]->send = false;
612    return 0;
613  }
614  WEBRTC_FUNC(StartReceive, (const int channel)) {
615    WEBRTC_CHECK_CHANNEL(channel);
616    channels_[channel]->receive_ = true;
617    return 0;
618  }
619  WEBRTC_FUNC(StopReceive, (const int channel)) {
620    WEBRTC_CHECK_CHANNEL(channel);
621    channels_[channel]->receive_ = false;
622    return 0;
623  }
624  WEBRTC_STUB(GetVersion, (char version[1024]));
625  WEBRTC_STUB(LastError, ());
626
627  // webrtc::ViECodec
628  WEBRTC_FUNC_CONST(NumberOfCodecs, ()) {
629    return num_codecs_;
630  };
631  WEBRTC_FUNC_CONST(GetCodec, (const unsigned char list_number,
632                               webrtc::VideoCodec& out_codec)) {
633    if (list_number >= NumberOfCodecs()) {
634      return -1;
635    }
636    memset(&out_codec, 0, sizeof(out_codec));
637    const cricket::VideoCodec& c(*codecs_[list_number]);
638    if ("I420" == c.name) {
639      out_codec.codecType = webrtc::kVideoCodecI420;
640    } else if ("VP8" == c.name) {
641      out_codec.codecType = webrtc::kVideoCodecVP8;
642    } else if ("red" == c.name) {
643      out_codec.codecType = webrtc::kVideoCodecRED;
644    } else if ("ulpfec" == c.name) {
645      out_codec.codecType = webrtc::kVideoCodecULPFEC;
646    } else {
647      out_codec.codecType = webrtc::kVideoCodecUnknown;
648    }
649    talk_base::strcpyn(out_codec.plName, sizeof(out_codec.plName),
650                       c.name.c_str());
651    out_codec.plType = c.id;
652    out_codec.width = c.width;
653    out_codec.height = c.height;
654    out_codec.startBitrate = kStartVideoBitrate;
655    out_codec.maxBitrate = kMaxVideoBitrate;
656    out_codec.minBitrate = kMinVideoBitrate;
657    out_codec.maxFramerate = c.framerate;
658    return 0;
659  };
660  WEBRTC_FUNC(SetSendCodec, (const int channel,
661                             const webrtc::VideoCodec& codec)) {
662    WEBRTC_CHECK_CHANNEL(channel);
663    channels_[channel]->send_codec = codec;
664    ++num_set_send_codecs_;
665    return 0;
666  };
667  WEBRTC_FUNC_CONST(GetSendCodec, (const int channel,
668                                   webrtc::VideoCodec& codec)) {  // NOLINT
669    WEBRTC_CHECK_CHANNEL(channel);
670    codec = channels_.find(channel)->second->send_codec;
671    return 0;
672  };
673  WEBRTC_FUNC(SetReceiveCodec, (const int channel,
674                                const webrtc::VideoCodec& codec)) {  // NOLINT
675    WEBRTC_CHECK_CHANNEL(channel);
676    channels_[channel]->recv_codecs.push_back(codec);
677    return 0;
678  };
679  WEBRTC_STUB_CONST(GetReceiveCodec, (const int, webrtc::VideoCodec&));
680  WEBRTC_STUB_CONST(GetCodecConfigParameters, (const int,
681      unsigned char*, unsigned char&));
682  WEBRTC_STUB(SetImageScaleStatus, (const int, const bool));
683  WEBRTC_STUB_CONST(GetSendCodecStastistics, (const int,
684      unsigned int&, unsigned int&));
685  WEBRTC_STUB_CONST(GetReceiveCodecStastistics, (const int,
686      unsigned int&, unsigned int&));
687  WEBRTC_STUB_CONST(GetReceiveSideDelay, (const int video_channel,
688                                          int* delay_ms));
689  WEBRTC_FUNC_CONST(GetCodecTargetBitrate, (const int channel,
690      unsigned int* codec_target_bitrate)) {
691    WEBRTC_CHECK_CHANNEL(channel);
692
693    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
694    if (it->second->send) {
695      // Assume the encoder produces the expected rate.
696      *codec_target_bitrate = it->second->send_video_bitrate_;
697    } else {
698      *codec_target_bitrate = 0;
699    }
700    return 0;
701  }
702  virtual unsigned int GetDiscardedPackets(const int channel) const {
703    return 0;
704  }
705
706  WEBRTC_STUB(SetKeyFrameRequestCallbackStatus, (const int, const bool));
707  WEBRTC_STUB(SetSignalKeyPacketLossStatus, (const int, const bool,
708      const bool));
709  WEBRTC_STUB(RegisterEncoderObserver, (const int,
710      webrtc::ViEEncoderObserver&));
711  WEBRTC_STUB(DeregisterEncoderObserver, (const int));
712  WEBRTC_STUB(RegisterDecoderObserver, (const int,
713      webrtc::ViEDecoderObserver&));
714  WEBRTC_STUB(DeregisterDecoderObserver, (const int));
715  WEBRTC_STUB(SendKeyFrame, (const int));
716  WEBRTC_STUB(WaitForFirstKeyFrame, (const int, const bool));
717  WEBRTC_STUB(StartDebugRecording, (int, const char*));
718  WEBRTC_STUB(StopDebugRecording, (int));
719
720  // webrtc::ViECapture
721  WEBRTC_STUB(NumberOfCaptureDevices, ());
722  WEBRTC_STUB(GetCaptureDevice, (unsigned int, char*,
723      const unsigned int, char*, const unsigned int));
724  WEBRTC_STUB(AllocateCaptureDevice, (const char*, const unsigned int, int&));
725  WEBRTC_FUNC(AllocateExternalCaptureDevice,
726              (int& capture_id, webrtc::ViEExternalCapture*& capture)) {
727    if (fail_alloc_capturer_) {
728      return -1;
729    }
730    if (kViECaptureIdMax == last_capturer_) {
731      return -1;
732    }
733    Capturer* cap = new Capturer();
734    capturers_[++last_capturer_] = cap;
735    capture_id = last_capturer_;
736    capture = cap;
737    return 0;
738  }
739  WEBRTC_STUB(AllocateCaptureDevice, (webrtc::VideoCaptureModule&, int&));
740  WEBRTC_FUNC(ReleaseCaptureDevice, (const int capture_id)) {
741    WEBRTC_CHECK_CAPTURER(capture_id);
742    delete capturers_[capture_id];
743    capturers_.erase(capture_id);
744    return 0;
745  }
746  WEBRTC_FUNC(ConnectCaptureDevice, (const int capture_id,
747                                     const int channel)) {
748    WEBRTC_CHECK_CHANNEL(channel);
749    WEBRTC_CHECK_CAPTURER(capture_id);
750    channels_[channel]->capture_id_ = capture_id;
751    capturers_[capture_id]->set_channel_id(channel);
752    return 0;
753  }
754  WEBRTC_FUNC(DisconnectCaptureDevice, (const int channel)) {
755    WEBRTC_CHECK_CHANNEL(channel);
756    int capture_id = channels_[channel]->capture_id_;
757    WEBRTC_CHECK_CAPTURER(capture_id);
758    channels_[channel]->capture_id_ = -1;
759    capturers_[capture_id]->set_channel_id(-1);
760    return 0;
761  }
762  WEBRTC_STUB(StartCapture, (const int, const webrtc::CaptureCapability&));
763  WEBRTC_STUB(StopCapture, (const int));
764  WEBRTC_STUB(SetRotateCapturedFrames, (const int,
765      const webrtc::RotateCapturedFrame));
766  WEBRTC_STUB(SetCaptureDelay, (const int, const unsigned int));
767  WEBRTC_STUB(NumberOfCapabilities, (const char*, const unsigned int));
768  WEBRTC_STUB(GetCaptureCapability, (const char*, const unsigned int,
769      const unsigned int, webrtc::CaptureCapability&));
770  WEBRTC_STUB(ShowCaptureSettingsDialogBox, (const char*, const unsigned int,
771      const char*, void*, const unsigned int, const unsigned int));
772  WEBRTC_STUB(GetOrientation, (const char*, webrtc::RotateCapturedFrame&));
773  WEBRTC_STUB(EnableBrightnessAlarm, (const int, const bool));
774  WEBRTC_STUB(RegisterObserver, (const int, webrtc::ViECaptureObserver&));
775  WEBRTC_STUB(DeregisterObserver, (const int));
776
777  // webrtc::ViENetwork
778  WEBRTC_VOID_FUNC(SetNetworkTransmissionState, (const int channel,
779                                                 const bool is_transmitting)) {
780    WEBRTC_ASSERT_CHANNEL(channel);
781    channels_[channel]->can_transmit_ = is_transmitting;
782  }
783  WEBRTC_STUB(RegisterSendTransport, (const int, webrtc::Transport&));
784  WEBRTC_STUB(DeregisterSendTransport, (const int));
785  WEBRTC_STUB(ReceivedRTPPacket, (const int, const void*, const int));
786  WEBRTC_STUB(ReceivedRTCPPacket, (const int, const void*, const int));
787  // Not using WEBRTC_STUB due to bool return value
788  virtual bool IsIPv6Enabled(int channel) { return true; }
789  WEBRTC_STUB(SetMTU, (int, unsigned int));
790  WEBRTC_STUB(SetPacketTimeoutNotification, (const int, bool, int));
791  WEBRTC_STUB(RegisterObserver, (const int, webrtc::ViENetworkObserver&));
792  WEBRTC_STUB(SetPeriodicDeadOrAliveStatus, (const int, const bool,
793    const unsigned int));
794
795  // webrtc::ViERender
796  WEBRTC_STUB(RegisterVideoRenderModule, (webrtc::VideoRender&));
797  WEBRTC_STUB(DeRegisterVideoRenderModule, (webrtc::VideoRender&));
798  WEBRTC_STUB(AddRenderer, (const int, void*, const unsigned int, const float,
799      const float, const float, const float));
800  WEBRTC_FUNC(RemoveRenderer, (const int render_id)) {
801    if (IsCapturerId(render_id)) {
802      WEBRTC_CHECK_CAPTURER(render_id);
803      return 0;
804    } else if (IsChannelId(render_id)) {
805      WEBRTC_CHECK_CHANNEL(render_id);
806      channels_[render_id]->has_renderer_ = false;
807      return 0;
808    }
809    return -1;
810  }
811  WEBRTC_FUNC(StartRender, (const int render_id)) {
812    if (IsCapturerId(render_id)) {
813      WEBRTC_CHECK_CAPTURER(render_id);
814      return 0;
815    } else if (IsChannelId(render_id)) {
816      WEBRTC_CHECK_CHANNEL(render_id);
817      channels_[render_id]->render_started_ = true;
818      return 0;
819    }
820    return -1;
821  }
822  WEBRTC_FUNC(StopRender, (const int render_id)) {
823    if (IsCapturerId(render_id)) {
824      WEBRTC_CHECK_CAPTURER(render_id);
825      return 0;
826    } else if (IsChannelId(render_id)) {
827      WEBRTC_CHECK_CHANNEL(render_id);
828      channels_[render_id]->render_started_ = false;
829      return 0;
830    }
831    return -1;
832  }
833  WEBRTC_STUB(SetExpectedRenderDelay, (int render_id, int render_delay));
834  WEBRTC_STUB(ConfigureRender, (int, const unsigned int, const float,
835      const float, const float, const float));
836  WEBRTC_STUB(MirrorRenderStream, (const int, const bool, const bool,
837      const bool));
838  WEBRTC_FUNC(AddRenderer, (const int render_id,
839                            webrtc::RawVideoType video_type,
840                            webrtc::ExternalRenderer* renderer)) {
841    if (IsCapturerId(render_id)) {
842      WEBRTC_CHECK_CAPTURER(render_id);
843      return 0;
844    } else if (IsChannelId(render_id)) {
845      WEBRTC_CHECK_CHANNEL(render_id);
846      channels_[render_id]->has_renderer_ = true;
847      return 0;
848    }
849    return -1;
850  }
851
852  // webrtc::ViERTP_RTCP
853  WEBRTC_FUNC(SetLocalSSRC, (const int channel,
854                             const unsigned int ssrc,
855                             const webrtc::StreamType usage,
856                             const unsigned char idx)) {
857    WEBRTC_CHECK_CHANNEL(channel);
858    channels_[channel]->ssrcs_[idx] = ssrc;
859    return 0;
860  }
861  WEBRTC_STUB_CONST(SetRemoteSSRCType, (const int,
862        const webrtc::StreamType, const unsigned int));
863
864  WEBRTC_FUNC_CONST(GetLocalSSRC, (const int channel,
865                                   unsigned int& ssrc)) {
866    // ssrcs_[0] is the default local ssrc.
867    WEBRTC_CHECK_CHANNEL(channel);
868    ssrc = channels_.find(channel)->second->ssrcs_[0];
869    return 0;
870  }
871  WEBRTC_STUB_CONST(GetRemoteSSRC, (const int, unsigned int&));
872  WEBRTC_STUB_CONST(GetRemoteCSRCs, (const int, unsigned int*));
873
874  WEBRTC_STUB(SetRtxSendPayloadType, (const int, const uint8));
875  WEBRTC_STUB(SetRtxReceivePayloadType, (const int, const uint8));
876
877  WEBRTC_STUB(SetStartSequenceNumber, (const int, unsigned short));
878  WEBRTC_FUNC(SetRTCPStatus,
879              (const int channel, const webrtc::ViERTCPMode mode)) {
880    WEBRTC_CHECK_CHANNEL(channel);
881    channels_[channel]->rtcp_status_ = mode;
882    return 0;
883  }
884  WEBRTC_STUB_CONST(GetRTCPStatus, (const int, webrtc::ViERTCPMode&));
885  WEBRTC_FUNC(SetRTCPCName, (const int channel,
886                             const char rtcp_cname[KMaxRTCPCNameLength])) {
887    WEBRTC_CHECK_CHANNEL(channel);
888    channels_[channel]->cname_.assign(rtcp_cname);
889    return 0;
890  }
891  WEBRTC_FUNC_CONST(GetRTCPCName, (const int channel,
892                                   char rtcp_cname[KMaxRTCPCNameLength])) {
893    WEBRTC_CHECK_CHANNEL(channel);
894    talk_base::strcpyn(rtcp_cname, KMaxRTCPCNameLength,
895                       channels_.find(channel)->second->cname_.c_str());
896    return 0;
897  }
898  WEBRTC_STUB_CONST(GetRemoteRTCPCName, (const int, char*));
899  WEBRTC_STUB(SendApplicationDefinedRTCPPacket, (const int, const unsigned char,
900      unsigned int, const char*, unsigned short));
901  WEBRTC_FUNC(SetNACKStatus, (const int channel, const bool enable)) {
902    WEBRTC_CHECK_CHANNEL(channel);
903    channels_[channel]->nack_ = enable;
904    channels_[channel]->hybrid_nack_fec_ = false;
905    return 0;
906  }
907  WEBRTC_STUB(SetFECStatus, (const int, const bool, const unsigned char,
908      const unsigned char));
909  WEBRTC_FUNC(SetHybridNACKFECStatus, (const int channel, const bool enable,
910      const unsigned char red_type, const unsigned char fec_type)) {
911    WEBRTC_CHECK_CHANNEL(channel);
912    if (red_type == fec_type ||
913        red_type == channels_[channel]->send_codec.plType ||
914        fec_type == channels_[channel]->send_codec.plType) {
915      return -1;
916    }
917    channels_[channel]->nack_ = false;
918    channels_[channel]->hybrid_nack_fec_ = enable;
919    return 0;
920  }
921  WEBRTC_FUNC(SetKeyFrameRequestMethod,
922              (const int channel,
923               const webrtc::ViEKeyFrameRequestMethod method)) {
924    WEBRTC_CHECK_CHANNEL(channel);
925    channels_[channel]->key_frame_request_method_ = method;
926    return 0;
927  }
928  WEBRTC_FUNC(SetSenderBufferingMode, (int channel, int target_delay)) {
929    WEBRTC_CHECK_CHANNEL(channel);
930    channels_[channel]->sender_target_delay_ = target_delay;
931    return 0;
932  }
933  WEBRTC_FUNC(SetReceiverBufferingMode, (int channel, int target_delay)) {
934    WEBRTC_CHECK_CHANNEL(channel);
935    channels_[channel]->receiver_target_delay_ = target_delay;
936    return 0;
937  }
938  // |Send| and |receive| are stored locally in variables that more clearly
939  // explain what they mean.
940  WEBRTC_FUNC(SetRembStatus, (int channel, bool send, bool receive)) {
941    WEBRTC_CHECK_CHANNEL(channel);
942    channels_[channel]->remb_contribute_ = receive;
943    channels_[channel]->remb_bw_partition_ = send;
944    return 0;
945  }
946  WEBRTC_FUNC(SetTMMBRStatus, (const int channel, const bool enable)) {
947    WEBRTC_CHECK_CHANNEL(channel);
948    channels_[channel]->tmmbr_ = enable;
949    return 0;
950  }
951  WEBRTC_FUNC(SetSendTimestampOffsetStatus, (int channel, bool enable,
952      int id)) {
953    WEBRTC_CHECK_CHANNEL(channel);
954    channels_[channel]->rtp_offset_send_id_ = (enable) ? id : 0;
955    return 0;
956  }
957  WEBRTC_FUNC(SetReceiveTimestampOffsetStatus, (int channel, bool enable,
958      int id)) {
959    WEBRTC_CHECK_CHANNEL(channel);
960    channels_[channel]->rtp_offset_receive_id_ = (enable) ? id : 0;
961    return 0;
962  }
963  WEBRTC_FUNC(SetSendAbsoluteSendTimeStatus, (int channel, bool enable,
964      int id)) {
965    WEBRTC_CHECK_CHANNEL(channel);
966    channels_[channel]->rtp_absolute_send_time_send_id_ = (enable) ? id : 0;
967    return 0;
968  }
969  WEBRTC_FUNC(SetReceiveAbsoluteSendTimeStatus, (int channel, bool enable,
970      int id)) {
971    WEBRTC_CHECK_CHANNEL(channel);
972    channels_[channel]->rtp_absolute_send_time_receive_id_ = (enable) ? id : 0;
973    return 0;
974  }
975  WEBRTC_FUNC(SetTransmissionSmoothingStatus, (int channel, bool enable)) {
976    WEBRTC_CHECK_CHANNEL(channel);
977    channels_[channel]->transmission_smoothing_ = enable;
978    return 0;
979  }
980  WEBRTC_STUB_CONST(GetReceivedRTCPStatistics, (const int, unsigned short&,
981      unsigned int&, unsigned int&, unsigned int&, int&));
982  WEBRTC_STUB_CONST(GetSentRTCPStatistics, (const int, unsigned short&,
983      unsigned int&, unsigned int&, unsigned int&, int&));
984  WEBRTC_STUB_CONST(GetRTPStatistics, (const int, unsigned int&, unsigned int&,
985      unsigned int&, unsigned int&));
986  WEBRTC_FUNC_CONST(GetBandwidthUsage, (const int channel,
987      unsigned int& total_bitrate, unsigned int& video_bitrate,
988      unsigned int& fec_bitrate, unsigned int& nack_bitrate)) {
989    WEBRTC_CHECK_CHANNEL(channel);
990    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
991    if (it->second->send) {
992      video_bitrate = it->second->send_video_bitrate_;
993      fec_bitrate = it->second->send_fec_bitrate_;
994      nack_bitrate = it->second->send_nack_bitrate_;
995      total_bitrate = video_bitrate + fec_bitrate + nack_bitrate;
996    } else {
997      total_bitrate = 0;
998      video_bitrate = 0;
999      fec_bitrate = 0;
1000      nack_bitrate = 0;
1001    }
1002    return 0;
1003  }
1004  WEBRTC_FUNC_CONST(GetEstimatedSendBandwidth, (const int channel,
1005      unsigned int* send_bandwidth_estimate)) {
1006    WEBRTC_CHECK_CHANNEL(channel);
1007    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
1008    // Assume the current video, fec and nack bitrate sums up to our estimate.
1009    if (it->second->send) {
1010      *send_bandwidth_estimate = it->second->send_bandwidth_;
1011    } else {
1012      *send_bandwidth_estimate = 0;
1013    }
1014    return 0;
1015  }
1016  WEBRTC_FUNC_CONST(GetEstimatedReceiveBandwidth, (const int channel,
1017      unsigned int* receive_bandwidth_estimate)) {
1018    WEBRTC_CHECK_CHANNEL(channel);
1019    std::map<int, Channel*>::const_iterator it = channels_.find(channel);
1020    if (it->second->receive_) {
1021    // For simplicity, assume all channels receive half of max send rate.
1022      *receive_bandwidth_estimate = it->second->receive_bandwidth_;
1023    } else {
1024      *receive_bandwidth_estimate = 0;
1025    }
1026    return 0;
1027  }
1028
1029  WEBRTC_STUB(StartRTPDump, (const int, const char*, webrtc::RTPDirections));
1030  WEBRTC_STUB(StopRTPDump, (const int, webrtc::RTPDirections));
1031  WEBRTC_STUB(RegisterRTPObserver, (const int, webrtc::ViERTPObserver&));
1032  WEBRTC_STUB(DeregisterRTPObserver, (const int));
1033  WEBRTC_STUB(RegisterRTCPObserver, (const int, webrtc::ViERTCPObserver&));
1034  WEBRTC_STUB(DeregisterRTCPObserver, (const int));
1035
1036  // webrtc::ViEImageProcess
1037  WEBRTC_STUB(RegisterCaptureEffectFilter, (const int,
1038      webrtc::ViEEffectFilter&));
1039  WEBRTC_STUB(DeregisterCaptureEffectFilter, (const int));
1040  WEBRTC_STUB(RegisterSendEffectFilter, (const int,
1041      webrtc::ViEEffectFilter&));
1042  WEBRTC_STUB(DeregisterSendEffectFilter, (const int));
1043  WEBRTC_STUB(RegisterRenderEffectFilter, (const int,
1044      webrtc::ViEEffectFilter&));
1045  WEBRTC_STUB(DeregisterRenderEffectFilter, (const int));
1046  WEBRTC_STUB(EnableDeflickering, (const int, const bool));
1047  WEBRTC_FUNC(EnableDenoising, (const int capture_id, const bool denoising)) {
1048    WEBRTC_CHECK_CAPTURER(capture_id);
1049    capturers_[capture_id]->set_denoising(denoising);
1050    return 0;
1051  }
1052  WEBRTC_STUB(EnableColorEnhancement, (const int, const bool));
1053
1054  // webrtc::ViEExternalCodec
1055  WEBRTC_FUNC(RegisterExternalSendCodec,
1056      (const int channel, const unsigned char pl_type, webrtc::VideoEncoder*,
1057          bool)) {
1058    WEBRTC_CHECK_CHANNEL(channel);
1059    channels_[channel]->ext_encoder_pl_types_.insert(pl_type);
1060    return 0;
1061  }
1062  WEBRTC_FUNC(DeRegisterExternalSendCodec,
1063      (const int channel, const unsigned char pl_type)) {
1064    WEBRTC_CHECK_CHANNEL(channel);
1065    channels_[channel]->ext_encoder_pl_types_.erase(pl_type);
1066    return 0;
1067  }
1068  WEBRTC_FUNC(RegisterExternalReceiveCodec,
1069      (const int channel, const unsigned int pl_type, webrtc::VideoDecoder*,
1070       bool, int)) {
1071    WEBRTC_CHECK_CHANNEL(channel);
1072    channels_[channel]->ext_decoder_pl_types_.insert(pl_type);
1073    return 0;
1074  }
1075  WEBRTC_FUNC(DeRegisterExternalReceiveCodec,
1076      (const int channel, const unsigned char pl_type)) {
1077    WEBRTC_CHECK_CHANNEL(channel);
1078    channels_[channel]->ext_decoder_pl_types_.erase(pl_type);
1079    return 0;
1080  }
1081
1082 private:
1083  bool IsChannelId(int id) const {
1084    return (id >= kViEChannelIdBase && id <= kViEChannelIdMax);
1085  }
1086  bool IsCapturerId(int id) const {
1087    return (id >= kViECaptureIdBase && id <= kViECaptureIdMax);
1088  }
1089
1090  bool inited_;
1091  int last_channel_;
1092  std::map<int, Channel*> channels_;
1093  bool fail_create_channel_;
1094  int last_capturer_;
1095  std::map<int, Capturer*> capturers_;
1096  bool fail_alloc_capturer_;
1097  const cricket::VideoCodec* const* codecs_;
1098  int num_codecs_;
1099  int num_set_send_codecs_;  // how many times we call SetSendCodec().
1100};
1101
1102}  // namespace cricket
1103
1104#endif  // TALK_MEDIA_WEBRTC_FAKEWEBRTCVIDEOENGINE_H_
1105