blob: 6ee2e8cda49f4dc4ea93e40d984a3aefe9a12658 [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_; }
99 // Set to true to have the channel optimistically allow data to be sent even
100 // when the channel isn't fully writable.
101 void set_optimistic_data_send(bool value) { optimistic_data_send_ = value; }
102 bool optimistic_data_send() const { return optimistic_data_send_; }
103
104 // This function returns true if we are using SRTP.
105 bool secure() const { return srtp_filter_.IsActive(); }
106 // The following function returns true if we are using
107 // DTLS-based keying. If you turned off SRTP later, however
108 // you could have secure() == false and dtls_secure() == true.
109 bool secure_dtls() const { return dtls_keyed_; }
110 // This function returns true if we require secure channel for call setup.
111 bool secure_required() const { return secure_required_; }
112
113 bool writable() const { return writable_; }
114 bool IsStreamMuted(uint32 ssrc);
115
116 // Channel control
117 bool SetLocalContent(const MediaContentDescription* content,
118 ContentAction action);
119 bool SetRemoteContent(const MediaContentDescription* content,
120 ContentAction action);
121 bool SetMaxSendBandwidth(int max_bandwidth);
122
123 bool Enable(bool enable);
124 // Mute sending media on the stream with SSRC |ssrc|
125 // If there is only one sending stream SSRC 0 can be used.
126 bool MuteStream(uint32 ssrc, bool mute);
127
128 // Multiplexing
129 bool AddRecvStream(const StreamParams& sp);
130 bool RemoveRecvStream(uint32 ssrc);
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000131 bool AddSendStream(const StreamParams& sp);
132 bool RemoveSendStream(uint32 ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133
134 // Monitoring
135 void StartConnectionMonitor(int cms);
136 void StopConnectionMonitor();
137
138 void set_srtp_signal_silent_time(uint32 silent_time) {
139 srtp_filter_.set_signal_silent_time(silent_time);
140 }
141
142 void set_content_name(const std::string& content_name) {
143 ASSERT(signaling_thread()->IsCurrent());
144 ASSERT(!writable_);
145 if (session_->state() != BaseSession::STATE_INIT) {
146 LOG(LS_ERROR) << "Content name for a channel can be changed only "
147 << "when BaseSession is in STATE_INIT state.";
148 return;
149 }
150 content_name_ = content_name;
151 }
152
153 template <class T>
154 void RegisterSendSink(T* sink,
155 void (T::*OnPacket)(const void*, size_t, bool),
156 SinkType type) {
157 talk_base::CritScope cs(&signal_send_packet_cs_);
158 if (SINK_POST_CRYPTO == type) {
159 SignalSendPacketPostCrypto.disconnect(sink);
160 SignalSendPacketPostCrypto.connect(sink, OnPacket);
161 } else {
162 SignalSendPacketPreCrypto.disconnect(sink);
163 SignalSendPacketPreCrypto.connect(sink, OnPacket);
164 }
165 }
166
167 void UnregisterSendSink(sigslot::has_slots<>* sink,
168 SinkType type) {
169 talk_base::CritScope cs(&signal_send_packet_cs_);
170 if (SINK_POST_CRYPTO == type) {
171 SignalSendPacketPostCrypto.disconnect(sink);
172 } else {
173 SignalSendPacketPreCrypto.disconnect(sink);
174 }
175 }
176
177 bool HasSendSinks(SinkType type) {
178 talk_base::CritScope cs(&signal_send_packet_cs_);
179 if (SINK_POST_CRYPTO == type) {
180 return !SignalSendPacketPostCrypto.is_empty();
181 } else {
182 return !SignalSendPacketPreCrypto.is_empty();
183 }
184 }
185
186 template <class T>
187 void RegisterRecvSink(T* sink,
188 void (T::*OnPacket)(const void*, size_t, bool),
189 SinkType type) {
190 talk_base::CritScope cs(&signal_recv_packet_cs_);
191 if (SINK_POST_CRYPTO == type) {
192 SignalRecvPacketPostCrypto.disconnect(sink);
193 SignalRecvPacketPostCrypto.connect(sink, OnPacket);
194 } else {
195 SignalRecvPacketPreCrypto.disconnect(sink);
196 SignalRecvPacketPreCrypto.connect(sink, OnPacket);
197 }
198 }
199
200 void UnregisterRecvSink(sigslot::has_slots<>* sink,
201 SinkType type) {
202 talk_base::CritScope cs(&signal_recv_packet_cs_);
203 if (SINK_POST_CRYPTO == type) {
204 SignalRecvPacketPostCrypto.disconnect(sink);
205 } else {
206 SignalRecvPacketPreCrypto.disconnect(sink);
207 }
208 }
209
210 bool HasRecvSinks(SinkType type) {
211 talk_base::CritScope cs(&signal_recv_packet_cs_);
212 if (SINK_POST_CRYPTO == type) {
213 return !SignalRecvPacketPostCrypto.is_empty();
214 } else {
215 return !SignalRecvPacketPreCrypto.is_empty();
216 }
217 }
218
219 SsrcMuxFilter* ssrc_filter() { return &ssrc_filter_; }
220
221 const std::vector<StreamParams>& local_streams() const {
222 return local_streams_;
223 }
224 const std::vector<StreamParams>& remote_streams() const {
225 return remote_streams_;
226 }
227
228 // Used for latency measurements.
229 sigslot::signal1<BaseChannel*> SignalFirstPacketReceived;
230
231 // Used to alert UI when the muted status changes, perhaps autonomously.
232 sigslot::repeater2<BaseChannel*, bool> SignalAutoMuted;
233
234 // Made public for easier testing.
235 void SetReadyToSend(TransportChannel* channel, bool ready);
236
237 protected:
238 MediaEngineInterface* media_engine() const { return media_engine_; }
239 virtual MediaChannel* media_channel() const { return media_channel_; }
240 void set_rtcp_transport_channel(TransportChannel* transport);
241 bool was_ever_writable() const { return was_ever_writable_; }
242 void set_local_content_direction(MediaContentDirection direction) {
243 local_content_direction_ = direction;
244 }
245 void set_remote_content_direction(MediaContentDirection direction) {
246 remote_content_direction_ = direction;
247 }
248 bool IsReadyToReceive() const;
249 bool IsReadyToSend() const;
250 talk_base::Thread* signaling_thread() { return session_->signaling_thread(); }
251 SrtpFilter* srtp_filter() { return &srtp_filter_; }
252 bool rtcp() const { return rtcp_; }
253
254 void Send(uint32 id, talk_base::MessageData* pdata = NULL);
255 void Post(uint32 id, talk_base::MessageData* pdata = NULL);
256 void PostDelayed(int cmsDelay, uint32 id = 0,
257 talk_base::MessageData* pdata = NULL);
258 void Clear(uint32 id = talk_base::MQID_ANY,
259 talk_base::MessageList* removed = NULL);
260 void FlushRtcpMessages();
261
262 // NetworkInterface implementation, called by MediaEngine
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000263 virtual bool SendPacket(talk_base::Buffer* packet,
264 talk_base::DiffServCodePoint dscp);
265 virtual bool SendRtcp(talk_base::Buffer* packet,
266 talk_base::DiffServCodePoint dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267 virtual int SetOption(SocketType type, talk_base::Socket::Option o, int val);
268
269 // From TransportChannel
270 void OnWritableState(TransportChannel* channel);
271 virtual void OnChannelRead(TransportChannel* channel, const char* data,
272 size_t len, int flags);
273 void OnReadyToSend(TransportChannel* channel);
274
275 bool PacketIsRtcp(const TransportChannel* channel, const char* data,
276 size_t len);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000277 bool SendPacket(bool rtcp, talk_base::Buffer* packet,
278 talk_base::DiffServCodePoint dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000279 virtual bool WantsPacket(bool rtcp, talk_base::Buffer* packet);
280 void HandlePacket(bool rtcp, talk_base::Buffer* packet);
281
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_;
364 bool optimistic_data_send_;
365 bool was_ever_writable_;
366 MediaContentDirection local_content_direction_;
367 MediaContentDirection remote_content_direction_;
368 std::set<uint32> muted_streams_;
369 bool has_received_packet_;
370 bool dtls_keyed_;
371 bool secure_required_;
372};
373
374// VoiceChannel is a specialization that adds support for early media, DTMF,
375// and input/output level monitoring.
376class VoiceChannel : public BaseChannel {
377 public:
378 VoiceChannel(talk_base::Thread* thread, MediaEngineInterface* media_engine,
379 VoiceMediaChannel* channel, BaseSession* session,
380 const std::string& content_name, bool rtcp);
381 ~VoiceChannel();
382 bool Init();
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000383 bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer);
384 bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000385
386 // downcasts a MediaChannel
387 virtual VoiceMediaChannel* media_channel() const {
388 return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel());
389 }
390
391 bool SetRingbackTone(const void* buf, int len);
392 void SetEarlyMedia(bool enable);
393 // This signal is emitted when we have gone a period of time without
394 // receiving early media. When received, a UI should start playing its
395 // own ringing sound
396 sigslot::signal1<VoiceChannel*> SignalEarlyMediaTimeout;
397
398 bool PlayRingbackTone(uint32 ssrc, bool play, bool loop);
399 // TODO(ronghuawu): Replace PressDTMF with InsertDtmf.
400 bool PressDTMF(int digit, bool playout);
401 // Returns if the telephone-event has been negotiated.
402 bool CanInsertDtmf();
403 // Send and/or play a DTMF |event| according to the |flags|.
404 // The DTMF out-of-band signal will be used on sending.
405 // The |ssrc| should be either 0 or a valid send stream ssrc.
henrike@webrtc.org9de257d2013-07-17 14:42:53 +0000406 // The valid value for the |event| are 0 which corresponding to DTMF
407 // event 0-9, *, #, A-D.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000408 bool InsertDtmf(uint32 ssrc, int event_code, int duration, int flags);
409 bool SetOutputScaling(uint32 ssrc, double left, double right);
410 // Get statistics about the current media session.
411 bool GetStats(VoiceMediaInfo* stats);
412
413 // Monitoring functions
414 sigslot::signal2<VoiceChannel*, const std::vector<ConnectionInfo>&>
415 SignalConnectionMonitor;
416
417 void StartMediaMonitor(int cms);
418 void StopMediaMonitor();
419 sigslot::signal2<VoiceChannel*, const VoiceMediaInfo&> SignalMediaMonitor;
420
421 void StartAudioMonitor(int cms);
422 void StopAudioMonitor();
423 bool IsAudioMonitorRunning() const;
424 sigslot::signal2<VoiceChannel*, const AudioInfo&> SignalAudioMonitor;
425
426 void StartTypingMonitor(const TypingMonitorOptions& settings);
427 void StopTypingMonitor();
428 bool IsTypingMonitorRunning() const;
429
430 // Overrides BaseChannel::MuteStream_w.
431 virtual bool MuteStream_w(uint32 ssrc, bool mute);
432
433 int GetInputLevel_w();
434 int GetOutputLevel_w();
435 void GetActiveStreams_w(AudioInfo::StreamList* actives);
436
437 // Signal errors from VoiceMediaChannel. Arguments are:
438 // ssrc(uint32), and error(VoiceMediaChannel::Error).
439 sigslot::signal3<VoiceChannel*, uint32, VoiceMediaChannel::Error>
440 SignalMediaError;
441
442 // Configuration and setting.
443 bool SetChannelOptions(const AudioOptions& options);
444
445 private:
446 // overrides from BaseChannel
447 virtual void OnChannelRead(TransportChannel* channel,
448 const char* data, size_t len, int flags);
449 virtual void ChangeState();
450 virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
451 virtual bool SetLocalContent_w(const MediaContentDescription* content,
452 ContentAction action);
453 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
454 ContentAction action);
455 bool SetRingbackTone_w(const void* buf, int len);
456 bool PlayRingbackTone_w(uint32 ssrc, bool play, bool loop);
457 void HandleEarlyMediaTimeout();
458 bool CanInsertDtmf_w();
459 bool InsertDtmf_w(uint32 ssrc, int event, int duration, int flags);
460 bool SetOutputScaling_w(uint32 ssrc, double left, double right);
461 bool GetStats_w(VoiceMediaInfo* stats);
462
463 virtual void OnMessage(talk_base::Message* pmsg);
464 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
465 virtual void OnConnectionMonitorUpdate(
466 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos);
467 virtual void OnMediaMonitorUpdate(
468 VoiceMediaChannel* media_channel, const VoiceMediaInfo& info);
469 void OnAudioMonitorUpdate(AudioMonitor* monitor, const AudioInfo& info);
470 void OnVoiceChannelError(uint32 ssrc, VoiceMediaChannel::Error error);
471 void SendLastMediaError();
472 void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
473 // Configuration and setting.
474 bool SetChannelOptions_w(const AudioOptions& options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000475 bool SetRenderer_w(uint32 ssrc, AudioRenderer* renderer, bool is_local);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000476
477 static const int kEarlyMediaTimeout = 1000;
478 bool received_media_;
479 talk_base::scoped_ptr<VoiceMediaMonitor> media_monitor_;
480 talk_base::scoped_ptr<AudioMonitor> audio_monitor_;
481 talk_base::scoped_ptr<TypingMonitor> typing_monitor_;
482};
483
484// VideoChannel is a specialization for video.
485class VideoChannel : public BaseChannel {
486 public:
487 // Make screen capturer virtual so that it can be overriden in testing.
488 // E.g. used to test that window events are triggered correctly.
489 class ScreenCapturerFactory {
490 public:
491 virtual VideoCapturer* CreateScreenCapturer(const ScreencastId& window) = 0;
492 virtual ~ScreenCapturerFactory() {}
493 };
494
495 VideoChannel(talk_base::Thread* thread, MediaEngineInterface* media_engine,
496 VideoMediaChannel* channel, BaseSession* session,
497 const std::string& content_name, bool rtcp,
498 VoiceChannel* voice_channel);
499 ~VideoChannel();
500 bool Init();
501
502 bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
503 bool ApplyViewRequest(const ViewRequest& request);
504
505 // TODO(pthatcher): Refactor to use a "capture id" instead of an
506 // ssrc here as the "key".
507 VideoCapturer* AddScreencast(uint32 ssrc, const ScreencastId& id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000508 bool SetCapturer(uint32 ssrc, VideoCapturer* capturer);
509 bool RemoveScreencast(uint32 ssrc);
510 // True if we've added a screencast. Doesn't matter if the capturer
511 // has been started or not.
512 bool IsScreencasting();
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000513 int GetScreencastFps(uint32 ssrc);
514 int GetScreencastMaxPixels(uint32 ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000515 // Get statistics about the current media session.
516 bool GetStats(VideoMediaInfo* stats);
517
518 sigslot::signal2<VideoChannel*, const std::vector<ConnectionInfo>&>
519 SignalConnectionMonitor;
520
521 void StartMediaMonitor(int cms);
522 void StopMediaMonitor();
523 sigslot::signal2<VideoChannel*, const VideoMediaInfo&> SignalMediaMonitor;
524 sigslot::signal2<uint32, talk_base::WindowEvent> SignalScreencastWindowEvent;
525
526 bool SendIntraFrame();
527 bool RequestIntraFrame();
528 sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
529 SignalMediaError;
530
531 void SetScreenCaptureFactory(
532 ScreenCapturerFactory* screencapture_factory);
533
534 // Configuration and setting.
535 bool SetChannelOptions(const VideoOptions& options);
536
537 protected:
538 // downcasts a MediaChannel
539 virtual VideoMediaChannel* media_channel() const {
540 return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
541 }
542
543 private:
544 typedef std::map<uint32, VideoCapturer*> ScreencastMap;
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000545 struct ScreencastDetailsMessageData;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000546
547 // overrides from BaseChannel
548 virtual void ChangeState();
549 virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
550 virtual bool SetLocalContent_w(const MediaContentDescription* content,
551 ContentAction action);
552 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
553 ContentAction action);
554 void SendIntraFrame_w() {
555 media_channel()->SendIntraFrame();
556 }
557 void RequestIntraFrame_w() {
558 media_channel()->RequestIntraFrame();
559 }
560
561 bool ApplyViewRequest_w(const ViewRequest& request);
562 void SetRenderer_w(uint32 ssrc, VideoRenderer* renderer);
563
564 VideoCapturer* AddScreencast_w(uint32 ssrc, const ScreencastId& id);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565 bool SetCapturer_w(uint32 ssrc, VideoCapturer* capturer);
566 bool RemoveScreencast_w(uint32 ssrc);
567 void OnScreencastWindowEvent_s(uint32 ssrc, talk_base::WindowEvent we);
568 bool IsScreencasting_w() const;
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000569 void ScreencastDetails_w(ScreencastDetailsMessageData* d) const;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 void SetScreenCaptureFactory_w(
571 ScreenCapturerFactory* screencapture_factory);
572 bool GetStats_w(VideoMediaInfo* stats);
573
574 virtual void OnMessage(talk_base::Message* pmsg);
575 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
576 virtual void OnConnectionMonitorUpdate(
577 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos);
578 virtual void OnMediaMonitorUpdate(
579 VideoMediaChannel* media_channel, const VideoMediaInfo& info);
580 virtual void OnScreencastWindowEvent(uint32 ssrc,
581 talk_base::WindowEvent event);
582 virtual void OnStateChange(VideoCapturer* capturer, CaptureState ev);
583 bool GetLocalSsrc(const VideoCapturer* capturer, uint32* ssrc);
584
585 void OnVideoChannelError(uint32 ssrc, VideoMediaChannel::Error error);
586 void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
587 // Configuration and setting.
588 bool SetChannelOptions_w(const VideoOptions& options);
589
590 VoiceChannel* voice_channel_;
591 VideoRenderer* renderer_;
592 talk_base::scoped_ptr<ScreenCapturerFactory> screencapture_factory_;
593 ScreencastMap screencast_capturers_;
594 talk_base::scoped_ptr<VideoMediaMonitor> media_monitor_;
595
596 talk_base::WindowEvent previous_we_;
597};
598
599// DataChannel is a specialization for data.
600class DataChannel : public BaseChannel {
601 public:
602 DataChannel(talk_base::Thread* thread,
603 DataMediaChannel* media_channel,
604 BaseSession* session,
605 const std::string& content_name,
606 bool rtcp);
607 ~DataChannel();
608 bool Init();
609
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000610 virtual bool SendData(const SendDataParams& params,
611 const talk_base::Buffer& payload,
612 SendDataResult* result);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000613
614 void StartMediaMonitor(int cms);
615 void StopMediaMonitor();
616
617 sigslot::signal2<DataChannel*, const DataMediaInfo&> SignalMediaMonitor;
618 sigslot::signal2<DataChannel*, const std::vector<ConnectionInfo>&>
619 SignalConnectionMonitor;
620 sigslot::signal3<DataChannel*, uint32, DataMediaChannel::Error>
621 SignalMediaError;
622 sigslot::signal3<DataChannel*,
623 const ReceiveDataParams&,
624 const talk_base::Buffer&>
625 SignalDataReceived;
626 // Signal for notifying when the channel becomes ready to send data.
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000627 // That occurs when the channel is enabled, the transport is writable,
628 // both local and remote descriptions are set, and the channel is unblocked.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000629 sigslot::signal1<bool> SignalReadyToSendData;
630
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000631 protected:
632 // downcasts a MediaChannel.
633 virtual DataMediaChannel* media_channel() const {
634 return static_cast<DataMediaChannel*>(BaseChannel::media_channel());
635 }
636
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000637 private:
638 struct SendDataMessageData : public talk_base::MessageData {
639 SendDataMessageData(const SendDataParams& params,
640 const talk_base::Buffer* payload,
641 SendDataResult* result)
642 : params(params),
643 payload(payload),
644 result(result),
645 succeeded(false) {
646 }
647
648 const SendDataParams& params;
649 const talk_base::Buffer* payload;
650 SendDataResult* result;
651 bool succeeded;
652 };
653
654 struct DataReceivedMessageData : public talk_base::MessageData {
655 // We copy the data because the data will become invalid after we
656 // handle DataMediaChannel::SignalDataReceived but before we fire
657 // SignalDataReceived.
658 DataReceivedMessageData(
659 const ReceiveDataParams& params, const char* data, size_t len)
660 : params(params),
661 payload(data, len) {
662 }
663 const ReceiveDataParams params;
664 const talk_base::Buffer payload;
665 };
666
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000667 typedef talk_base::TypedMessageData<bool> DataChannelReadyToSendMessageData;
668
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 // overrides from BaseChannel
670 virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
671 // If data_channel_type_ is DCT_NONE, set it. Otherwise, check that
672 // it's the same as what was set previously. Returns false if it's
673 // set to one type one type and changed to another type later.
674 bool SetDataChannelType(DataChannelType new_data_channel_type);
675 // Same as SetDataChannelType, but extracts the type from the
676 // DataContentDescription.
677 bool SetDataChannelTypeFromContent(const DataContentDescription* content);
678 virtual bool SetMaxSendBandwidth_w(int max_bandwidth);
679 virtual bool SetLocalContent_w(const MediaContentDescription* content,
680 ContentAction action);
681 virtual bool SetRemoteContent_w(const MediaContentDescription* content,
682 ContentAction action);
683 virtual void ChangeState();
684 virtual bool WantsPacket(bool rtcp, talk_base::Buffer* packet);
685
686 virtual void OnMessage(talk_base::Message* pmsg);
687 virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
688 virtual void OnConnectionMonitorUpdate(
689 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos);
690 virtual void OnMediaMonitorUpdate(
691 DataMediaChannel* media_channel, const DataMediaInfo& info);
692 virtual bool ShouldSetupDtlsSrtp() const;
693 void OnDataReceived(
694 const ReceiveDataParams& params, const char* data, size_t len);
695 void OnDataChannelError(uint32 ssrc, DataMediaChannel::Error error);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000696 void OnDataChannelReadyToSend(bool writable);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000697 void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
698
699 talk_base::scoped_ptr<DataMediaMonitor> media_monitor_;
700 // TODO(pthatcher): Make a separate SctpDataChannel and
701 // RtpDataChannel instead of using this.
702 DataChannelType data_channel_type_;
703};
704
705} // namespace cricket
706
707#endif // TALK_SESSION_MEDIA_CHANNEL_H_