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