OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "webrtc/pc/channel.h" | 13 #include "webrtc/pc/channel.h" |
14 | 14 |
15 #include "webrtc/audio_sink.h" | 15 #include "webrtc/audio_sink.h" |
16 #include "webrtc/base/bind.h" | 16 #include "webrtc/base/bind.h" |
17 #include "webrtc/base/buffer.h" | |
18 #include "webrtc/base/byteorder.h" | 17 #include "webrtc/base/byteorder.h" |
19 #include "webrtc/base/common.h" | 18 #include "webrtc/base/common.h" |
| 19 #include "webrtc/base/copyonwritebuffer.h" |
20 #include "webrtc/base/dscp.h" | 20 #include "webrtc/base/dscp.h" |
21 #include "webrtc/base/logging.h" | 21 #include "webrtc/base/logging.h" |
22 #include "webrtc/base/trace_event.h" | 22 #include "webrtc/base/trace_event.h" |
23 #include "webrtc/media/base/mediaconstants.h" | 23 #include "webrtc/media/base/mediaconstants.h" |
24 #include "webrtc/media/base/rtputils.h" | 24 #include "webrtc/media/base/rtputils.h" |
25 #include "webrtc/p2p/base/transportchannel.h" | 25 #include "webrtc/p2p/base/transportchannel.h" |
26 #include "webrtc/pc/channelmanager.h" | 26 #include "webrtc/pc/channelmanager.h" |
27 | 27 |
28 namespace cricket { | 28 namespace cricket { |
29 using rtc::Bind; | 29 using rtc::Bind; |
(...skipping 24 matching lines...) Expand all Loading... |
54 | 54 |
55 static const int kAgcMinus10db = -10; | 55 static const int kAgcMinus10db = -10; |
56 | 56 |
57 static void SafeSetError(const std::string& message, std::string* error_desc) { | 57 static void SafeSetError(const std::string& message, std::string* error_desc) { |
58 if (error_desc) { | 58 if (error_desc) { |
59 *error_desc = message; | 59 *error_desc = message; |
60 } | 60 } |
61 } | 61 } |
62 | 62 |
63 struct PacketMessageData : public rtc::MessageData { | 63 struct PacketMessageData : public rtc::MessageData { |
64 rtc::Buffer packet; | 64 rtc::CopyOnWriteBuffer packet; |
65 rtc::PacketOptions options; | 65 rtc::PacketOptions options; |
66 }; | 66 }; |
67 | 67 |
68 struct VoiceChannelErrorMessageData : public rtc::MessageData { | 68 struct VoiceChannelErrorMessageData : public rtc::MessageData { |
69 VoiceChannelErrorMessageData(uint32_t in_ssrc, | 69 VoiceChannelErrorMessageData(uint32_t in_ssrc, |
70 VoiceMediaChannel::Error in_error) | 70 VoiceMediaChannel::Error in_error) |
71 : ssrc(in_ssrc), error(in_error) {} | 71 : ssrc(in_ssrc), error(in_error) {} |
72 uint32_t ssrc; | 72 uint32_t ssrc; |
73 VoiceMediaChannel::Error error; | 73 VoiceMediaChannel::Error error; |
74 }; | 74 }; |
(...skipping 11 matching lines...) Expand all Loading... |
86 DataMediaChannel::Error in_error) | 86 DataMediaChannel::Error in_error) |
87 : ssrc(in_ssrc), error(in_error) {} | 87 : ssrc(in_ssrc), error(in_error) {} |
88 uint32_t ssrc; | 88 uint32_t ssrc; |
89 DataMediaChannel::Error error; | 89 DataMediaChannel::Error error; |
90 }; | 90 }; |
91 | 91 |
92 static const char* PacketType(bool rtcp) { | 92 static const char* PacketType(bool rtcp) { |
93 return (!rtcp) ? "RTP" : "RTCP"; | 93 return (!rtcp) ? "RTP" : "RTCP"; |
94 } | 94 } |
95 | 95 |
96 static bool ValidPacket(bool rtcp, const rtc::Buffer* packet) { | 96 static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { |
97 // Check the packet size. We could check the header too if needed. | 97 // Check the packet size. We could check the header too if needed. |
98 return (packet && | 98 return (packet && |
99 packet->size() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) && | 99 packet->size() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) && |
100 packet->size() <= kMaxRtpPacketLen); | 100 packet->size() <= kMaxRtpPacketLen); |
101 } | 101 } |
102 | 102 |
103 static bool IsReceiveContentDirection(MediaContentDirection direction) { | 103 static bool IsReceiveContentDirection(MediaContentDirection direction) { |
104 return direction == MD_SENDRECV || direction == MD_RECVONLY; | 104 return direction == MD_SENDRECV || direction == MD_RECVONLY; |
105 } | 105 } |
106 | 106 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 | 428 |
429 bool BaseChannel::IsReadyToSend() const { | 429 bool BaseChannel::IsReadyToSend() const { |
430 // Send outgoing data if we are enabled, have local and remote content, | 430 // Send outgoing data if we are enabled, have local and remote content, |
431 // and we have had some form of connectivity. | 431 // and we have had some form of connectivity. |
432 return enabled() && IsReceiveContentDirection(remote_content_direction_) && | 432 return enabled() && IsReceiveContentDirection(remote_content_direction_) && |
433 IsSendContentDirection(local_content_direction_) && | 433 IsSendContentDirection(local_content_direction_) && |
434 was_ever_writable() && | 434 was_ever_writable() && |
435 (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp()); | 435 (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp()); |
436 } | 436 } |
437 | 437 |
438 bool BaseChannel::SendPacket(rtc::Buffer* packet, | 438 bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet, |
439 const rtc::PacketOptions& options) { | 439 const rtc::PacketOptions& options) { |
440 return SendPacket(false, packet, options); | 440 return SendPacket(false, packet, options); |
441 } | 441 } |
442 | 442 |
443 bool BaseChannel::SendRtcp(rtc::Buffer* packet, | 443 bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet, |
444 const rtc::PacketOptions& options) { | 444 const rtc::PacketOptions& options) { |
445 return SendPacket(true, packet, options); | 445 return SendPacket(true, packet, options); |
446 } | 446 } |
447 | 447 |
448 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, | 448 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, |
449 int value) { | 449 int value) { |
450 TransportChannel* channel = NULL; | 450 TransportChannel* channel = NULL; |
451 switch (type) { | 451 switch (type) { |
452 case ST_RTP: | 452 case ST_RTP: |
453 channel = transport_channel_; | 453 channel = transport_channel_; |
(...skipping 18 matching lines...) Expand all Loading... |
472 const char* data, size_t len, | 472 const char* data, size_t len, |
473 const rtc::PacketTime& packet_time, | 473 const rtc::PacketTime& packet_time, |
474 int flags) { | 474 int flags) { |
475 TRACE_EVENT0("webrtc", "BaseChannel::OnChannelRead"); | 475 TRACE_EVENT0("webrtc", "BaseChannel::OnChannelRead"); |
476 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine | 476 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine |
477 ASSERT(worker_thread_ == rtc::Thread::Current()); | 477 ASSERT(worker_thread_ == rtc::Thread::Current()); |
478 | 478 |
479 // When using RTCP multiplexing we might get RTCP packets on the RTP | 479 // When using RTCP multiplexing we might get RTCP packets on the RTP |
480 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. | 480 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. |
481 bool rtcp = PacketIsRtcp(channel, data, len); | 481 bool rtcp = PacketIsRtcp(channel, data, len); |
482 rtc::Buffer packet(data, len); | 482 rtc::CopyOnWriteBuffer packet(data, len); |
483 HandlePacket(rtcp, &packet, packet_time); | 483 HandlePacket(rtcp, &packet, packet_time); |
484 } | 484 } |
485 | 485 |
486 void BaseChannel::OnReadyToSend(TransportChannel* channel) { | 486 void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
487 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 487 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
488 SetReadyToSend(channel == rtcp_transport_channel_, true); | 488 SetReadyToSend(channel == rtcp_transport_channel_, true); |
489 } | 489 } |
490 | 490 |
491 void BaseChannel::OnDtlsState(TransportChannel* channel, | 491 void BaseChannel::OnDtlsState(TransportChannel* channel, |
492 DtlsTransportState state) { | 492 DtlsTransportState state) { |
(...skipping 29 matching lines...) Expand all Loading... |
522 } | 522 } |
523 } | 523 } |
524 | 524 |
525 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, | 525 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, |
526 const char* data, size_t len) { | 526 const char* data, size_t len) { |
527 return (channel == rtcp_transport_channel_ || | 527 return (channel == rtcp_transport_channel_ || |
528 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); | 528 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); |
529 } | 529 } |
530 | 530 |
531 bool BaseChannel::SendPacket(bool rtcp, | 531 bool BaseChannel::SendPacket(bool rtcp, |
532 rtc::Buffer* packet, | 532 rtc::CopyOnWriteBuffer* packet, |
533 const rtc::PacketOptions& options) { | 533 const rtc::PacketOptions& options) { |
534 // SendPacket gets called from MediaEngine, typically on an encoder thread. | 534 // SendPacket gets called from MediaEngine, typically on an encoder thread. |
535 // If the thread is not our worker thread, we will post to our worker | 535 // If the thread is not our worker thread, we will post to our worker |
536 // so that the real work happens on our worker. This avoids us having to | 536 // so that the real work happens on our worker. This avoids us having to |
537 // synchronize access to all the pieces of the send path, including | 537 // synchronize access to all the pieces of the send path, including |
538 // SRTP and the inner workings of the transport channels. | 538 // SRTP and the inner workings of the transport channels. |
539 // The only downside is that we can't return a proper failure code if | 539 // The only downside is that we can't return a proper failure code if |
540 // needed. Since UDP is unreliable anyway, this should be a non-issue. | 540 // needed. Since UDP is unreliable anyway, this should be a non-issue. |
541 if (rtc::Thread::Current() != worker_thread_) { | 541 if (rtc::Thread::Current() != worker_thread_) { |
542 // Avoid a copy by transferring the ownership of the packet data. | 542 // Avoid a copy by transferring the ownership of the packet data. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 if (ret != static_cast<int>(packet->size())) { | 643 if (ret != static_cast<int>(packet->size())) { |
644 if (channel->GetError() == EWOULDBLOCK) { | 644 if (channel->GetError() == EWOULDBLOCK) { |
645 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; | 645 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; |
646 SetReadyToSend(rtcp, false); | 646 SetReadyToSend(rtcp, false); |
647 } | 647 } |
648 return false; | 648 return false; |
649 } | 649 } |
650 return true; | 650 return true; |
651 } | 651 } |
652 | 652 |
653 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { | 653 bool BaseChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { |
654 // Protect ourselves against crazy data. | 654 // Protect ourselves against crazy data. |
655 if (!ValidPacket(rtcp, packet)) { | 655 if (!ValidPacket(rtcp, packet)) { |
656 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " | 656 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " |
657 << PacketType(rtcp) | 657 << PacketType(rtcp) |
658 << " packet: wrong size=" << packet->size(); | 658 << " packet: wrong size=" << packet->size(); |
659 return false; | 659 return false; |
660 } | 660 } |
661 if (rtcp) { | 661 if (rtcp) { |
662 // Permit all (seemingly valid) RTCP packets. | 662 // Permit all (seemingly valid) RTCP packets. |
663 return true; | 663 return true; |
664 } | 664 } |
665 // Check whether we handle this payload. | 665 // Check whether we handle this payload. |
666 return bundle_filter_.DemuxPacket(packet->data<uint8_t>(), packet->size()); | 666 return bundle_filter_.DemuxPacket(packet->data(), packet->size()); |
667 } | 667 } |
668 | 668 |
669 void BaseChannel::HandlePacket(bool rtcp, rtc::Buffer* packet, | 669 void BaseChannel::HandlePacket(bool rtcp, rtc::CopyOnWriteBuffer* packet, |
670 const rtc::PacketTime& packet_time) { | 670 const rtc::PacketTime& packet_time) { |
671 if (!WantsPacket(rtcp, packet)) { | 671 if (!WantsPacket(rtcp, packet)) { |
672 return; | 672 return; |
673 } | 673 } |
674 | 674 |
675 // We are only interested in the first rtp packet because that | 675 // We are only interested in the first rtp packet because that |
676 // indicates the media has started flowing. | 676 // indicates the media has started flowing. |
677 if (!has_received_packet_ && !rtcp) { | 677 if (!has_received_packet_ && !rtcp) { |
678 has_received_packet_ = true; | 678 has_received_packet_ = true; |
679 signaling_thread()->Post(this, MSG_FIRSTPACKETRECEIVED); | 679 signaling_thread()->Post(this, MSG_FIRSTPACKETRECEIVED); |
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 media_channel()->SignalDataReceived.connect( | 1901 media_channel()->SignalDataReceived.connect( |
1902 this, &DataChannel::OnDataReceived); | 1902 this, &DataChannel::OnDataReceived); |
1903 media_channel()->SignalReadyToSend.connect( | 1903 media_channel()->SignalReadyToSend.connect( |
1904 this, &DataChannel::OnDataChannelReadyToSend); | 1904 this, &DataChannel::OnDataChannelReadyToSend); |
1905 media_channel()->SignalStreamClosedRemotely.connect( | 1905 media_channel()->SignalStreamClosedRemotely.connect( |
1906 this, &DataChannel::OnStreamClosedRemotely); | 1906 this, &DataChannel::OnStreamClosedRemotely); |
1907 return true; | 1907 return true; |
1908 } | 1908 } |
1909 | 1909 |
1910 bool DataChannel::SendData(const SendDataParams& params, | 1910 bool DataChannel::SendData(const SendDataParams& params, |
1911 const rtc::Buffer& payload, | 1911 const rtc::CopyOnWriteBuffer& payload, |
1912 SendDataResult* result) { | 1912 SendDataResult* result) { |
1913 return InvokeOnWorker(Bind(&DataMediaChannel::SendData, | 1913 return InvokeOnWorker(Bind(&DataMediaChannel::SendData, |
1914 media_channel(), params, payload, result)); | 1914 media_channel(), params, payload, result)); |
1915 } | 1915 } |
1916 | 1916 |
1917 const ContentInfo* DataChannel::GetFirstContent( | 1917 const ContentInfo* DataChannel::GetFirstContent( |
1918 const SessionDescription* sdesc) { | 1918 const SessionDescription* sdesc) { |
1919 return GetFirstDataContent(sdesc); | 1919 return GetFirstDataContent(sdesc); |
1920 } | 1920 } |
1921 | 1921 |
1922 bool DataChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { | 1922 bool DataChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { |
1923 if (data_channel_type_ == DCT_SCTP) { | 1923 if (data_channel_type_ == DCT_SCTP) { |
1924 // TODO(pthatcher): Do this in a more robust way by checking for | 1924 // TODO(pthatcher): Do this in a more robust way by checking for |
1925 // SCTP or DTLS. | 1925 // SCTP or DTLS. |
1926 return !IsRtpPacket(packet->data(), packet->size()); | 1926 return !IsRtpPacket(packet->data(), packet->size()); |
1927 } else if (data_channel_type_ == DCT_RTP) { | 1927 } else if (data_channel_type_ == DCT_RTP) { |
1928 return BaseChannel::WantsPacket(rtcp, packet); | 1928 return BaseChannel::WantsPacket(rtcp, packet); |
1929 } | 1929 } |
1930 return false; | 1930 return false; |
1931 } | 1931 } |
1932 | 1932 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 return (data_channel_type_ == DCT_RTP) && BaseChannel::ShouldSetupDtlsSrtp(); | 2186 return (data_channel_type_ == DCT_RTP) && BaseChannel::ShouldSetupDtlsSrtp(); |
2187 } | 2187 } |
2188 | 2188 |
2189 void DataChannel::OnStreamClosedRemotely(uint32_t sid) { | 2189 void DataChannel::OnStreamClosedRemotely(uint32_t sid) { |
2190 rtc::TypedMessageData<uint32_t>* message = | 2190 rtc::TypedMessageData<uint32_t>* message = |
2191 new rtc::TypedMessageData<uint32_t>(sid); | 2191 new rtc::TypedMessageData<uint32_t>(sid); |
2192 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2192 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
2193 } | 2193 } |
2194 | 2194 |
2195 } // namespace cricket | 2195 } // namespace cricket |
OLD | NEW |