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