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