Index: webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc |
index 4392f52e6a4daf53f85deba4bffdee12f04a8df3..168557d22409802c99e0d80b3b3e2ae6f00140ec 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc |
@@ -17,6 +17,7 @@ |
#include "webrtc/base/checks.h" |
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" |
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" |
#include "webrtc/system_wrappers/interface/logging.h" |
@@ -29,12 +30,15 @@ using namespace RTCPHelp; |
// The number of RTCP time intervals needed to trigger a timeout. |
const int kRrTimeoutIntervals = 3; |
+const int64_t kMaxWarningLogIntervalMs = 10000; |
+ |
RTCPReceiver::RTCPReceiver( |
Clock* clock, |
bool receiver_only, |
RtcpPacketTypeCounterObserver* packet_type_counter_observer, |
RtcpBandwidthObserver* rtcp_bandwidth_observer, |
RtcpIntraFrameObserver* rtcp_intra_frame_observer, |
+ TransportFeedbackObserver* transport_feedback_observer, |
ModuleRtpRtcpImpl* owner) |
: TMMBRHelp(), |
_clock(clock), |
@@ -46,6 +50,7 @@ RTCPReceiver::RTCPReceiver( |
CriticalSectionWrapper::CreateCriticalSection()), |
_cbRtcpBandwidthObserver(rtcp_bandwidth_observer), |
_cbRtcpIntraFrameObserver(rtcp_intra_frame_observer), |
+ _cbTransportFeedbackObserver(transport_feedback_observer), |
_criticalSectionRTCPReceiver( |
CriticalSectionWrapper::CreateCriticalSection()), |
main_ssrc_(0), |
@@ -61,7 +66,9 @@ RTCPReceiver::RTCPReceiver( |
_lastReceivedRrMs(0), |
_lastIncreasedSequenceNumberMs(0), |
stats_callback_(NULL), |
- packet_type_counter_observer_(packet_type_counter_observer) { |
+ packet_type_counter_observer_(packet_type_counter_observer), |
+ num_skipped_packets_(0), |
+ last_skipped_packets_warning_(clock->TimeInMilliseconds()) { |
memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo)); |
} |
@@ -349,6 +356,9 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, |
// generic application messages |
HandleAPPItem(*rtcpParser, rtcpPacketInformation); |
break; |
+ case RTCPPacketTypes::kTransportFeedback: |
+ HandleTransportFeedback(rtcpParser, &rtcpPacketInformation); |
+ break; |
default: |
rtcpParser->Iterate(); |
break; |
@@ -361,6 +371,19 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, |
main_ssrc_, packet_type_counter_); |
} |
+ num_skipped_packets_ += rtcpParser->NumSkippedBlocks(); |
+ |
+ int64_t now = _clock->TimeInMilliseconds(); |
+ if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs && |
+ num_skipped_packets_ > 0) { |
+ last_skipped_packets_warning_ = now; |
+ LOG(LS_WARNING) |
+ << num_skipped_packets_ |
+ << " RTCP blocks were skipped due to being malformed or of " |
+ "unrecognized/unsupported type, during the past " |
+ << (kMaxWarningLogIntervalMs / 1000) << " second period."; |
+ } |
+ |
return 0; |
} |
@@ -1252,6 +1275,17 @@ void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser, |
rtcpParser.Iterate(); |
} |
+void RTCPReceiver::HandleTransportFeedback( |
+ RTCPUtility::RTCPParserV2* rtcp_parser, |
+ RTCPHelp::RTCPPacketInformation* rtcp_packet_information) { |
+ rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket(); |
+ RTC_DCHECK(packet != nullptr); |
+ rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback; |
+ rtcp_packet_information->transport_feedback_.reset( |
+ static_cast<rtcp::TransportFeedback*>(packet)); |
+ |
+ rtcp_parser->Iterate(); |
+} |
int32_t RTCPReceiver::UpdateTMMBR() { |
int32_t numBoundingSet = 0; |
uint32_t bitrate = 0; |
@@ -1321,11 +1355,11 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket( |
local_ssrc = main_ssrc_; |
} |
if (!receiver_only_ && |
- rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) { |
+ (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) { |
_rtpRtcp.OnRequestSendReport(); |
} |
if (!receiver_only_ && |
- rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) { |
+ (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) { |
if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) { |
LOG(LS_VERBOSE) << "Incoming NACK length: " |
<< rtcpPacketInformation.nackSequenceNumbers.size(); |
@@ -1376,6 +1410,17 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket( |
now); |
} |
} |
+ if (_cbTransportFeedbackObserver && |
+ (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) { |
+ uint32_t media_source_ssrc = |
+ rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc(); |
+ if (media_source_ssrc == main_ssrc_ || |
+ registered_ssrcs_.find(media_source_ssrc) != |
+ registered_ssrcs_.end()) { |
+ _cbTransportFeedbackObserver->OnTransportFeedback( |
+ *rtcpPacketInformation.transport_feedback_.get()); |
+ } |
+ } |
} |
if (!receiver_only_) { |