• 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/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:
RtpHelper()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) {}
recv_extensions()62   const std::vector<RtpHeaderExtension>& recv_extensions() {
63     return recv_extensions_;
64   }
send_extensions()65   const std::vector<RtpHeaderExtension>& send_extensions() {
66     return send_extensions_;
67   }
sending()68   bool sending() const { return sending_; }
playout()69   bool playout() const { return playout_; }
rtp_packets()70   const std::list<std::string>& rtp_packets() const { return rtp_packets_; }
rtcp_packets()71   const std::list<std::string>& rtcp_packets() const { return rtcp_packets_; }
72 
SendRtp(const void * data,int len,const rtc::PacketOptions & options)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   }
SendRtcp(const void * data,int len)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 
CheckRtp(const void * data,int len)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   }
CheckRtcp(const void * data,int len)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   }
CheckNoRtp()105   bool CheckNoRtp() { return rtp_packets_.empty(); }
CheckNoRtcp()106   bool CheckNoRtcp() { return rtcp_packets_.empty(); }
set_fail_set_send_codecs(bool fail)107   void set_fail_set_send_codecs(bool fail) { fail_set_send_codecs_ = fail; }
set_fail_set_recv_codecs(bool fail)108   void set_fail_set_recv_codecs(bool fail) { fail_set_recv_codecs_ = fail; }
AddSendStream(const StreamParams & sp)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   }
RemoveSendStream(uint32_t ssrc)117   virtual bool RemoveSendStream(uint32_t ssrc) {
118     return RemoveStreamBySsrc(&send_streams_, ssrc);
119   }
AddRecvStream(const StreamParams & sp)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   }
RemoveRecvStream(uint32_t ssrc)128   virtual bool RemoveRecvStream(uint32_t ssrc) {
129     return RemoveStreamBySsrc(&receive_streams_, ssrc);
130   }
IsStreamMuted(uint32_t ssrc)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   }
send_streams()140   const std::vector<StreamParams>& send_streams() const {
141     return send_streams_;
142   }
recv_streams()143   const std::vector<StreamParams>& recv_streams() const {
144     return receive_streams_;
145   }
HasRecvStream(uint32_t ssrc)146   bool HasRecvStream(uint32_t ssrc) const {
147     return GetStreamBySsrc(receive_streams_, ssrc) != nullptr;
148   }
HasSendStream(uint32_t ssrc)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.
send_ssrc()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.
rtcp_cname()162   const std::string rtcp_cname() {
163     if (send_streams_.empty())
164       return "";
165     return send_streams_[0].cname;
166   }
167 
ready_to_send()168   bool ready_to_send() const {
169     return ready_to_send_;
170   }
171 
172  protected:
MuteStream(uint32_t ssrc,bool mute)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   }
set_sending(bool send)184   bool set_sending(bool send) {
185     sending_ = send;
186     return true;
187   }
set_playout(bool playout)188   void set_playout(bool playout) { playout_ = playout; }
SetRecvRtpHeaderExtensions(const std::vector<RtpHeaderExtension> & extensions)189   bool SetRecvRtpHeaderExtensions(
190       const std::vector<RtpHeaderExtension>& extensions) {
191     recv_extensions_ = extensions;
192     return true;
193   }
SetSendRtpHeaderExtensions(const std::vector<RtpHeaderExtension> & extensions)194   bool SetSendRtpHeaderExtensions(
195       const std::vector<RtpHeaderExtension>& extensions) {
196     send_extensions_ = extensions;
197     return true;
198   }
OnPacketReceived(rtc::Buffer * packet,const rtc::PacketTime & packet_time)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   }
OnRtcpReceived(rtc::Buffer * packet,const rtc::PacketTime & packet_time)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   }
OnReadyToSend(bool ready)207   virtual void OnReadyToSend(bool ready) {
208     ready_to_send_ = ready;
209   }
fail_set_send_codecs()210   bool fail_set_send_codecs() const { return fail_set_send_codecs_; }
fail_set_recv_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 {
DtmfInfoDtmfInfo233     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   };
FakeVoiceMediaChannel(FakeVoiceEngine * engine,const AudioOptions & options)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();
recv_codecs()249   const std::vector<AudioCodec>& recv_codecs() const { return recv_codecs_; }
send_codecs()250   const std::vector<AudioCodec>& send_codecs() const { return send_codecs_; }
codecs()251   const std::vector<AudioCodec>& codecs() const { return send_codecs(); }
dtmf_info_queue()252   const std::vector<DtmfInfo>& dtmf_info_queue() const {
253     return dtmf_info_queue_;
254   }
options()255   const AudioOptions& options() const { return options_; }
256 
SetSendParameters(const AudioSendParameters & params)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 
SetRecvParameters(const AudioRecvParameters & params)264   virtual bool SetRecvParameters(const AudioRecvParameters& params) {
265     return (SetRecvCodecs(params.codecs) &&
266             SetRecvRtpHeaderExtensions(params.extensions));
267   }
SetPlayout(bool playout)268   virtual bool SetPlayout(bool playout) {
269     set_playout(playout);
270     return true;
271   }
SetSend(SendFlags flag)272   virtual bool SetSend(SendFlags flag) {
273     return set_sending(flag != SEND_NOTHING);
274   }
SetAudioSend(uint32_t ssrc,bool enable,const AudioOptions * options,AudioRenderer * renderer)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   }
AddRecvStream(const StreamParams & sp)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   }
RemoveRecvStream(uint32_t ssrc)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 
GetActiveStreams(AudioInfo::StreamList * streams)303   virtual bool GetActiveStreams(AudioInfo::StreamList* streams) { return true; }
GetOutputLevel()304   virtual int GetOutputLevel() { return 0; }
set_time_since_last_typing(int ms)305   void set_time_since_last_typing(int ms) { time_since_last_typing_ = ms; }
GetTimeSinceLastTyping()306   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)307   virtual void SetTypingDetectionParameters(
308       int time_window, int cost_per_typing, int reporting_threshold,
309       int penalty_decay, int type_event_delay) {}
310 
CanInsertDtmf()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   }
InsertDtmf(uint32_t ssrc,int event_code,int duration)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 
SetOutputVolume(uint32_t ssrc,double volume)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   }
GetOutputVolume(uint32_t ssrc,double * volume)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 
GetStats(VoiceMediaInfo * info)348   virtual bool GetStats(VoiceMediaInfo* info) { return false; }
349 
SetRawAudioSink(uint32_t ssrc,rtc::scoped_ptr<webrtc::AudioSinkInterface> sink)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:
VoiceChannelAudioSink(AudioRenderer * renderer)359     explicit VoiceChannelAudioSink(AudioRenderer* renderer)
360         : renderer_(renderer) {
361       renderer_->SetSink(this);
362     }
~VoiceChannelAudioSink()363     virtual ~VoiceChannelAudioSink() {
364       if (renderer_) {
365         renderer_->SetSink(NULL);
366       }
367     }
OnData(const void * audio_data,int bits_per_sample,int sample_rate,size_t number_of_channels,size_t number_of_frames)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 {}
OnClose()373     void OnClose() override { renderer_ = NULL; }
renderer()374     AudioRenderer* renderer() const { return renderer_; }
375 
376    private:
377     AudioRenderer* renderer_;
378   };
379 
SetRecvCodecs(const std::vector<AudioCodec> & codecs)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   }
SetSendCodecs(const std::vector<AudioCodec> & codecs)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   }
SetMaxSendBandwidth(int bps)396   bool SetMaxSendBandwidth(int bps) { return true; }
SetOptions(const AudioOptions & options)397   bool SetOptions(const AudioOptions& options) {
398     // Does a "merge" of current options and set options.
399     options_.SetAll(options);
400     return true;
401   }
SetLocalRenderer(uint32_t ssrc,AudioRenderer * renderer)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.
CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo & info,uint32_t ssrc,int event_code,int duration)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:
FakeVideoMediaChannel(FakeVideoEngine * engine,const VideoOptions & options)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 
recv_codecs()453   const std::vector<VideoCodec>& recv_codecs() const { return recv_codecs_; }
send_codecs()454   const std::vector<VideoCodec>& send_codecs() const { return send_codecs_; }
codecs()455   const std::vector<VideoCodec>& codecs() const { return send_codecs(); }
rendering()456   bool rendering() const { return playout(); }
options()457   const VideoOptions& options() const { return options_; }
renderers()458   const std::map<uint32_t, VideoRenderer*>& renderers() const {
459     return renderers_;
460   }
max_bps()461   int max_bps() const { return max_bps_; }
GetSendStreamFormat(uint32_t ssrc,VideoFormat * format)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   }
SetSendStreamFormat(uint32_t ssrc,const VideoFormat & format)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   }
SetSendParameters(const VideoSendParameters & params)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 
SetRecvParameters(const VideoRecvParameters & params)483   virtual bool SetRecvParameters(const VideoRecvParameters& params) {
484     return (SetRecvCodecs(params.codecs) &&
485             SetRecvRtpHeaderExtensions(params.extensions));
486   }
AddSendStream(const StreamParams & sp)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   }
RemoveSendStream(uint32_t ssrc)494   virtual bool RemoveSendStream(uint32_t ssrc) {
495     send_formats_.erase(ssrc);
496     return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc);
497   }
498 
GetSendCodec(VideoCodec * send_codec)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   }
SetRenderer(uint32_t ssrc,VideoRenderer * r)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 
SetSend(bool send)516   virtual bool SetSend(bool send) { return set_sending(send); }
SetVideoSend(uint32_t ssrc,bool enable,const VideoOptions * options)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   }
SetCapturer(uint32_t ssrc,VideoCapturer * capturer)527   virtual bool SetCapturer(uint32_t ssrc, VideoCapturer* capturer) {
528     capturers_[ssrc] = capturer;
529     return true;
530   }
HasCapturer(uint32_t ssrc)531   bool HasCapturer(uint32_t ssrc) const {
532     return capturers_.find(ssrc) != capturers_.end();
533   }
AddRecvStream(const StreamParams & sp)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   }
RemoveRecvStream(uint32_t ssrc)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 
GetStats(VideoMediaInfo * info)547   virtual bool GetStats(VideoMediaInfo* info) { return false; }
SendIntraFrame()548   virtual bool SendIntraFrame() {
549     sent_intra_frame_ = true;
550     return true;
551   }
RequestIntraFrame()552   virtual bool RequestIntraFrame() {
553     requested_intra_frame_ = true;
554     return true;
555   }
UpdateAspectRatio(int ratio_w,int ratio_h)556   virtual void UpdateAspectRatio(int ratio_w, int ratio_h) {}
set_sent_intra_frame(bool v)557   void set_sent_intra_frame(bool v) { sent_intra_frame_ = v; }
sent_intra_frame()558   bool sent_intra_frame() const { return sent_intra_frame_; }
set_requested_intra_frame(bool v)559   void set_requested_intra_frame(bool v) { requested_intra_frame_ = v; }
requested_intra_frame()560   bool requested_intra_frame() const { return requested_intra_frame_; }
561 
562  private:
SetRecvCodecs(const std::vector<VideoCodec> & codecs)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   }
SetSendCodecs(const std::vector<VideoCodec> & codecs)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   }
SetOptions(const VideoOptions & options)584   bool SetOptions(const VideoOptions& options) {
585     options_ = options;
586     return true;
587   }
SetMaxSendBandwidth(int bps)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.
SetSendStreamDefaultFormat(uint32_t ssrc)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:
FakeDataMediaChannel(void * unused,const DataOptions & options)617   explicit FakeDataMediaChannel(void* unused, const DataOptions& options)
618       : send_blocked_(false), max_bps_(-1) {}
~FakeDataMediaChannel()619   ~FakeDataMediaChannel() {}
recv_codecs()620   const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; }
send_codecs()621   const std::vector<DataCodec>& send_codecs() const { return send_codecs_; }
codecs()622   const std::vector<DataCodec>& codecs() const { return send_codecs(); }
max_bps()623   int max_bps() const { return max_bps_; }
624 
SetSendParameters(const DataSendParameters & params)625   virtual bool SetSendParameters(const DataSendParameters& params) {
626     return (SetSendCodecs(params.codecs) &&
627             SetMaxSendBandwidth(params.max_bandwidth_bps));
628   }
SetRecvParameters(const DataRecvParameters & params)629   virtual bool SetRecvParameters(const DataRecvParameters& params) {
630     return SetRecvCodecs(params.codecs);
631   }
SetSend(bool send)632   virtual bool SetSend(bool send) { return set_sending(send); }
SetReceive(bool receive)633   virtual bool SetReceive(bool receive) {
634     set_playout(receive);
635     return true;
636   }
AddRecvStream(const StreamParams & sp)637   virtual bool AddRecvStream(const StreamParams& sp) {
638     if (!RtpHelper<DataMediaChannel>::AddRecvStream(sp))
639       return false;
640     return true;
641   }
RemoveRecvStream(uint32_t ssrc)642   virtual bool RemoveRecvStream(uint32_t ssrc) {
643     if (!RtpHelper<DataMediaChannel>::RemoveRecvStream(ssrc))
644       return false;
645     return true;
646   }
647 
SendData(const SendDataParams & params,const rtc::Buffer & payload,SendDataResult * result)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 
last_sent_data_params()661   SendDataParams last_sent_data_params() { return last_sent_data_params_; }
last_sent_data()662   std::string last_sent_data() { return last_sent_data_; }
is_send_blocked()663   bool is_send_blocked() { return send_blocked_; }
set_send_blocked(bool blocked)664   void set_send_blocked(bool blocked) { send_blocked_ = blocked; }
665 
666  private:
SetRecvCodecs(const std::vector<DataCodec> & codecs)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   }
SetSendCodecs(const std::vector<DataCodec> & codecs)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   }
SetMaxSendBandwidth(int bps)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:
FakeBaseEngine()700   FakeBaseEngine()
701       : options_changed_(false),
702         fail_create_channel_(false) {}
set_fail_create_channel(bool fail)703   void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; }
704 
GetCapabilities()705   RtpCapabilities GetCapabilities() const { return capabilities_; }
set_rtp_header_extensions(const std::vector<RtpHeaderExtension> & extensions)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:
FakeVoiceEngine()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   }
Init(rtc::Thread * worker_thread)728   bool Init(rtc::Thread* worker_thread) { return true; }
Terminate()729   void Terminate() {}
GetAudioState()730   rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const {
731     return rtc::scoped_refptr<webrtc::AudioState>();
732   }
733 
CreateChannel(webrtc::Call * call,const AudioOptions & options)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   }
GetChannel(size_t index)744   FakeVoiceMediaChannel* GetChannel(size_t index) {
745     return (channels_.size() > index) ? channels_[index] : NULL;
746   }
UnregisterChannel(VoiceMediaChannel * channel)747   void UnregisterChannel(VoiceMediaChannel* channel) {
748     channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
749   }
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 
GetOutputVolume(int * level)754   bool GetOutputVolume(int* level) {
755     *level = output_volume_;
756     return true;
757   }
SetOutputVolume(int level)758   bool SetOutputVolume(int level) {
759     output_volume_ = level;
760     return true;
761   }
762 
GetInputLevel()763   int GetInputLevel() { return 0; }
764 
StartAecDump(rtc::PlatformFile file)765   bool StartAecDump(rtc::PlatformFile file) { return false; }
766 
StopAecDump()767   void StopAecDump() {}
768 
StartRtcEventLog(rtc::PlatformFile file)769   bool StartRtcEventLog(rtc::PlatformFile file) { return false; }
770 
StopRtcEventLog()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:
FakeVideoEngine()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   }
Init()788   void Init() {}
SetOptions(const VideoOptions & options)789   bool SetOptions(const VideoOptions& options) {
790     options_ = options;
791     options_changed_ = true;
792     return true;
793   }
794 
CreateChannel(webrtc::Call * call,const VideoOptions & options)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   }
GetChannel(size_t index)805   FakeVideoMediaChannel* GetChannel(size_t index) {
806     return (channels_.size() > index) ? channels_[index] : NULL;
807   }
UnregisterChannel(VideoMediaChannel * channel)808   void UnregisterChannel(VideoMediaChannel* channel) {
809     channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
810   }
811 
codecs()812   const std::vector<VideoCodec>& codecs() const { return codecs_; }
FindCodec(const VideoCodec & in)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   }
SetCodecs(const std::vector<VideoCodec> codecs)821   void SetCodecs(const std::vector<VideoCodec> codecs) { codecs_ = codecs; }
822 
SetCaptureDevice(const Device * device)823   bool SetCaptureDevice(const Device* device) {
824     in_device_ = (device) ? device->name : "";
825     options_changed_ = true;
826     return true;
827   }
SetCapture(bool capture)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:
FakeMediaEngine()846   FakeMediaEngine() {}
~FakeMediaEngine()847   virtual ~FakeMediaEngine() {}
848 
SetAudioCodecs(const std::vector<AudioCodec> & codecs)849   void SetAudioCodecs(const std::vector<AudioCodec>& codecs) {
850     voice_.SetCodecs(codecs);
851   }
SetVideoCodecs(const std::vector<VideoCodec> & codecs)852   void SetVideoCodecs(const std::vector<VideoCodec>& codecs) {
853     video_.SetCodecs(codecs);
854   }
855 
SetAudioRtpHeaderExtensions(const std::vector<RtpHeaderExtension> & extensions)856   void SetAudioRtpHeaderExtensions(
857       const std::vector<RtpHeaderExtension>& extensions) {
858     voice_.set_rtp_header_extensions(extensions);
859   }
SetVideoRtpHeaderExtensions(const std::vector<RtpHeaderExtension> & extensions)860   void SetVideoRtpHeaderExtensions(
861       const std::vector<RtpHeaderExtension>& extensions) {
862     video_.set_rtp_header_extensions(extensions);
863   }
864 
GetVoiceChannel(size_t index)865   FakeVoiceMediaChannel* GetVoiceChannel(size_t index) {
866     return voice_.GetChannel(index);
867   }
GetVideoChannel(size_t index)868   FakeVideoMediaChannel* GetVideoChannel(size_t index) {
869     return video_.GetChannel(index);
870   }
871 
output_volume()872   int output_volume() const { return voice_.output_volume_; }
capture()873   bool capture() const { return video_.capture_; }
options_changed()874   bool options_changed() const {
875     return video_.options_changed_;
876   }
clear_options_changed()877   void clear_options_changed() {
878     video_.options_changed_ = false;
879   }
set_fail_create_channel(bool fail)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:
CompositeMediaEngineWithFakeVoiceEngine()892   CompositeMediaEngineWithFakeVoiceEngine() {}
~CompositeMediaEngineWithFakeVoiceEngine()893   virtual ~CompositeMediaEngineWithFakeVoiceEngine() {}
894 
SetAudioCodecs(const std::vector<AudioCodec> & codecs)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
~FakeVoiceMediaChannel()901 inline FakeVoiceMediaChannel::~FakeVoiceMediaChannel() {
902   if (engine_) {
903     engine_->UnregisterChannel(this);
904   }
905 }
906 
~FakeVideoMediaChannel()907 inline FakeVideoMediaChannel::~FakeVideoMediaChannel() {
908   if (engine_) {
909     engine_->UnregisterChannel(this);
910   }
911 }
912 
913 class FakeDataEngine : public DataEngineInterface {
914  public:
FakeDataEngine()915   FakeDataEngine() : last_channel_type_(DCT_NONE) {}
916 
CreateChannel(DataChannelType data_channel_type)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 
GetChannel(size_t index)924   FakeDataMediaChannel* GetChannel(size_t index) {
925     return (channels_.size() > index) ? channels_[index] : NULL;
926   }
927 
UnregisterChannel(DataMediaChannel * channel)928   void UnregisterChannel(DataMediaChannel* channel) {
929     channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
930   }
931 
SetDataCodecs(const std::vector<DataCodec> & data_codecs)932   virtual void SetDataCodecs(const std::vector<DataCodec>& data_codecs) {
933     data_codecs_ = data_codecs;
934   }
935 
data_codecs()936   virtual const std::vector<DataCodec>& data_codecs() { return data_codecs_; }
937 
last_channel_type()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