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