blob: 9c9847fb2b08a134664ab0daab7aa1ead831dc2f [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#include "talk/session/media/channel.h"
29
30#include "talk/base/buffer.h"
31#include "talk/base/byteorder.h"
32#include "talk/base/common.h"
mallinath@webrtc.org1112c302013-09-23 20:34:45 +000033#include "talk/base/dscp.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/base/logging.h"
35#include "talk/media/base/rtputils.h"
36#include "talk/p2p/base/transportchannel.h"
37#include "talk/session/media/channelmanager.h"
38#include "talk/session/media/mediamessages.h"
39#include "talk/session/media/rtcpmuxfilter.h"
40#include "talk/session/media/typingmonitor.h"
41
42
43namespace cricket {
44
45enum {
46 MSG_ENABLE = 1,
47 MSG_DISABLE,
48 MSG_MUTESTREAM,
49 MSG_ISSTREAMMUTED,
50 MSG_SETREMOTECONTENT,
51 MSG_SETLOCALCONTENT,
52 MSG_EARLYMEDIATIMEOUT,
53 MSG_CANINSERTDTMF,
54 MSG_INSERTDTMF,
55 MSG_GETSTATS,
56 MSG_SETRENDERER,
57 MSG_ADDRECVSTREAM,
58 MSG_REMOVERECVSTREAM,
wu@webrtc.orgcadf9042013-08-30 21:24:16 +000059 MSG_ADDSENDSTREAM,
60 MSG_REMOVESENDSTREAM,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061 MSG_SETRINGBACKTONE,
62 MSG_PLAYRINGBACKTONE,
63 MSG_SETMAXSENDBANDWIDTH,
64 MSG_ADDSCREENCAST,
65 MSG_REMOVESCREENCAST,
66 MSG_SENDINTRAFRAME,
67 MSG_REQUESTINTRAFRAME,
68 MSG_SCREENCASTWINDOWEVENT,
69 MSG_RTPPACKET,
70 MSG_RTCPPACKET,
71 MSG_CHANNEL_ERROR,
72 MSG_SETCHANNELOPTIONS,
73 MSG_SCALEVOLUME,
74 MSG_HANDLEVIEWREQUEST,
75 MSG_READYTOSENDDATA,
76 MSG_SENDDATA,
77 MSG_DATARECEIVED,
78 MSG_SETCAPTURER,
79 MSG_ISSCREENCASTING,
wu@webrtc.orgcadf9042013-08-30 21:24:16 +000080 MSG_GETSCREENCASTDETAILS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081 MSG_SETSCREENCASTFACTORY,
82 MSG_FIRSTPACKETRECEIVED,
83 MSG_SESSION_ERROR,
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +000084 MSG_NEWSTREAMRECEIVED,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085};
86
87// Value specified in RFC 5764.
88static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp";
89
90static const int kAgcMinus10db = -10;
91
92// TODO(hellner): use the device manager for creation of screen capturers when
93// the cl enabling it has landed.
94class NullScreenCapturerFactory : public VideoChannel::ScreenCapturerFactory {
95 public:
96 VideoCapturer* CreateScreenCapturer(const ScreencastId& window) {
97 return NULL;
98 }
99};
100
101
102VideoChannel::ScreenCapturerFactory* CreateScreenCapturerFactory() {
103 return new NullScreenCapturerFactory();
104}
105
106struct SetContentData : public talk_base::MessageData {
107 SetContentData(const MediaContentDescription* content, ContentAction action)
108 : content(content),
109 action(action),
110 result(false) {
111 }
112 const MediaContentDescription* content;
113 ContentAction action;
114 bool result;
115};
116
117struct SetBandwidthData : public talk_base::MessageData {
118 explicit SetBandwidthData(int value) : value(value), result(false) {}
119 int value;
120 bool result;
121};
122
123struct SetRingbackToneMessageData : public talk_base::MessageData {
124 SetRingbackToneMessageData(const void* b, int l)
125 : buf(b),
126 len(l),
127 result(false) {
128 }
129 const void* buf;
130 int len;
131 bool result;
132};
133
134struct PlayRingbackToneMessageData : public talk_base::MessageData {
135 PlayRingbackToneMessageData(uint32 s, bool p, bool l)
136 : ssrc(s),
137 play(p),
138 loop(l),
139 result(false) {
140 }
141 uint32 ssrc;
142 bool play;
143 bool loop;
144 bool result;
145};
146typedef talk_base::TypedMessageData<bool> BoolMessageData;
147struct DtmfMessageData : public talk_base::MessageData {
148 DtmfMessageData(uint32 ssrc, int event, int duration, int flags)
149 : ssrc(ssrc),
150 event(event),
151 duration(duration),
152 flags(flags),
153 result(false) {
154 }
155 uint32 ssrc;
156 int event;
157 int duration;
158 int flags;
159 bool result;
160};
161struct ScaleVolumeMessageData : public talk_base::MessageData {
162 ScaleVolumeMessageData(uint32 s, double l, double r)
163 : ssrc(s),
164 left(l),
165 right(r),
166 result(false) {
167 }
168 uint32 ssrc;
169 double left;
170 double right;
171 bool result;
172};
173
174struct VoiceStatsMessageData : public talk_base::MessageData {
175 explicit VoiceStatsMessageData(VoiceMediaInfo* stats)
176 : result(false),
177 stats(stats) {
178 }
179 bool result;
180 VoiceMediaInfo* stats;
181};
182
183struct VideoStatsMessageData : public talk_base::MessageData {
184 explicit VideoStatsMessageData(VideoMediaInfo* stats)
185 : result(false),
186 stats(stats) {
187 }
188 bool result;
189 VideoMediaInfo* stats;
190};
191
192struct PacketMessageData : public talk_base::MessageData {
193 talk_base::Buffer packet;
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000194 talk_base::DiffServCodePoint dscp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195};
196
197struct AudioRenderMessageData: public talk_base::MessageData {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000198 AudioRenderMessageData(uint32 s, AudioRenderer* r, bool l)
199 : ssrc(s), renderer(r), is_local(l), result(false) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 uint32 ssrc;
201 AudioRenderer* renderer;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000202 bool is_local;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203 bool result;
204};
205
206struct VideoRenderMessageData : public talk_base::MessageData {
207 VideoRenderMessageData(uint32 s, VideoRenderer* r) : ssrc(s), renderer(r) {}
208 uint32 ssrc;
209 VideoRenderer* renderer;
210};
211
212struct AddScreencastMessageData : public talk_base::MessageData {
213 AddScreencastMessageData(uint32 s, const ScreencastId& id)
214 : ssrc(s),
215 window_id(id),
216 result(NULL) {
217 }
218 uint32 ssrc;
219 ScreencastId window_id;
220 VideoCapturer* result;
221};
222
223struct RemoveScreencastMessageData : public talk_base::MessageData {
224 explicit RemoveScreencastMessageData(uint32 s) : ssrc(s), result(false) {}
225 uint32 ssrc;
226 bool result;
227};
228
229struct ScreencastEventMessageData : public talk_base::MessageData {
230 ScreencastEventMessageData(uint32 s, talk_base::WindowEvent we)
231 : ssrc(s),
232 event(we) {
233 }
234 uint32 ssrc;
235 talk_base::WindowEvent event;
236};
237
238struct ViewRequestMessageData : public talk_base::MessageData {
239 explicit ViewRequestMessageData(const ViewRequest& r)
240 : request(r),
241 result(false) {
242 }
243 ViewRequest request;
244 bool result;
245};
246
247struct VoiceChannelErrorMessageData : public talk_base::MessageData {
248 VoiceChannelErrorMessageData(uint32 in_ssrc,
249 VoiceMediaChannel::Error in_error)
250 : ssrc(in_ssrc),
251 error(in_error) {
252 }
253 uint32 ssrc;
254 VoiceMediaChannel::Error error;
255};
256
257struct VideoChannelErrorMessageData : public talk_base::MessageData {
258 VideoChannelErrorMessageData(uint32 in_ssrc,
259 VideoMediaChannel::Error in_error)
260 : ssrc(in_ssrc),
261 error(in_error) {
262 }
263 uint32 ssrc;
264 VideoMediaChannel::Error error;
265};
266
267struct DataChannelErrorMessageData : public talk_base::MessageData {
268 DataChannelErrorMessageData(uint32 in_ssrc,
269 DataMediaChannel::Error in_error)
270 : ssrc(in_ssrc),
271 error(in_error) {}
272 uint32 ssrc;
273 DataMediaChannel::Error error;
274};
275
276struct SessionErrorMessageData : public talk_base::MessageData {
277 explicit SessionErrorMessageData(cricket::BaseSession::Error error)
278 : error_(error) {}
279
280 BaseSession::Error error_;
281};
282
283struct SsrcMessageData : public talk_base::MessageData {
284 explicit SsrcMessageData(uint32 ssrc) : ssrc(ssrc), result(false) {}
285 uint32 ssrc;
286 bool result;
287};
288
289struct StreamMessageData : public talk_base::MessageData {
290 explicit StreamMessageData(const StreamParams& in_sp)
291 : sp(in_sp),
292 result(false) {
293 }
294 StreamParams sp;
295 bool result;
296};
297
298struct MuteStreamData : public talk_base::MessageData {
299 MuteStreamData(uint32 ssrc, bool mute)
300 : ssrc(ssrc), mute(mute), result(false) {}
301 uint32 ssrc;
302 bool mute;
303 bool result;
304};
305
306struct AudioOptionsMessageData : public talk_base::MessageData {
307 explicit AudioOptionsMessageData(const AudioOptions& options)
308 : options(options),
309 result(false) {
310 }
311 AudioOptions options;
312 bool result;
313};
314
315struct VideoOptionsMessageData : public talk_base::MessageData {
316 explicit VideoOptionsMessageData(const VideoOptions& options)
317 : options(options),
318 result(false) {
319 }
320 VideoOptions options;
321 bool result;
322};
323
324struct SetCapturerMessageData : public talk_base::MessageData {
325 SetCapturerMessageData(uint32 s, VideoCapturer* c)
326 : ssrc(s),
327 capturer(c),
328 result(false) {
329 }
330 uint32 ssrc;
331 VideoCapturer* capturer;
332 bool result;
333};
334
335struct IsScreencastingMessageData : public talk_base::MessageData {
336 IsScreencastingMessageData()
337 : result(false) {
338 }
339 bool result;
340};
341
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000342struct VideoChannel::ScreencastDetailsMessageData :
343 public talk_base::MessageData {
344 explicit ScreencastDetailsMessageData(uint32 s)
345 : ssrc(s), fps(0), screencast_max_pixels(0) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346 }
347 uint32 ssrc;
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000348 int fps;
349 int screencast_max_pixels;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350};
351
352struct SetScreenCaptureFactoryMessageData : public talk_base::MessageData {
353 explicit SetScreenCaptureFactoryMessageData(
354 VideoChannel::ScreenCapturerFactory* f)
355 : screencapture_factory(f) {
356 }
357 VideoChannel::ScreenCapturerFactory* screencapture_factory;
358};
359
360static const char* PacketType(bool rtcp) {
361 return (!rtcp) ? "RTP" : "RTCP";
362}
363
364static bool ValidPacket(bool rtcp, const talk_base::Buffer* packet) {
365 // Check the packet size. We could check the header too if needed.
366 return (packet &&
367 packet->length() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) &&
368 packet->length() <= kMaxRtpPacketLen);
369}
370
371static bool IsReceiveContentDirection(MediaContentDirection direction) {
372 return direction == MD_SENDRECV || direction == MD_RECVONLY;
373}
374
375static bool IsSendContentDirection(MediaContentDirection direction) {
376 return direction == MD_SENDRECV || direction == MD_SENDONLY;
377}
378
379static const MediaContentDescription* GetContentDescription(
380 const ContentInfo* cinfo) {
381 if (cinfo == NULL)
382 return NULL;
383 return static_cast<const MediaContentDescription*>(cinfo->description);
384}
385
386BaseChannel::BaseChannel(talk_base::Thread* thread,
387 MediaEngineInterface* media_engine,
388 MediaChannel* media_channel, BaseSession* session,
389 const std::string& content_name, bool rtcp)
390 : worker_thread_(thread),
391 media_engine_(media_engine),
392 session_(session),
393 media_channel_(media_channel),
394 content_name_(content_name),
395 rtcp_(rtcp),
396 transport_channel_(NULL),
397 rtcp_transport_channel_(NULL),
398 enabled_(false),
399 writable_(false),
400 rtp_ready_to_send_(false),
401 rtcp_ready_to_send_(false),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000402 was_ever_writable_(false),
403 local_content_direction_(MD_INACTIVE),
404 remote_content_direction_(MD_INACTIVE),
405 has_received_packet_(false),
406 dtls_keyed_(false),
407 secure_required_(false) {
408 ASSERT(worker_thread_ == talk_base::Thread::Current());
409 LOG(LS_INFO) << "Created channel for " << content_name;
410}
411
412BaseChannel::~BaseChannel() {
413 ASSERT(worker_thread_ == talk_base::Thread::Current());
wu@webrtc.org78187522013-10-07 23:32:02 +0000414 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000415 StopConnectionMonitor();
416 FlushRtcpMessages(); // Send any outstanding RTCP packets.
417 Clear(); // eats any outstanding messages or packets
418 // We must destroy the media channel before the transport channel, otherwise
419 // the media channel may try to send on the dead transport channel. NULLing
420 // is not an effective strategy since the sends will come on another thread.
421 delete media_channel_;
422 set_rtcp_transport_channel(NULL);
423 if (transport_channel_ != NULL)
424 session_->DestroyChannel(content_name_, transport_channel_->component());
425 LOG(LS_INFO) << "Destroyed channel";
426}
427
428bool BaseChannel::Init(TransportChannel* transport_channel,
429 TransportChannel* rtcp_transport_channel) {
430 if (transport_channel == NULL) {
431 return false;
432 }
433 if (rtcp() && rtcp_transport_channel == NULL) {
434 return false;
435 }
436 transport_channel_ = transport_channel;
437
438 if (!SetDtlsSrtpCiphers(transport_channel_, false)) {
439 return false;
440 }
441
442 media_channel_->SetInterface(this);
443 transport_channel_->SignalWritableState.connect(
444 this, &BaseChannel::OnWritableState);
445 transport_channel_->SignalReadPacket.connect(
446 this, &BaseChannel::OnChannelRead);
447 transport_channel_->SignalReadyToSend.connect(
448 this, &BaseChannel::OnReadyToSend);
449
450 session_->SignalNewLocalDescription.connect(
451 this, &BaseChannel::OnNewLocalDescription);
452 session_->SignalNewRemoteDescription.connect(
453 this, &BaseChannel::OnNewRemoteDescription);
454
455 set_rtcp_transport_channel(rtcp_transport_channel);
456 return true;
457}
458
wu@webrtc.org78187522013-10-07 23:32:02 +0000459void BaseChannel::Deinit() {
460 media_channel_->SetInterface(NULL);
461}
462
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463// Can be called from thread other than worker thread
464bool BaseChannel::Enable(bool enable) {
465 Send(enable ? MSG_ENABLE : MSG_DISABLE);
466 return true;
467}
468
469// Can be called from thread other than worker thread
470bool BaseChannel::MuteStream(uint32 ssrc, bool mute) {
471 MuteStreamData data(ssrc, mute);
472 Send(MSG_MUTESTREAM, &data);
473 return data.result;
474}
475
476bool BaseChannel::IsStreamMuted(uint32 ssrc) {
477 SsrcMessageData data(ssrc);
478 Send(MSG_ISSTREAMMUTED, &data);
479 return data.result;
480}
481
482bool BaseChannel::AddRecvStream(const StreamParams& sp) {
483 StreamMessageData data(sp);
484 Send(MSG_ADDRECVSTREAM, &data);
485 return data.result;
486}
487
488bool BaseChannel::RemoveRecvStream(uint32 ssrc) {
489 SsrcMessageData data(ssrc);
490 Send(MSG_REMOVERECVSTREAM, &data);
491 return data.result;
492}
493
wu@webrtc.orgcadf9042013-08-30 21:24:16 +0000494bool BaseChannel::AddSendStream(const StreamParams& sp) {
495 StreamMessageData data(sp);
496 Send(MSG_ADDSENDSTREAM, &data);
497 return data.result;
498}
499
500bool BaseChannel::RemoveSendStream(uint32 ssrc) {
501 SsrcMessageData data(ssrc);
502 Send(MSG_REMOVESENDSTREAM, &data);
503 return data.result;
504}
505
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
507 ContentAction action) {
508 SetContentData data(content, action);
509 Send(MSG_SETLOCALCONTENT, &data);
510 return data.result;
511}
512
513bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
514 ContentAction action) {
515 SetContentData data(content, action);
516 Send(MSG_SETREMOTECONTENT, &data);
517 return data.result;
518}
519
520bool BaseChannel::SetMaxSendBandwidth(int max_bandwidth) {
521 SetBandwidthData data(max_bandwidth);
522 Send(MSG_SETMAXSENDBANDWIDTH, &data);
523 return data.result;
524}
525
526void BaseChannel::StartConnectionMonitor(int cms) {
527 socket_monitor_.reset(new SocketMonitor(transport_channel_,
528 worker_thread(),
529 talk_base::Thread::Current()));
530 socket_monitor_->SignalUpdate.connect(
531 this, &BaseChannel::OnConnectionMonitorUpdate);
532 socket_monitor_->Start(cms);
533}
534
535void BaseChannel::StopConnectionMonitor() {
536 if (socket_monitor_) {
537 socket_monitor_->Stop();
538 socket_monitor_.reset();
539 }
540}
541
542void BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) {
543 if (rtcp_transport_channel_ != channel) {
544 if (rtcp_transport_channel_) {
545 session_->DestroyChannel(
546 content_name_, rtcp_transport_channel_->component());
547 }
548 rtcp_transport_channel_ = channel;
549 if (rtcp_transport_channel_) {
550 // TODO(juberti): Propagate this error code
551 VERIFY(SetDtlsSrtpCiphers(rtcp_transport_channel_, true));
552 rtcp_transport_channel_->SignalWritableState.connect(
553 this, &BaseChannel::OnWritableState);
554 rtcp_transport_channel_->SignalReadPacket.connect(
555 this, &BaseChannel::OnChannelRead);
556 rtcp_transport_channel_->SignalReadyToSend.connect(
557 this, &BaseChannel::OnReadyToSend);
558 }
559 }
560}
561
562bool BaseChannel::IsReadyToReceive() const {
563 // Receive data if we are enabled and have local content,
564 return enabled() && IsReceiveContentDirection(local_content_direction_);
565}
566
567bool BaseChannel::IsReadyToSend() const {
568 // Send outgoing data if we are enabled, have local and remote content,
569 // and we have had some form of connectivity.
570 return enabled() &&
571 IsReceiveContentDirection(remote_content_direction_) &&
572 IsSendContentDirection(local_content_direction_) &&
573 was_ever_writable();
574}
575
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000576bool BaseChannel::SendPacket(talk_base::Buffer* packet,
577 talk_base::DiffServCodePoint dscp) {
578 return SendPacket(false, packet, dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579}
580
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000581bool BaseChannel::SendRtcp(talk_base::Buffer* packet,
582 talk_base::DiffServCodePoint dscp) {
583 return SendPacket(true, packet, dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584}
585
586int BaseChannel::SetOption(SocketType type, talk_base::Socket::Option opt,
587 int value) {
588 switch (type) {
589 case ST_RTP: return transport_channel_->SetOption(opt, value);
590 case ST_RTCP: return rtcp_transport_channel_->SetOption(opt, value);
591 default: return -1;
592 }
593}
594
595void BaseChannel::OnWritableState(TransportChannel* channel) {
596 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
597 if (transport_channel_->writable()
598 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) {
599 ChannelWritable_w();
600 } else {
601 ChannelNotWritable_w();
602 }
603}
604
605void BaseChannel::OnChannelRead(TransportChannel* channel,
606 const char* data, size_t len, int flags) {
607 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
608 ASSERT(worker_thread_ == talk_base::Thread::Current());
609
610 // When using RTCP multiplexing we might get RTCP packets on the RTP
611 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP.
612 bool rtcp = PacketIsRtcp(channel, data, len);
613 talk_base::Buffer packet(data, len);
614 HandlePacket(rtcp, &packet);
615}
616
617void BaseChannel::OnReadyToSend(TransportChannel* channel) {
618 SetReadyToSend(channel, true);
619}
620
621void BaseChannel::SetReadyToSend(TransportChannel* channel, bool ready) {
622 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
623 if (channel == transport_channel_) {
624 rtp_ready_to_send_ = ready;
625 }
626 if (channel == rtcp_transport_channel_) {
627 rtcp_ready_to_send_ = ready;
628 }
629
630 if (!ready) {
631 // Notify the MediaChannel when either rtp or rtcp channel can't send.
632 media_channel_->OnReadyToSend(false);
633 } else if (rtp_ready_to_send_ &&
634 // In the case of rtcp mux |rtcp_transport_channel_| will be null.
635 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) {
636 // Notify the MediaChannel when both rtp and rtcp channel can send.
637 media_channel_->OnReadyToSend(true);
638 }
639}
640
641bool BaseChannel::PacketIsRtcp(const TransportChannel* channel,
642 const char* data, size_t len) {
643 return (channel == rtcp_transport_channel_ ||
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000644 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645}
646
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000647bool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet,
648 talk_base::DiffServCodePoint dscp) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 // SendPacket gets called from MediaEngine, typically on an encoder thread.
650 // If the thread is not our worker thread, we will post to our worker
651 // so that the real work happens on our worker. This avoids us having to
652 // synchronize access to all the pieces of the send path, including
653 // SRTP and the inner workings of the transport channels.
654 // The only downside is that we can't return a proper failure code if
655 // needed. Since UDP is unreliable anyway, this should be a non-issue.
656 if (talk_base::Thread::Current() != worker_thread_) {
657 // Avoid a copy by transferring the ownership of the packet data.
658 int message_id = (!rtcp) ? MSG_RTPPACKET : MSG_RTCPPACKET;
659 PacketMessageData* data = new PacketMessageData;
660 packet->TransferTo(&data->packet);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000661 data->dscp = dscp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000662 worker_thread_->Post(this, message_id, data);
663 return true;
664 }
665
666 // Now that we are on the correct thread, ensure we have a place to send this
667 // packet before doing anything. (We might get RTCP packets that we don't
668 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
669 // transport.
670 TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ?
671 transport_channel_ : rtcp_transport_channel_;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000672 if (!channel || !channel->writable()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673 return false;
674 }
675
676 // Protect ourselves against crazy data.
677 if (!ValidPacket(rtcp, packet)) {
678 LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
679 << PacketType(rtcp) << " packet: wrong size="
680 << packet->length();
681 return false;
682 }
683
684 // Signal to the media sink before protecting the packet.
685 {
686 talk_base::CritScope cs(&signal_send_packet_cs_);
687 SignalSendPacketPreCrypto(packet->data(), packet->length(), rtcp);
688 }
689
690 // Protect if needed.
691 if (srtp_filter_.IsActive()) {
692 bool res;
693 char* data = packet->data();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000694 int len = static_cast<int>(packet->length());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695 if (!rtcp) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000696 res = srtp_filter_.ProtectRtp(data, len,
697 static_cast<int>(packet->capacity()), &len);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 if (!res) {
699 int seq_num = -1;
700 uint32 ssrc = 0;
701 GetRtpSeqNum(data, len, &seq_num);
702 GetRtpSsrc(data, len, &ssrc);
703 LOG(LS_ERROR) << "Failed to protect " << content_name_
704 << " RTP packet: size=" << len
705 << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
706 return false;
707 }
708 } else {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000709 res = srtp_filter_.ProtectRtcp(data, len,
710 static_cast<int>(packet->capacity()),
711 &len);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712 if (!res) {
713 int type = -1;
714 GetRtcpType(data, len, &type);
715 LOG(LS_ERROR) << "Failed to protect " << content_name_
716 << " RTCP packet: size=" << len << ", type=" << type;
717 return false;
718 }
719 }
720
721 // Update the length of the packet now that we've added the auth tag.
722 packet->SetLength(len);
723 } else if (secure_required_) {
724 // This is a double check for something that supposedly can't happen.
725 LOG(LS_ERROR) << "Can't send outgoing " << PacketType(rtcp)
726 << " packet when SRTP is inactive and crypto is required";
727
728 ASSERT(false);
729 return false;
730 }
731
732 // Signal to the media sink after protecting the packet.
733 {
734 talk_base::CritScope cs(&signal_send_packet_cs_);
735 SignalSendPacketPostCrypto(packet->data(), packet->length(), rtcp);
736 }
737
738 // Bon voyage.
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000739 int ret = channel->SendPacket(packet->data(), packet->length(), dscp,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0);
741 if (ret != static_cast<int>(packet->length())) {
742 if (channel->GetError() == EWOULDBLOCK) {
743 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket.";
744 SetReadyToSend(channel, false);
745 }
746 return false;
747 }
748 return true;
749}
750
751bool BaseChannel::WantsPacket(bool rtcp, talk_base::Buffer* packet) {
752 // Protect ourselves against crazy data.
753 if (!ValidPacket(rtcp, packet)) {
754 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " "
755 << PacketType(rtcp) << " packet: wrong size="
756 << packet->length();
757 return false;
758 }
759 // If this channel is suppose to handle RTP data, that is determined by
760 // checking against ssrc filter. This is necessary to do it here to avoid
761 // double decryption.
762 if (ssrc_filter_.IsActive() &&
763 !ssrc_filter_.DemuxPacket(packet->data(), packet->length(), rtcp)) {
764 return false;
765 }
766
767 return true;
768}
769
770void BaseChannel::HandlePacket(bool rtcp, talk_base::Buffer* packet) {
771 if (!WantsPacket(rtcp, packet)) {
772 return;
773 }
774
775 if (!has_received_packet_) {
776 has_received_packet_ = true;
777 signaling_thread()->Post(this, MSG_FIRSTPACKETRECEIVED);
778 }
779
780 // Signal to the media sink before unprotecting the packet.
781 {
782 talk_base::CritScope cs(&signal_recv_packet_cs_);
783 SignalRecvPacketPostCrypto(packet->data(), packet->length(), rtcp);
784 }
785
786 // Unprotect the packet, if needed.
787 if (srtp_filter_.IsActive()) {
788 char* data = packet->data();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000789 int len = static_cast<int>(packet->length());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 bool res;
791 if (!rtcp) {
792 res = srtp_filter_.UnprotectRtp(data, len, &len);
793 if (!res) {
794 int seq_num = -1;
795 uint32 ssrc = 0;
796 GetRtpSeqNum(data, len, &seq_num);
797 GetRtpSsrc(data, len, &ssrc);
798 LOG(LS_ERROR) << "Failed to unprotect " << content_name_
799 << " RTP packet: size=" << len
800 << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
801 return;
802 }
803 } else {
804 res = srtp_filter_.UnprotectRtcp(data, len, &len);
805 if (!res) {
806 int type = -1;
807 GetRtcpType(data, len, &type);
808 LOG(LS_ERROR) << "Failed to unprotect " << content_name_
809 << " RTCP packet: size=" << len << ", type=" << type;
810 return;
811 }
812 }
813
814 packet->SetLength(len);
815 } else if (secure_required_) {
816 // Our session description indicates that SRTP is required, but we got a
817 // packet before our SRTP filter is active. This means either that
818 // a) we got SRTP packets before we received the SDES keys, in which case
819 // we can't decrypt it anyway, or
820 // b) we got SRTP packets before DTLS completed on both the RTP and RTCP
821 // channels, so we haven't yet extracted keys, even if DTLS did complete
822 // on the channel that the packets are being sent on. It's really good
823 // practice to wait for both RTP and RTCP to be good to go before sending
824 // media, to prevent weird failure modes, so it's fine for us to just eat
825 // packets here. This is all sidestepped if RTCP mux is used anyway.
826 LOG(LS_WARNING) << "Can't process incoming " << PacketType(rtcp)
827 << " packet when SRTP is inactive and crypto is required";
828 return;
829 }
830
831 // Signal to the media sink after unprotecting the packet.
832 {
833 talk_base::CritScope cs(&signal_recv_packet_cs_);
834 SignalRecvPacketPreCrypto(packet->data(), packet->length(), rtcp);
835 }
836
837 // Push it down to the media channel.
838 if (!rtcp) {
839 media_channel_->OnPacketReceived(packet);
840 } else {
841 media_channel_->OnRtcpReceived(packet);
842 }
843}
844
845void BaseChannel::OnNewLocalDescription(
846 BaseSession* session, ContentAction action) {
847 const ContentInfo* content_info =
848 GetFirstContent(session->local_description());
849 const MediaContentDescription* content_desc =
850 GetContentDescription(content_info);
851 if (content_desc && content_info && !content_info->rejected &&
852 !SetLocalContent(content_desc, action)) {
853 LOG(LS_ERROR) << "Failure in SetLocalContent with action " << action;
854 session->SetError(BaseSession::ERROR_CONTENT);
855 }
856}
857
858void BaseChannel::OnNewRemoteDescription(
859 BaseSession* session, ContentAction action) {
860 const ContentInfo* content_info =
861 GetFirstContent(session->remote_description());
862 const MediaContentDescription* content_desc =
863 GetContentDescription(content_info);
864 if (content_desc && content_info && !content_info->rejected &&
865 !SetRemoteContent(content_desc, action)) {
866 LOG(LS_ERROR) << "Failure in SetRemoteContent with action " << action;
867 session->SetError(BaseSession::ERROR_CONTENT);
868 }
869}
870
871void BaseChannel::EnableMedia_w() {
872 ASSERT(worker_thread_ == talk_base::Thread::Current());
873 if (enabled_)
874 return;
875
876 LOG(LS_INFO) << "Channel enabled";
877 enabled_ = true;
878 ChangeState();
879}
880
881void BaseChannel::DisableMedia_w() {
882 ASSERT(worker_thread_ == talk_base::Thread::Current());
883 if (!enabled_)
884 return;
885
886 LOG(LS_INFO) << "Channel disabled";
887 enabled_ = false;
888 ChangeState();
889}
890
891bool BaseChannel::MuteStream_w(uint32 ssrc, bool mute) {
892 ASSERT(worker_thread_ == talk_base::Thread::Current());
893 bool ret = media_channel()->MuteStream(ssrc, mute);
894 if (ret) {
895 if (mute)
896 muted_streams_.insert(ssrc);
897 else
898 muted_streams_.erase(ssrc);
899 }
900 return ret;
901}
902
903bool BaseChannel::IsStreamMuted_w(uint32 ssrc) {
904 ASSERT(worker_thread_ == talk_base::Thread::Current());
905 return muted_streams_.find(ssrc) != muted_streams_.end();
906}
907
908void BaseChannel::ChannelWritable_w() {
909 ASSERT(worker_thread_ == talk_base::Thread::Current());
910 if (writable_)
911 return;
912
913 LOG(LS_INFO) << "Channel socket writable ("
914 << transport_channel_->content_name() << ", "
915 << transport_channel_->component() << ")"
916 << (was_ever_writable_ ? "" : " for the first time");
917
918 std::vector<ConnectionInfo> infos;
919 transport_channel_->GetStats(&infos);
920 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin();
921 it != infos.end(); ++it) {
922 if (it->best_connection) {
923 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString()
924 << "->" << it->remote_candidate.ToSensitiveString();
925 break;
926 }
927 }
928
929 // If we're doing DTLS-SRTP, now is the time.
930 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) {
931 if (!SetupDtlsSrtp(false)) {
932 LOG(LS_ERROR) << "Couldn't finish DTLS-SRTP on RTP channel";
933 SessionErrorMessageData data(BaseSession::ERROR_TRANSPORT);
934 // Sent synchronously.
935 signaling_thread()->Send(this, MSG_SESSION_ERROR, &data);
936 return;
937 }
938
939 if (rtcp_transport_channel_) {
940 if (!SetupDtlsSrtp(true)) {
941 LOG(LS_ERROR) << "Couldn't finish DTLS-SRTP on RTCP channel";
942 SessionErrorMessageData data(BaseSession::ERROR_TRANSPORT);
943 // Sent synchronously.
944 signaling_thread()->Send(this, MSG_SESSION_ERROR, &data);
945 return;
946 }
947 }
948 }
949
950 was_ever_writable_ = true;
951 writable_ = true;
952 ChangeState();
953}
954
955bool BaseChannel::SetDtlsSrtpCiphers(TransportChannel *tc, bool rtcp) {
956 std::vector<std::string> ciphers;
957 // We always use the default SRTP ciphers for RTCP, but we may use different
958 // ciphers for RTP depending on the media type.
959 if (!rtcp) {
960 GetSrtpCiphers(&ciphers);
961 } else {
962 GetSupportedDefaultCryptoSuites(&ciphers);
963 }
964 return tc->SetSrtpCiphers(ciphers);
965}
966
967bool BaseChannel::ShouldSetupDtlsSrtp() const {
968 return true;
969}
970
971// This function returns true if either DTLS-SRTP is not in use
972// *or* DTLS-SRTP is successfully set up.
973bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) {
974 bool ret = false;
975
976 TransportChannel *channel = rtcp_channel ?
977 rtcp_transport_channel_ : transport_channel_;
978
979 // No DTLS
980 if (!channel->IsDtlsActive())
981 return true;
982
983 std::string selected_cipher;
984
985 if (!channel->GetSrtpCipher(&selected_cipher)) {
986 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher";
987 return false;
988 }
989
990 LOG(LS_INFO) << "Installing keys from DTLS-SRTP on "
991 << content_name() << " "
992 << PacketType(rtcp_channel);
993
994 // OK, we're now doing DTLS (RFC 5764)
995 std::vector<unsigned char> dtls_buffer(SRTP_MASTER_KEY_KEY_LEN * 2 +
996 SRTP_MASTER_KEY_SALT_LEN * 2);
997
998 // RFC 5705 exporter using the RFC 5764 parameters
999 if (!channel->ExportKeyingMaterial(
1000 kDtlsSrtpExporterLabel,
1001 NULL, 0, false,
1002 &dtls_buffer[0], dtls_buffer.size())) {
1003 LOG(LS_WARNING) << "DTLS-SRTP key export failed";
1004 ASSERT(false); // This should never happen
1005 return false;
1006 }
1007
1008 // Sync up the keys with the DTLS-SRTP interface
1009 std::vector<unsigned char> client_write_key(SRTP_MASTER_KEY_KEY_LEN +
1010 SRTP_MASTER_KEY_SALT_LEN);
1011 std::vector<unsigned char> server_write_key(SRTP_MASTER_KEY_KEY_LEN +
1012 SRTP_MASTER_KEY_SALT_LEN);
1013 size_t offset = 0;
1014 memcpy(&client_write_key[0], &dtls_buffer[offset],
1015 SRTP_MASTER_KEY_KEY_LEN);
1016 offset += SRTP_MASTER_KEY_KEY_LEN;
1017 memcpy(&server_write_key[0], &dtls_buffer[offset],
1018 SRTP_MASTER_KEY_KEY_LEN);
1019 offset += SRTP_MASTER_KEY_KEY_LEN;
1020 memcpy(&client_write_key[SRTP_MASTER_KEY_KEY_LEN],
1021 &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
1022 offset += SRTP_MASTER_KEY_SALT_LEN;
1023 memcpy(&server_write_key[SRTP_MASTER_KEY_KEY_LEN],
1024 &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
1025
1026 std::vector<unsigned char> *send_key, *recv_key;
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +00001027 talk_base::SSLRole role;
1028 if (!channel->GetSslRole(&role)) {
1029 LOG(LS_WARNING) << "GetSslRole failed";
1030 return false;
1031 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001032
sergeyu@chromium.org0be6aa02013-08-23 23:21:25 +00001033 if (role == talk_base::SSL_SERVER) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001034 send_key = &server_write_key;
1035 recv_key = &client_write_key;
1036 } else {
1037 send_key = &client_write_key;
1038 recv_key = &server_write_key;
1039 }
1040
1041 if (rtcp_channel) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001042 ret = srtp_filter_.SetRtcpParams(
1043 selected_cipher,
1044 &(*send_key)[0],
1045 static_cast<int>(send_key->size()),
1046 selected_cipher,
1047 &(*recv_key)[0],
1048 static_cast<int>(recv_key->size()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001049 } else {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001050 ret = srtp_filter_.SetRtpParams(
1051 selected_cipher,
1052 &(*send_key)[0],
1053 static_cast<int>(send_key->size()),
1054 selected_cipher,
1055 &(*recv_key)[0],
1056 static_cast<int>(recv_key->size()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057 }
1058
1059 if (!ret)
1060 LOG(LS_WARNING) << "DTLS-SRTP key installation failed";
1061 else
1062 dtls_keyed_ = true;
1063
1064 return ret;
1065}
1066
1067void BaseChannel::ChannelNotWritable_w() {
1068 ASSERT(worker_thread_ == talk_base::Thread::Current());
1069 if (!writable_)
1070 return;
1071
1072 LOG(LS_INFO) << "Channel socket not writable ("
1073 << transport_channel_->content_name() << ", "
1074 << transport_channel_->component() << ")";
1075 writable_ = false;
1076 ChangeState();
1077}
1078
1079// Sets the maximum video bandwidth for automatic bandwidth adjustment.
1080bool BaseChannel::SetMaxSendBandwidth_w(int max_bandwidth) {
1081 return media_channel()->SetSendBandwidth(true, max_bandwidth);
1082}
1083
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001084// |dtls| will be set to true if DTLS is active for transport channel and
1085// crypto is empty.
1086bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos,
1087 bool* dtls) {
1088 *dtls = transport_channel_->IsDtlsActive();
1089 if (*dtls && !cryptos.empty()) {
1090 LOG(LS_WARNING) << "Cryptos must be empty when DTLS is active.";
1091 return false;
1092 }
1093 return true;
1094}
1095
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001096bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos,
1097 ContentAction action, ContentSource src) {
1098 bool ret = false;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001099 bool dtls = false;
1100 ret = CheckSrtpConfig(cryptos, &dtls);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001101 switch (action) {
1102 case CA_OFFER:
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001103 // If DTLS is already active on the channel, we could be renegotiating
1104 // here. We don't update the srtp filter.
1105 if (ret && !dtls) {
1106 ret = srtp_filter_.SetOffer(cryptos, src);
1107 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001108 break;
1109 case CA_PRANSWER:
1110 // If we're doing DTLS-SRTP, we don't want to update the filter
1111 // with an answer, because we already have SRTP parameters.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001112 if (ret && !dtls) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001113 ret = srtp_filter_.SetProvisionalAnswer(cryptos, src);
1114 }
1115 break;
1116 case CA_ANSWER:
1117 // If we're doing DTLS-SRTP, we don't want to update the filter
1118 // with an answer, because we already have SRTP parameters.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001119 if (ret && !dtls) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001120 ret = srtp_filter_.SetAnswer(cryptos, src);
1121 }
1122 break;
1123 case CA_UPDATE:
1124 // no crypto params.
1125 ret = true;
1126 break;
1127 default:
1128 break;
1129 }
1130 return ret;
1131}
1132
1133bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action,
1134 ContentSource src) {
1135 bool ret = false;
1136 switch (action) {
1137 case CA_OFFER:
1138 ret = rtcp_mux_filter_.SetOffer(enable, src);
1139 break;
1140 case CA_PRANSWER:
1141 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src);
1142 break;
1143 case CA_ANSWER:
1144 ret = rtcp_mux_filter_.SetAnswer(enable, src);
1145 if (ret && rtcp_mux_filter_.IsActive()) {
1146 // We activated RTCP mux, close down the RTCP transport.
1147 set_rtcp_transport_channel(NULL);
1148 }
1149 break;
1150 case CA_UPDATE:
1151 // No RTCP mux info.
1152 ret = true;
1153 default:
1154 break;
1155 }
1156 // |rtcp_mux_filter_| can be active if |action| is CA_PRANSWER or
1157 // CA_ANSWER, but we only want to tear down the RTCP transport channel if we
1158 // received a final answer.
1159 if (ret && rtcp_mux_filter_.IsActive()) {
1160 // If the RTP transport is already writable, then so are we.
1161 if (transport_channel_->writable()) {
1162 ChannelWritable_w();
1163 }
1164 }
1165
1166 return ret;
1167}
1168
1169bool BaseChannel::AddRecvStream_w(const StreamParams& sp) {
1170 ASSERT(worker_thread() == talk_base::Thread::Current());
1171 if (!media_channel()->AddRecvStream(sp))
1172 return false;
1173
1174 return ssrc_filter_.AddStream(sp);
1175}
1176
1177bool BaseChannel::RemoveRecvStream_w(uint32 ssrc) {
1178 ASSERT(worker_thread() == talk_base::Thread::Current());
1179 ssrc_filter_.RemoveStream(ssrc);
1180 return media_channel()->RemoveRecvStream(ssrc);
1181}
1182
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001183bool BaseChannel::AddSendStream_w(const StreamParams& sp) {
1184 ASSERT(worker_thread() == talk_base::Thread::Current());
1185 return media_channel()->AddSendStream(sp);
1186}
1187
1188bool BaseChannel::RemoveSendStream_w(uint32 ssrc) {
1189 ASSERT(worker_thread() == talk_base::Thread::Current());
1190 return media_channel()->RemoveSendStream(ssrc);
1191}
1192
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001193bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,
1194 ContentAction action) {
1195 if (!VERIFY(action == CA_OFFER || action == CA_ANSWER ||
1196 action == CA_PRANSWER || action == CA_UPDATE))
1197 return false;
1198
1199 // If this is an update, streams only contain streams that have changed.
1200 if (action == CA_UPDATE) {
1201 for (StreamParamsVec::const_iterator it = streams.begin();
1202 it != streams.end(); ++it) {
1203 StreamParams existing_stream;
1204 bool stream_exist = GetStreamByIds(local_streams_, it->groupid,
1205 it->id, &existing_stream);
1206 if (!stream_exist && it->has_ssrcs()) {
1207 if (media_channel()->AddSendStream(*it)) {
1208 local_streams_.push_back(*it);
1209 LOG(LS_INFO) << "Add send stream ssrc: " << it->first_ssrc();
1210 } else {
1211 LOG(LS_INFO) << "Failed to add send stream ssrc: "
1212 << it->first_ssrc();
1213 return false;
1214 }
1215 } else if (stream_exist && !it->has_ssrcs()) {
1216 if (!media_channel()->RemoveSendStream(existing_stream.first_ssrc())) {
1217 LOG(LS_ERROR) << "Failed to remove send stream with ssrc "
1218 << it->first_ssrc() << ".";
1219 return false;
1220 }
1221 RemoveStreamBySsrc(&local_streams_, existing_stream.first_ssrc());
1222 } else {
1223 LOG(LS_WARNING) << "Ignore unsupported stream update";
1224 }
1225 }
1226 return true;
1227 }
1228 // Else streams are all the streams we want to send.
1229
1230 // Check for streams that have been removed.
1231 bool ret = true;
1232 for (StreamParamsVec::const_iterator it = local_streams_.begin();
1233 it != local_streams_.end(); ++it) {
1234 if (!GetStreamBySsrc(streams, it->first_ssrc(), NULL)) {
1235 if (!media_channel()->RemoveSendStream(it->first_ssrc())) {
1236 LOG(LS_ERROR) << "Failed to remove send stream with ssrc "
1237 << it->first_ssrc() << ".";
1238 ret = false;
1239 }
1240 }
1241 }
1242 // Check for new streams.
1243 for (StreamParamsVec::const_iterator it = streams.begin();
1244 it != streams.end(); ++it) {
1245 if (!GetStreamBySsrc(local_streams_, it->first_ssrc(), NULL)) {
1246 if (media_channel()->AddSendStream(*it)) {
1247 LOG(LS_INFO) << "Add send ssrc: " << it->ssrcs[0];
1248 } else {
1249 LOG(LS_INFO) << "Failed to add send stream ssrc: " << it->first_ssrc();
1250 ret = false;
1251 }
1252 }
1253 }
1254 local_streams_ = streams;
1255 return ret;
1256}
1257
1258bool BaseChannel::UpdateRemoteStreams_w(
1259 const std::vector<StreamParams>& streams,
1260 ContentAction action) {
1261 if (!VERIFY(action == CA_OFFER || action == CA_ANSWER ||
1262 action == CA_PRANSWER || action == CA_UPDATE))
1263 return false;
1264
1265 // If this is an update, streams only contain streams that have changed.
1266 if (action == CA_UPDATE) {
1267 for (StreamParamsVec::const_iterator it = streams.begin();
1268 it != streams.end(); ++it) {
1269 StreamParams existing_stream;
1270 bool stream_exists = GetStreamByIds(remote_streams_, it->groupid,
1271 it->id, &existing_stream);
1272 if (!stream_exists && it->has_ssrcs()) {
1273 if (AddRecvStream_w(*it)) {
1274 remote_streams_.push_back(*it);
1275 LOG(LS_INFO) << "Add remote stream ssrc: " << it->first_ssrc();
1276 } else {
1277 LOG(LS_INFO) << "Failed to add remote stream ssrc: "
1278 << it->first_ssrc();
1279 return false;
1280 }
1281 } else if (stream_exists && !it->has_ssrcs()) {
1282 if (!RemoveRecvStream_w(existing_stream.first_ssrc())) {
1283 LOG(LS_ERROR) << "Failed to remove remote stream with ssrc "
1284 << it->first_ssrc() << ".";
1285 return false;
1286 }
1287 RemoveStreamBySsrc(&remote_streams_, existing_stream.first_ssrc());
1288 } else {
1289 LOG(LS_WARNING) << "Ignore unsupported stream update."
1290 << " Stream exists? " << stream_exists
1291 << " existing stream = " << existing_stream.ToString()
1292 << " new stream = " << it->ToString();
1293 }
1294 }
1295 return true;
1296 }
1297 // Else streams are all the streams we want to receive.
1298
1299 // Check for streams that have been removed.
1300 bool ret = true;
1301 for (StreamParamsVec::const_iterator it = remote_streams_.begin();
1302 it != remote_streams_.end(); ++it) {
1303 if (!GetStreamBySsrc(streams, it->first_ssrc(), NULL)) {
1304 if (!RemoveRecvStream_w(it->first_ssrc())) {
1305 LOG(LS_ERROR) << "Failed to remove remote stream with ssrc "
1306 << it->first_ssrc() << ".";
1307 ret = false;
1308 }
1309 }
1310 }
1311 // Check for new streams.
1312 for (StreamParamsVec::const_iterator it = streams.begin();
1313 it != streams.end(); ++it) {
1314 if (!GetStreamBySsrc(remote_streams_, it->first_ssrc(), NULL)) {
1315 if (AddRecvStream_w(*it)) {
1316 LOG(LS_INFO) << "Add remote ssrc: " << it->ssrcs[0];
1317 } else {
1318 LOG(LS_INFO) << "Failed to add remote stream ssrc: "
1319 << it->first_ssrc();
1320 ret = false;
1321 }
1322 }
1323 }
1324 remote_streams_ = streams;
1325 return ret;
1326}
1327
1328bool BaseChannel::SetBaseLocalContent_w(const MediaContentDescription* content,
1329 ContentAction action) {
1330 // Cache secure_required_ for belt and suspenders check on SendPacket
1331 secure_required_ = content->crypto_required();
1332 bool ret = UpdateLocalStreams_w(content->streams(), action);
1333 // Set local SRTP parameters (what we will encrypt with).
1334 ret &= SetSrtp_w(content->cryptos(), action, CS_LOCAL);
1335 // Set local RTCP mux parameters.
1336 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_LOCAL);
1337 // Set local RTP header extensions.
1338 if (content->rtp_header_extensions_set()) {
1339 ret &= media_channel()->SetRecvRtpHeaderExtensions(
1340 content->rtp_header_extensions());
1341 }
1342 set_local_content_direction(content->direction());
1343 return ret;
1344}
1345
1346bool BaseChannel::SetBaseRemoteContent_w(const MediaContentDescription* content,
1347 ContentAction action) {
1348 bool ret = UpdateRemoteStreams_w(content->streams(), action);
1349 // Set remote SRTP parameters (what the other side will encrypt with).
1350 ret &= SetSrtp_w(content->cryptos(), action, CS_REMOTE);
1351 // Set remote RTCP mux parameters.
1352 ret &= SetRtcpMux_w(content->rtcp_mux(), action, CS_REMOTE);
1353 // Set remote RTP header extensions.
1354 if (content->rtp_header_extensions_set()) {
1355 ret &= media_channel()->SetSendRtpHeaderExtensions(
1356 content->rtp_header_extensions());
1357 }
1358 if (content->bandwidth() != kAutoBandwidth) {
1359 ret &= media_channel()->SetSendBandwidth(false, content->bandwidth());
1360 }
1361 set_remote_content_direction(content->direction());
1362 return ret;
1363}
1364
1365void BaseChannel::OnMessage(talk_base::Message *pmsg) {
1366 switch (pmsg->message_id) {
1367 case MSG_ENABLE:
1368 EnableMedia_w();
1369 break;
1370 case MSG_DISABLE:
1371 DisableMedia_w();
1372 break;
1373 case MSG_MUTESTREAM: {
1374 MuteStreamData* data = static_cast<MuteStreamData*>(pmsg->pdata);
1375 data->result = MuteStream_w(data->ssrc, data->mute);
1376 break;
1377 }
1378 case MSG_ISSTREAMMUTED: {
1379 SsrcMessageData* data = static_cast<SsrcMessageData*>(pmsg->pdata);
1380 data->result = IsStreamMuted_w(data->ssrc);
1381 break;
1382 }
1383 case MSG_SETLOCALCONTENT: {
1384 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
1385 data->result = SetLocalContent_w(data->content, data->action);
1386 break;
1387 }
1388 case MSG_SETREMOTECONTENT: {
1389 SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
1390 data->result = SetRemoteContent_w(data->content, data->action);
1391 break;
1392 }
1393 case MSG_ADDRECVSTREAM: {
1394 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
1395 data->result = AddRecvStream_w(data->sp);
1396 break;
1397 }
1398 case MSG_REMOVERECVSTREAM: {
1399 SsrcMessageData* data = static_cast<SsrcMessageData*>(pmsg->pdata);
1400 data->result = RemoveRecvStream_w(data->ssrc);
1401 break;
1402 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00001403 case MSG_ADDSENDSTREAM: {
1404 StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
1405 data->result = AddSendStream_w(data->sp);
1406 break;
1407 }
1408 case MSG_REMOVESENDSTREAM: {
1409 SsrcMessageData* data = static_cast<SsrcMessageData*>(pmsg->pdata);
1410 data->result = RemoveSendStream_w(data->ssrc);
1411 break;
1412 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413 case MSG_SETMAXSENDBANDWIDTH: {
1414 SetBandwidthData* data = static_cast<SetBandwidthData*>(pmsg->pdata);
1415 data->result = SetMaxSendBandwidth_w(data->value);
1416 break;
1417 }
1418
1419 case MSG_RTPPACKET:
1420 case MSG_RTCPPACKET: {
1421 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001422 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet, data->dscp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423 delete data; // because it is Posted
1424 break;
1425 }
1426 case MSG_FIRSTPACKETRECEIVED: {
1427 SignalFirstPacketReceived(this);
1428 break;
1429 }
1430 case MSG_SESSION_ERROR: {
1431 SessionErrorMessageData* data = static_cast<SessionErrorMessageData*>
1432 (pmsg->pdata);
1433 session_->SetError(data->error_);
1434 break;
1435 }
1436 }
1437}
1438
1439void BaseChannel::Send(uint32 id, talk_base::MessageData *pdata) {
1440 worker_thread_->Send(this, id, pdata);
1441}
1442
1443void BaseChannel::Post(uint32 id, talk_base::MessageData *pdata) {
1444 worker_thread_->Post(this, id, pdata);
1445}
1446
1447void BaseChannel::PostDelayed(int cmsDelay, uint32 id,
1448 talk_base::MessageData *pdata) {
1449 worker_thread_->PostDelayed(cmsDelay, this, id, pdata);
1450}
1451
1452void BaseChannel::Clear(uint32 id, talk_base::MessageList* removed) {
1453 worker_thread_->Clear(this, id, removed);
1454}
1455
1456void BaseChannel::FlushRtcpMessages() {
1457 // Flush all remaining RTCP messages. This should only be called in
1458 // destructor.
1459 ASSERT(talk_base::Thread::Current() == worker_thread_);
1460 talk_base::MessageList rtcp_messages;
1461 Clear(MSG_RTCPPACKET, &rtcp_messages);
1462 for (talk_base::MessageList::iterator it = rtcp_messages.begin();
1463 it != rtcp_messages.end(); ++it) {
1464 Send(MSG_RTCPPACKET, it->pdata);
1465 }
1466}
1467
1468VoiceChannel::VoiceChannel(talk_base::Thread* thread,
1469 MediaEngineInterface* media_engine,
1470 VoiceMediaChannel* media_channel,
1471 BaseSession* session,
1472 const std::string& content_name,
1473 bool rtcp)
1474 : BaseChannel(thread, media_engine, media_channel, session, content_name,
1475 rtcp),
1476 received_media_(false) {
1477}
1478
1479VoiceChannel::~VoiceChannel() {
1480 StopAudioMonitor();
1481 StopMediaMonitor();
1482 // this can't be done in the base class, since it calls a virtual
1483 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001484 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485}
1486
1487bool VoiceChannel::Init() {
1488 TransportChannel* rtcp_channel = rtcp() ? session()->CreateChannel(
1489 content_name(), "rtcp", ICE_CANDIDATE_COMPONENT_RTCP) : NULL;
1490 if (!BaseChannel::Init(session()->CreateChannel(
1491 content_name(), "rtp", ICE_CANDIDATE_COMPONENT_RTP),
1492 rtcp_channel)) {
1493 return false;
1494 }
1495 media_channel()->SignalMediaError.connect(
1496 this, &VoiceChannel::OnVoiceChannelError);
1497 srtp_filter()->SignalSrtpError.connect(
1498 this, &VoiceChannel::OnSrtpError);
1499 return true;
1500}
1501
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001502bool VoiceChannel::SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) {
1503 AudioRenderMessageData data(ssrc, renderer, false);
1504 Send(MSG_SETRENDERER, &data);
1505 return data.result;
1506}
1507
1508bool VoiceChannel::SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) {
1509 AudioRenderMessageData data(ssrc, renderer, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001510 Send(MSG_SETRENDERER, &data);
1511 return data.result;
1512}
1513
1514bool VoiceChannel::SetRingbackTone(const void* buf, int len) {
1515 SetRingbackToneMessageData data(buf, len);
1516 Send(MSG_SETRINGBACKTONE, &data);
1517 return data.result;
1518}
1519
1520// TODO(juberti): Handle early media the right way. We should get an explicit
1521// ringing message telling us to start playing local ringback, which we cancel
1522// if any early media actually arrives. For now, we do the opposite, which is
1523// to wait 1 second for early media, and start playing local ringback if none
1524// arrives.
1525void VoiceChannel::SetEarlyMedia(bool enable) {
1526 if (enable) {
1527 // Start the early media timeout
1528 PostDelayed(kEarlyMediaTimeout, MSG_EARLYMEDIATIMEOUT);
1529 } else {
1530 // Stop the timeout if currently going.
1531 Clear(MSG_EARLYMEDIATIMEOUT);
1532 }
1533}
1534
1535bool VoiceChannel::PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
1536 PlayRingbackToneMessageData data(ssrc, play, loop);
1537 Send(MSG_PLAYRINGBACKTONE, &data);
1538 return data.result;
1539}
1540
1541bool VoiceChannel::PressDTMF(int digit, bool playout) {
1542 int flags = DF_SEND;
1543 if (playout) {
1544 flags |= DF_PLAY;
1545 }
1546 int duration_ms = 160;
1547 return InsertDtmf(0, digit, duration_ms, flags);
1548}
1549
1550bool VoiceChannel::CanInsertDtmf() {
1551 BoolMessageData data(false);
1552 Send(MSG_CANINSERTDTMF, &data);
1553 return data.data();
1554}
1555
1556bool VoiceChannel::InsertDtmf(uint32 ssrc, int event_code, int duration,
1557 int flags) {
1558 DtmfMessageData data(ssrc, event_code, duration, flags);
1559 Send(MSG_INSERTDTMF, &data);
1560 return data.result;
1561}
1562
1563bool VoiceChannel::SetOutputScaling(uint32 ssrc, double left, double right) {
1564 ScaleVolumeMessageData data(ssrc, left, right);
1565 Send(MSG_SCALEVOLUME, &data);
1566 return data.result;
1567}
1568bool VoiceChannel::GetStats(VoiceMediaInfo* stats) {
1569 VoiceStatsMessageData data(stats);
1570 Send(MSG_GETSTATS, &data);
1571 return data.result;
1572}
1573
1574void VoiceChannel::StartMediaMonitor(int cms) {
1575 media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(),
1576 talk_base::Thread::Current()));
1577 media_monitor_->SignalUpdate.connect(
1578 this, &VoiceChannel::OnMediaMonitorUpdate);
1579 media_monitor_->Start(cms);
1580}
1581
1582void VoiceChannel::StopMediaMonitor() {
1583 if (media_monitor_) {
1584 media_monitor_->Stop();
1585 media_monitor_->SignalUpdate.disconnect(this);
1586 media_monitor_.reset();
1587 }
1588}
1589
1590void VoiceChannel::StartAudioMonitor(int cms) {
1591 audio_monitor_.reset(new AudioMonitor(this, talk_base::Thread::Current()));
1592 audio_monitor_
1593 ->SignalUpdate.connect(this, &VoiceChannel::OnAudioMonitorUpdate);
1594 audio_monitor_->Start(cms);
1595}
1596
1597void VoiceChannel::StopAudioMonitor() {
1598 if (audio_monitor_) {
1599 audio_monitor_->Stop();
1600 audio_monitor_.reset();
1601 }
1602}
1603
1604bool VoiceChannel::IsAudioMonitorRunning() const {
1605 return (audio_monitor_.get() != NULL);
1606}
1607
1608void VoiceChannel::StartTypingMonitor(const TypingMonitorOptions& settings) {
1609 typing_monitor_.reset(new TypingMonitor(this, worker_thread(), settings));
1610 SignalAutoMuted.repeat(typing_monitor_->SignalMuted);
1611}
1612
1613void VoiceChannel::StopTypingMonitor() {
1614 typing_monitor_.reset();
1615}
1616
1617bool VoiceChannel::IsTypingMonitorRunning() const {
1618 return typing_monitor_;
1619}
1620
1621bool VoiceChannel::MuteStream_w(uint32 ssrc, bool mute) {
1622 bool ret = BaseChannel::MuteStream_w(ssrc, mute);
1623 if (typing_monitor_ && mute)
1624 typing_monitor_->OnChannelMuted();
1625 return ret;
1626}
1627
1628int VoiceChannel::GetInputLevel_w() {
1629 return media_engine()->GetInputLevel();
1630}
1631
1632int VoiceChannel::GetOutputLevel_w() {
1633 return media_channel()->GetOutputLevel();
1634}
1635
1636void VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) {
1637 media_channel()->GetActiveStreams(actives);
1638}
1639
1640void VoiceChannel::OnChannelRead(TransportChannel* channel,
1641 const char* data, size_t len, int flags) {
1642 BaseChannel::OnChannelRead(channel, data, len, flags);
1643
1644 // Set a flag when we've received an RTP packet. If we're waiting for early
1645 // media, this will disable the timeout.
1646 if (!received_media_ && !PacketIsRtcp(channel, data, len)) {
1647 received_media_ = true;
1648 }
1649}
1650
1651void VoiceChannel::ChangeState() {
1652 // Render incoming data if we're the active call, and we have the local
1653 // content. We receive data on the default channel and multiplexed streams.
1654 bool recv = IsReadyToReceive();
1655 if (!media_channel()->SetPlayout(recv)) {
1656 SendLastMediaError();
1657 }
1658
1659 // Send outgoing data if we're the active call, we have the remote content,
1660 // and we have had some form of connectivity.
1661 bool send = IsReadyToSend();
1662 SendFlags send_flag = send ? SEND_MICROPHONE : SEND_NOTHING;
1663 if (!media_channel()->SetSend(send_flag)) {
1664 LOG(LS_ERROR) << "Failed to SetSend " << send_flag << " on voice channel";
1665 SendLastMediaError();
1666 }
1667
1668 LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
1669}
1670
1671const ContentInfo* VoiceChannel::GetFirstContent(
1672 const SessionDescription* sdesc) {
1673 return GetFirstAudioContent(sdesc);
1674}
1675
1676bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
1677 ContentAction action) {
1678 ASSERT(worker_thread() == talk_base::Thread::Current());
1679 LOG(LS_INFO) << "Setting local voice description";
1680
1681 const AudioContentDescription* audio =
1682 static_cast<const AudioContentDescription*>(content);
1683 ASSERT(audio != NULL);
1684 if (!audio) return false;
1685
1686 bool ret = SetBaseLocalContent_w(content, action);
1687 // Set local audio codecs (what we want to receive).
1688 // TODO(whyuan): Change action != CA_UPDATE to !audio->partial() when partial
1689 // is set properly.
1690 if (action != CA_UPDATE || audio->has_codecs()) {
1691 ret &= media_channel()->SetRecvCodecs(audio->codecs());
1692 }
1693
1694 // If everything worked, see if we can start receiving.
1695 if (ret) {
1696 ChangeState();
1697 } else {
1698 LOG(LS_WARNING) << "Failed to set local voice description";
1699 }
1700 return ret;
1701}
1702
1703bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
1704 ContentAction action) {
1705 ASSERT(worker_thread() == talk_base::Thread::Current());
1706 LOG(LS_INFO) << "Setting remote voice description";
1707
1708 const AudioContentDescription* audio =
1709 static_cast<const AudioContentDescription*>(content);
1710 ASSERT(audio != NULL);
1711 if (!audio) return false;
1712
1713 bool ret = true;
1714 // Set remote video codecs (what the other side wants to receive).
1715 if (action != CA_UPDATE || audio->has_codecs()) {
1716 ret &= media_channel()->SetSendCodecs(audio->codecs());
1717 }
1718
1719 ret &= SetBaseRemoteContent_w(content, action);
1720
1721 if (action != CA_UPDATE) {
1722 // Tweak our audio processing settings, if needed.
1723 AudioOptions audio_options;
1724 if (!media_channel()->GetOptions(&audio_options)) {
1725 LOG(LS_WARNING) << "Can not set audio options from on remote content.";
1726 } else {
1727 if (audio->conference_mode()) {
1728 audio_options.conference_mode.Set(true);
1729 }
1730 if (audio->agc_minus_10db()) {
1731 audio_options.adjust_agc_delta.Set(kAgcMinus10db);
1732 }
1733 if (!media_channel()->SetOptions(audio_options)) {
1734 // Log an error on failure, but don't abort the call.
1735 LOG(LS_ERROR) << "Failed to set voice channel options";
1736 }
1737 }
1738 }
1739
1740 // If everything worked, see if we can start sending.
1741 if (ret) {
1742 ChangeState();
1743 } else {
1744 LOG(LS_WARNING) << "Failed to set remote voice description";
1745 }
1746 return ret;
1747}
1748
1749bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) {
1750 ASSERT(worker_thread() == talk_base::Thread::Current());
1751 return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len);
1752}
1753
1754bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) {
1755 ASSERT(worker_thread() == talk_base::Thread::Current());
1756 if (play) {
1757 LOG(LS_INFO) << "Playing ringback tone, loop=" << loop;
1758 } else {
1759 LOG(LS_INFO) << "Stopping ringback tone";
1760 }
1761 return media_channel()->PlayRingbackTone(ssrc, play, loop);
1762}
1763
1764void VoiceChannel::HandleEarlyMediaTimeout() {
1765 // This occurs on the main thread, not the worker thread.
1766 if (!received_media_) {
1767 LOG(LS_INFO) << "No early media received before timeout";
1768 SignalEarlyMediaTimeout(this);
1769 }
1770}
1771
1772bool VoiceChannel::CanInsertDtmf_w() {
1773 return media_channel()->CanInsertDtmf();
1774}
1775
1776bool VoiceChannel::InsertDtmf_w(uint32 ssrc, int event, int duration,
1777 int flags) {
1778 if (!enabled()) {
1779 return false;
1780 }
1781
1782 return media_channel()->InsertDtmf(ssrc, event, duration, flags);
1783}
1784
1785bool VoiceChannel::SetOutputScaling_w(uint32 ssrc, double left, double right) {
1786 return media_channel()->SetOutputScaling(ssrc, left, right);
1787}
1788
1789bool VoiceChannel::GetStats_w(VoiceMediaInfo* stats) {
1790 return media_channel()->GetStats(stats);
1791}
1792
1793bool VoiceChannel::SetChannelOptions(const AudioOptions& options) {
1794 AudioOptionsMessageData data(options);
1795 Send(MSG_SETCHANNELOPTIONS, &data);
1796 return data.result;
1797}
1798
1799bool VoiceChannel::SetChannelOptions_w(const AudioOptions& options) {
1800 return media_channel()->SetOptions(options);
1801}
1802
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001803bool VoiceChannel::SetRenderer_w(uint32 ssrc, AudioRenderer* renderer,
1804 bool is_local) {
1805 if (is_local)
1806 return media_channel()->SetLocalRenderer(ssrc, renderer);
1807
1808 return media_channel()->SetRemoteRenderer(ssrc, renderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809}
1810
1811void VoiceChannel::OnMessage(talk_base::Message *pmsg) {
1812 switch (pmsg->message_id) {
1813 case MSG_SETRINGBACKTONE: {
1814 SetRingbackToneMessageData* data =
1815 static_cast<SetRingbackToneMessageData*>(pmsg->pdata);
1816 data->result = SetRingbackTone_w(data->buf, data->len);
1817 break;
1818 }
1819 case MSG_PLAYRINGBACKTONE: {
1820 PlayRingbackToneMessageData* data =
1821 static_cast<PlayRingbackToneMessageData*>(pmsg->pdata);
1822 data->result = PlayRingbackTone_w(data->ssrc, data->play, data->loop);
1823 break;
1824 }
1825 case MSG_EARLYMEDIATIMEOUT:
1826 HandleEarlyMediaTimeout();
1827 break;
1828 case MSG_CANINSERTDTMF: {
1829 BoolMessageData* data =
1830 static_cast<BoolMessageData*>(pmsg->pdata);
1831 data->data() = CanInsertDtmf_w();
1832 break;
1833 }
1834 case MSG_INSERTDTMF: {
1835 DtmfMessageData* data =
1836 static_cast<DtmfMessageData*>(pmsg->pdata);
1837 data->result = InsertDtmf_w(data->ssrc, data->event, data->duration,
1838 data->flags);
1839 break;
1840 }
1841 case MSG_SCALEVOLUME: {
1842 ScaleVolumeMessageData* data =
1843 static_cast<ScaleVolumeMessageData*>(pmsg->pdata);
1844 data->result = SetOutputScaling_w(data->ssrc, data->left, data->right);
1845 break;
1846 }
1847 case MSG_GETSTATS: {
1848 VoiceStatsMessageData* data =
1849 static_cast<VoiceStatsMessageData*>(pmsg->pdata);
1850 data->result = GetStats_w(data->stats);
1851 break;
1852 }
1853 case MSG_CHANNEL_ERROR: {
1854 VoiceChannelErrorMessageData* data =
1855 static_cast<VoiceChannelErrorMessageData*>(pmsg->pdata);
1856 SignalMediaError(this, data->ssrc, data->error);
1857 delete data;
1858 break;
1859 }
1860 case MSG_SETCHANNELOPTIONS: {
1861 AudioOptionsMessageData* data =
1862 static_cast<AudioOptionsMessageData*>(pmsg->pdata);
1863 data->result = SetChannelOptions_w(data->options);
1864 break;
1865 }
1866 case MSG_SETRENDERER: {
1867 AudioRenderMessageData* data =
1868 static_cast<AudioRenderMessageData*>(pmsg->pdata);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001869 data->result = SetRenderer_w(data->ssrc, data->renderer, data->is_local);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001870 break;
1871 }
1872 default:
1873 BaseChannel::OnMessage(pmsg);
1874 break;
1875 }
1876}
1877
1878void VoiceChannel::OnConnectionMonitorUpdate(
1879 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
1880 SignalConnectionMonitor(this, infos);
1881}
1882
1883void VoiceChannel::OnMediaMonitorUpdate(
1884 VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) {
1885 ASSERT(media_channel == this->media_channel());
1886 SignalMediaMonitor(this, info);
1887}
1888
1889void VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor,
1890 const AudioInfo& info) {
1891 SignalAudioMonitor(this, info);
1892}
1893
1894void VoiceChannel::OnVoiceChannelError(
1895 uint32 ssrc, VoiceMediaChannel::Error err) {
1896 VoiceChannelErrorMessageData* data = new VoiceChannelErrorMessageData(
1897 ssrc, err);
1898 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
1899}
1900
1901void VoiceChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
1902 SrtpFilter::Error error) {
1903 switch (error) {
1904 case SrtpFilter::ERROR_FAIL:
1905 OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1906 VoiceMediaChannel::ERROR_REC_SRTP_ERROR :
1907 VoiceMediaChannel::ERROR_PLAY_SRTP_ERROR);
1908 break;
1909 case SrtpFilter::ERROR_AUTH:
1910 OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
1911 VoiceMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
1912 VoiceMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
1913 break;
1914 case SrtpFilter::ERROR_REPLAY:
1915 // Only receving channel should have this error.
1916 ASSERT(mode == SrtpFilter::UNPROTECT);
1917 OnVoiceChannelError(ssrc, VoiceMediaChannel::ERROR_PLAY_SRTP_REPLAY);
1918 break;
1919 default:
1920 break;
1921 }
1922}
1923
1924void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
1925 GetSupportedAudioCryptoSuites(ciphers);
1926}
1927
1928VideoChannel::VideoChannel(talk_base::Thread* thread,
1929 MediaEngineInterface* media_engine,
1930 VideoMediaChannel* media_channel,
1931 BaseSession* session,
1932 const std::string& content_name,
1933 bool rtcp,
1934 VoiceChannel* voice_channel)
1935 : BaseChannel(thread, media_engine, media_channel, session, content_name,
1936 rtcp),
1937 voice_channel_(voice_channel),
1938 renderer_(NULL),
1939 screencapture_factory_(CreateScreenCapturerFactory()),
1940 previous_we_(talk_base::WE_CLOSE) {
1941}
1942
1943bool VideoChannel::Init() {
1944 TransportChannel* rtcp_channel = rtcp() ? session()->CreateChannel(
1945 content_name(), "video_rtcp", ICE_CANDIDATE_COMPONENT_RTCP) : NULL;
1946 if (!BaseChannel::Init(session()->CreateChannel(
1947 content_name(), "video_rtp", ICE_CANDIDATE_COMPONENT_RTP),
1948 rtcp_channel)) {
1949 return false;
1950 }
1951 media_channel()->SignalMediaError.connect(
1952 this, &VideoChannel::OnVideoChannelError);
1953 srtp_filter()->SignalSrtpError.connect(
1954 this, &VideoChannel::OnSrtpError);
1955 return true;
1956}
1957
1958void VoiceChannel::SendLastMediaError() {
1959 uint32 ssrc;
1960 VoiceMediaChannel::Error error;
1961 media_channel()->GetLastMediaError(&ssrc, &error);
1962 SignalMediaError(this, ssrc, error);
1963}
1964
1965VideoChannel::~VideoChannel() {
1966 std::vector<uint32> screencast_ssrcs;
1967 ScreencastMap::iterator iter;
1968 while (!screencast_capturers_.empty()) {
1969 if (!RemoveScreencast(screencast_capturers_.begin()->first)) {
1970 LOG(LS_ERROR) << "Unable to delete screencast with ssrc "
1971 << screencast_capturers_.begin()->first;
1972 ASSERT(false);
1973 break;
1974 }
1975 }
1976
1977 StopMediaMonitor();
1978 // this can't be done in the base class, since it calls a virtual
1979 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00001980
1981 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001982}
1983
1984bool VideoChannel::SetRenderer(uint32 ssrc, VideoRenderer* renderer) {
1985 VideoRenderMessageData data(ssrc, renderer);
1986 Send(MSG_SETRENDERER, &data);
1987 return true;
1988}
1989
1990bool VideoChannel::ApplyViewRequest(const ViewRequest& request) {
1991 ViewRequestMessageData data(request);
1992 Send(MSG_HANDLEVIEWREQUEST, &data);
1993 return data.result;
1994}
1995
1996VideoCapturer* VideoChannel::AddScreencast(
1997 uint32 ssrc, const ScreencastId& id) {
1998 AddScreencastMessageData data(ssrc, id);
1999 Send(MSG_ADDSCREENCAST, &data);
2000 return data.result;
2001}
2002
2003bool VideoChannel::SetCapturer(uint32 ssrc, VideoCapturer* capturer) {
2004 SetCapturerMessageData data(ssrc, capturer);
2005 Send(MSG_SETCAPTURER, &data);
2006 return data.result;
2007}
2008
2009bool VideoChannel::RemoveScreencast(uint32 ssrc) {
2010 RemoveScreencastMessageData data(ssrc);
2011 Send(MSG_REMOVESCREENCAST, &data);
2012 return data.result;
2013}
2014
2015bool VideoChannel::IsScreencasting() {
2016 IsScreencastingMessageData data;
2017 Send(MSG_ISSCREENCASTING, &data);
2018 return data.result;
2019}
2020
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002021int VideoChannel::GetScreencastFps(uint32 ssrc) {
2022 ScreencastDetailsMessageData data(ssrc);
2023 Send(MSG_GETSCREENCASTDETAILS, &data);
2024 return data.fps;
2025}
2026
2027int VideoChannel::GetScreencastMaxPixels(uint32 ssrc) {
2028 ScreencastDetailsMessageData data(ssrc);
2029 Send(MSG_GETSCREENCASTDETAILS, &data);
2030 return data.screencast_max_pixels;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002031}
2032
2033bool VideoChannel::SendIntraFrame() {
2034 Send(MSG_SENDINTRAFRAME);
2035 return true;
2036}
2037
2038bool VideoChannel::RequestIntraFrame() {
2039 Send(MSG_REQUESTINTRAFRAME);
2040 return true;
2041}
2042
2043void VideoChannel::SetScreenCaptureFactory(
2044 ScreenCapturerFactory* screencapture_factory) {
2045 SetScreenCaptureFactoryMessageData data(screencapture_factory);
2046 Send(MSG_SETSCREENCASTFACTORY, &data);
2047}
2048
2049void VideoChannel::ChangeState() {
2050 // Render incoming data if we're the active call, and we have the local
2051 // content. We receive data on the default channel and multiplexed streams.
2052 bool recv = IsReadyToReceive();
2053 if (!media_channel()->SetRender(recv)) {
2054 LOG(LS_ERROR) << "Failed to SetRender on video channel";
2055 // TODO(gangji): Report error back to server.
2056 }
2057
2058 // Send outgoing data if we're the active call, we have the remote content,
2059 // and we have had some form of connectivity.
2060 bool send = IsReadyToSend();
2061 if (!media_channel()->SetSend(send)) {
2062 LOG(LS_ERROR) << "Failed to SetSend on video channel";
2063 // TODO(gangji): Report error back to server.
2064 }
2065
2066 LOG(LS_INFO) << "Changing video state, recv=" << recv << " send=" << send;
2067}
2068
2069bool VideoChannel::GetStats(VideoMediaInfo* stats) {
2070 VideoStatsMessageData data(stats);
2071 Send(MSG_GETSTATS, &data);
2072 return data.result;
2073}
2074
2075void VideoChannel::StartMediaMonitor(int cms) {
2076 media_monitor_.reset(new VideoMediaMonitor(media_channel(), worker_thread(),
2077 talk_base::Thread::Current()));
2078 media_monitor_->SignalUpdate.connect(
2079 this, &VideoChannel::OnMediaMonitorUpdate);
2080 media_monitor_->Start(cms);
2081}
2082
2083void VideoChannel::StopMediaMonitor() {
2084 if (media_monitor_) {
2085 media_monitor_->Stop();
2086 media_monitor_.reset();
2087 }
2088}
2089
2090const ContentInfo* VideoChannel::GetFirstContent(
2091 const SessionDescription* sdesc) {
2092 return GetFirstVideoContent(sdesc);
2093}
2094
2095bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
2096 ContentAction action) {
2097 ASSERT(worker_thread() == talk_base::Thread::Current());
2098 LOG(LS_INFO) << "Setting local video description";
2099
2100 const VideoContentDescription* video =
2101 static_cast<const VideoContentDescription*>(content);
2102 ASSERT(video != NULL);
2103 if (!video) return false;
2104
2105 bool ret = SetBaseLocalContent_w(content, action);
2106 // Set local video codecs (what we want to receive).
2107 if (action != CA_UPDATE || video->has_codecs()) {
2108 ret &= media_channel()->SetRecvCodecs(video->codecs());
2109 }
2110
2111 if (action != CA_UPDATE) {
2112 VideoOptions video_options;
2113 media_channel()->GetOptions(&video_options);
2114 video_options.buffered_mode_latency.Set(video->buffered_mode_latency());
2115
2116 if (!media_channel()->SetOptions(video_options)) {
2117 // Log an error on failure, but don't abort the call.
2118 LOG(LS_ERROR) << "Failed to set video channel options";
2119 }
2120 }
2121
2122 // If everything worked, see if we can start receiving.
2123 if (ret) {
2124 ChangeState();
2125 } else {
2126 LOG(LS_WARNING) << "Failed to set local video description";
2127 }
2128 return ret;
2129}
2130
2131bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
2132 ContentAction action) {
2133 ASSERT(worker_thread() == talk_base::Thread::Current());
2134 LOG(LS_INFO) << "Setting remote video description";
2135
2136 const VideoContentDescription* video =
2137 static_cast<const VideoContentDescription*>(content);
2138 ASSERT(video != NULL);
2139 if (!video) return false;
2140
2141 bool ret = true;
2142 // Set remote video codecs (what the other side wants to receive).
2143 if (action != CA_UPDATE || video->has_codecs()) {
2144 ret &= media_channel()->SetSendCodecs(video->codecs());
2145 }
2146
2147 ret &= SetBaseRemoteContent_w(content, action);
2148
2149 if (action != CA_UPDATE) {
2150 // Tweak our video processing settings, if needed.
2151 VideoOptions video_options;
2152 media_channel()->GetOptions(&video_options);
2153 video_options.conference_mode.Set(video->conference_mode());
2154 video_options.buffered_mode_latency.Set(video->buffered_mode_latency());
2155
2156 if (!media_channel()->SetOptions(video_options)) {
2157 // Log an error on failure, but don't abort the call.
2158 LOG(LS_ERROR) << "Failed to set video channel options";
2159 }
2160 }
2161
2162 // If everything worked, see if we can start sending.
2163 if (ret) {
2164 ChangeState();
2165 } else {
2166 LOG(LS_WARNING) << "Failed to set remote video description";
2167 }
2168 return ret;
2169}
2170
2171bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) {
2172 bool ret = true;
2173 // Set the send format for each of the local streams. If the view request
2174 // does not contain a local stream, set its send format to 0x0, which will
2175 // drop all frames.
2176 for (std::vector<StreamParams>::const_iterator it = local_streams().begin();
2177 it != local_streams().end(); ++it) {
2178 VideoFormat format(0, 0, 0, cricket::FOURCC_I420);
2179 StaticVideoViews::const_iterator view;
2180 for (view = request.static_video_views.begin();
2181 view != request.static_video_views.end(); ++view) {
2182 if (view->selector.Matches(*it)) {
2183 format.width = view->width;
2184 format.height = view->height;
2185 format.interval = cricket::VideoFormat::FpsToInterval(view->framerate);
2186 break;
2187 }
2188 }
2189
2190 ret &= media_channel()->SetSendStreamFormat(it->first_ssrc(), format);
2191 }
2192
2193 // Check if the view request has invalid streams.
2194 for (StaticVideoViews::const_iterator it = request.static_video_views.begin();
2195 it != request.static_video_views.end(); ++it) {
2196 if (!GetStream(local_streams(), it->selector, NULL)) {
2197 LOG(LS_WARNING) << "View request for ("
2198 << it->selector.ssrc << ", '"
2199 << it->selector.groupid << "', '"
2200 << it->selector.streamid << "'"
2201 << ") is not in the local streams.";
2202 }
2203 }
2204
2205 return ret;
2206}
2207
2208void VideoChannel::SetRenderer_w(uint32 ssrc, VideoRenderer* renderer) {
2209 media_channel()->SetRenderer(ssrc, renderer);
2210}
2211
2212VideoCapturer* VideoChannel::AddScreencast_w(
2213 uint32 ssrc, const ScreencastId& id) {
2214 if (screencast_capturers_.find(ssrc) != screencast_capturers_.end()) {
2215 return NULL;
2216 }
2217 VideoCapturer* screen_capturer =
2218 screencapture_factory_->CreateScreenCapturer(id);
2219 if (!screen_capturer) {
2220 return NULL;
2221 }
2222 screen_capturer->SignalStateChange.connect(this,
2223 &VideoChannel::OnStateChange);
2224 screencast_capturers_[ssrc] = screen_capturer;
2225 return screen_capturer;
2226}
2227
2228bool VideoChannel::SetCapturer_w(uint32 ssrc, VideoCapturer* capturer) {
2229 return media_channel()->SetCapturer(ssrc, capturer);
2230}
2231
2232bool VideoChannel::RemoveScreencast_w(uint32 ssrc) {
2233 ScreencastMap::iterator iter = screencast_capturers_.find(ssrc);
2234 if (iter == screencast_capturers_.end()) {
2235 return false;
2236 }
2237 // Clean up VideoCapturer.
2238 delete iter->second;
2239 screencast_capturers_.erase(iter);
2240 return true;
2241}
2242
2243bool VideoChannel::IsScreencasting_w() const {
2244 return !screencast_capturers_.empty();
2245}
2246
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002247void VideoChannel::ScreencastDetails_w(
2248 ScreencastDetailsMessageData* data) const {
2249 ScreencastMap::const_iterator iter = screencast_capturers_.find(data->ssrc);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002250 if (iter == screencast_capturers_.end()) {
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002251 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002252 }
2253 VideoCapturer* capturer = iter->second;
2254 const VideoFormat* video_format = capturer->GetCaptureFormat();
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002255 data->fps = VideoFormat::IntervalToFps(video_format->interval);
2256 data->screencast_max_pixels = capturer->screencast_max_pixels();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002257}
2258
2259void VideoChannel::SetScreenCaptureFactory_w(
2260 ScreenCapturerFactory* screencapture_factory) {
2261 if (screencapture_factory == NULL) {
2262 screencapture_factory_.reset(CreateScreenCapturerFactory());
2263 } else {
2264 screencapture_factory_.reset(screencapture_factory);
2265 }
2266}
2267
2268bool VideoChannel::GetStats_w(VideoMediaInfo* stats) {
2269 return media_channel()->GetStats(stats);
2270}
2271
2272void VideoChannel::OnScreencastWindowEvent_s(uint32 ssrc,
2273 talk_base::WindowEvent we) {
2274 ASSERT(signaling_thread() == talk_base::Thread::Current());
2275 SignalScreencastWindowEvent(ssrc, we);
2276}
2277
2278bool VideoChannel::SetChannelOptions(const VideoOptions &options) {
2279 VideoOptionsMessageData data(options);
2280 Send(MSG_SETCHANNELOPTIONS, &data);
2281 return data.result;
2282}
2283
2284bool VideoChannel::SetChannelOptions_w(const VideoOptions &options) {
2285 return media_channel()->SetOptions(options);
2286}
2287
2288void VideoChannel::OnMessage(talk_base::Message *pmsg) {
2289 switch (pmsg->message_id) {
2290 case MSG_SETRENDERER: {
2291 const VideoRenderMessageData* data =
2292 static_cast<VideoRenderMessageData*>(pmsg->pdata);
2293 SetRenderer_w(data->ssrc, data->renderer);
2294 break;
2295 }
2296 case MSG_ADDSCREENCAST: {
2297 AddScreencastMessageData* data =
2298 static_cast<AddScreencastMessageData*>(pmsg->pdata);
2299 data->result = AddScreencast_w(data->ssrc, data->window_id);
2300 break;
2301 }
2302 case MSG_SETCAPTURER: {
2303 SetCapturerMessageData* data =
2304 static_cast<SetCapturerMessageData*>(pmsg->pdata);
2305 data->result = SetCapturer_w(data->ssrc, data->capturer);
2306 break;
2307 }
2308 case MSG_REMOVESCREENCAST: {
2309 RemoveScreencastMessageData* data =
2310 static_cast<RemoveScreencastMessageData*>(pmsg->pdata);
2311 data->result = RemoveScreencast_w(data->ssrc);
2312 break;
2313 }
2314 case MSG_SCREENCASTWINDOWEVENT: {
2315 const ScreencastEventMessageData* data =
2316 static_cast<ScreencastEventMessageData*>(pmsg->pdata);
2317 OnScreencastWindowEvent_s(data->ssrc, data->event);
2318 delete data;
2319 break;
2320 }
2321 case MSG_ISSCREENCASTING: {
2322 IsScreencastingMessageData* data =
2323 static_cast<IsScreencastingMessageData*>(pmsg->pdata);
2324 data->result = IsScreencasting_w();
2325 break;
2326 }
wu@webrtc.orgcadf9042013-08-30 21:24:16 +00002327 case MSG_GETSCREENCASTDETAILS: {
2328 ScreencastDetailsMessageData* data =
2329 static_cast<ScreencastDetailsMessageData*>(pmsg->pdata);
2330 ScreencastDetails_w(data);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002331 break;
2332 }
2333 case MSG_SENDINTRAFRAME: {
2334 SendIntraFrame_w();
2335 break;
2336 }
2337 case MSG_REQUESTINTRAFRAME: {
2338 RequestIntraFrame_w();
2339 break;
2340 }
2341 case MSG_SETCHANNELOPTIONS: {
2342 VideoOptionsMessageData* data =
2343 static_cast<VideoOptionsMessageData*>(pmsg->pdata);
2344 data->result = SetChannelOptions_w(data->options);
2345 break;
2346 }
2347 case MSG_CHANNEL_ERROR: {
2348 const VideoChannelErrorMessageData* data =
2349 static_cast<VideoChannelErrorMessageData*>(pmsg->pdata);
2350 SignalMediaError(this, data->ssrc, data->error);
2351 delete data;
2352 break;
2353 }
2354 case MSG_HANDLEVIEWREQUEST: {
2355 ViewRequestMessageData* data =
2356 static_cast<ViewRequestMessageData*>(pmsg->pdata);
2357 data->result = ApplyViewRequest_w(data->request);
2358 break;
2359 }
2360 case MSG_SETSCREENCASTFACTORY: {
2361 SetScreenCaptureFactoryMessageData* data =
2362 static_cast<SetScreenCaptureFactoryMessageData*>(pmsg->pdata);
2363 SetScreenCaptureFactory_w(data->screencapture_factory);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00002364 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365 }
2366 case MSG_GETSTATS: {
2367 VideoStatsMessageData* data =
2368 static_cast<VideoStatsMessageData*>(pmsg->pdata);
2369 data->result = GetStats_w(data->stats);
2370 break;
2371 }
2372 default:
2373 BaseChannel::OnMessage(pmsg);
2374 break;
2375 }
2376}
2377
2378void VideoChannel::OnConnectionMonitorUpdate(
2379 SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos) {
2380 SignalConnectionMonitor(this, infos);
2381}
2382
2383// TODO(pthatcher): Look into removing duplicate code between
2384// audio, video, and data, perhaps by using templates.
2385void VideoChannel::OnMediaMonitorUpdate(
2386 VideoMediaChannel* media_channel, const VideoMediaInfo &info) {
2387 ASSERT(media_channel == this->media_channel());
2388 SignalMediaMonitor(this, info);
2389}
2390
2391void VideoChannel::OnScreencastWindowEvent(uint32 ssrc,
2392 talk_base::WindowEvent event) {
2393 ScreencastEventMessageData* pdata =
2394 new ScreencastEventMessageData(ssrc, event);
2395 signaling_thread()->Post(this, MSG_SCREENCASTWINDOWEVENT, pdata);
2396}
2397
2398void VideoChannel::OnStateChange(VideoCapturer* capturer, CaptureState ev) {
2399 // Map capturer events to window events. In the future we may want to simply
2400 // pass these events up directly.
2401 talk_base::WindowEvent we;
2402 if (ev == CS_STOPPED) {
2403 we = talk_base::WE_CLOSE;
2404 } else if (ev == CS_PAUSED) {
2405 we = talk_base::WE_MINIMIZE;
2406 } else if (ev == CS_RUNNING && previous_we_ == talk_base::WE_MINIMIZE) {
2407 we = talk_base::WE_RESTORE;
2408 } else {
2409 return;
2410 }
2411 previous_we_ = we;
2412
2413 uint32 ssrc = 0;
2414 if (!GetLocalSsrc(capturer, &ssrc)) {
2415 return;
2416 }
2417 ScreencastEventMessageData* pdata =
2418 new ScreencastEventMessageData(ssrc, we);
2419 signaling_thread()->Post(this, MSG_SCREENCASTWINDOWEVENT, pdata);
2420}
2421
2422bool VideoChannel::GetLocalSsrc(const VideoCapturer* capturer, uint32* ssrc) {
2423 *ssrc = 0;
2424 for (ScreencastMap::iterator iter = screencast_capturers_.begin();
2425 iter != screencast_capturers_.end(); ++iter) {
2426 if (iter->second == capturer) {
2427 *ssrc = iter->first;
2428 return true;
2429 }
2430 }
2431 return false;
2432}
2433
2434void VideoChannel::OnVideoChannelError(uint32 ssrc,
2435 VideoMediaChannel::Error error) {
2436 VideoChannelErrorMessageData* data = new VideoChannelErrorMessageData(
2437 ssrc, error);
2438 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
2439}
2440
2441void VideoChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
2442 SrtpFilter::Error error) {
2443 switch (error) {
2444 case SrtpFilter::ERROR_FAIL:
2445 OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2446 VideoMediaChannel::ERROR_REC_SRTP_ERROR :
2447 VideoMediaChannel::ERROR_PLAY_SRTP_ERROR);
2448 break;
2449 case SrtpFilter::ERROR_AUTH:
2450 OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2451 VideoMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
2452 VideoMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
2453 break;
2454 case SrtpFilter::ERROR_REPLAY:
2455 // Only receving channel should have this error.
2456 ASSERT(mode == SrtpFilter::UNPROTECT);
2457 // TODO(gangji): Turn on the signaling of replay error once we have
2458 // switched to the new mechanism for doing video retransmissions.
2459 // OnVideoChannelError(ssrc, VideoMediaChannel::ERROR_PLAY_SRTP_REPLAY);
2460 break;
2461 default:
2462 break;
2463 }
2464}
2465
2466
2467void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
2468 GetSupportedVideoCryptoSuites(ciphers);
2469}
2470
2471DataChannel::DataChannel(talk_base::Thread* thread,
2472 DataMediaChannel* media_channel,
2473 BaseSession* session,
2474 const std::string& content_name,
2475 bool rtcp)
2476 // MediaEngine is NULL
2477 : BaseChannel(thread, NULL, media_channel, session, content_name, rtcp),
2478 data_channel_type_(cricket::DCT_NONE) {
2479}
2480
2481DataChannel::~DataChannel() {
2482 StopMediaMonitor();
2483 // this can't be done in the base class, since it calls a virtual
2484 DisableMedia_w();
wu@webrtc.org78187522013-10-07 23:32:02 +00002485
2486 Deinit();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487}
2488
2489bool DataChannel::Init() {
2490 TransportChannel* rtcp_channel = rtcp() ? session()->CreateChannel(
2491 content_name(), "data_rtcp", ICE_CANDIDATE_COMPONENT_RTCP) : NULL;
2492 if (!BaseChannel::Init(session()->CreateChannel(
2493 content_name(), "data_rtp", ICE_CANDIDATE_COMPONENT_RTP),
2494 rtcp_channel)) {
2495 return false;
2496 }
2497 media_channel()->SignalDataReceived.connect(
2498 this, &DataChannel::OnDataReceived);
2499 media_channel()->SignalMediaError.connect(
2500 this, &DataChannel::OnDataChannelError);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00002501 media_channel()->SignalReadyToSend.connect(
2502 this, &DataChannel::OnDataChannelReadyToSend);
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002503 media_channel()->SignalNewStreamReceived.connect(
2504 this, &DataChannel::OnDataChannelNewStreamReceived);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002505 srtp_filter()->SignalSrtpError.connect(
2506 this, &DataChannel::OnSrtpError);
2507 return true;
2508}
2509
2510bool DataChannel::SendData(const SendDataParams& params,
2511 const talk_base::Buffer& payload,
2512 SendDataResult* result) {
2513 SendDataMessageData message_data(params, &payload, result);
2514 Send(MSG_SENDDATA, &message_data);
2515 return message_data.succeeded;
2516}
2517
2518const ContentInfo* DataChannel::GetFirstContent(
2519 const SessionDescription* sdesc) {
2520 return GetFirstDataContent(sdesc);
2521}
2522
2523
2524static bool IsRtpPacket(const talk_base::Buffer* packet) {
2525 int version;
2526 if (!GetRtpVersion(packet->data(), packet->length(), &version)) {
2527 return false;
2528 }
2529
2530 return version == 2;
2531}
2532
2533bool DataChannel::WantsPacket(bool rtcp, talk_base::Buffer* packet) {
2534 if (data_channel_type_ == DCT_SCTP) {
2535 // TODO(pthatcher): Do this in a more robust way by checking for
2536 // SCTP or DTLS.
2537 return !IsRtpPacket(packet);
2538 } else if (data_channel_type_ == DCT_RTP) {
2539 return BaseChannel::WantsPacket(rtcp, packet);
2540 }
2541 return false;
2542}
2543
2544// Sets the maximum bandwidth. Anything over this will be dropped.
2545bool DataChannel::SetMaxSendBandwidth_w(int max_bps) {
2546 LOG(LS_INFO) << "DataChannel: Setting max bandwidth to " << max_bps;
2547 return media_channel()->SetSendBandwidth(false, max_bps);
2548}
2549
2550bool DataChannel::SetDataChannelType(DataChannelType new_data_channel_type) {
2551 // It hasn't been set before, so set it now.
2552 if (data_channel_type_ == DCT_NONE) {
2553 data_channel_type_ = new_data_channel_type;
2554 return true;
2555 }
2556
2557 // It's been set before, but doesn't match. That's bad.
2558 if (data_channel_type_ != new_data_channel_type) {
2559 LOG(LS_WARNING) << "Data channel type mismatch."
2560 << " Expected " << data_channel_type_
2561 << " Got " << new_data_channel_type;
2562 return false;
2563 }
2564
2565 // It's hasn't changed. Nothing to do.
2566 return true;
2567}
2568
2569bool DataChannel::SetDataChannelTypeFromContent(
2570 const DataContentDescription* content) {
2571 bool is_sctp = ((content->protocol() == kMediaProtocolSctp) ||
2572 (content->protocol() == kMediaProtocolDtlsSctp));
2573 DataChannelType data_channel_type = is_sctp ? DCT_SCTP : DCT_RTP;
2574 return SetDataChannelType(data_channel_type);
2575}
2576
2577bool DataChannel::SetLocalContent_w(const MediaContentDescription* content,
2578 ContentAction action) {
2579 ASSERT(worker_thread() == talk_base::Thread::Current());
2580 LOG(LS_INFO) << "Setting local data description";
2581
2582 const DataContentDescription* data =
2583 static_cast<const DataContentDescription*>(content);
2584 ASSERT(data != NULL);
2585 if (!data) return false;
2586
2587 bool ret = false;
2588 if (!SetDataChannelTypeFromContent(data)) {
2589 return false;
2590 }
2591
2592 if (data_channel_type_ == DCT_SCTP) {
2593 // SCTP data channels don't need the rest of the stuff.
2594 ret = UpdateLocalStreams_w(data->streams(), action);
2595 if (ret) {
2596 set_local_content_direction(content->direction());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002597 // As in SetRemoteContent_w, make sure we set the local SCTP port
2598 // number as specified in our DataContentDescription.
2599 ret = media_channel()->SetRecvCodecs(data->codecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002600 }
2601 } else {
2602 ret = SetBaseLocalContent_w(content, action);
2603
2604 if (action != CA_UPDATE || data->has_codecs()) {
2605 ret &= media_channel()->SetRecvCodecs(data->codecs());
2606 }
2607 }
2608
2609 // If everything worked, see if we can start receiving.
2610 if (ret) {
2611 ChangeState();
2612 } else {
2613 LOG(LS_WARNING) << "Failed to set local data description";
2614 }
2615 return ret;
2616}
2617
2618bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content,
2619 ContentAction action) {
2620 ASSERT(worker_thread() == talk_base::Thread::Current());
2621
2622 const DataContentDescription* data =
2623 static_cast<const DataContentDescription*>(content);
2624 ASSERT(data != NULL);
2625 if (!data) return false;
2626
2627 bool ret = true;
2628 if (!SetDataChannelTypeFromContent(data)) {
2629 return false;
2630 }
2631
2632 if (data_channel_type_ == DCT_SCTP) {
2633 LOG(LS_INFO) << "Setting SCTP remote data description";
2634 // SCTP data channels don't need the rest of the stuff.
2635 ret = UpdateRemoteStreams_w(content->streams(), action);
2636 if (ret) {
2637 set_remote_content_direction(content->direction());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002638 // We send the SCTP port number (not to be confused with the underlying
2639 // UDP port number) as a codec parameter. Make sure it gets there.
2640 ret = media_channel()->SetSendCodecs(data->codecs());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002641 }
2642 } else {
2643 // If the remote data doesn't have codecs and isn't an update, it
2644 // must be empty, so ignore it.
2645 if (action != CA_UPDATE && !data->has_codecs()) {
2646 return true;
2647 }
2648 LOG(LS_INFO) << "Setting remote data description";
2649
2650 // Set remote video codecs (what the other side wants to receive).
2651 if (action != CA_UPDATE || data->has_codecs()) {
2652 ret &= media_channel()->SetSendCodecs(data->codecs());
2653 }
2654
2655 if (ret) {
2656 ret &= SetBaseRemoteContent_w(content, action);
2657 }
2658
2659 if (action != CA_UPDATE) {
2660 int bandwidth_bps = data->bandwidth();
2661 bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth);
2662 ret &= media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps);
2663 }
2664 }
2665
2666 // If everything worked, see if we can start sending.
2667 if (ret) {
2668 ChangeState();
2669 } else {
2670 LOG(LS_WARNING) << "Failed to set remote data description";
2671 }
2672 return ret;
2673}
2674
2675void DataChannel::ChangeState() {
2676 // Render incoming data if we're the active call, and we have the local
2677 // content. We receive data on the default channel and multiplexed streams.
2678 bool recv = IsReadyToReceive();
2679 if (!media_channel()->SetReceive(recv)) {
2680 LOG(LS_ERROR) << "Failed to SetReceive on data channel";
2681 }
2682
2683 // Send outgoing data if we're the active call, we have the remote content,
2684 // and we have had some form of connectivity.
2685 bool send = IsReadyToSend();
2686 if (!media_channel()->SetSend(send)) {
2687 LOG(LS_ERROR) << "Failed to SetSend on data channel";
2688 }
2689
2690 // Post to trigger SignalReadyToSendData.
2691 signaling_thread()->Post(this, MSG_READYTOSENDDATA,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00002692 new DataChannelReadyToSendMessageData(send));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693
2694 LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
2695}
2696
2697void DataChannel::OnMessage(talk_base::Message *pmsg) {
2698 switch (pmsg->message_id) {
2699 case MSG_READYTOSENDDATA: {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00002700 DataChannelReadyToSendMessageData* data =
2701 static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002702 SignalReadyToSendData(data->data());
2703 delete data;
2704 break;
2705 }
2706 case MSG_SENDDATA: {
2707 SendDataMessageData* msg =
2708 static_cast<SendDataMessageData*>(pmsg->pdata);
2709 msg->succeeded = media_channel()->SendData(
2710 msg->params, *(msg->payload), msg->result);
2711 break;
2712 }
2713 case MSG_DATARECEIVED: {
2714 DataReceivedMessageData* data =
2715 static_cast<DataReceivedMessageData*>(pmsg->pdata);
2716 SignalDataReceived(this, data->params, data->payload);
2717 delete data;
2718 break;
2719 }
2720 case MSG_CHANNEL_ERROR: {
2721 const DataChannelErrorMessageData* data =
2722 static_cast<DataChannelErrorMessageData*>(pmsg->pdata);
2723 SignalMediaError(this, data->ssrc, data->error);
2724 delete data;
2725 break;
2726 }
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002727 case MSG_NEWSTREAMRECEIVED: {
2728 DataChannelNewStreamReceivedMessageData* data =
2729 static_cast<DataChannelNewStreamReceivedMessageData*>(pmsg->pdata);
2730 SignalNewStreamReceived(data->label, data->init);
2731 delete data;
2732 break;
2733 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002734 default:
2735 BaseChannel::OnMessage(pmsg);
2736 break;
2737 }
2738}
2739
2740void DataChannel::OnConnectionMonitorUpdate(
2741 SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
2742 SignalConnectionMonitor(this, infos);
2743}
2744
2745void DataChannel::StartMediaMonitor(int cms) {
2746 media_monitor_.reset(new DataMediaMonitor(media_channel(), worker_thread(),
2747 talk_base::Thread::Current()));
2748 media_monitor_->SignalUpdate.connect(
2749 this, &DataChannel::OnMediaMonitorUpdate);
2750 media_monitor_->Start(cms);
2751}
2752
2753void DataChannel::StopMediaMonitor() {
2754 if (media_monitor_) {
2755 media_monitor_->Stop();
2756 media_monitor_->SignalUpdate.disconnect(this);
2757 media_monitor_.reset();
2758 }
2759}
2760
2761void DataChannel::OnMediaMonitorUpdate(
2762 DataMediaChannel* media_channel, const DataMediaInfo& info) {
2763 ASSERT(media_channel == this->media_channel());
2764 SignalMediaMonitor(this, info);
2765}
2766
2767void DataChannel::OnDataReceived(
2768 const ReceiveDataParams& params, const char* data, size_t len) {
2769 DataReceivedMessageData* msg = new DataReceivedMessageData(
2770 params, data, len);
2771 signaling_thread()->Post(this, MSG_DATARECEIVED, msg);
2772}
2773
2774void DataChannel::OnDataChannelError(
2775 uint32 ssrc, DataMediaChannel::Error err) {
2776 DataChannelErrorMessageData* data = new DataChannelErrorMessageData(
2777 ssrc, err);
2778 signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
2779}
2780
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00002781void DataChannel::OnDataChannelReadyToSend(bool writable) {
2782 // This is usded for congestion control to indicate that the stream is ready
2783 // to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
2784 // that the transport channel is ready.
2785 signaling_thread()->Post(this, MSG_READYTOSENDDATA,
2786 new DataChannelReadyToSendMessageData(writable));
2787}
2788
wu@webrtc.org1d1ffc92013-10-16 18:12:02 +00002789void DataChannel::OnDataChannelNewStreamReceived(
2790 const std::string& label, const webrtc::DataChannelInit& init) {
2791 signaling_thread()->Post(
2792 this,
2793 MSG_NEWSTREAMRECEIVED,
2794 new DataChannelNewStreamReceivedMessageData(label, init));
2795}
2796
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002797void DataChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
2798 SrtpFilter::Error error) {
2799 switch (error) {
2800 case SrtpFilter::ERROR_FAIL:
2801 OnDataChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2802 DataMediaChannel::ERROR_SEND_SRTP_ERROR :
2803 DataMediaChannel::ERROR_RECV_SRTP_ERROR);
2804 break;
2805 case SrtpFilter::ERROR_AUTH:
2806 OnDataChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
2807 DataMediaChannel::ERROR_SEND_SRTP_AUTH_FAILED :
2808 DataMediaChannel::ERROR_RECV_SRTP_AUTH_FAILED);
2809 break;
2810 case SrtpFilter::ERROR_REPLAY:
2811 // Only receving channel should have this error.
2812 ASSERT(mode == SrtpFilter::UNPROTECT);
2813 OnDataChannelError(ssrc, DataMediaChannel::ERROR_RECV_SRTP_REPLAY);
2814 break;
2815 default:
2816 break;
2817 }
2818}
2819
2820void DataChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
2821 GetSupportedDataCryptoSuites(ciphers);
2822}
2823
2824bool DataChannel::ShouldSetupDtlsSrtp() const {
2825 return (data_channel_type_ == DCT_RTP);
2826}
2827
2828} // namespace cricket