Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2004 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_BASE_FAKEMEDIAENGINE_H_
     29 #define TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_
     30 
     31 #include <list>
     32 #include <map>
     33 #include <set>
     34 #include <string>
     35 #include <vector>
     36 
     37 #include "talk/base/buffer.h"
     38 #include "talk/base/stringutils.h"
     39 #include "talk/media/base/audiorenderer.h"
     40 #include "talk/media/base/mediaengine.h"
     41 #include "talk/media/base/rtputils.h"
     42 #include "talk/media/base/streamparams.h"
     43 #include "talk/p2p/base/sessiondescription.h"
     44 
     45 namespace cricket {
     46 
     47 class FakeMediaEngine;
     48 class FakeVideoEngine;
     49 class FakeVoiceEngine;
     50 
     51 // A common helper class that handles sending and receiving RTP/RTCP packets.
     52 template <class Base> class RtpHelper : public Base {
     53  public:
     54   RtpHelper()
     55       : sending_(false),
     56         playout_(false),
     57         fail_set_send_codecs_(false),
     58         fail_set_recv_codecs_(false),
     59         send_ssrc_(0),
     60         ready_to_send_(false) {}
     61   const std::vector<RtpHeaderExtension>& recv_extensions() {
     62     return recv_extensions_;
     63   }
     64   const std::vector<RtpHeaderExtension>& send_extensions() {
     65     return send_extensions_;
     66   }
     67   bool sending() const { return sending_; }
     68   bool playout() const { return playout_; }
     69   const std::list<std::string>& rtp_packets() const { return rtp_packets_; }
     70   const std::list<std::string>& rtcp_packets() const { return rtcp_packets_; }
     71 
     72   bool SendRtp(const void* data, int len) {
     73     if (!sending_) {
     74       return false;
     75     }
     76     talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
     77     return Base::SendPacket(&packet);
     78   }
     79   bool SendRtcp(const void* data, int len) {
     80     talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
     81     return Base::SendRtcp(&packet);
     82   }
     83 
     84   bool CheckRtp(const void* data, int len) {
     85     bool success = !rtp_packets_.empty();
     86     if (success) {
     87       std::string packet = rtp_packets_.front();
     88       rtp_packets_.pop_front();
     89       success = (packet == std::string(static_cast<const char*>(data), len));
     90     }
     91     return success;
     92   }
     93   bool CheckRtcp(const void* data, int len) {
     94     bool success = !rtcp_packets_.empty();
     95     if (success) {
     96       std::string packet = rtcp_packets_.front();
     97       rtcp_packets_.pop_front();
     98       success = (packet == std::string(static_cast<const char*>(data), len));
     99     }
    100     return success;
    101   }
    102   bool CheckNoRtp() { return rtp_packets_.empty(); }
    103   bool CheckNoRtcp() { return rtcp_packets_.empty(); }
    104   virtual bool SetRecvRtpHeaderExtensions(
    105       const std::vector<RtpHeaderExtension>& extensions) {
    106     recv_extensions_ = extensions;
    107     return true;
    108   }
    109   virtual bool SetSendRtpHeaderExtensions(
    110       const std::vector<RtpHeaderExtension>& extensions) {
    111     send_extensions_ = extensions;
    112     return true;
    113   }
    114   void set_fail_set_send_codecs(bool fail) { fail_set_send_codecs_ = fail; }
    115   void set_fail_set_recv_codecs(bool fail) { fail_set_recv_codecs_ = fail; }
    116   virtual bool AddSendStream(const StreamParams& sp) {
    117     if (std::find(send_streams_.begin(), send_streams_.end(), sp) !=
    118         send_streams_.end()) {
    119       return false;
    120     }
    121     send_streams_.push_back(sp);
    122     return true;
    123   }
    124   virtual bool RemoveSendStream(uint32 ssrc) {
    125     return RemoveStreamBySsrc(&send_streams_, ssrc);
    126   }
    127   virtual bool AddRecvStream(const StreamParams& sp) {
    128     if (std::find(receive_streams_.begin(), receive_streams_.end(), sp) !=
    129         receive_streams_.end()) {
    130       return false;
    131     }
    132     receive_streams_.push_back(sp);
    133     return true;
    134   }
    135   virtual bool RemoveRecvStream(uint32 ssrc) {
    136     return RemoveStreamBySsrc(&receive_streams_, ssrc);
    137   }
    138   virtual bool MuteStream(uint32 ssrc, bool on) {
    139     if (!HasSendStream(ssrc) && ssrc != 0)
    140       return false;
    141     if (on)
    142       muted_streams_.insert(ssrc);
    143     else
    144       muted_streams_.erase(ssrc);
    145     return true;
    146   }
    147   bool IsStreamMuted(uint32 ssrc) const {
    148     bool ret = muted_streams_.find(ssrc) != muted_streams_.end();
    149     // If |ssrc = 0| check if the first send stream is muted.
    150     if (!ret && ssrc == 0 && !send_streams_.empty()) {
    151       return muted_streams_.find(send_streams_[0].first_ssrc()) !=
    152              muted_streams_.end();
    153     }
    154     return ret;
    155   }
    156   const std::vector<StreamParams>& send_streams() const {
    157     return send_streams_;
    158   }
    159   const std::vector<StreamParams>& recv_streams() const {
    160     return receive_streams_;
    161   }
    162   bool HasRecvStream(uint32 ssrc) const {
    163     return GetStreamBySsrc(receive_streams_, ssrc, NULL);
    164   }
    165   bool HasSendStream(uint32 ssrc) const {
    166     return GetStreamBySsrc(send_streams_, ssrc, NULL);
    167   }
    168   // TODO(perkj): This is to support legacy unit test that only check one
    169   // sending stream.
    170   const uint32 send_ssrc() {
    171     if (send_streams_.empty())
    172       return 0;
    173     return send_streams_[0].first_ssrc();
    174   }
    175 
    176   // TODO(perkj): This is to support legacy unit test that only check one
    177   // sending stream.
    178   const std::string rtcp_cname() {
    179     if (send_streams_.empty())
    180       return "";
    181     return send_streams_[0].cname;
    182   }
    183 
    184   bool ready_to_send() const {
    185     return ready_to_send_;
    186   }
    187 
    188  protected:
    189   bool set_sending(bool send) {
    190     sending_ = send;
    191     return true;
    192   }
    193   void set_playout(bool playout) { playout_ = playout; }
    194   virtual void OnPacketReceived(talk_base::Buffer* packet) {
    195     rtp_packets_.push_back(std::string(packet->data(), packet->length()));
    196   }
    197   virtual void OnRtcpReceived(talk_base::Buffer* packet) {
    198     rtcp_packets_.push_back(std::string(packet->data(), packet->length()));
    199   }
    200   virtual void OnReadyToSend(bool ready) {
    201     ready_to_send_ = ready;
    202   }
    203   bool fail_set_send_codecs() const { return fail_set_send_codecs_; }
    204   bool fail_set_recv_codecs() const { return fail_set_recv_codecs_; }
    205 
    206  private:
    207   bool sending_;
    208   bool playout_;
    209   std::vector<RtpHeaderExtension> recv_extensions_;
    210   std::vector<RtpHeaderExtension> send_extensions_;
    211   std::list<std::string> rtp_packets_;
    212   std::list<std::string> rtcp_packets_;
    213   std::vector<StreamParams> send_streams_;
    214   std::vector<StreamParams> receive_streams_;
    215   std::set<uint32> muted_streams_;
    216   bool fail_set_send_codecs_;
    217   bool fail_set_recv_codecs_;
    218   uint32 send_ssrc_;
    219   std::string rtcp_cname_;
    220   bool ready_to_send_;
    221 };
    222 
    223 class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {
    224  public:
    225   struct DtmfInfo {
    226     DtmfInfo(uint32 ssrc, int event_code, int duration, int flags)
    227         : ssrc(ssrc), event_code(event_code), duration(duration), flags(flags) {
    228     }
    229     uint32 ssrc;
    230     int event_code;
    231     int duration;
    232     int flags;
    233   };
    234   explicit FakeVoiceMediaChannel(FakeVoiceEngine* engine)
    235       : engine_(engine),
    236         fail_set_send_(false),
    237         ringback_tone_ssrc_(0),
    238         ringback_tone_play_(false),
    239         ringback_tone_loop_(false),
    240         time_since_last_typing_(-1) {
    241     output_scalings_[0] = OutputScaling();  // For default channel.
    242   }
    243   ~FakeVoiceMediaChannel();
    244   const std::vector<AudioCodec>& recv_codecs() const { return recv_codecs_; }
    245   const std::vector<AudioCodec>& send_codecs() const { return send_codecs_; }
    246   const std::vector<AudioCodec>& codecs() const { return send_codecs(); }
    247   const std::vector<DtmfInfo>& dtmf_info_queue() const {
    248     return dtmf_info_queue_;
    249   }
    250   const AudioOptions& options() const { return options_; }
    251 
    252   uint32 ringback_tone_ssrc() const { return ringback_tone_ssrc_; }
    253   bool ringback_tone_play() const { return ringback_tone_play_; }
    254   bool ringback_tone_loop() const { return ringback_tone_loop_; }
    255 
    256   virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) {
    257     if (fail_set_recv_codecs()) {
    258       // Fake the failure in SetRecvCodecs.
    259       return false;
    260     }
    261     recv_codecs_ = codecs;
    262     return true;
    263   }
    264   virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs) {
    265     if (fail_set_send_codecs()) {
    266       // Fake the failure in SetSendCodecs.
    267       return false;
    268     }
    269     send_codecs_ = codecs;
    270     return true;
    271   }
    272   virtual bool SetPlayout(bool playout) {
    273     set_playout(playout);
    274     return true;
    275   }
    276   virtual bool SetSend(SendFlags flag) {
    277     if (fail_set_send_) {
    278       return false;
    279     }
    280     return set_sending(flag != SEND_NOTHING);
    281   }
    282   virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
    283   virtual bool AddRecvStream(const StreamParams& sp) {
    284     if (!RtpHelper<VoiceMediaChannel>::AddRecvStream(sp))
    285       return false;
    286     output_scalings_[sp.first_ssrc()] = OutputScaling();
    287     return true;
    288   }
    289   virtual bool RemoveRecvStream(uint32 ssrc) {
    290     if (!RtpHelper<VoiceMediaChannel>::RemoveRecvStream(ssrc))
    291       return false;
    292     output_scalings_.erase(ssrc);
    293     return true;
    294   }
    295   virtual bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) {
    296     std::map<uint32, AudioRenderer*>::iterator it =
    297         remote_renderers_.find(ssrc);
    298     if (renderer) {
    299       if (it != remote_renderers_.end()) {
    300         ASSERT(it->second == renderer);
    301       } else {
    302         remote_renderers_.insert(std::make_pair(ssrc, renderer));
    303         renderer->AddChannel(0);
    304       }
    305     } else {
    306       if (it != remote_renderers_.end()) {
    307         it->second->RemoveChannel(0);
    308         remote_renderers_.erase(it);
    309       } else {
    310         return false;
    311       }
    312     }
    313     return true;
    314   }
    315   virtual bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) {
    316     std::map<uint32, AudioRenderer*>::iterator it = local_renderers_.find(ssrc);
    317     if (renderer) {
    318       if (it != local_renderers_.end()) {
    319         ASSERT(it->second == renderer);
    320       } else {
    321         local_renderers_.insert(std::make_pair(ssrc, renderer));
    322         renderer->AddChannel(0);
    323       }
    324     } else {
    325       if (it != local_renderers_.end()) {
    326         it->second->RemoveChannel(0);
    327         local_renderers_.erase(it);
    328       } else {
    329         return false;
    330       }
    331     }
    332     return true;
    333   }
    334 
    335   virtual bool GetActiveStreams(AudioInfo::StreamList* streams) { return true; }
    336   virtual int GetOutputLevel() { return 0; }
    337   void set_time_since_last_typing(int ms) { time_since_last_typing_ = ms; }
    338   virtual int GetTimeSinceLastTyping() { return time_since_last_typing_; }
    339   virtual void SetTypingDetectionParameters(
    340       int time_window, int cost_per_typing, int reporting_threshold,
    341       int penalty_decay, int type_event_delay) {}
    342 
    343   virtual bool SetRingbackTone(const char* buf, int len) { return true; }
    344   virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
    345     ringback_tone_ssrc_ = ssrc;
    346     ringback_tone_play_ = play;
    347     ringback_tone_loop_ = loop;
    348     return true;
    349   }
    350 
    351   virtual bool CanInsertDtmf() {
    352     for (std::vector<AudioCodec>::const_iterator it = send_codecs_.begin();
    353          it != send_codecs_.end(); ++it) {
    354       // Find the DTMF telephone event "codec".
    355       if (_stricmp(it->name.c_str(), "telephone-event") == 0) {
    356         return true;
    357       }
    358     }
    359     return false;
    360   }
    361   virtual bool InsertDtmf(uint32 ssrc, int event_code, int duration,
    362                           int flags) {
    363     dtmf_info_queue_.push_back(DtmfInfo(ssrc, event_code, duration, flags));
    364     return true;
    365   }
    366 
    367   virtual bool SetOutputScaling(uint32 ssrc, double left, double right) {
    368     if (0 == ssrc) {
    369       std::map<uint32, OutputScaling>::iterator it;
    370       for (it = output_scalings_.begin(); it != output_scalings_.end(); ++it) {
    371         it->second.left = left;
    372         it->second.right = right;
    373       }
    374       return true;
    375     } else if (output_scalings_.find(ssrc) != output_scalings_.end()) {
    376       output_scalings_[ssrc].left = left;
    377       output_scalings_[ssrc].right = right;
    378       return true;
    379     }
    380     return false;
    381   }
    382   virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) {
    383     if (output_scalings_.find(ssrc) == output_scalings_.end())
    384       return false;
    385     *left = output_scalings_[ssrc].left;
    386     *right = output_scalings_[ssrc].right;
    387     return true;
    388   }
    389 
    390   virtual bool GetStats(VoiceMediaInfo* info) { return false; }
    391   virtual void GetLastMediaError(uint32* ssrc,
    392                                  VoiceMediaChannel::Error* error) {
    393     *ssrc = 0;
    394     *error = fail_set_send_ ? VoiceMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED
    395                             : VoiceMediaChannel::ERROR_NONE;
    396   }
    397 
    398   void set_fail_set_send(bool fail) { fail_set_send_ = fail; }
    399   void TriggerError(uint32 ssrc, VoiceMediaChannel::Error error) {
    400     VoiceMediaChannel::SignalMediaError(ssrc, error);
    401   }
    402 
    403   virtual bool SetOptions(const AudioOptions& options) {
    404     // Does a "merge" of current options and set options.
    405     options_.SetAll(options);
    406     return true;
    407   }
    408   virtual bool GetOptions(AudioOptions* options) const {
    409     *options = options_;
    410     return true;
    411   }
    412 
    413  private:
    414   struct OutputScaling {
    415     OutputScaling() : left(1.0), right(1.0) {}
    416     double left, right;
    417   };
    418 
    419   FakeVoiceEngine* engine_;
    420   std::vector<AudioCodec> recv_codecs_;
    421   std::vector<AudioCodec> send_codecs_;
    422   std::map<uint32, OutputScaling> output_scalings_;
    423   std::vector<DtmfInfo> dtmf_info_queue_;
    424   bool fail_set_send_;
    425   uint32 ringback_tone_ssrc_;
    426   bool ringback_tone_play_;
    427   bool ringback_tone_loop_;
    428   int time_since_last_typing_;
    429   AudioOptions options_;
    430   std::map<uint32, AudioRenderer*> local_renderers_;
    431   std::map<uint32, AudioRenderer*> remote_renderers_;
    432 };
    433 
    434 // A helper function to compare the FakeVoiceMediaChannel::DtmfInfo.
    435 inline bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info,
    436                             uint32 ssrc, int event_code, int duration,
    437                             int flags) {
    438   return (info.duration == duration && info.event_code == event_code &&
    439           info.flags == flags && info.ssrc == ssrc);
    440 }
    441 
    442 class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
    443  public:
    444   explicit FakeVideoMediaChannel(FakeVideoEngine* engine)
    445       : engine_(engine),
    446         sent_intra_frame_(false),
    447         requested_intra_frame_(false) {}
    448   ~FakeVideoMediaChannel();
    449 
    450   const std::vector<VideoCodec>& recv_codecs() const { return recv_codecs_; }
    451   const std::vector<VideoCodec>& send_codecs() const { return send_codecs_; }
    452   const std::vector<VideoCodec>& codecs() const { return send_codecs(); }
    453   bool rendering() const { return playout(); }
    454   const VideoOptions& options() const { return options_; }
    455   const std::map<uint32, VideoRenderer*>& renderers() const {
    456     return renderers_;
    457   }
    458   bool GetSendStreamFormat(uint32 ssrc, VideoFormat* format) {
    459     if (send_formats_.find(ssrc) == send_formats_.end()) {
    460       return false;
    461     }
    462     *format = send_formats_[ssrc];
    463     return true;
    464   }
    465   virtual bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format) {
    466     if (send_formats_.find(ssrc) == send_formats_.end()) {
    467       return false;
    468     }
    469     send_formats_[ssrc] = format;
    470     return true;
    471   }
    472 
    473   virtual bool AddSendStream(const StreamParams& sp) {
    474     if (!RtpHelper<VideoMediaChannel>::AddSendStream(sp)) {
    475       return false;
    476     }
    477     SetSendStreamDefaultFormat(sp.first_ssrc());
    478     return true;
    479   }
    480   virtual bool RemoveSendStream(uint32 ssrc) {
    481     send_formats_.erase(ssrc);
    482     return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc);
    483   }
    484 
    485   virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) {
    486     if (fail_set_recv_codecs()) {
    487       // Fake the failure in SetRecvCodecs.
    488       return false;
    489     }
    490     recv_codecs_ = codecs;
    491     return true;
    492   }
    493   virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) {
    494     if (fail_set_send_codecs()) {
    495       // Fake the failure in SetSendCodecs.
    496       return false;
    497     }
    498     send_codecs_ = codecs;
    499 
    500     for (std::vector<StreamParams>::const_iterator it = send_streams().begin();
    501          it != send_streams().end(); ++it) {
    502       SetSendStreamDefaultFormat(it->first_ssrc());
    503     }
    504     return true;
    505   }
    506   virtual bool GetSendCodec(VideoCodec* send_codec) {
    507     if (send_codecs_.empty()) {
    508       return false;
    509     }
    510     *send_codec = send_codecs_[0];
    511     return true;
    512   }
    513   virtual bool SetRender(bool render) {
    514     set_playout(render);
    515     return true;
    516   }
    517   virtual bool SetRenderer(uint32 ssrc, VideoRenderer* r) {
    518     if (ssrc != 0 && renderers_.find(ssrc) == renderers_.end()) {
    519       return false;
    520     }
    521     if (ssrc != 0) {
    522       renderers_[ssrc] = r;
    523     }
    524     return true;
    525   }
    526 
    527   virtual bool SetSend(bool send) { return set_sending(send); }
    528   virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) {
    529     capturers_[ssrc] = capturer;
    530     return true;
    531   }
    532   bool HasCapturer(uint32 ssrc) const {
    533     return capturers_.find(ssrc) != capturers_.end();
    534   }
    535   virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
    536   virtual bool AddRecvStream(const StreamParams& sp) {
    537     if (!RtpHelper<VideoMediaChannel>::AddRecvStream(sp))
    538       return false;
    539     renderers_[sp.first_ssrc()] = NULL;
    540     return true;
    541   }
    542   virtual bool RemoveRecvStream(uint32 ssrc) {
    543     if (!RtpHelper<VideoMediaChannel>::RemoveRecvStream(ssrc))
    544       return false;
    545     renderers_.erase(ssrc);
    546     return true;
    547   }
    548 
    549   virtual bool GetStats(VideoMediaInfo* info) { return false; }
    550   virtual bool SendIntraFrame() {
    551     sent_intra_frame_ = true;
    552     return true;
    553   }
    554   virtual bool RequestIntraFrame() {
    555     requested_intra_frame_ = true;
    556     return true;
    557   }
    558   virtual bool SetOptions(const VideoOptions& options) {
    559     options_ = options;
    560     return true;
    561   }
    562   virtual bool GetOptions(VideoOptions* options) const {
    563     *options = options_;
    564     return true;
    565   }
    566   virtual void UpdateAspectRatio(int ratio_w, int ratio_h) {}
    567   void set_sent_intra_frame(bool v) { sent_intra_frame_ = v; }
    568   bool sent_intra_frame() const { return sent_intra_frame_; }
    569   void set_requested_intra_frame(bool v) { requested_intra_frame_ = v; }
    570   bool requested_intra_frame() const { return requested_intra_frame_; }
    571 
    572  private:
    573   // Be default, each send stream uses the first send codec format.
    574   void SetSendStreamDefaultFormat(uint32 ssrc) {
    575     if (!send_codecs_.empty()) {
    576       send_formats_[ssrc] = VideoFormat(
    577           send_codecs_[0].width, send_codecs_[0].height,
    578           cricket::VideoFormat::FpsToInterval(send_codecs_[0].framerate),
    579           cricket::FOURCC_I420);
    580     }
    581   }
    582 
    583   FakeVideoEngine* engine_;
    584   std::vector<VideoCodec> recv_codecs_;
    585   std::vector<VideoCodec> send_codecs_;
    586   std::map<uint32, VideoRenderer*> renderers_;
    587   std::map<uint32, VideoFormat> send_formats_;
    588   std::map<uint32, VideoCapturer*> capturers_;
    589   bool sent_intra_frame_;
    590   bool requested_intra_frame_;
    591   VideoOptions options_;
    592 };
    593 
    594 class FakeSoundclipMedia : public SoundclipMedia {
    595  public:
    596   virtual bool PlaySound(const char* buf, int len, int flags) { return true; }
    597 };
    598 
    599 class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
    600  public:
    601   explicit FakeDataMediaChannel(void* unused)
    602       : auto_bandwidth_(false), send_blocked_(false), max_bps_(-1) {}
    603   ~FakeDataMediaChannel() {}
    604   const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; }
    605   const std::vector<DataCodec>& send_codecs() const { return send_codecs_; }
    606   const std::vector<DataCodec>& codecs() const { return send_codecs(); }
    607   bool auto_bandwidth() const { return auto_bandwidth_; }
    608   int max_bps() const { return max_bps_; }
    609 
    610   virtual bool SetRecvCodecs(const std::vector<DataCodec>& codecs) {
    611     if (fail_set_recv_codecs()) {
    612       // Fake the failure in SetRecvCodecs.
    613       return false;
    614     }
    615     recv_codecs_ = codecs;
    616     return true;
    617   }
    618   virtual bool SetSendCodecs(const std::vector<DataCodec>& codecs) {
    619     if (fail_set_send_codecs()) {
    620       // Fake the failure in SetSendCodecs.
    621       return false;
    622     }
    623     send_codecs_ = codecs;
    624     return true;
    625   }
    626   virtual bool SetSend(bool send) { return set_sending(send); }
    627   virtual bool SetReceive(bool receive) {
    628     set_playout(receive);
    629     return true;
    630   }
    631   virtual bool SetSendBandwidth(bool autobw, int bps) {
    632     auto_bandwidth_ = autobw;
    633     max_bps_ = bps;
    634     return true;
    635   }
    636   virtual bool AddRecvStream(const StreamParams& sp) {
    637     if (!RtpHelper<DataMediaChannel>::AddRecvStream(sp))
    638       return false;
    639     return true;
    640   }
    641   virtual bool RemoveRecvStream(uint32 ssrc) {
    642     if (!RtpHelper<DataMediaChannel>::RemoveRecvStream(ssrc))
    643       return false;
    644     return true;
    645   }
    646 
    647   virtual bool SendData(const SendDataParams& params,
    648                         const talk_base::Buffer& payload,
    649                         SendDataResult* result) {
    650     if (send_blocked_) {
    651       *result = SDR_BLOCK;
    652       return false;
    653     } else {
    654       last_sent_data_params_ = params;
    655       last_sent_data_ = std::string(payload.data(), payload.length());
    656       return true;
    657     }
    658   }
    659 
    660   SendDataParams last_sent_data_params() { return last_sent_data_params_; }
    661   std::string last_sent_data() { return last_sent_data_; }
    662   bool is_send_blocked() { return send_blocked_; }
    663   void set_send_blocked(bool blocked) { send_blocked_ = blocked; }
    664 
    665  private:
    666   std::vector<DataCodec> recv_codecs_;
    667   std::vector<DataCodec> send_codecs_;
    668   SendDataParams last_sent_data_params_;
    669   std::string last_sent_data_;
    670   bool auto_bandwidth_;
    671   bool send_blocked_;
    672   int max_bps_;
    673 };
    674 
    675 // A base class for all of the shared parts between FakeVoiceEngine
    676 // and FakeVideoEngine.
    677 class FakeBaseEngine {
    678  public:
    679   FakeBaseEngine()
    680       : loglevel_(-1),
    681         options_(0),
    682         options_changed_(false),
    683         fail_create_channel_(false) {}
    684   bool Init(talk_base::Thread* worker_thread) { return true; }
    685   void Terminate() {}
    686 
    687   bool SetOptions(int options) {
    688     options_ = options;
    689     options_changed_ = true;
    690     return true;
    691   }
    692 
    693   void SetLogging(int level, const char* filter) {
    694     loglevel_ = level;
    695     logfilter_ = filter;
    696   }
    697 
    698   void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; }
    699 
    700   const std::vector<RtpHeaderExtension>& rtp_header_extensions() const {
    701     return rtp_header_extensions_;
    702   }
    703 
    704  protected:
    705   int loglevel_;
    706   std::string logfilter_;
    707   int options_;
    708   // Flag used by optionsmessagehandler_unittest for checking whether any
    709   // relevant setting has been updated.
    710   // TODO(thaloun): Replace with explicit checks of before & after values.
    711   bool options_changed_;
    712   bool fail_create_channel_;
    713   std::vector<RtpHeaderExtension> rtp_header_extensions_;
    714 };
    715 
    716 class FakeVoiceEngine : public FakeBaseEngine {
    717  public:
    718   FakeVoiceEngine()
    719       : output_volume_(-1),
    720         delay_offset_(0),
    721         rx_processor_(NULL),
    722         tx_processor_(NULL) {
    723     // Add a fake audio codec. Note that the name must not be "" as there are
    724     // sanity checks against that.
    725     codecs_.push_back(AudioCodec(101, "fake_audio_codec", 0, 0, 1, 0));
    726   }
    727   int GetCapabilities() { return AUDIO_SEND | AUDIO_RECV; }
    728 
    729   VoiceMediaChannel* CreateChannel() {
    730     if (fail_create_channel_) {
    731       return NULL;
    732     }
    733 
    734     FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(this);
    735     channels_.push_back(ch);
    736     return ch;
    737   }
    738   FakeVoiceMediaChannel* GetChannel(size_t index) {
    739     return (channels_.size() > index) ? channels_[index] : NULL;
    740   }
    741   void UnregisterChannel(VoiceMediaChannel* channel) {
    742     channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
    743   }
    744   SoundclipMedia* CreateSoundclip() { return new FakeSoundclipMedia(); }
    745 
    746   const std::vector<AudioCodec>& codecs() { return codecs_; }
    747   void SetCodecs(const std::vector<AudioCodec> codecs) { codecs_ = codecs; }
    748 
    749   bool SetDelayOffset(int offset) {
    750     delay_offset_ = offset;
    751     return true;
    752   }
    753 
    754   bool SetDevices(const Device* in_device, const Device* out_device) {
    755     in_device_ = (in_device) ? in_device->name : "";
    756     out_device_ = (out_device) ? out_device->name : "";
    757     options_changed_ = true;
    758     return true;
    759   }
    760 
    761   bool GetOutputVolume(int* level) {
    762     *level = output_volume_;
    763     return true;
    764   }
    765 
    766   bool SetOutputVolume(int level) {
    767     output_volume_ = level;
    768     options_changed_ = true;
    769     return true;
    770   }
    771 
    772   int GetInputLevel() { return 0; }
    773 
    774   bool SetLocalMonitor(bool enable) { return true; }
    775 
    776   bool RegisterProcessor(uint32 ssrc, VoiceProcessor* voice_processor,
    777                          MediaProcessorDirection direction) {
    778     if (direction == MPD_RX) {
    779       rx_processor_ = voice_processor;
    780       return true;
    781     } else if (direction == MPD_TX) {
    782       tx_processor_ = voice_processor;
    783       return true;
    784     }
    785     return false;
    786   }
    787 
    788   bool UnregisterProcessor(uint32 ssrc, VoiceProcessor* voice_processor,
    789                            MediaProcessorDirection direction) {
    790     bool unregistered = false;
    791     if (direction & MPD_RX) {
    792       rx_processor_ = NULL;
    793       unregistered = true;
    794     }
    795     if (direction & MPD_TX) {
    796       tx_processor_ = NULL;
    797       unregistered = true;
    798     }
    799     return unregistered;
    800   }
    801 
    802  private:
    803   std::vector<FakeVoiceMediaChannel*> channels_;
    804   std::vector<AudioCodec> codecs_;
    805   int output_volume_;
    806   int delay_offset_;
    807   std::string in_device_;
    808   std::string out_device_;
    809   VoiceProcessor* rx_processor_;
    810   VoiceProcessor* tx_processor_;
    811 
    812   friend class FakeMediaEngine;
    813 };
    814 
    815 class FakeVideoEngine : public FakeBaseEngine {
    816  public:
    817   FakeVideoEngine() : renderer_(NULL), capture_(false), processor_(NULL) {
    818     // Add a fake video codec. Note that the name must not be "" as there are
    819     // sanity checks against that.
    820     codecs_.push_back(VideoCodec(0, "fake_video_codec", 0, 0, 0, 0));
    821   }
    822   int GetCapabilities() { return VIDEO_SEND | VIDEO_RECV; }
    823   bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) {
    824     default_encoder_config_ = config;
    825     return true;
    826   }
    827   const VideoEncoderConfig& default_encoder_config() const {
    828     return default_encoder_config_;
    829   }
    830 
    831   VideoMediaChannel* CreateChannel(VoiceMediaChannel* channel) {
    832     if (fail_create_channel_) {
    833       return NULL;
    834     }
    835 
    836     FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(this);
    837     channels_.push_back(ch);
    838     return ch;
    839   }
    840   FakeVideoMediaChannel* GetChannel(size_t index) {
    841     return (channels_.size() > index) ? channels_[index] : NULL;
    842   }
    843   void UnregisterChannel(VideoMediaChannel* channel) {
    844     channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
    845   }
    846 
    847   const std::vector<VideoCodec>& codecs() const { return codecs_; }
    848   bool FindCodec(const VideoCodec& in) {
    849     for (size_t i = 0; i < codecs_.size(); ++i) {
    850       if (codecs_[i].Matches(in)) {
    851         return true;
    852       }
    853     }
    854     return false;
    855   }
    856   void SetCodecs(const std::vector<VideoCodec> codecs) { codecs_ = codecs; }
    857 
    858   bool SetCaptureDevice(const Device* device) {
    859     in_device_ = (device) ? device->name : "";
    860     options_changed_ = true;
    861     return true;
    862   }
    863   bool SetLocalRenderer(VideoRenderer* r) {
    864     renderer_ = r;
    865     return true;
    866   }
    867   bool SetVideoCapturer(VideoCapturer* /*capturer*/) { return true; }
    868   VideoCapturer* GetVideoCapturer() const { return NULL; }
    869   bool SetCapture(bool capture) {
    870     capture_ = capture;
    871     return true;
    872   }
    873   VideoFormat GetStartCaptureFormat() const {
    874     return VideoFormat(640, 480, cricket::VideoFormat::FpsToInterval(30),
    875                        FOURCC_I420);
    876   }
    877 
    878   sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange;
    879 
    880  private:
    881   std::vector<FakeVideoMediaChannel*> channels_;
    882   std::vector<VideoCodec> codecs_;
    883   VideoEncoderConfig default_encoder_config_;
    884   std::string in_device_;
    885   VideoRenderer* renderer_;
    886   bool capture_;
    887   VideoProcessor* processor_;
    888 
    889   friend class FakeMediaEngine;
    890 };
    891 
    892 class FakeMediaEngine :
    893     public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> {
    894  public:
    895   FakeMediaEngine() {
    896     voice_ = FakeVoiceEngine();
    897     video_ = FakeVideoEngine();
    898   }
    899   virtual ~FakeMediaEngine() {}
    900 
    901   virtual void SetAudioCodecs(const std::vector<AudioCodec> codecs) {
    902     voice_.SetCodecs(codecs);
    903   }
    904 
    905   virtual void SetVideoCodecs(const std::vector<VideoCodec> codecs) {
    906     video_.SetCodecs(codecs);
    907   }
    908 
    909   FakeVoiceMediaChannel* GetVoiceChannel(size_t index) {
    910     return voice_.GetChannel(index);
    911   }
    912 
    913   FakeVideoMediaChannel* GetVideoChannel(size_t index) {
    914     return video_.GetChannel(index);
    915   }
    916 
    917   int audio_options() const { return voice_.options_; }
    918   int audio_delay_offset() const { return voice_.delay_offset_; }
    919   int output_volume() const { return voice_.output_volume_; }
    920   const VideoEncoderConfig& default_video_encoder_config() const {
    921     return video_.default_encoder_config_;
    922   }
    923   const std::string& audio_in_device() const { return voice_.in_device_; }
    924   const std::string& audio_out_device() const { return voice_.out_device_; }
    925   VideoRenderer* local_renderer() { return video_.renderer_; }
    926   int voice_loglevel() const { return voice_.loglevel_; }
    927   const std::string& voice_logfilter() const { return voice_.logfilter_; }
    928   int video_loglevel() const { return video_.loglevel_; }
    929   const std::string& video_logfilter() const { return video_.logfilter_; }
    930   bool capture() const { return video_.capture_; }
    931   bool options_changed() const {
    932     return voice_.options_changed_ || video_.options_changed_;
    933   }
    934   void clear_options_changed() {
    935     video_.options_changed_ = false;
    936     voice_.options_changed_ = false;
    937   }
    938   void set_fail_create_channel(bool fail) {
    939     voice_.set_fail_create_channel(fail);
    940     video_.set_fail_create_channel(fail);
    941   }
    942   bool voice_processor_registered(MediaProcessorDirection direction) const {
    943     if (direction == MPD_RX) {
    944       return voice_.rx_processor_ != NULL;
    945     } else if (direction == MPD_TX) {
    946       return voice_.tx_processor_ != NULL;
    947     }
    948     return false;
    949   }
    950 };
    951 
    952 // CompositeMediaEngine with FakeVoiceEngine to expose SetAudioCodecs to
    953 // establish a media connectionwith minimum set of audio codes required
    954 template <class VIDEO>
    955 class CompositeMediaEngineWithFakeVoiceEngine :
    956     public CompositeMediaEngine<FakeVoiceEngine, VIDEO> {
    957  public:
    958   CompositeMediaEngineWithFakeVoiceEngine() {}
    959   virtual ~CompositeMediaEngineWithFakeVoiceEngine() {}
    960 
    961   virtual void SetAudioCodecs(const std::vector<AudioCodec>& codecs) {
    962     CompositeMediaEngine<FakeVoiceEngine, VIDEO>::voice_.SetCodecs(codecs);
    963   }
    964 };
    965 
    966 // Have to come afterwards due to declaration order
    967 inline FakeVoiceMediaChannel::~FakeVoiceMediaChannel() {
    968   if (engine_) {
    969     engine_->UnregisterChannel(this);
    970   }
    971 }
    972 
    973 inline FakeVideoMediaChannel::~FakeVideoMediaChannel() {
    974   if (engine_) {
    975     engine_->UnregisterChannel(this);
    976   }
    977 }
    978 
    979 class FakeDataEngine : public DataEngineInterface {
    980  public:
    981   FakeDataEngine() : last_channel_type_(DCT_NONE) {}
    982 
    983   virtual DataMediaChannel* CreateChannel(DataChannelType data_channel_type) {
    984     last_channel_type_ = data_channel_type;
    985     FakeDataMediaChannel* ch = new FakeDataMediaChannel(this);
    986     channels_.push_back(ch);
    987     return ch;
    988   }
    989 
    990   FakeDataMediaChannel* GetChannel(size_t index) {
    991     return (channels_.size() > index) ? channels_[index] : NULL;
    992   }
    993 
    994   void UnregisterChannel(DataMediaChannel* channel) {
    995     channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
    996   }
    997 
    998   virtual void SetDataCodecs(const std::vector<DataCodec>& data_codecs) {
    999     data_codecs_ = data_codecs;
   1000   }
   1001 
   1002   virtual const std::vector<DataCodec>& data_codecs() { return data_codecs_; }
   1003 
   1004   DataChannelType last_channel_type() const { return last_channel_type_; }
   1005 
   1006  private:
   1007   std::vector<FakeDataMediaChannel*> channels_;
   1008   std::vector<DataCodec> data_codecs_;
   1009   DataChannelType last_channel_type_;
   1010 };
   1011 
   1012 }  // namespace cricket
   1013 
   1014 #endif  // TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_
   1015