OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 | 163 |
164 template <class Codec, class Options> | 164 template <class Codec, class Options> |
165 void RtpSendParametersFromMediaDescription( | 165 void RtpSendParametersFromMediaDescription( |
166 const MediaContentDescriptionImpl<Codec>* desc, | 166 const MediaContentDescriptionImpl<Codec>* desc, |
167 RtpSendParameters<Codec, Options>* send_params) { | 167 RtpSendParameters<Codec, Options>* send_params) { |
168 RtpParametersFromMediaDescription(desc, send_params); | 168 RtpParametersFromMediaDescription(desc, send_params); |
169 send_params->max_bandwidth_bps = desc->bandwidth(); | 169 send_params->max_bandwidth_bps = desc->bandwidth(); |
170 } | 170 } |
171 | 171 |
172 BaseChannel::BaseChannel(rtc::Thread* thread, | 172 BaseChannel::BaseChannel(rtc::Thread* thread, |
173 MediaChannel* media_channel, BaseSession* session, | 173 MediaChannel* media_channel, |
174 const std::string& content_name, bool rtcp) | 174 TransportController* transport_controller, |
| 175 const std::string& content_name, |
| 176 bool rtcp) |
175 : worker_thread_(thread), | 177 : worker_thread_(thread), |
176 session_(session), | 178 transport_controller_(transport_controller), |
177 media_channel_(media_channel), | 179 media_channel_(media_channel), |
178 content_name_(content_name), | 180 content_name_(content_name), |
179 rtcp_(rtcp), | 181 rtcp_transport_enabled_(rtcp), |
180 transport_channel_(NULL), | 182 transport_channel_(nullptr), |
181 rtcp_transport_channel_(NULL), | 183 rtcp_transport_channel_(nullptr), |
182 enabled_(false), | 184 enabled_(false), |
183 writable_(false), | 185 writable_(false), |
184 rtp_ready_to_send_(false), | 186 rtp_ready_to_send_(false), |
185 rtcp_ready_to_send_(false), | 187 rtcp_ready_to_send_(false), |
186 was_ever_writable_(false), | 188 was_ever_writable_(false), |
187 local_content_direction_(MD_INACTIVE), | 189 local_content_direction_(MD_INACTIVE), |
188 remote_content_direction_(MD_INACTIVE), | 190 remote_content_direction_(MD_INACTIVE), |
189 has_received_packet_(false), | 191 has_received_packet_(false), |
190 dtls_keyed_(false), | 192 dtls_keyed_(false), |
191 secure_required_(false), | 193 secure_required_(false), |
192 rtp_abs_sendtime_extn_id_(-1) { | 194 rtp_abs_sendtime_extn_id_(-1) { |
193 ASSERT(worker_thread_ == rtc::Thread::Current()); | 195 ASSERT(worker_thread_ == rtc::Thread::Current()); |
194 LOG(LS_INFO) << "Created channel for " << content_name; | 196 LOG(LS_INFO) << "Created channel for " << content_name; |
195 } | 197 } |
196 | 198 |
197 BaseChannel::~BaseChannel() { | 199 BaseChannel::~BaseChannel() { |
198 ASSERT(worker_thread_ == rtc::Thread::Current()); | 200 ASSERT(worker_thread_ == rtc::Thread::Current()); |
199 Deinit(); | 201 Deinit(); |
200 StopConnectionMonitor(); | 202 StopConnectionMonitor(); |
201 FlushRtcpMessages(); // Send any outstanding RTCP packets. | 203 FlushRtcpMessages(); // Send any outstanding RTCP packets. |
202 worker_thread_->Clear(this); // eats any outstanding messages or packets | 204 worker_thread_->Clear(this); // eats any outstanding messages or packets |
203 // We must destroy the media channel before the transport channel, otherwise | 205 // We must destroy the media channel before the transport channel, otherwise |
204 // the media channel may try to send on the dead transport channel. NULLing | 206 // the media channel may try to send on the dead transport channel. NULLing |
205 // is not an effective strategy since the sends will come on another thread. | 207 // is not an effective strategy since the sends will come on another thread. |
206 delete media_channel_; | 208 delete media_channel_; |
207 set_transport_channel(nullptr); | 209 // Note that we don't just call set_transport_channel(nullptr) because that |
208 set_rtcp_transport_channel(nullptr); | 210 // would call a pure virtual method which we can't do from a destructor. |
| 211 if (transport_channel_) { |
| 212 DisconnectFromTransportChannel(transport_channel_); |
| 213 transport_controller_->DestroyTransportChannel_w( |
| 214 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); |
| 215 } |
| 216 if (rtcp_transport_channel_) { |
| 217 DisconnectFromTransportChannel(rtcp_transport_channel_); |
| 218 transport_controller_->DestroyTransportChannel_w( |
| 219 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
| 220 } |
209 LOG(LS_INFO) << "Destroyed channel"; | 221 LOG(LS_INFO) << "Destroyed channel"; |
210 } | 222 } |
211 | 223 |
212 bool BaseChannel::Init() { | 224 bool BaseChannel::Init() { |
213 if (!SetTransportChannels(session(), rtcp())) { | 225 if (!SetTransport(content_name())) { |
214 return false; | 226 return false; |
215 } | 227 } |
216 | 228 |
217 if (!SetDtlsSrtpCiphers(transport_channel(), false)) { | 229 if (!SetDtlsSrtpCiphers(transport_channel(), false)) { |
218 return false; | 230 return false; |
219 } | 231 } |
220 if (rtcp() && !SetDtlsSrtpCiphers(rtcp_transport_channel(), true)) { | 232 if (rtcp_transport_enabled() && |
| 233 !SetDtlsSrtpCiphers(rtcp_transport_channel(), true)) { |
221 return false; | 234 return false; |
222 } | 235 } |
223 | 236 |
224 // Both RTP and RTCP channels are set, we can call SetInterface on | 237 // Both RTP and RTCP channels are set, we can call SetInterface on |
225 // media channel and it can set network options. | 238 // media channel and it can set network options. |
226 media_channel_->SetInterface(this); | 239 media_channel_->SetInterface(this); |
227 return true; | 240 return true; |
228 } | 241 } |
229 | 242 |
230 void BaseChannel::Deinit() { | 243 void BaseChannel::Deinit() { |
231 media_channel_->SetInterface(NULL); | 244 media_channel_->SetInterface(NULL); |
232 } | 245 } |
233 | 246 |
234 bool BaseChannel::SetTransportChannels(BaseSession* session, bool rtcp) { | 247 bool BaseChannel::SetTransport(const std::string& transport_name) { |
235 return worker_thread_->Invoke<bool>(Bind( | 248 return worker_thread_->Invoke<bool>( |
236 &BaseChannel::SetTransportChannels_w, this, session, rtcp)); | 249 Bind(&BaseChannel::SetTransport_w, this, transport_name)); |
237 } | 250 } |
238 | 251 |
239 bool BaseChannel::SetTransportChannels_w(BaseSession* session, bool rtcp) { | 252 bool BaseChannel::SetTransport_w(const std::string& transport_name) { |
240 ASSERT(worker_thread_ == rtc::Thread::Current()); | 253 ASSERT(worker_thread_ == rtc::Thread::Current()); |
241 | 254 |
242 set_transport_channel(session->CreateChannel( | 255 if (transport_name == transport_name_) { |
243 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP)); | 256 // Nothing to do if transport name isn't changing |
| 257 return true; |
| 258 } |
| 259 |
| 260 set_transport_channel(transport_controller_->CreateTransportChannel_w( |
| 261 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); |
244 if (!transport_channel()) { | 262 if (!transport_channel()) { |
245 return false; | 263 return false; |
246 } | 264 } |
247 if (rtcp) { | 265 if (rtcp_transport_enabled()) { |
248 set_rtcp_transport_channel(session->CreateChannel( | 266 LOG(LS_INFO) << "Create RTCP TransportChannel for " << content_name() |
249 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP)); | 267 << " on " << transport_name << " transport "; |
| 268 set_rtcp_transport_channel(transport_controller_->CreateTransportChannel_w( |
| 269 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP)); |
250 if (!rtcp_transport_channel()) { | 270 if (!rtcp_transport_channel()) { |
251 return false; | 271 return false; |
252 } | 272 } |
253 } else { | |
254 set_rtcp_transport_channel(nullptr); | |
255 } | 273 } |
256 | 274 |
| 275 transport_name_ = transport_name; |
257 return true; | 276 return true; |
258 } | 277 } |
259 | 278 |
260 void BaseChannel::set_transport_channel(TransportChannel* new_tc) { | 279 void BaseChannel::set_transport_channel(TransportChannel* new_tc) { |
261 ASSERT(worker_thread_ == rtc::Thread::Current()); | 280 ASSERT(worker_thread_ == rtc::Thread::Current()); |
262 | 281 |
263 TransportChannel* old_tc = transport_channel_; | 282 TransportChannel* old_tc = transport_channel_; |
264 | 283 if (!old_tc && !new_tc) { |
265 if (old_tc == new_tc) { | 284 // Nothing to do |
266 return; | 285 return; |
267 } | 286 } |
| 287 ASSERT(old_tc != new_tc); |
| 288 |
268 if (old_tc) { | 289 if (old_tc) { |
269 DisconnectFromTransportChannel(old_tc); | 290 DisconnectFromTransportChannel(old_tc); |
270 session()->DestroyChannel( | 291 transport_controller_->DestroyTransportChannel_w( |
271 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP); | 292 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); |
272 } | 293 } |
273 | 294 |
274 transport_channel_ = new_tc; | 295 transport_channel_ = new_tc; |
275 | 296 |
276 if (new_tc) { | 297 if (new_tc) { |
277 ConnectToTransportChannel(new_tc); | 298 ConnectToTransportChannel(new_tc); |
| 299 for (const auto& pair : socket_options_) { |
| 300 new_tc->SetOption(pair.first, pair.second); |
| 301 } |
278 } | 302 } |
| 303 |
| 304 // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| 305 // setting new channel |
| 306 UpdateWritableState_w(); |
| 307 SetReadyToSend(false, new_tc && new_tc->writable()); |
279 } | 308 } |
280 | 309 |
281 void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { | 310 void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { |
282 ASSERT(worker_thread_ == rtc::Thread::Current()); | 311 ASSERT(worker_thread_ == rtc::Thread::Current()); |
283 | 312 |
284 TransportChannel* old_tc = rtcp_transport_channel_; | 313 TransportChannel* old_tc = rtcp_transport_channel_; |
285 | 314 if (!old_tc && !new_tc) { |
286 if (old_tc == new_tc) { | 315 // Nothing to do |
287 return; | 316 return; |
288 } | 317 } |
| 318 ASSERT(old_tc != new_tc); |
| 319 |
289 if (old_tc) { | 320 if (old_tc) { |
290 DisconnectFromTransportChannel(old_tc); | 321 DisconnectFromTransportChannel(old_tc); |
291 session()->DestroyChannel( | 322 transport_controller_->DestroyTransportChannel_w( |
292 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP); | 323 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
293 } | 324 } |
294 | 325 |
295 rtcp_transport_channel_ = new_tc; | 326 rtcp_transport_channel_ = new_tc; |
296 | 327 |
297 if (new_tc) { | 328 if (new_tc) { |
298 ConnectToTransportChannel(new_tc); | 329 ConnectToTransportChannel(new_tc); |
| 330 for (const auto& pair : rtcp_socket_options_) { |
| 331 new_tc->SetOption(pair.first, pair.second); |
| 332 } |
299 } | 333 } |
| 334 |
| 335 // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| 336 // setting new channel |
| 337 UpdateWritableState_w(); |
| 338 SetReadyToSend(true, new_tc && new_tc->writable()); |
300 } | 339 } |
301 | 340 |
302 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { | 341 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
303 ASSERT(worker_thread_ == rtc::Thread::Current()); | 342 ASSERT(worker_thread_ == rtc::Thread::Current()); |
304 | 343 |
305 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 344 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
306 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); | 345 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
307 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | 346 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
308 } | 347 } |
309 | 348 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 rtc::DiffServCodePoint dscp) { | 439 rtc::DiffServCodePoint dscp) { |
401 return SendPacket(true, packet, dscp); | 440 return SendPacket(true, packet, dscp); |
402 } | 441 } |
403 | 442 |
404 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, | 443 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, |
405 int value) { | 444 int value) { |
406 TransportChannel* channel = NULL; | 445 TransportChannel* channel = NULL; |
407 switch (type) { | 446 switch (type) { |
408 case ST_RTP: | 447 case ST_RTP: |
409 channel = transport_channel_; | 448 channel = transport_channel_; |
| 449 socket_options_.push_back( |
| 450 std::pair<rtc::Socket::Option, int>(opt, value)); |
410 break; | 451 break; |
411 case ST_RTCP: | 452 case ST_RTCP: |
412 channel = rtcp_transport_channel_; | 453 channel = rtcp_transport_channel_; |
| 454 rtcp_socket_options_.push_back( |
| 455 std::pair<rtc::Socket::Option, int>(opt, value)); |
413 break; | 456 break; |
414 } | 457 } |
415 return channel ? channel->SetOption(opt, value) : -1; | 458 return channel ? channel->SetOption(opt, value) : -1; |
416 } | 459 } |
417 | 460 |
418 void BaseChannel::OnWritableState(TransportChannel* channel) { | 461 void BaseChannel::OnWritableState(TransportChannel* channel) { |
419 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 462 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
420 if (transport_channel_->writable() | 463 UpdateWritableState_w(); |
421 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { | |
422 ChannelWritable_w(); | |
423 } else { | |
424 ChannelNotWritable_w(); | |
425 } | |
426 } | 464 } |
427 | 465 |
428 void BaseChannel::OnChannelRead(TransportChannel* channel, | 466 void BaseChannel::OnChannelRead(TransportChannel* channel, |
429 const char* data, size_t len, | 467 const char* data, size_t len, |
430 const rtc::PacketTime& packet_time, | 468 const rtc::PacketTime& packet_time, |
431 int flags) { | 469 int flags) { |
432 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine | 470 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine |
433 ASSERT(worker_thread_ == rtc::Thread::Current()); | 471 ASSERT(worker_thread_ == rtc::Thread::Current()); |
434 | 472 |
435 // When using RTCP multiplexing we might get RTCP packets on the RTP | 473 // When using RTCP multiplexing we might get RTCP packets on the RTP |
436 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. | 474 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. |
437 bool rtcp = PacketIsRtcp(channel, data, len); | 475 bool rtcp = PacketIsRtcp(channel, data, len); |
438 rtc::Buffer packet(data, len); | 476 rtc::Buffer packet(data, len); |
439 HandlePacket(rtcp, &packet, packet_time); | 477 HandlePacket(rtcp, &packet, packet_time); |
440 } | 478 } |
441 | 479 |
442 void BaseChannel::OnReadyToSend(TransportChannel* channel) { | 480 void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
443 SetReadyToSend(channel, true); | 481 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| 482 SetReadyToSend(channel == rtcp_transport_channel_, true); |
444 } | 483 } |
445 | 484 |
446 void BaseChannel::SetReadyToSend(TransportChannel* channel, bool ready) { | 485 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
447 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 486 if (rtcp) { |
448 if (channel == transport_channel_) { | 487 rtcp_ready_to_send_ = ready; |
| 488 } else { |
449 rtp_ready_to_send_ = ready; | 489 rtp_ready_to_send_ = ready; |
450 } | 490 } |
451 if (channel == rtcp_transport_channel_) { | |
452 rtcp_ready_to_send_ = ready; | |
453 } | |
454 | 491 |
455 if (!ready) { | 492 if (rtp_ready_to_send_ && |
| 493 // In the case of rtcp mux |rtcp_transport_channel_| will be null. |
| 494 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { |
| 495 // Notify the MediaChannel when both rtp and rtcp channel can send. |
| 496 media_channel_->OnReadyToSend(true); |
| 497 } else { |
456 // Notify the MediaChannel when either rtp or rtcp channel can't send. | 498 // Notify the MediaChannel when either rtp or rtcp channel can't send. |
457 media_channel_->OnReadyToSend(false); | 499 media_channel_->OnReadyToSend(false); |
458 } else if (rtp_ready_to_send_ && | |
459 // In the case of rtcp mux |rtcp_transport_channel_| will be null. | |
460 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { | |
461 // Notify the MediaChannel when both rtp and rtcp channel can send. | |
462 media_channel_->OnReadyToSend(true); | |
463 } | 500 } |
464 } | 501 } |
465 | 502 |
466 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, | 503 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, |
467 const char* data, size_t len) { | 504 const char* data, size_t len) { |
468 return (channel == rtcp_transport_channel_ || | 505 return (channel == rtcp_transport_channel_ || |
469 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); | 506 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); |
470 } | 507 } |
471 | 508 |
472 bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, | 509 bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 return false; | 611 return false; |
575 } | 612 } |
576 | 613 |
577 // Bon voyage. | 614 // Bon voyage. |
578 int ret = | 615 int ret = |
579 channel->SendPacket(packet->data<char>(), packet->size(), options, | 616 channel->SendPacket(packet->data<char>(), packet->size(), options, |
580 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); | 617 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); |
581 if (ret != static_cast<int>(packet->size())) { | 618 if (ret != static_cast<int>(packet->size())) { |
582 if (channel->GetError() == EWOULDBLOCK) { | 619 if (channel->GetError() == EWOULDBLOCK) { |
583 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; | 620 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; |
584 SetReadyToSend(channel, false); | 621 SetReadyToSend(rtcp, false); |
585 } | 622 } |
586 return false; | 623 return false; |
587 } | 624 } |
588 return true; | 625 return true; |
589 } | 626 } |
590 | 627 |
591 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { | 628 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { |
592 // Protect ourselves against crazy data. | 629 // Protect ourselves against crazy data. |
593 if (!ValidPacket(rtcp, packet)) { | 630 if (!ValidPacket(rtcp, packet)) { |
594 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " | 631 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 void BaseChannel::DisableMedia_w() { | 745 void BaseChannel::DisableMedia_w() { |
709 ASSERT(worker_thread_ == rtc::Thread::Current()); | 746 ASSERT(worker_thread_ == rtc::Thread::Current()); |
710 if (!enabled_) | 747 if (!enabled_) |
711 return; | 748 return; |
712 | 749 |
713 LOG(LS_INFO) << "Channel disabled"; | 750 LOG(LS_INFO) << "Channel disabled"; |
714 enabled_ = false; | 751 enabled_ = false; |
715 ChangeState(); | 752 ChangeState(); |
716 } | 753 } |
717 | 754 |
| 755 void BaseChannel::UpdateWritableState_w() { |
| 756 if (transport_channel_ && transport_channel_->writable() && |
| 757 (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { |
| 758 ChannelWritable_w(); |
| 759 } else { |
| 760 ChannelNotWritable_w(); |
| 761 } |
| 762 } |
| 763 |
718 void BaseChannel::ChannelWritable_w() { | 764 void BaseChannel::ChannelWritable_w() { |
719 ASSERT(worker_thread_ == rtc::Thread::Current()); | 765 ASSERT(worker_thread_ == rtc::Thread::Current()); |
720 if (writable_) | 766 if (writable_) |
721 return; | 767 return; |
722 | 768 |
723 LOG(LS_INFO) << "Channel socket writable (" | 769 LOG(LS_INFO) << "Channel writable (" << content_name_ << ")" |
724 << transport_channel_->content_name() << ", " | |
725 << transport_channel_->component() << ")" | |
726 << (was_ever_writable_ ? "" : " for the first time"); | 770 << (was_ever_writable_ ? "" : " for the first time"); |
727 | 771 |
728 std::vector<ConnectionInfo> infos; | 772 std::vector<ConnectionInfo> infos; |
729 transport_channel_->GetStats(&infos); | 773 transport_channel_->GetStats(&infos); |
730 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); | 774 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); |
731 it != infos.end(); ++it) { | 775 it != infos.end(); ++it) { |
732 if (it->best_connection) { | 776 if (it->best_connection) { |
733 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() | 777 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() |
734 << "->" << it->remote_candidate.ToSensitiveString(); | 778 << "->" << it->remote_candidate.ToSensitiveString(); |
735 break; | 779 break; |
736 } | 780 } |
737 } | 781 } |
738 | 782 |
739 // If we're doing DTLS-SRTP, now is the time. | 783 // If we're doing DTLS-SRTP, now is the time. |
740 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { | 784 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { |
741 if (!SetupDtlsSrtp(false)) { | 785 if (!SetupDtlsSrtp(false)) { |
742 SignalDtlsSetupFailure(this, false); | 786 SignalDtlsSetupFailure_w(false); |
743 return; | 787 return; |
744 } | 788 } |
745 | 789 |
746 if (rtcp_transport_channel_) { | 790 if (rtcp_transport_channel_) { |
747 if (!SetupDtlsSrtp(true)) { | 791 if (!SetupDtlsSrtp(true)) { |
748 SignalDtlsSetupFailure(this, true); | 792 SignalDtlsSetupFailure_w(true); |
749 return; | 793 return; |
750 } | 794 } |
751 } | 795 } |
752 } | 796 } |
753 | 797 |
754 was_ever_writable_ = true; | 798 was_ever_writable_ = true; |
755 writable_ = true; | 799 writable_ = true; |
756 ChangeState(); | 800 ChangeState(); |
757 } | 801 } |
758 | 802 |
(...skipping 22 matching lines...) Expand all Loading... |
781 | 825 |
782 bool BaseChannel::ShouldSetupDtlsSrtp() const { | 826 bool BaseChannel::ShouldSetupDtlsSrtp() const { |
783 return true; | 827 return true; |
784 } | 828 } |
785 | 829 |
786 // This function returns true if either DTLS-SRTP is not in use | 830 // This function returns true if either DTLS-SRTP is not in use |
787 // *or* DTLS-SRTP is successfully set up. | 831 // *or* DTLS-SRTP is successfully set up. |
788 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { | 832 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { |
789 bool ret = false; | 833 bool ret = false; |
790 | 834 |
791 TransportChannel *channel = rtcp_channel ? | 835 TransportChannel* channel = |
792 rtcp_transport_channel_ : transport_channel_; | 836 rtcp_channel ? rtcp_transport_channel_ : transport_channel_; |
793 | 837 |
794 // No DTLS | 838 // No DTLS |
795 if (!channel->IsDtlsActive()) | 839 if (!channel->IsDtlsActive()) |
796 return true; | 840 return true; |
797 | 841 |
798 std::string selected_cipher; | 842 std::string selected_cipher; |
799 | 843 |
800 if (!channel->GetSrtpCipher(&selected_cipher)) { | 844 if (!channel->GetSrtpCipher(&selected_cipher)) { |
801 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher"; | 845 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher"; |
802 return false; | 846 return false; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 dtls_keyed_ = true; | 921 dtls_keyed_ = true; |
878 | 922 |
879 return ret; | 923 return ret; |
880 } | 924 } |
881 | 925 |
882 void BaseChannel::ChannelNotWritable_w() { | 926 void BaseChannel::ChannelNotWritable_w() { |
883 ASSERT(worker_thread_ == rtc::Thread::Current()); | 927 ASSERT(worker_thread_ == rtc::Thread::Current()); |
884 if (!writable_) | 928 if (!writable_) |
885 return; | 929 return; |
886 | 930 |
887 LOG(LS_INFO) << "Channel socket not writable (" | 931 LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")"; |
888 << transport_channel_->content_name() << ", " | |
889 << transport_channel_->component() << ")"; | |
890 writable_ = false; | 932 writable_ = false; |
891 ChangeState(); | 933 ChangeState(); |
892 } | 934 } |
893 | 935 |
894 bool BaseChannel::SetRtpTransportParameters_w( | 936 bool BaseChannel::SetRtpTransportParameters_w( |
895 const MediaContentDescription* content, | 937 const MediaContentDescription* content, |
896 ContentAction action, | 938 ContentAction action, |
897 ContentSource src, | 939 ContentSource src, |
898 std::string* error_desc) { | 940 std::string* error_desc) { |
899 if (action == CA_UPDATE) { | 941 if (action == CA_UPDATE) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 } | 1020 } |
979 | 1021 |
980 void BaseChannel::ActivateRtcpMux() { | 1022 void BaseChannel::ActivateRtcpMux() { |
981 worker_thread_->Invoke<void>(Bind( | 1023 worker_thread_->Invoke<void>(Bind( |
982 &BaseChannel::ActivateRtcpMux_w, this)); | 1024 &BaseChannel::ActivateRtcpMux_w, this)); |
983 } | 1025 } |
984 | 1026 |
985 void BaseChannel::ActivateRtcpMux_w() { | 1027 void BaseChannel::ActivateRtcpMux_w() { |
986 if (!rtcp_mux_filter_.IsActive()) { | 1028 if (!rtcp_mux_filter_.IsActive()) { |
987 rtcp_mux_filter_.SetActive(); | 1029 rtcp_mux_filter_.SetActive(); |
988 set_rtcp_transport_channel(NULL); | 1030 set_rtcp_transport_channel(nullptr); |
| 1031 rtcp_transport_enabled_ = false; |
989 } | 1032 } |
990 } | 1033 } |
991 | 1034 |
992 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, | 1035 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, |
993 ContentSource src, | 1036 ContentSource src, |
994 std::string* error_desc) { | 1037 std::string* error_desc) { |
995 bool ret = false; | 1038 bool ret = false; |
996 switch (action) { | 1039 switch (action) { |
997 case CA_OFFER: | 1040 case CA_OFFER: |
998 ret = rtcp_mux_filter_.SetOffer(enable, src); | 1041 ret = rtcp_mux_filter_.SetOffer(enable, src); |
999 break; | 1042 break; |
1000 case CA_PRANSWER: | 1043 case CA_PRANSWER: |
1001 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); | 1044 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); |
1002 break; | 1045 break; |
1003 case CA_ANSWER: | 1046 case CA_ANSWER: |
1004 ret = rtcp_mux_filter_.SetAnswer(enable, src); | 1047 ret = rtcp_mux_filter_.SetAnswer(enable, src); |
1005 if (ret && rtcp_mux_filter_.IsActive()) { | 1048 if (ret && rtcp_mux_filter_.IsActive()) { |
1006 // We activated RTCP mux, close down the RTCP transport. | 1049 // We activated RTCP mux, close down the RTCP transport. |
1007 set_rtcp_transport_channel(NULL); | 1050 LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() |
| 1051 << " by destroying RTCP transport channel for " |
| 1052 << transport_name(); |
| 1053 set_rtcp_transport_channel(nullptr); |
| 1054 rtcp_transport_enabled_ = false; |
1008 } | 1055 } |
1009 break; | 1056 break; |
1010 case CA_UPDATE: | 1057 case CA_UPDATE: |
1011 // No RTCP mux info. | 1058 // No RTCP mux info. |
1012 ret = true; | 1059 ret = true; |
1013 break; | 1060 break; |
1014 default: | 1061 default: |
1015 break; | 1062 break; |
1016 } | 1063 } |
1017 if (!ret) { | 1064 if (!ret) { |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 worker_thread_->Clear(this, MSG_RTCPPACKET, &rtcp_messages); | 1271 worker_thread_->Clear(this, MSG_RTCPPACKET, &rtcp_messages); |
1225 for (rtc::MessageList::iterator it = rtcp_messages.begin(); | 1272 for (rtc::MessageList::iterator it = rtcp_messages.begin(); |
1226 it != rtcp_messages.end(); ++it) { | 1273 it != rtcp_messages.end(); ++it) { |
1227 worker_thread_->Send(this, MSG_RTCPPACKET, it->pdata); | 1274 worker_thread_->Send(this, MSG_RTCPPACKET, it->pdata); |
1228 } | 1275 } |
1229 } | 1276 } |
1230 | 1277 |
1231 VoiceChannel::VoiceChannel(rtc::Thread* thread, | 1278 VoiceChannel::VoiceChannel(rtc::Thread* thread, |
1232 MediaEngineInterface* media_engine, | 1279 MediaEngineInterface* media_engine, |
1233 VoiceMediaChannel* media_channel, | 1280 VoiceMediaChannel* media_channel, |
1234 BaseSession* session, | 1281 TransportController* transport_controller, |
1235 const std::string& content_name, | 1282 const std::string& content_name, |
1236 bool rtcp) | 1283 bool rtcp) |
1237 : BaseChannel(thread, media_channel, session, content_name, | 1284 : BaseChannel(thread, |
| 1285 media_channel, |
| 1286 transport_controller, |
| 1287 content_name, |
1238 rtcp), | 1288 rtcp), |
1239 media_engine_(media_engine), | 1289 media_engine_(media_engine), |
1240 received_media_(false) { | 1290 received_media_(false) {} |
1241 } | |
1242 | 1291 |
1243 VoiceChannel::~VoiceChannel() { | 1292 VoiceChannel::~VoiceChannel() { |
1244 StopAudioMonitor(); | 1293 StopAudioMonitor(); |
1245 StopMediaMonitor(); | 1294 StopMediaMonitor(); |
1246 // this can't be done in the base class, since it calls a virtual | 1295 // this can't be done in the base class, since it calls a virtual |
1247 DisableMedia_w(); | 1296 DisableMedia_w(); |
1248 Deinit(); | 1297 Deinit(); |
1249 } | 1298 } |
1250 | 1299 |
1251 bool VoiceChannel::Init() { | 1300 bool VoiceChannel::Init() { |
1252 if (!BaseChannel::Init()) { | 1301 if (!BaseChannel::Init()) { |
1253 return false; | 1302 return false; |
1254 } | 1303 } |
1255 media_channel()->SignalMediaError.connect( | 1304 media_channel()->SignalMediaError.connect( |
1256 this, &VoiceChannel::OnVoiceChannelError); | 1305 this, &VoiceChannel::OnVoiceChannelError); |
1257 srtp_filter()->SignalSrtpError.connect( | 1306 srtp_filter()->SignalSrtpError.connect( |
1258 this, &VoiceChannel::OnSrtpError); | 1307 this, &VoiceChannel::OnSrtpError); |
1259 return true; | 1308 return true; |
1260 } | 1309 } |
1261 | 1310 |
1262 bool VoiceChannel::SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) { | 1311 bool VoiceChannel::SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) { |
1263 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetRemoteRenderer, | 1312 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetRemoteRenderer, |
1264 media_channel(), ssrc, renderer)); | 1313 media_channel(), ssrc, renderer)); |
1265 } | 1314 } |
1266 | 1315 |
1267 bool VoiceChannel::SetAudioSend(uint32 ssrc, bool mute, | 1316 bool VoiceChannel::SetAudioSend(uint32 ssrc, |
| 1317 bool mute, |
1268 const AudioOptions* options, | 1318 const AudioOptions* options, |
1269 AudioRenderer* renderer) { | 1319 AudioRenderer* renderer) { |
1270 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetAudioSend, | 1320 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetAudioSend, media_channel(), |
1271 media_channel(), ssrc, mute, options, renderer)); | 1321 ssrc, mute, options, renderer)); |
1272 } | 1322 } |
1273 | 1323 |
1274 bool VoiceChannel::SetRingbackTone(const void* buf, int len) { | 1324 bool VoiceChannel::SetRingbackTone(const void* buf, int len) { |
1275 return InvokeOnWorker(Bind(&VoiceChannel::SetRingbackTone_w, this, buf, len)); | 1325 return InvokeOnWorker(Bind(&VoiceChannel::SetRingbackTone_w, this, buf, len)); |
1276 } | 1326 } |
1277 | 1327 |
1278 // TODO(juberti): Handle early media the right way. We should get an explicit | 1328 // TODO(juberti): Handle early media the right way. We should get an explicit |
1279 // ringing message telling us to start playing local ringback, which we cancel | 1329 // ringing message telling us to start playing local ringback, which we cancel |
1280 // if any early media actually arrives. For now, we do the opposite, which is | 1330 // if any early media actually arrives. For now, we do the opposite, which is |
1281 // to wait 1 second for early media, and start playing local ringback if none | 1331 // to wait 1 second for early media, and start playing local ringback if none |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 break; | 1650 break; |
1601 } | 1651 } |
1602 } | 1652 } |
1603 | 1653 |
1604 void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { | 1654 void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { |
1605 GetSupportedAudioCryptoSuites(ciphers); | 1655 GetSupportedAudioCryptoSuites(ciphers); |
1606 } | 1656 } |
1607 | 1657 |
1608 VideoChannel::VideoChannel(rtc::Thread* thread, | 1658 VideoChannel::VideoChannel(rtc::Thread* thread, |
1609 VideoMediaChannel* media_channel, | 1659 VideoMediaChannel* media_channel, |
1610 BaseSession* session, | 1660 TransportController* transport_controller, |
1611 const std::string& content_name, | 1661 const std::string& content_name, |
1612 bool rtcp) | 1662 bool rtcp) |
1613 : BaseChannel(thread, media_channel, session, content_name, | 1663 : BaseChannel(thread, |
| 1664 media_channel, |
| 1665 transport_controller, |
| 1666 content_name, |
1614 rtcp), | 1667 rtcp), |
1615 renderer_(NULL), | 1668 renderer_(NULL), |
1616 previous_we_(rtc::WE_CLOSE) { | 1669 previous_we_(rtc::WE_CLOSE) {} |
1617 } | |
1618 | 1670 |
1619 bool VideoChannel::Init() { | 1671 bool VideoChannel::Init() { |
1620 if (!BaseChannel::Init()) { | 1672 if (!BaseChannel::Init()) { |
1621 return false; | 1673 return false; |
1622 } | 1674 } |
1623 media_channel()->SignalMediaError.connect( | 1675 media_channel()->SignalMediaError.connect( |
1624 this, &VideoChannel::OnVideoChannelError); | 1676 this, &VideoChannel::OnVideoChannelError); |
1625 srtp_filter()->SignalSrtpError.connect( | 1677 srtp_filter()->SignalSrtpError.connect( |
1626 this, &VideoChannel::OnSrtpError); | 1678 this, &VideoChannel::OnSrtpError); |
1627 return true; | 1679 return true; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 &VideoMediaChannel::SendIntraFrame, media_channel())); | 1752 &VideoMediaChannel::SendIntraFrame, media_channel())); |
1701 return true; | 1753 return true; |
1702 } | 1754 } |
1703 | 1755 |
1704 bool VideoChannel::RequestIntraFrame() { | 1756 bool VideoChannel::RequestIntraFrame() { |
1705 worker_thread()->Invoke<void>(Bind( | 1757 worker_thread()->Invoke<void>(Bind( |
1706 &VideoMediaChannel::RequestIntraFrame, media_channel())); | 1758 &VideoMediaChannel::RequestIntraFrame, media_channel())); |
1707 return true; | 1759 return true; |
1708 } | 1760 } |
1709 | 1761 |
1710 bool VideoChannel::SetVideoSend(uint32 ssrc, bool mute, | 1762 bool VideoChannel::SetVideoSend(uint32 ssrc, |
| 1763 bool mute, |
1711 const VideoOptions* options) { | 1764 const VideoOptions* options) { |
1712 return InvokeOnWorker(Bind(&VideoMediaChannel::SetVideoSend, | 1765 return InvokeOnWorker(Bind(&VideoMediaChannel::SetVideoSend, media_channel(), |
1713 media_channel(), ssrc, mute, options)); | 1766 ssrc, mute, options)); |
1714 } | 1767 } |
1715 | 1768 |
1716 void VideoChannel::ChangeState() { | 1769 void VideoChannel::ChangeState() { |
1717 // Render incoming data if we're the active call, and we have the local | 1770 // Render incoming data if we're the active call, and we have the local |
1718 // content. We receive data on the default channel and multiplexed streams. | 1771 // content. We receive data on the default channel and multiplexed streams. |
1719 bool recv = IsReadyToReceive(); | 1772 bool recv = IsReadyToReceive(); |
1720 if (!media_channel()->SetRender(recv)) { | 1773 if (!media_channel()->SetRender(recv)) { |
1721 LOG(LS_ERROR) << "Failed to SetRender on video channel"; | 1774 LOG(LS_ERROR) << "Failed to SetRender on video channel"; |
1722 // TODO(gangji): Report error back to server. | 1775 // TODO(gangji): Report error back to server. |
1723 } | 1776 } |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2038 break; | 2091 break; |
2039 } | 2092 } |
2040 } | 2093 } |
2041 | 2094 |
2042 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { | 2095 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { |
2043 GetSupportedVideoCryptoSuites(ciphers); | 2096 GetSupportedVideoCryptoSuites(ciphers); |
2044 } | 2097 } |
2045 | 2098 |
2046 DataChannel::DataChannel(rtc::Thread* thread, | 2099 DataChannel::DataChannel(rtc::Thread* thread, |
2047 DataMediaChannel* media_channel, | 2100 DataMediaChannel* media_channel, |
2048 BaseSession* session, | 2101 TransportController* transport_controller, |
2049 const std::string& content_name, | 2102 const std::string& content_name, |
2050 bool rtcp) | 2103 bool rtcp) |
2051 : BaseChannel(thread, media_channel, session, content_name, rtcp), | 2104 : BaseChannel(thread, |
| 2105 media_channel, |
| 2106 transport_controller, |
| 2107 content_name, |
| 2108 rtcp), |
2052 data_channel_type_(cricket::DCT_NONE), | 2109 data_channel_type_(cricket::DCT_NONE), |
2053 ready_to_send_data_(false) { | 2110 ready_to_send_data_(false) {} |
2054 } | |
2055 | 2111 |
2056 DataChannel::~DataChannel() { | 2112 DataChannel::~DataChannel() { |
2057 StopMediaMonitor(); | 2113 StopMediaMonitor(); |
2058 // this can't be done in the base class, since it calls a virtual | 2114 // this can't be done in the base class, since it calls a virtual |
2059 DisableMedia_w(); | 2115 DisableMedia_w(); |
2060 | 2116 |
2061 Deinit(); | 2117 Deinit(); |
2062 } | 2118 } |
2063 | 2119 |
2064 bool DataChannel::Init() { | 2120 bool DataChannel::Init() { |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2379 return (data_channel_type_ == DCT_RTP); | 2435 return (data_channel_type_ == DCT_RTP); |
2380 } | 2436 } |
2381 | 2437 |
2382 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2438 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
2383 rtc::TypedMessageData<uint32>* message = | 2439 rtc::TypedMessageData<uint32>* message = |
2384 new rtc::TypedMessageData<uint32>(sid); | 2440 new rtc::TypedMessageData<uint32>(sid); |
2385 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2441 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
2386 } | 2442 } |
2387 | 2443 |
2388 } // namespace cricket | 2444 } // namespace cricket |
OLD | NEW |