Chromium Code Reviews| Index: webrtc/pc/channel.cc |
| diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc |
| index 1312d63b37e02865ff42defb4b14217605f6a555..7ec536d2a7242460c9a3b498f90bdfee2ec59a12 100644 |
| --- a/webrtc/pc/channel.cc |
| +++ b/webrtc/pc/channel.cc |
| @@ -15,6 +15,7 @@ |
| #include "webrtc/audio_sink.h" |
| #include "webrtc/base/bind.h" |
| #include "webrtc/base/byteorder.h" |
| +#include "webrtc/base/checks.h" |
| #include "webrtc/base/common.h" |
| #include "webrtc/base/copyonwritebuffer.h" |
| #include "webrtc/base/dscp.h" |
| @@ -171,7 +172,7 @@ BaseChannel::BaseChannel(rtc::Thread* worker_thread, |
| transport_controller_(transport_controller), |
| rtcp_enabled_(rtcp), |
| media_channel_(media_channel) { |
| - ASSERT(worker_thread_ == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); |
| if (transport_controller) { |
| RTC_DCHECK_EQ(network_thread, transport_controller->network_thread()); |
| } |
| @@ -180,7 +181,7 @@ BaseChannel::BaseChannel(rtc::Thread* worker_thread, |
| BaseChannel::~BaseChannel() { |
| TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel"); |
| - ASSERT(worker_thread_ == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); |
| Deinit(); |
| StopConnectionMonitor(); |
| // Eats any outstanding messages or packets. |
| @@ -280,7 +281,7 @@ bool BaseChannel::SetTransport_n(const std::string& transport_name) { |
| RTC_DCHECK(network_thread_->IsCurrent()); |
| if (transport_name == transport_name_) { |
| - // Nothing to do if transport name isn't changing |
| + // Nothing to do if transport name isn't changing. |
| return true; |
| } |
| @@ -289,7 +290,7 @@ bool BaseChannel::SetTransport_n(const std::string& transport_name) { |
| // negotiated parameters. |
| if (ShouldSetupDtlsSrtp_n()) { |
| // Set |writable_| to false such that UpdateWritableState_w can set up |
| - // DTLS-SRTP when the writable_ becomes true again. |
| + // DTLS-SRTP when |writable_| becomes true again. |
| writable_ = false; |
| srtp_filter_.ResetParams(); |
| } |
| @@ -320,7 +321,7 @@ bool BaseChannel::SetTransport_n(const std::string& transport_name) { |
| if (rtcp_transport_channel_) { |
| // We can only update the RTCP ready to send after set_transport_channel has |
| // handled channel writability. |
| - SetReadyToSend(true, rtcp_transport_channel_->writable()); |
| + SetTransportChannelReadyToSend(true, rtcp_transport_channel_->writable()); |
| } |
| transport_name_ = transport_name; |
| return true; |
| @@ -331,10 +332,10 @@ void BaseChannel::SetTransportChannel_n(TransportChannel* new_tc) { |
| TransportChannel* old_tc = transport_channel_; |
| if (!old_tc && !new_tc) { |
| - // Nothing to do |
| + // Nothing to do. |
| return; |
| } |
| - ASSERT(old_tc != new_tc); |
| + RTC_DCHECK(old_tc != new_tc); |
| if (old_tc) { |
| DisconnectFromTransportChannel(old_tc); |
| @@ -352,9 +353,16 @@ void BaseChannel::SetTransportChannel_n(TransportChannel* new_tc) { |
| } |
| // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| - // setting new channel |
| + // setting new transport channels. |
| UpdateWritableState_n(); |
| - SetReadyToSend(false, new_tc && new_tc->writable()); |
| + // On setting a new channel, assume it's ready to send if it's writable, |
| + // because we have no way of knowing otherwise (the channel doesn't give us |
| + // "was last send successful?"). |
| + // |
| + // This won't always be accurate (the last SendPacket call from another |
| + // BaseChannel could have resulted in an error), but even so, we'll just |
| + // encounter the error again and update "ready to send" accordingly. |
| + SetTransportChannelReadyToSend(false, new_tc && new_tc->writable()); |
| } |
| void BaseChannel::SetRtcpTransportChannel_n(TransportChannel* new_tc, |
| @@ -363,10 +371,10 @@ void BaseChannel::SetRtcpTransportChannel_n(TransportChannel* new_tc, |
| TransportChannel* old_tc = rtcp_transport_channel_; |
| if (!old_tc && !new_tc) { |
| - // Nothing to do |
| + // Nothing to do. |
| return; |
| } |
| - ASSERT(old_tc != new_tc); |
| + RTC_DCHECK(old_tc != new_tc); |
| if (old_tc) { |
| DisconnectFromTransportChannel(old_tc); |
| @@ -390,7 +398,14 @@ void BaseChannel::SetRtcpTransportChannel_n(TransportChannel* new_tc, |
| // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| // setting new channel |
| UpdateWritableState_n(); |
| - SetReadyToSend(true, new_tc && new_tc->writable()); |
| + // On setting a new channel, assume it's ready to send if it's writable, |
| + // because we have no way of knowing otherwise (the channel doesn't give us |
| + // "was last send successful?"). |
| + // |
| + // This won't always be accurate (the last SendPacket call from another |
| + // BaseChannel could have resulted in an error), but even so, we'll just |
|
Taylor Brandstetter
2016/08/24 23:40:34
I know this comment is duplicated, but so is the r
|
| + // encounter the error again and update "ready to send" accordingly. |
| + SetTransportChannelReadyToSend(true, new_tc && new_tc->writable()); |
| } |
| } |
| @@ -487,22 +502,23 @@ bool BaseChannel::GetConnectionStats(ConnectionInfos* infos) { |
| return transport_channel_->GetStats(infos); |
| } |
| -bool BaseChannel::IsReadyToReceive_w() const { |
| +bool BaseChannel::IsReadyToReceiveMedia_w() const { |
| // Receive data if we are enabled and have local content, |
| return enabled() && IsReceiveContentDirection(local_content_direction_); |
| } |
| -bool BaseChannel::IsReadyToSend_w() const { |
| +bool BaseChannel::IsReadyToSendMedia_w() const { |
| + // Need to access some state updated on the network thread. |
| + return network_thread_->Invoke<bool>( |
| + RTC_FROM_HERE, Bind(&BaseChannel::IsReadyToSendMedia_n, this)); |
| +} |
| + |
| +bool BaseChannel::IsReadyToSendMedia_n() const { |
| // Send outgoing data if we are enabled, have local and remote content, |
| // and we have had some form of connectivity. |
| return enabled() && IsReceiveContentDirection(remote_content_direction_) && |
| IsSendContentDirection(local_content_direction_) && |
| - network_thread_->Invoke<bool>( |
| - RTC_FROM_HERE, Bind(&BaseChannel::IsTransportReadyToSend_n, this)); |
| -} |
| - |
| -bool BaseChannel::IsTransportReadyToSend_n() const { |
| - return was_ever_writable() && |
| + was_ever_writable() && |
| (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp_n()); |
| } |
| @@ -570,8 +586,9 @@ void BaseChannel::OnChannelRead(TransportChannel* channel, |
| } |
| void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
| - ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| - SetReadyToSend(channel == rtcp_transport_channel_, true); |
| + RTC_DCHECK(channel == transport_channel_ || |
| + channel == rtcp_transport_channel_); |
| + SetTransportChannelReadyToSend(channel == rtcp_transport_channel_, true); |
| } |
| void BaseChannel::OnDtlsState(TransportChannel* channel, |
| @@ -595,7 +612,8 @@ void BaseChannel::OnSelectedCandidatePairChanged( |
| CandidatePairInterface* selected_candidate_pair, |
| int last_sent_packet_id, |
| bool ready_to_send) { |
| - ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| + RTC_DCHECK(channel == transport_channel_ || |
| + channel == rtcp_transport_channel_); |
| RTC_DCHECK(network_thread_->IsCurrent()); |
| std::string transport_name = channel->transport_name(); |
| rtc::NetworkRoute network_route; |
| @@ -611,7 +629,7 @@ void BaseChannel::OnSelectedCandidatePairChanged( |
| network_route)); |
| } |
| -void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
| +void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) { |
| RTC_DCHECK(network_thread_->IsCurrent()); |
| if (rtcp) { |
| rtcp_ready_to_send_ = ready; |
| @@ -741,7 +759,7 @@ bool BaseChannel::SendPacket(bool rtcp, |
| LOG(LS_ERROR) << "Can't send outgoing " << PacketType(rtcp) |
| << " packet when SRTP is inactive and crypto is required"; |
| - ASSERT(false); |
| + RTC_DCHECK(false); |
| return false; |
| } |
| @@ -752,7 +770,7 @@ bool BaseChannel::SendPacket(bool rtcp, |
| if (ret != static_cast<int>(packet->size())) { |
| if (channel->GetError() == ENOTCONN) { |
| LOG(LS_WARNING) << "Got ENOTCONN from transport."; |
| - SetReadyToSend(rtcp, false); |
| + SetTransportChannelReadyToSend(rtcp, false); |
| } |
| return false; |
| } |
| @@ -883,23 +901,23 @@ bool BaseChannel::PushdownRemoteDescription( |
| } |
| void BaseChannel::EnableMedia_w() { |
| - ASSERT(worker_thread_ == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); |
| if (enabled_) |
| return; |
| LOG(LS_INFO) << "Channel enabled"; |
| enabled_ = true; |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| } |
| void BaseChannel::DisableMedia_w() { |
| - ASSERT(worker_thread_ == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); |
| if (!enabled_) |
| return; |
| LOG(LS_INFO) << "Channel disabled"; |
| enabled_ = false; |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| } |
| void BaseChannel::UpdateWritableState_n() { |
| @@ -934,7 +952,7 @@ void BaseChannel::ChannelWritable_n() { |
| was_ever_writable_ = true; |
| MaybeSetupDtlsSrtp_n(); |
| writable_ = true; |
| - ChangeState(); |
| + UpdateMediaSendRecvState(); |
| } |
| void BaseChannel::SignalDtlsSetupFailure_n(bool rtcp) { |
| @@ -945,7 +963,7 @@ void BaseChannel::SignalDtlsSetupFailure_n(bool rtcp) { |
| } |
| void BaseChannel::SignalDtlsSetupFailure_s(bool rtcp) { |
| - ASSERT(signaling_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(signaling_thread() == rtc::Thread::Current()); |
| SignalDtlsSetupFailure(this, rtcp); |
| } |
| @@ -1005,7 +1023,7 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp_channel) { |
| NULL, 0, false, |
| &dtls_buffer[0], dtls_buffer.size())) { |
| LOG(LS_WARNING) << "DTLS-SRTP key export failed"; |
| - ASSERT(false); // This should never happen |
| + RTC_DCHECK(false); // This should never happen |
| return false; |
| } |
| @@ -1085,7 +1103,7 @@ void BaseChannel::ChannelNotWritable_n() { |
| LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")"; |
| writable_ = false; |
| - ChangeState(); |
| + UpdateMediaSendRecvState(); |
| } |
| bool BaseChannel::SetRtpTransportParameters( |
| @@ -1208,6 +1226,8 @@ bool BaseChannel::SetRtcpMux_n(bool enable, |
| ret = rtcp_mux_filter_.SetOffer(enable, src); |
| break; |
| case CA_PRANSWER: |
| + // This may activate RTCP muxing, but we don't yet destroy the channel |
| + // because the final answer may deactivate it. |
| ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); |
| break; |
| case CA_ANSWER: |
| @@ -1245,12 +1265,12 @@ bool BaseChannel::SetRtcpMux_n(bool enable, |
| } |
| bool BaseChannel::AddRecvStream_w(const StreamParams& sp) { |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| return media_channel()->AddRecvStream(sp); |
| } |
| bool BaseChannel::RemoveRecvStream_w(uint32_t ssrc) { |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| return media_channel()->RemoveRecvStream(ssrc); |
| } |
| @@ -1664,21 +1684,22 @@ void VoiceChannel::OnChannelRead(TransportChannel* channel, |
| } |
| } |
| -void BaseChannel::ChangeState() { |
| +void BaseChannel::UpdateMediaSendRecvState() { |
| RTC_DCHECK(network_thread_->IsCurrent()); |
| - invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, |
| - Bind(&BaseChannel::ChangeState_w, this)); |
| + invoker_.AsyncInvoke<void>( |
| + RTC_FROM_HERE, worker_thread_, |
| + Bind(&BaseChannel::UpdateMediaSendRecvState_w, this)); |
| } |
| -void VoiceChannel::ChangeState_w() { |
| +void VoiceChannel::UpdateMediaSendRecvState_w() { |
| // Render incoming data if we're the active call, and we have the local |
| // content. We receive data on the default channel and multiplexed streams. |
| - bool recv = IsReadyToReceive_w(); |
| + bool recv = IsReadyToReceiveMedia_w(); |
| media_channel()->SetPlayout(recv); |
| // Send outgoing data if we're the active call, we have the remote content, |
| // and we have had some form of connectivity. |
| - bool send = IsReadyToSend_w(); |
| + bool send = IsReadyToSendMedia_w(); |
| media_channel()->SetSend(send); |
| LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send; |
| @@ -1693,12 +1714,12 @@ bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, |
| ContentAction action, |
| std::string* error_desc) { |
| TRACE_EVENT0("webrtc", "VoiceChannel::SetLocalContent_w"); |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| LOG(LS_INFO) << "Setting local voice description"; |
| const AudioContentDescription* audio = |
| static_cast<const AudioContentDescription*>(content); |
| - ASSERT(audio != NULL); |
| + RTC_DCHECK(audio != NULL); |
| if (!audio) { |
| SafeSetError("Can't find audio content in local description.", error_desc); |
| return false; |
| @@ -1730,7 +1751,7 @@ bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, |
| } |
| set_local_content_direction(content->direction()); |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| return true; |
| } |
| @@ -1738,12 +1759,12 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| ContentAction action, |
| std::string* error_desc) { |
| TRACE_EVENT0("webrtc", "VoiceChannel::SetRemoteContent_w"); |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| LOG(LS_INFO) << "Setting remote voice description"; |
| const AudioContentDescription* audio = |
| static_cast<const AudioContentDescription*>(content); |
| - ASSERT(audio != NULL); |
| + RTC_DCHECK(audio != NULL); |
| if (!audio) { |
| SafeSetError("Can't find audio content in remote description.", error_desc); |
| return false; |
| @@ -1781,7 +1802,7 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| } |
| set_remote_content_direction(content->direction()); |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| return true; |
| } |
| @@ -1826,7 +1847,7 @@ void VoiceChannel::OnConnectionMonitorUpdate( |
| void VoiceChannel::OnMediaMonitorUpdate( |
| VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) { |
| - ASSERT(media_channel == this->media_channel()); |
| + RTC_DCHECK(media_channel == this->media_channel()); |
| SignalMediaMonitor(this, info); |
| } |
| @@ -1935,10 +1956,10 @@ bool VideoChannel::SetRtpReceiveParameters_w(uint32_t ssrc, |
| return media_channel()->SetRtpReceiveParameters(ssrc, parameters); |
| } |
| -void VideoChannel::ChangeState_w() { |
| +void VideoChannel::UpdateMediaSendRecvState_w() { |
| // Send outgoing data if we're the active call, we have the remote content, |
| // and we have had some form of connectivity. |
| - bool send = IsReadyToSend_w(); |
| + bool send = IsReadyToSendMedia_w(); |
| if (!media_channel()->SetSend(send)) { |
| LOG(LS_ERROR) << "Failed to SetSend on video channel"; |
| // TODO(gangji): Report error back to server. |
| @@ -1976,12 +1997,12 @@ bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content, |
| ContentAction action, |
| std::string* error_desc) { |
| TRACE_EVENT0("webrtc", "VideoChannel::SetLocalContent_w"); |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| LOG(LS_INFO) << "Setting local video description"; |
| const VideoContentDescription* video = |
| static_cast<const VideoContentDescription*>(content); |
| - ASSERT(video != NULL); |
| + RTC_DCHECK(video != NULL); |
| if (!video) { |
| SafeSetError("Can't find video content in local description.", error_desc); |
| return false; |
| @@ -2013,7 +2034,7 @@ bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content, |
| } |
| set_local_content_direction(content->direction()); |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| return true; |
| } |
| @@ -2021,12 +2042,12 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| ContentAction action, |
| std::string* error_desc) { |
| TRACE_EVENT0("webrtc", "VideoChannel::SetRemoteContent_w"); |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| LOG(LS_INFO) << "Setting remote video description"; |
| const VideoContentDescription* video = |
| static_cast<const VideoContentDescription*>(content); |
| - ASSERT(video != NULL); |
| + RTC_DCHECK(video != NULL); |
| if (!video) { |
| SafeSetError("Can't find video content in remote description.", error_desc); |
| return false; |
| @@ -2065,7 +2086,7 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| } |
| set_remote_content_direction(content->direction()); |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| return true; |
| } |
| @@ -2092,7 +2113,7 @@ void VideoChannel::OnConnectionMonitorUpdate( |
| // audio, video, and data, perhaps by using templates. |
| void VideoChannel::OnMediaMonitorUpdate( |
| VideoMediaChannel* media_channel, const VideoMediaInfo &info) { |
| - ASSERT(media_channel == this->media_channel()); |
| + RTC_DCHECK(media_channel == this->media_channel()); |
| SignalMediaMonitor(this, info); |
| } |
| @@ -2197,12 +2218,12 @@ bool DataChannel::SetLocalContent_w(const MediaContentDescription* content, |
| ContentAction action, |
| std::string* error_desc) { |
| TRACE_EVENT0("webrtc", "DataChannel::SetLocalContent_w"); |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| LOG(LS_INFO) << "Setting local data description"; |
| const DataContentDescription* data = |
| static_cast<const DataContentDescription*>(content); |
| - ASSERT(data != NULL); |
| + RTC_DCHECK(data != NULL); |
| if (!data) { |
| SafeSetError("Can't find data content in local description.", error_desc); |
| return false; |
| @@ -2245,7 +2266,7 @@ bool DataChannel::SetLocalContent_w(const MediaContentDescription* content, |
| } |
| set_local_content_direction(content->direction()); |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| return true; |
| } |
| @@ -2253,11 +2274,11 @@ bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| ContentAction action, |
| std::string* error_desc) { |
| TRACE_EVENT0("webrtc", "DataChannel::SetRemoteContent_w"); |
| - ASSERT(worker_thread() == rtc::Thread::Current()); |
| + RTC_DCHECK(worker_thread() == rtc::Thread::Current()); |
| const DataContentDescription* data = |
| static_cast<const DataContentDescription*>(content); |
| - ASSERT(data != NULL); |
| + RTC_DCHECK(data != NULL); |
| if (!data) { |
| SafeSetError("Can't find data content in remote description.", error_desc); |
| return false; |
| @@ -2300,21 +2321,21 @@ bool DataChannel::SetRemoteContent_w(const MediaContentDescription* content, |
| } |
| set_remote_content_direction(content->direction()); |
| - ChangeState_w(); |
| + UpdateMediaSendRecvState_w(); |
| return true; |
| } |
| -void DataChannel::ChangeState_w() { |
| +void DataChannel::UpdateMediaSendRecvState_w() { |
| // Render incoming data if we're the active call, and we have the local |
| // content. We receive data on the default channel and multiplexed streams. |
| - bool recv = IsReadyToReceive_w(); |
| + bool recv = IsReadyToReceiveMedia_w(); |
| if (!media_channel()->SetReceive(recv)) { |
| LOG(LS_ERROR) << "Failed to SetReceive on data channel"; |
| } |
| // Send outgoing data if we're the active call, we have the remote content, |
| // and we have had some form of connectivity. |
| - bool send = IsReadyToSend_w(); |
| + bool send = IsReadyToSendMedia_w(); |
| if (!media_channel()->SetSend(send)) { |
| LOG(LS_ERROR) << "Failed to SetSend on data channel"; |
| } |
| @@ -2384,7 +2405,7 @@ void DataChannel::StopMediaMonitor() { |
| void DataChannel::OnMediaMonitorUpdate( |
| DataMediaChannel* media_channel, const DataMediaInfo& info) { |
| - ASSERT(media_channel == this->media_channel()); |
| + RTC_DCHECK(media_channel == this->media_channel()); |
| SignalMediaMonitor(this, info); |
| } |