blob: bf9a83791077fe7c584630c0d8cb56b7112ceb67 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
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_SESSION_MEDIA_CHANNEL_H_
29#define TALK_SESSION_MEDIA_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/base/window.h"
39#include "talk/media/base/mediachannel.h"
40#include "talk/media/base/mediaengine.h"
41#include "talk/media/base/screencastid.h"
42#include "talk/media/base/streamparams.h"
43#include "talk/media/base/videocapturer.h"
44#include "talk/p2p/base/session.h"
45#include "talk/p2p/client/socketmonitor.h"
46#include "talk/session/media/audiomonitor.h"
47#include "talk/session/media/mediamonitor.h"
48#include "talk/session/media/mediasession.h"
49#include "talk/session/media/rtcpmuxfilter.h"
50#include "talk/session/media/srtpfilter.h"
51#include "talk/session/media/ssrcmuxfilter.h"
52
53namespace cricket {
54
55struct CryptoParams;
56class MediaContentDescription;
57struct TypingMonitorOptions;
58class TypingMonitor;
59struct ViewRequest;
60
61enum SinkType {
62 SINK_PRE_CRYPTO, // Sink packets before encryption or after decryption.
63 SINK_POST_CRYPTO // Sink packets after encryption or before decryption.
64};
65
66// BaseChannel contains logic common to voice and video, including
67// enable/mute, marshaling calls to a worker thread, and
68// connection and media monitors.
wu@webrtc.org78187522013-10-07 23:32:02 +000069//
70// WARNING! SUBCLASSES MUST CALL Deinit() IN THEIR DESTRUCTORS!
71// This is required to avoid a data race between the destructor modifying the
72// vtable, and the media channel's thread using BaseChannel as the
73// NetworkInterface.
74
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075class BaseChannel
76 : public talk_base::MessageHandler, public sigslot::has_slots<>,
77 public MediaChannel::NetworkInterface {
78 public:
79 BaseChannel(talk_base::Thread* thread, MediaEngineInterface* media_engine,
80 MediaChannel* channel, BaseSession* session,
81 const std::string& content_name, bool rtcp);
82 virtual ~BaseChannel();
83 bool Init(TransportChannel* transport_channel,
84 TransportChannel* rtcp_transport_channel);
wu@webrtc.org78187522013-10-07 23:32:02 +000085 // Deinit may be called multiple times and is simply ignored if it's alreay
86 // done.
87 void Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088
89 talk_base::Thread* worker_thread() const { return worker_thread_; }
90 BaseSession* session() const { return session_; }
91 const std::string& content_name() { return content_name_; }
92 TransportChannel* transport_channel() const {
93 return transport_channel_;
94 }
95 TransportChannel* rtcp_transport_channel() const {
96 return rtcp_transport_channel_;
97 }
98 bool enabled() const { return enabled_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099
100 // This function returns true if we are using SRTP.
101 bool secure() const { return srtp_filter_.IsActive(); }
102 // The following function returns true if we are using
103 // DTLS-based keying. If you turned off SRTP later, however
104 // you could have secure() == false and dtls_secure() == true.
105 bool secure_dtls() const { return dtls_keyed_; }
106 // This function returns true if we require secure channel for call setup.
107 bool secure_required() const { return secure_required_; }
108
109 bool writable() const { return writable_; }
110 bool IsStreamMuted(uint32 ssrc);
111
112 // Channel control
113 bool SetLocalContent(const MediaContentDescription* content,
114 ContentAction action);
115 bool SetRemoteContent(const MediaContentDescription* content,
116 ContentAction action);
117 bool SetMaxSendBandwidth(int max_bandwidth);
118
119 bool Enable(bool enable);
120 // Mute sending media on the stream with SSRC |ssrc|
121 // If there is only one sending stream SSRC 0 can be used.
122 bool MuteStream(uint32 ssrc, bool mute);
123
124 // Multiplexing
125 bool AddRecvStream(const StreamParams& sp);
126 bool RemoveRecvStream(uint32 ssrc);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000127 bool AddSendStream(const StreamParams& sp);
128 bool RemoveSendStream(uint32 ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129
130 // Monitoring
131 void StartConnectionMonitor(int cms);
132 void StopConnectionMonitor();
133
134 void set_srtp_signal_silent_time(uint32 silent_time) {
135 srtp_filter_.set_signal_silent_time(silent_time);
136 }
137
138 void set_content_name(const std::string& content_name) {
139 ASSERT(signaling_thread()->IsCurrent());
140 ASSERT(!writable_);
141 if (session_->state() != BaseSession::STATE_INIT) {
142 LOG(LS_ERROR) << "Content name for a channel can be changed only "
143 << "when BaseSession is in STATE_INIT state.";
144 return;
145 }
146 content_name_ = content_name;
147 }
148
149 template <class T>
150 void RegisterSendSink(T* sink,
151 void (T::*OnPacket)(const void*, size_t, bool),
152 SinkType type) {
153 talk_base::CritScope cs(&signal_send_packet_cs_);
154 if (SINK_POST_CRYPTO == type) {
155 SignalSendPacketPostCrypto.disconnect(sink);
156 SignalSendPacketPostCrypto.connect(sink, OnPacket);
157 } else {
158 SignalSendPacketPreCrypto.disconnect(sink);
159 SignalSendPacketPreCrypto.connect(sink, OnPacket);
160 }
161 }
162
163 void UnregisterSendSink(sigslot::has_slots<>* sink,
164 SinkType type) {
165 talk_base::CritScope cs(&signal_send_packet_cs_);
166 if (SINK_POST_CRYPTO == type) {
167 SignalSendPacketPostCrypto.disconnect(sink);
168 } else {
169 SignalSendPacketPreCrypto.disconnect(sink);
170 }
171 }
172
173 bool HasSendSinks(SinkType type) {
174 talk_base::CritScope cs(&signal_send_packet_cs_);
175 if (SINK_POST_CRYPTO == type) {
176 return !SignalSendPacketPostCrypto.is_empty();
177 } else {
178 return !SignalSendPacketPreCrypto.is_empty();
179 }
180 }
181
182 template <class T>
183 void RegisterRecvSink(T* sink,
184 void (T::*OnPacket)(const void*, size_t, bool),
185 SinkType type) {
186 talk_base::CritScope cs(&signal_recv_packet_cs_);
187 if (SINK_POST_CRYPTO == type) {
188 SignalRecvPacketPostCrypto.disconnect(sink);
189 SignalRecvPacketPostCrypto.connect(sink, OnPacket);
190 } else {
191 SignalRecvPacketPreCrypto.disconnect(sink);
192 SignalRecvPacketPreCrypto.connect(sink, OnPacket);
193 }
194 }
195
196 void UnregisterRecvSink(sigslot::has_slots<>* sink,
197 SinkType type) {
198 talk_base::CritScope cs(&signal_recv_packet_cs_);
199 if (SINK_POST_CRYPTO == type) {
200 SignalRecvPacketPostCrypto.disconnect(sink);
201 } else {
202 SignalRecvPacketPreCrypto.disconnect(sink);
203 }
204 }
205
206 bool HasRecvSinks(SinkType type) {
207 talk_base::CritScope cs(&signal_recv_packet_cs_);
208 if (SINK_POST_CRYPTO == type) {
209 return !SignalRecvPacketPostCrypto.is_empty();
210 } else {
211 return !SignalRecvPacketPreCrypto.is_empty();
212 }
213 }
214
215 SsrcMuxFilter* ssrc_filter() { return &ssrc_filter_; }
216
217 const std::vector<StreamParams>& local_streams() const {
218 return local_streams_;
219 }
220 const std::vector<StreamParams>& remote_streams() const {
221 return remote_streams_;
222 }
223
224 // Used for latency measurements.
225 sigslot::signal1<BaseChannel*> SignalFirstPacketReceived;
226
227 // Used to alert UI when the muted status changes, perhaps autonomously.
228 sigslot::repeater2<BaseChannel*, bool> SignalAutoMuted;
229
230 // Made public for easier testing.
231 void SetReadyToSend(TransportChannel* channel, bool ready);
232
233 protected:
234 MediaEngineInterface* media_engine() const { return media_engine_; }
235 virtual MediaChannel* media_channel() const { return media_channel_; }
236 void set_rtcp_transport_channel(TransportChannel* transport);
237 bool was_ever_writable() const { return was_ever_writable_; }
238 void set_local_content_direction(MediaContentDirection direction) {
239 local_content_direction_ = direction;
240 }
241 void set_remote_content_direction(MediaContentDirection direction) {
242 remote_content_direction_ = direction;
243 }
244 bool IsReadyToReceive() const;
245 bool IsReadyToSend() const;
246 talk_base::Thread* signaling_thread() { return session_->signaling_thread(); }
247 SrtpFilter* srtp_filter() { return &srtp_filter_; }
248 bool rtcp() const { return rtcp_; }
249
250 void Send(uint32 id, talk_base::MessageData* pdata = NULL);
251 void Post(uint32 id, talk_base::MessageData* pdata = NULL);
252 void PostDelayed(int cmsDelay, uint32 id = 0,
253 talk_base::MessageData* pdata = NULL);
254 void Clear(uint32 id = talk_base::MQID_ANY,
255 talk_base::MessageList* removed = NULL);
256 void FlushRtcpMessages();
257
258 // NetworkInterface implementation, called by MediaEngine
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000259 virtual bool SendPacket(talk_base::Buffer* packet,
260 talk_base::DiffServCodePoint dscp);
261 virtual bool SendRtcp(talk_base::Buffer* packet,
262 talk_base::DiffServCodePoint dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 virtual int SetOption(SocketType type, talk_base::Socket::Option o, int val);
264
265 // From TransportChannel
266 void OnWritableState(TransportChannel* channel);
wu@webrtc.orga9890802013-12-13 00:21:03 +0000267 virtual void OnChannelRead(TransportChannel* channel,
268 const char* data,
269 size_t len,
270 const talk_base::PacketTime& packet_time,
271 int flags);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 void OnReadyToSend(TransportChannel* channel);
273
274 bool PacketIsRtcp(const TransportChannel* channel, const char* data,
275 size_t len);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000276 bool SendPacket(bool rtcp, talk_base::Buffer* packet,
277 talk_base::DiffServCodePoint dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 virtual bool WantsPacket(bool rtcp, talk_base::Buffer* packet);
wu@webrtc.orga9890802013-12-13 00:21:03 +0000279 void HandlePacket(bool rtcp, talk_base::Buffer* packet,
280 const talk_base::PacketTime& packet_time);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281
282 // Apply the new local/remote session description.
283 void OnNewLocalDescription(BaseSession* session, ContentAction action);
284 void OnNewRemoteDescription(BaseSession* session, ContentAction action);
285
286 void EnableMedia_w();
287 void DisableMedia_w();
288 virtual bool MuteStream_w(uint32 ssrc, bool mute);
289 bool IsStreamMuted_w(uint32 ssrc);
290 void ChannelWritable_w();
291 void ChannelNotWritable_w();
292 bool AddRecvStream_w(const StreamParams& sp);
293 bool RemoveRecvStream_w(uint32 ssrc);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000294 bool AddSendStream_w(const StreamParams& sp);
295 bool RemoveSendStream_w(uint32 ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000296 virtual bool ShouldSetupDtlsSrtp() const;
297 // Do the DTLS key expansion and impose it on the SRTP/SRTCP filters.
298 // |rtcp_channel| indicates whether to set up the RTP or RTCP filter.
299 bool SetupDtlsSrtp(bool rtcp_channel);
300 // Set the DTLS-SRTP cipher policy on this channel as appropriate.
301 bool SetDtlsSrtpCiphers(TransportChannel *tc, bool rtcp);
302
303 virtual void ChangeState() = 0;
304
305 // Gets the content info appropriate to the channel (audio or video).
306 virtual const ContentInfo* GetFirstContent(
307 const SessionDescription* sdesc) = 0;
308 bool UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
309 ContentAction action);
310 bool UpdateRemoteStreams_w(const std::vector<StreamParams>& streams,
311 ContentAction action);
312 bool SetBaseLocalContent_w(const MediaContentDescription* content,
313 ContentAction action);
314 virtual bool SetLocalContent_w(const MediaContentDescription* content,
315 ContentAction action) = 0;
316 bool SetBaseRemoteContent_w(const MediaContentDescription* content,
317 ContentAction action);
318 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
319 ContentAction action) = 0;
320
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000321 bool CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, bool* dtls);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 bool SetSrtp_w(const std::vector<CryptoParams>& params, ContentAction action,
323 ContentSource src);
324 bool SetRtcpMux_w(bool enable, ContentAction action, ContentSource src);
325
326 virtual bool SetMaxSendBandwidth_w(int max_bandwidth);
327
328 // From MessageHandler
329 virtual void OnMessage(talk_base::Message* pmsg);
330
331 // Handled in derived classes
332 // Get the SRTP ciphers to use for RTP media
333 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const = 0;
334 virtual void OnConnectionMonitorUpdate(SocketMonitor* monitor,
335 const std::vector<ConnectionInfo>& infos) = 0;
336
337 private:
338 sigslot::signal3<const void*, size_t, bool> SignalSendPacketPreCrypto;
339 sigslot::signal3<const void*, size_t, bool> SignalSendPacketPostCrypto;
340 sigslot::signal3<const void*, size_t, bool> SignalRecvPacketPreCrypto;
341 sigslot::signal3<const void*, size_t, bool> SignalRecvPacketPostCrypto;
342 talk_base::CriticalSection signal_send_packet_cs_;
343 talk_base::CriticalSection signal_recv_packet_cs_;
344
345 talk_base::Thread* worker_thread_;
346 MediaEngineInterface* media_engine_;
347 BaseSession* session_;
348 MediaChannel* media_channel_;
349 std::vector<StreamParams> local_streams_;
350 std::vector<StreamParams> remote_streams_;
351
352 std::string content_name_;
353 bool rtcp_;
354 TransportChannel* transport_channel_;
355 TransportChannel* rtcp_transport_channel_;
356 SrtpFilter srtp_filter_;
357 RtcpMuxFilter rtcp_mux_filter_;
358 SsrcMuxFilter ssrc_filter_;
359 talk_base::scoped_ptr<SocketMonitor> socket_monitor_;
360 bool enabled_;
361 bool writable_;
362 bool rtp_ready_to_send_;
363 bool rtcp_ready_to_send_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 bool was_ever_writable_;
365 MediaContentDirection local_content_direction_;
366 MediaContentDirection remote_content_direction_;
367 std::set<uint32> muted_streams_;
368 bool has_received_packet_;
369 bool dtls_keyed_;
370 bool secure_required_;
371};
372
373// VoiceChannel is a specialization that adds support for early media, DTMF,
374// and input/output level monitoring.
375class VoiceChannel : public BaseChannel {
376 public:
377 VoiceChannel(talk_base::Thread* thread, MediaEngineInterface* media_engine,
378 VoiceMediaChannel* channel, BaseSession* session,
379 const std::string& content_name, bool rtcp);
380 ~VoiceChannel();
381 bool Init();
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000382 bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer);
383 bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384
385 // downcasts a MediaChannel
386 virtual VoiceMediaChannel* media_channel() const {
387 return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel());
388 }
389
390 bool SetRingbackTone(const void* buf, int len);
391 void SetEarlyMedia(bool enable);
392 // This signal is emitted when we have gone a period of time without
393 // receiving early media. When received, a UI should start playing its
394 // own ringing sound
395 sigslot::signal1<VoiceChannel*> SignalEarlyMediaTimeout;
396
397 bool PlayRingbackTone(uint32 ssrc, bool play, bool loop);
398 // TODO(ronghuawu): Replace PressDTMF with InsertDtmf.
399 bool PressDTMF(int digit, bool playout);
400 // Returns if the telephone-event has been negotiated.
401 bool CanInsertDtmf();
402 // Send and/or play a DTMF |event| according to the |flags|.
403 // The DTMF out-of-band signal will be used on sending.
404 // The |ssrc| should be either 0 or a valid send stream ssrc.
henrike@webrtc.org9de257d2013-07-17 14:42:53 +0000405 // The valid value for the |event| are 0 which corresponding to DTMF
406 // event 0-9, *, #, A-D.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407 bool InsertDtmf(uint32 ssrc, int event_code, int duration, int flags);
408 bool SetOutputScaling(uint32 ssrc, double left, double right);
409 // Get statistics about the current media session.
410 bool GetStats(VoiceMediaInfo* stats);
411
412 // Monitoring functions
413 sigslot::signal2<VoiceChannel*, const std::vector<ConnectionInfo>&>
414 SignalConnectionMonitor;
415
416 void StartMediaMonitor(int cms);
417 void StopMediaMonitor();
418 sigslot::signal2<VoiceChannel*, const VoiceMediaInfo&> SignalMediaMonitor;
419
420 void StartAudioMonitor(int cms);
421 void StopAudioMonitor();
422 bool IsAudioMonitorRunning() const;
423 sigslot::signal2<VoiceChannel*, const AudioInfo&> SignalAudioMonitor;
424
425 void StartTypingMonitor(const TypingMonitorOptions& settings);
426 void StopTypingMonitor();
427 bool IsTypingMonitorRunning() const;
428
429 // Overrides BaseChannel::MuteStream_w.
430 virtual bool MuteStream_w(uint32 ssrc, bool mute);
431
432 int GetInputLevel_w();
433 int GetOutputLevel_w();
434 void GetActiveStreams_w(AudioInfo::StreamList* actives);
435
436 // Signal errors from VoiceMediaChannel. Arguments are:
437 // ssrc(uint32), and error(VoiceMediaChannel::Error).
438 sigslot::signal3<VoiceChannel*, uint32, VoiceMediaChannel::Error>
439 SignalMediaError;
440
441 // Configuration and setting.
442 bool SetChannelOptions(const AudioOptions& options);
443
444 private:
445 // overrides from BaseChannel
446 virtual void OnChannelRead(TransportChannel* channel,
wu@webrtc.orga9890802013-12-13 00:21:03 +0000447 const char* data, size_t len,
448 const talk_base::PacketTime& packet_time,
449 int flags);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 virtual void ChangeState();
451 virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
452 virtual bool SetLocalContent_w(const MediaContentDescription* content,
453 ContentAction action);
454 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
455 ContentAction action);
456 bool SetRingbackTone_w(const void* buf, int len);
457 bool PlayRingbackTone_w(uint32 ssrc, bool play, bool loop);
458 void HandleEarlyMediaTimeout();
459 bool CanInsertDtmf_w();
460 bool InsertDtmf_w(uint32 ssrc, int event, int duration, int flags);
461 bool SetOutputScaling_w(uint32 ssrc, double left, double right);
462 bool GetStats_w(VoiceMediaInfo* stats);
463
464 virtual void OnMessage(talk_base::Message* pmsg);
465 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
466 virtual void OnConnectionMonitorUpdate(
467 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos);
468 virtual void OnMediaMonitorUpdate(
469 VoiceMediaChannel* media_channel, const VoiceMediaInfo& info);
470 void OnAudioMonitorUpdate(AudioMonitor* monitor, const AudioInfo& info);
471 void OnVoiceChannelError(uint32 ssrc, VoiceMediaChannel::Error error);
472 void SendLastMediaError();
473 void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
474 // Configuration and setting.
475 bool SetChannelOptions_w(const AudioOptions& options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000476 bool SetRenderer_w(uint32 ssrc, AudioRenderer* renderer, bool is_local);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000477
478 static const int kEarlyMediaTimeout = 1000;
479 bool received_media_;
480 talk_base::scoped_ptr<VoiceMediaMonitor> media_monitor_;
481 talk_base::scoped_ptr<AudioMonitor> audio_monitor_;
482 talk_base::scoped_ptr<TypingMonitor> typing_monitor_;
483};
484
485// VideoChannel is a specialization for video.
486class VideoChannel : public BaseChannel {
487 public:
488 // Make screen capturer virtual so that it can be overriden in testing.
489 // E.g. used to test that window events are triggered correctly.
490 class ScreenCapturerFactory {
491 public:
492 virtual VideoCapturer* CreateScreenCapturer(const ScreencastId& window) = 0;
493 virtual ~ScreenCapturerFactory() {}
494 };
495
496 VideoChannel(talk_base::Thread* thread, MediaEngineInterface* media_engine,
497 VideoMediaChannel* channel, BaseSession* session,
498 const std::string& content_name, bool rtcp,
499 VoiceChannel* voice_channel);
500 ~VideoChannel();
501 bool Init();
502
503 bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
504 bool ApplyViewRequest(const ViewRequest& request);
505
506 // TODO(pthatcher): Refactor to use a "capture id" instead of an
507 // ssrc here as the "key".
508 VideoCapturer* AddScreencast(uint32 ssrc, const ScreencastId& id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000509 bool SetCapturer(uint32 ssrc, VideoCapturer* capturer);
510 bool RemoveScreencast(uint32 ssrc);
511 // True if we've added a screencast. Doesn't matter if the capturer
512 // has been started or not.
513 bool IsScreencasting();
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000514 int GetScreencastFps(uint32 ssrc);
515 int GetScreencastMaxPixels(uint32 ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000516 // Get statistics about the current media session.
517 bool GetStats(VideoMediaInfo* stats);
518
519 sigslot::signal2<VideoChannel*, const std::vector<ConnectionInfo>&>
520 SignalConnectionMonitor;
521
522 void StartMediaMonitor(int cms);
523 void StopMediaMonitor();
524 sigslot::signal2<VideoChannel*, const VideoMediaInfo&> SignalMediaMonitor;
525 sigslot::signal2<uint32, talk_base::WindowEvent> SignalScreencastWindowEvent;
526
527 bool SendIntraFrame();
528 bool RequestIntraFrame();
529 sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
530 SignalMediaError;
531
532 void SetScreenCaptureFactory(
533 ScreenCapturerFactory* screencapture_factory);
534
535 // Configuration and setting.
536 bool SetChannelOptions(const VideoOptions& options);
537
538 protected:
539 // downcasts a MediaChannel
540 virtual VideoMediaChannel* media_channel() const {
541 return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
542 }
543
544 private:
545 typedef std::map<uint32, VideoCapturer*> ScreencastMap;
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000546 struct ScreencastDetailsMessageData;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000547
548 // overrides from BaseChannel
549 virtual void ChangeState();
550 virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
551 virtual bool SetLocalContent_w(const MediaContentDescription* content,
552 ContentAction action);
553 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
554 ContentAction action);
555 void SendIntraFrame_w() {
556 media_channel()->SendIntraFrame();
557 }
558 void RequestIntraFrame_w() {
559 media_channel()->RequestIntraFrame();
560 }
561
562 bool ApplyViewRequest_w(const ViewRequest& request);
563 void SetRenderer_w(uint32 ssrc, VideoRenderer* renderer);
564
565 VideoCapturer* AddScreencast_w(uint32 ssrc, const ScreencastId& id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000566 bool SetCapturer_w(uint32 ssrc, VideoCapturer* capturer);
567 bool RemoveScreencast_w(uint32 ssrc);
568 void OnScreencastWindowEvent_s(uint32 ssrc, talk_base::WindowEvent we);
569 bool IsScreencasting_w() const;
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000570 void ScreencastDetails_w(ScreencastDetailsMessageData* d) const;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571 void SetScreenCaptureFactory_w(
572 ScreenCapturerFactory* screencapture_factory);
573 bool GetStats_w(VideoMediaInfo* stats);
574
575 virtual void OnMessage(talk_base::Message* pmsg);
576 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
577 virtual void OnConnectionMonitorUpdate(
578 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos);
579 virtual void OnMediaMonitorUpdate(
580 VideoMediaChannel* media_channel, const VideoMediaInfo& info);
581 virtual void OnScreencastWindowEvent(uint32 ssrc,
582 talk_base::WindowEvent event);
583 virtual void OnStateChange(VideoCapturer* capturer, CaptureState ev);
584 bool GetLocalSsrc(const VideoCapturer* capturer, uint32* ssrc);
585
586 void OnVideoChannelError(uint32 ssrc, VideoMediaChannel::Error error);
587 void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
588 // Configuration and setting.
589 bool SetChannelOptions_w(const VideoOptions& options);
590
591 VoiceChannel* voice_channel_;
592 VideoRenderer* renderer_;
593 talk_base::scoped_ptr<ScreenCapturerFactory> screencapture_factory_;
594 ScreencastMap screencast_capturers_;
595 talk_base::scoped_ptr<VideoMediaMonitor> media_monitor_;
596
597 talk_base::WindowEvent previous_we_;
598};
599
600// DataChannel is a specialization for data.
601class DataChannel : public BaseChannel {
602 public:
603 DataChannel(talk_base::Thread* thread,
604 DataMediaChannel* media_channel,
605 BaseSession* session,
606 const std::string& content_name,
607 bool rtcp);
608 ~DataChannel();
609 bool Init();
610
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000611 virtual bool SendData(const SendDataParams& params,
612 const talk_base::Buffer& payload,
613 SendDataResult* result);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000614
615 void StartMediaMonitor(int cms);
616 void StopMediaMonitor();
617
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000618 // Should be called on the signaling thread only.
619 bool ready_to_send_data() const {
620 return ready_to_send_data_;
621 }
622
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000623 sigslot::signal2<DataChannel*, const DataMediaInfo&> SignalMediaMonitor;
624 sigslot::signal2<DataChannel*, const std::vector<ConnectionInfo>&>
625 SignalConnectionMonitor;
626 sigslot::signal3<DataChannel*, uint32, DataMediaChannel::Error>
627 SignalMediaError;
628 sigslot::signal3<DataChannel*,
629 const ReceiveDataParams&,
630 const talk_base::Buffer&>
631 SignalDataReceived;
632 // Signal for notifying when the channel becomes ready to send data.
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000633 // That occurs when the channel is enabled, the transport is writable,
634 // both local and remote descriptions are set, and the channel is unblocked.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635 sigslot::signal1<bool> SignalReadyToSendData;
636
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000637 protected:
638 // downcasts a MediaChannel.
639 virtual DataMediaChannel* media_channel() const {
640 return static_cast<DataMediaChannel*>(BaseChannel::media_channel());
641 }
642
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000643 private:
644 struct SendDataMessageData : public talk_base::MessageData {
645 SendDataMessageData(const SendDataParams& params,
646 const talk_base::Buffer* payload,
647 SendDataResult* result)
648 : params(params),
649 payload(payload),
650 result(result),
651 succeeded(false) {
652 }
653
654 const SendDataParams& params;
655 const talk_base::Buffer* payload;
656 SendDataResult* result;
657 bool succeeded;
658 };
659
660 struct DataReceivedMessageData : public talk_base::MessageData {
661 // We copy the data because the data will become invalid after we
662 // handle DataMediaChannel::SignalDataReceived but before we fire
663 // SignalDataReceived.
664 DataReceivedMessageData(
665 const ReceiveDataParams& params, const char* data, size_t len)
666 : params(params),
667 payload(data, len) {
668 }
669 const ReceiveDataParams params;
670 const talk_base::Buffer payload;
671 };
672
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000673 typedef talk_base::TypedMessageData<bool> DataChannelReadyToSendMessageData;
674
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000675 // overrides from BaseChannel
676 virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
677 // If data_channel_type_ is DCT_NONE, set it. Otherwise, check that
678 // it's the same as what was set previously. Returns false if it's
679 // set to one type one type and changed to another type later.
680 bool SetDataChannelType(DataChannelType new_data_channel_type);
681 // Same as SetDataChannelType, but extracts the type from the
682 // DataContentDescription.
683 bool SetDataChannelTypeFromContent(const DataContentDescription* content);
684 virtual bool SetMaxSendBandwidth_w(int max_bandwidth);
685 virtual bool SetLocalContent_w(const MediaContentDescription* content,
686 ContentAction action);
687 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
688 ContentAction action);
689 virtual void ChangeState();
690 virtual bool WantsPacket(bool rtcp, talk_base::Buffer* packet);
691
692 virtual void OnMessage(talk_base::Message* pmsg);
693 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
694 virtual void OnConnectionMonitorUpdate(
695 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos);
696 virtual void OnMediaMonitorUpdate(
697 DataMediaChannel* media_channel, const DataMediaInfo& info);
698 virtual bool ShouldSetupDtlsSrtp() const;
699 void OnDataReceived(
700 const ReceiveDataParams& params, const char* data, size_t len);
701 void OnDataChannelError(uint32 ssrc, DataMediaChannel::Error error);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000702 void OnDataChannelReadyToSend(bool writable);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703 void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
704
705 talk_base::scoped_ptr<DataMediaMonitor> media_monitor_;
706 // TODO(pthatcher): Make a separate SctpDataChannel and
707 // RtpDataChannel instead of using this.
708 DataChannelType data_channel_type_;
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000709 bool ready_to_send_data_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000710};
711
712} // namespace cricket
713
714#endif // TALK_SESSION_MEDIA_CHANNEL_H_