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