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