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