• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004--2007, 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_SESSION_PHONE_CHANNEL_H_
29 #define TALK_SESSION_PHONE_CHANNEL_H_
30 
31 #include <string>
32 #include <vector>
33 
34 #include "talk/base/asyncudpsocket.h"
35 #include "talk/base/criticalsection.h"
36 #include "talk/base/network.h"
37 #include "talk/base/sigslot.h"
38 #include "talk/p2p/client/socketmonitor.h"
39 #include "talk/p2p/base/session.h"
40 #include "talk/session/phone/audiomonitor.h"
41 #include "talk/session/phone/mediaengine.h"
42 #include "talk/session/phone/mediachannel.h"
43 #include "talk/session/phone/mediamonitor.h"
44 #include "talk/session/phone/rtcpmuxfilter.h"
45 #include "talk/session/phone/srtpfilter.h"
46 
47 namespace cricket {
48 
49 class MediaContentDescription;
50 class MediaSinkInterface;
51 struct CryptoParams;
52 
53 enum {
54   MSG_ENABLE = 1,
55   MSG_DISABLE = 2,
56   MSG_MUTE = 3,
57   MSG_UNMUTE = 4,
58   MSG_SETREMOTECONTENT = 5,
59   MSG_SETLOCALCONTENT = 6,
60   MSG_EARLYMEDIATIMEOUT = 8,
61   MSG_PRESSDTMF = 9,
62   MSG_SETRENDERER = 10,
63   MSG_ADDSTREAM = 11,
64   MSG_REMOVESTREAM = 12,
65   MSG_SETRINGBACKTONE = 13,
66   MSG_PLAYRINGBACKTONE = 14,
67   MSG_SETMAXSENDBANDWIDTH = 15,
68   MSG_SETRTCPCNAME = 18,
69   MSG_SENDINTRAFRAME = 19,
70   MSG_REQUESTINTRAFRAME = 20,
71   MSG_RTPPACKET = 22,
72   MSG_RTCPPACKET = 23,
73   MSG_CHANNEL_ERROR = 24
74 };
75 
76 // BaseChannel contains logic common to voice and video, including
77 // enable/mute, marshaling calls to a worker thread, and
78 // connection and media monitors.
79 class BaseChannel
80     : public talk_base::MessageHandler, public sigslot::has_slots<>,
81       public MediaChannel::NetworkInterface {
82  public:
83   BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine,
84               MediaChannel* channel, BaseSession* session,
85               const std::string& content_name,
86               TransportChannel* transport_channel);
87   virtual ~BaseChannel();
88 
worker_thread()89   talk_base::Thread* worker_thread() const { return worker_thread_; }
session()90   BaseSession* session() const { return session_; }
content_name()91   const std::string& content_name() { return content_name_; }
transport_channel()92   TransportChannel* transport_channel() const {
93     return transport_channel_;
94   }
rtcp_transport_channel()95   TransportChannel* rtcp_transport_channel() const {
96     return rtcp_transport_channel_;
97   }
enabled()98   bool enabled() const { return enabled_; }
secure()99   bool secure() const { return srtp_filter_.IsActive(); }
100 
101   // Channel control
102   bool SetRtcpCName(const std::string& cname);
103   bool SetLocalContent(const MediaContentDescription* content,
104                        ContentAction action);
105   bool SetRemoteContent(const MediaContentDescription* content,
106                         ContentAction action);
107   bool SetMaxSendBandwidth(int max_bandwidth);
108 
109   bool Enable(bool enable);
110   bool Mute(bool mute);
111 
112   // Multiplexing
113   bool RemoveStream(uint32 ssrc);
114 
115   // Monitoring
116   void StartConnectionMonitor(int cms);
117   void StopConnectionMonitor();
118 
119   // Set and get media sinks for recording media.
set_received_media_sink(MediaSinkInterface * sink)120   void set_received_media_sink(MediaSinkInterface* sink) {
121     talk_base::CritScope cs(&sink_critical_section_);
122     received_media_sink_ = sink;
123   }
received_media_sink()124   const MediaSinkInterface* received_media_sink() {
125     talk_base::CritScope cs(&sink_critical_section_);
126     return received_media_sink_;
127   }
set_sent_media_sink(MediaSinkInterface * sink)128   void set_sent_media_sink(MediaSinkInterface* sink) {
129     talk_base::CritScope cs(&sink_critical_section_);
130     sent_media_sink_ = sink;
131   }
sent_media_sink()132   const MediaSinkInterface* sent_media_sink() {
133     talk_base::CritScope cs(&sink_critical_section_);
134     return sent_media_sink_;
135   }
136 
137  protected:
media_engine()138   MediaEngine* media_engine() const { return media_engine_; }
media_channel()139   virtual MediaChannel* media_channel() const { return media_channel_; }
140   void set_rtcp_transport_channel(TransportChannel* transport);
writable()141   bool writable() const { return writable_; }
has_codec()142   bool has_codec() const { return has_codec_; }
set_has_codec(bool has_codec)143   void set_has_codec(bool has_codec) { has_codec_ = has_codec; }
muted()144   bool muted() const { return muted_; }
signaling_thread()145   talk_base::Thread* signaling_thread() { return session_->signaling_thread(); }
146 
147   void Send(uint32 id, talk_base::MessageData *pdata = NULL);
148   void Post(uint32 id, talk_base::MessageData *pdata = NULL);
149   void PostDelayed(int cmsDelay, uint32 id = 0,
150                    talk_base::MessageData *pdata = NULL);
151   void Clear(uint32 id = talk_base::MQID_ANY,
152              talk_base::MessageList* removed = NULL);
153   void FlushRtcpMessages();
154 
155   // NetworkInterface implementation, called by MediaEngine
156   virtual bool SendPacket(talk_base::Buffer* packet);
157   virtual bool SendRtcp(talk_base::Buffer* packet);
158   virtual int SetOption(SocketType type, talk_base::Socket::Option o, int val);
159 
160   // From TransportChannel
161   void OnWritableState(TransportChannel* channel);
162   void OnChannelRead(TransportChannel* channel, const char *data, size_t len);
163 
164   bool SendPacket(bool rtcp, talk_base::Buffer* packet);
165   void HandlePacket(bool rtcp, talk_base::Buffer* packet);
166 
167   // Setting the send codec based on the remote description.
168   void OnSessionState(BaseSession* session, BaseSession::State state);
169 
170   void EnableMedia_w();
171   void DisableMedia_w();
172   void MuteMedia_w();
173   void UnmuteMedia_w();
174   void ChannelWritable_w();
175   void ChannelNotWritable_w();
176 
177   struct StreamMessageData : public talk_base::MessageData {
StreamMessageDataStreamMessageData178     StreamMessageData(uint32 s1, uint32 s2) : ssrc1(s1), ssrc2(s2) {}
179     uint32 ssrc1;
180     uint32 ssrc2;
181   };
182   virtual void RemoveStream_w(uint32 ssrc) = 0;
183 
184   virtual void ChangeState() = 0;
185 
186   struct SetRtcpCNameData : public talk_base::MessageData {
SetRtcpCNameDataSetRtcpCNameData187     explicit SetRtcpCNameData(const std::string& cname)
188         : cname(cname), result(false) {}
189     std::string cname;
190     bool result;
191   };
192   bool SetRtcpCName_w(const std::string& cname);
193 
194   struct SetContentData : public talk_base::MessageData {
SetContentDataSetContentData195     SetContentData(const MediaContentDescription* content,
196                    ContentAction action)
197         : content(content), action(action), result(false) {}
198     const MediaContentDescription* content;
199     ContentAction action;
200     bool result;
201   };
202 
203   // Gets the content appropriate to the channel (audio or video).
204   virtual const MediaContentDescription* GetFirstContent(
205       const SessionDescription* sdesc) = 0;
206   virtual bool SetLocalContent_w(const MediaContentDescription* content,
207                                  ContentAction action) = 0;
208   virtual bool SetRemoteContent_w(const MediaContentDescription* content,
209                                   ContentAction action) = 0;
210 
211   bool SetSrtp_w(const std::vector<CryptoParams>& params, ContentAction action,
212                  ContentSource src);
213   bool SetRtcpMux_w(bool enable, ContentAction action, ContentSource src);
214 
215   struct SetBandwidthData : public talk_base::MessageData {
SetBandwidthDataSetBandwidthData216     explicit SetBandwidthData(int value) : value(value), result(false) {}
217     int value;
218     bool result;
219   };
220   bool SetMaxSendBandwidth_w(int max_bandwidth);
221 
222   // From MessageHandler
223   virtual void OnMessage(talk_base::Message *pmsg);
224 
225   // Handled in derived classes
226   virtual void OnConnectionMonitorUpdate(SocketMonitor *monitor,
227       const std::vector<ConnectionInfo> &infos) = 0;
228 
229  private:
230   talk_base::Thread *worker_thread_;
231   MediaEngine *media_engine_;
232   BaseSession *session_;
233   MediaChannel *media_channel_;
234   // Media sinks to handle the received or sent RTP/RTCP packets. These are
235   // reference to the objects owned by the media recorder.
236   MediaSinkInterface* received_media_sink_;
237   MediaSinkInterface* sent_media_sink_;
238   talk_base::CriticalSection sink_critical_section_;
239 
240   std::string content_name_;
241   TransportChannel *transport_channel_;
242   TransportChannel *rtcp_transport_channel_;
243   SrtpFilter srtp_filter_;
244   RtcpMuxFilter rtcp_mux_filter_;
245   talk_base::scoped_ptr<SocketMonitor> socket_monitor_;
246   bool enabled_;
247   bool writable_;
248   bool has_codec_;
249   bool muted_;
250 };
251 
252 // VoiceChannel is a specialization that adds support for early media, DTMF,
253 // and input/output level monitoring.
254 class VoiceChannel : public BaseChannel {
255  public:
256   VoiceChannel(talk_base::Thread *thread, MediaEngine *media_engine,
257                VoiceMediaChannel *channel, BaseSession *session,
258                const std::string& content_name, bool rtcp);
259   ~VoiceChannel();
260 
261   // downcasts a MediaChannel
media_channel()262   virtual VoiceMediaChannel* media_channel() const {
263     return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel());
264   }
265 
266   // Add an incoming stream with the specified SSRC.
267   bool AddStream(uint32 ssrc);
268 
269   bool SetRingbackTone(const void* buf, int len);
270   void SetEarlyMedia(bool enable);
271   // This signal is emitted when we have gone a period of time without
272   // receiving early media. When received, a UI should start playing its
273   // own ringing sound
274   sigslot::signal1<VoiceChannel*> SignalEarlyMediaTimeout;
275 
276   bool PlayRingbackTone(bool play, bool loop);
277   bool PressDTMF(int digit, bool playout);
278 
279   // Monitoring functions
280   sigslot::signal2<VoiceChannel*, const std::vector<ConnectionInfo> &>
281       SignalConnectionMonitor;
282 
283   void StartMediaMonitor(int cms);
284   void StopMediaMonitor();
285   sigslot::signal2<VoiceChannel*, const VoiceMediaInfo&> SignalMediaMonitor;
286 
287   void StartAudioMonitor(int cms);
288   void StopAudioMonitor();
289   sigslot::signal2<VoiceChannel*, const AudioInfo&> SignalAudioMonitor;
290 
291   int GetInputLevel_w();
292   int GetOutputLevel_w();
293   void GetActiveStreams_w(AudioInfo::StreamList* actives);
294 
295   // Signal errors from VoiceMediaChannel.  Arguments are:
296   //     ssrc(uint32), and error(VoiceMediaChannel::Error).
297   sigslot::signal3<VoiceChannel*, uint32, VoiceMediaChannel::Error>
298       SignalMediaError;
299 
300  private:
301   struct SetRingbackToneMessageData : public talk_base::MessageData {
SetRingbackToneMessageDataSetRingbackToneMessageData302     SetRingbackToneMessageData(const void* b, int l)
303         : buf(b),
304           len(l) {
305     }
306     const void* buf;
307     int len;
308   };
309   struct PlayRingbackToneMessageData : public talk_base::MessageData {
PlayRingbackToneMessageDataPlayRingbackToneMessageData310     PlayRingbackToneMessageData(bool p, bool l)
311         : play(p),
312           loop(l),
313           result(false) {
314     }
315     bool play;
316     bool loop;
317     bool result;
318   };
319   struct DtmfMessageData : public talk_base::MessageData {
DtmfMessageDataDtmfMessageData320     DtmfMessageData(int d, bool p)
321         : digit(d),
322           playout(p),
323           result(false) {
324     }
325     int digit;
326     bool playout;
327     bool result;
328   };
329 
330   // overrides from BaseChannel
331   virtual void OnChannelRead(TransportChannel* channel,
332                              const char *data, size_t len);
333   virtual void ChangeState();
334   virtual const MediaContentDescription* GetFirstContent(
335       const SessionDescription* sdesc);
336   virtual bool SetLocalContent_w(const MediaContentDescription* content,
337                                  ContentAction action);
338   virtual bool SetRemoteContent_w(const MediaContentDescription* content,
339                                   ContentAction action);
340 
341   void AddStream_w(uint32 ssrc);
342   void RemoveStream_w(uint32 ssrc);
343 
344   void SetRingbackTone_w(const void* buf, int len);
345   bool PlayRingbackTone_w(bool play, bool loop);
346   void HandleEarlyMediaTimeout();
347   bool PressDTMF_w(int digit, bool playout);
348 
349   virtual void OnMessage(talk_base::Message *pmsg);
350   virtual void OnConnectionMonitorUpdate(
351       SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos);
352   virtual void OnMediaMonitorUpdate(
353       VoiceMediaChannel *media_channel, const VoiceMediaInfo& info);
354   void OnAudioMonitorUpdate(AudioMonitor *monitor, const AudioInfo& info);
355   void OnVoiceChannelError(uint32 ssrc, VoiceMediaChannel::Error error);
356   void SendLastMediaError();
357 
358   static const int kEarlyMediaTimeout = 1000;
359   bool received_media_;
360   talk_base::scoped_ptr<VoiceMediaMonitor> media_monitor_;
361   talk_base::scoped_ptr<AudioMonitor> audio_monitor_;
362 };
363 
364 // VideoChannel is a specialization for video.
365 class VideoChannel : public BaseChannel {
366  public:
367   VideoChannel(talk_base::Thread *thread, MediaEngine *media_engine,
368                VideoMediaChannel *channel, BaseSession *session,
369                const std::string& content_name, bool rtcp,
370                VoiceChannel *voice_channel);
371   ~VideoChannel();
372 
373   // downcasts a MediaChannel
media_channel()374   virtual VideoMediaChannel* media_channel() const {
375     return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
376   }
377 
378   // Add an incoming stream with the specified SSRC.
379   bool AddStream(uint32 ssrc, uint32 voice_ssrc);
380 
381   bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
382 
383 
384   sigslot::signal2<VideoChannel*, const std::vector<ConnectionInfo> &>
385       SignalConnectionMonitor;
386 
387   void StartMediaMonitor(int cms);
388   void StopMediaMonitor();
389   sigslot::signal2<VideoChannel*, const VideoMediaInfo&> SignalMediaMonitor;
390 
391   bool SendIntraFrame();
392   bool RequestIntraFrame();
393 
394   sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
395       SignalMediaError;
396 
397  private:
398   // overrides from BaseChannel
399   virtual void ChangeState();
400   virtual const MediaContentDescription* GetFirstContent(
401       const SessionDescription* sdesc);
402   virtual bool SetLocalContent_w(const MediaContentDescription* content,
403                                  ContentAction action);
404   virtual bool SetRemoteContent_w(const MediaContentDescription* content,
405                                   ContentAction action);
406 
407   void AddStream_w(uint32 ssrc, uint32 voice_ssrc);
408   void RemoveStream_w(uint32 ssrc);
409 
SendIntraFrame_w()410   void SendIntraFrame_w() {
411     media_channel()->SendIntraFrame();
412   }
RequestIntraFrame_w()413   void RequestIntraFrame_w() {
414     media_channel()->RequestIntraFrame();
415   }
416 
417   struct RenderMessageData : public talk_base::MessageData {
RenderMessageDataRenderMessageData418     RenderMessageData(uint32 s, VideoRenderer* r) : ssrc(s), renderer(r) {}
419     uint32 ssrc;
420     VideoRenderer* renderer;
421   };
422 
423 
424   void SetRenderer_w(uint32 ssrc, VideoRenderer* renderer);
425 
426 
427   virtual void OnMessage(talk_base::Message *pmsg);
428   virtual void OnConnectionMonitorUpdate(
429       SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos);
430   virtual void OnMediaMonitorUpdate(
431       VideoMediaChannel *media_channel, const VideoMediaInfo& info);
432   void OnVideoChannelError(uint32 ssrc, VideoMediaChannel::Error error);
433 
434   VoiceChannel *voice_channel_;
435   VideoRenderer *renderer_;
436   talk_base::scoped_ptr<VideoMediaMonitor> media_monitor_;
437 };
438 
439 }  // namespace cricket
440 
441 #endif  // TALK_SESSION_PHONE_CHANNEL_H_
442