diff options
author | Erik Språng <sprang@webrtc.org> | 2015-09-24 15:06:57 +0200 |
---|---|---|
committer | Erik Språng <sprang@webrtc.org> | 2015-09-24 13:07:17 +0000 |
commit | 6b8d3551681f40b880507cecc88f478a12383cc7 (patch) | |
tree | ac12260207483555367f9f6ab93bee1528f37a1e /webrtc/modules | |
parent | 8c266e6baff043a1fa5c9134f46042908a376d5b (diff) | |
download | webrtc-6b8d3551681f40b880507cecc88f478a12383cc7.tar.gz |
Reland "Wire up send-side bandwidth estimation."
Revert was patchset #8 id:140001 of https://codereview.webrtc.org/1338203003/
The culprit was RTC_DCHECK(poller_thread_->Start()); in rampup_test.cc
BUG=webrtc:4173
R=stefan@webrtc.org
Review URL: https://codereview.webrtc.org/1362303002 .
Cr-Commit-Position: refs/heads/master@{#10052}
Diffstat (limited to 'webrtc/modules')
-rw-r--r-- | webrtc/modules/modules.gyp | 1 | ||||
-rw-r--r-- | webrtc/modules/remote_bitrate_estimator/BUILD.gn | 4 | ||||
-rw-r--r-- | webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc | 1 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h | 3 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc | 10 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_packet.h | 4 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc | 51 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_receiver.h | 9 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc | 4 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h | 5 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc | 33 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_sender.h | 3 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_utility.cc | 80 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtcp_utility.h | 11 | ||||
-rw-r--r-- | webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 1 |
15 files changed, 157 insertions, 63 deletions
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index fb46a13071..d593dd1d46 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -215,6 +215,7 @@ 'pacing/packet_router_unittest.cc', 'remote_bitrate_estimator/bwe_simulations.cc', 'remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h', + 'remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h', 'remote_bitrate_estimator/inter_arrival_unittest.cc', 'remote_bitrate_estimator/overuse_detector_unittest.cc', 'remote_bitrate_estimator/rate_statistics_unittest.cc', diff --git a/webrtc/modules/remote_bitrate_estimator/BUILD.gn b/webrtc/modules/remote_bitrate_estimator/BUILD.gn index 5f0be091df..99c297dda6 100644 --- a/webrtc/modules/remote_bitrate_estimator/BUILD.gn +++ b/webrtc/modules/remote_bitrate_estimator/BUILD.gn @@ -36,7 +36,11 @@ source_set("rbe_components") { "overuse_estimator.h", "remote_bitrate_estimator_abs_send_time.cc", "remote_bitrate_estimator_single_stream.cc", + "remote_estimator_proxy.cc", + "remote_estimator_proxy.h", "send_time_history.cc", + "transport_feedback_adapter.cc", + "transport_feedback_adapter.h", ] configs += [ "../..:common_config" ] diff --git a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc index 4c01098f0b..5f51bc55e9 100644 --- a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc +++ b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc @@ -107,6 +107,7 @@ void TransportFeedbackAdapter::OnTransportFeedback( << ". Send time history too small?"; } } + RTC_DCHECK(bitrate_estimator_.get() != nullptr); bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector); } diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h index 9ff7406b4f..5e18116c34 100644 --- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h +++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h @@ -111,7 +111,8 @@ enum RTCPPacketType : uint32_t { kRtcpRemb = 0x10000, kRtcpTransmissionTimeOffset = 0x20000, kRtcpXrReceiverReferenceTime = 0x40000, - kRtcpXrDlrrReportBlock = 0x80000 + kRtcpXrDlrrReportBlock = 0x80000, + kRtcpTransportFeedback = 0x100000, }; enum KeyFrameRequestMethod diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc index a03af2435f..eb6d35ed3e 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc @@ -60,7 +60,11 @@ class RtcpFormatRembTest : public ::testing::Test { RtcpFormatRembTest() : over_use_detector_options_(), system_clock_(Clock::GetRealTimeClock()), + dummy_rtp_rtcp_impl_(nullptr), receive_statistics_(ReceiveStatistics::Create(system_clock_)), + rtcp_sender_(nullptr), + rtcp_receiver_(nullptr), + test_transport_(nullptr), remote_bitrate_observer_(), remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream( &remote_bitrate_observer_, @@ -87,9 +91,9 @@ void RtcpFormatRembTest::SetUp() { configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get(); dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration); rtcp_sender_ = - new RTCPSender(false, system_clock_, receive_statistics_.get(), NULL); - rtcp_receiver_ = new RTCPReceiver(system_clock_, false, NULL, NULL, NULL, - dummy_rtp_rtcp_impl_); + new RTCPSender(false, system_clock_, receive_statistics_.get(), nullptr); + rtcp_receiver_ = new RTCPReceiver(system_clock_, false, nullptr, nullptr, + nullptr, nullptr, dummy_rtp_rtcp_impl_); test_transport_ = new TestTransport(rtcp_receiver_); EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h index f29540100b..3c34957c36 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_packet.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_packet.h @@ -91,6 +91,9 @@ class RtcpPacket { size_t max_length, PacketReadyCallback* callback) const; + // Size of this packet in bytes (including headers, excluding nested packets). + virtual size_t BlockLength() const = 0; + protected: RtcpPacket() {} @@ -109,7 +112,6 @@ class RtcpPacket { size_t* index, RtcpPacket::PacketReadyCallback* callback) const; - virtual size_t BlockLength() const = 0; size_t HeaderLength() const; static const size_t kHeaderLength = 4; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index 4392f52e6a..168557d224 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_) { diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h index 9392e51d26..68cf231be1 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h @@ -34,6 +34,7 @@ public: RtcpPacketTypeCounterObserver* packet_type_counter_observer, RtcpBandwidthObserver* rtcp_bandwidth_observer, RtcpIntraFrameObserver* rtcp_intra_frame_observer, + TransportFeedbackObserver* transport_feedback_observer, ModuleRtpRtcpImpl* owner); virtual ~RTCPReceiver(); @@ -216,6 +217,10 @@ protected: void HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser, RTCPHelp::RTCPPacketInformation& rtcpPacketInformation); + void HandleTransportFeedback( + RTCPUtility::RTCPParserV2* rtcp_parser, + RTCPHelp::RTCPPacketInformation* rtcp_packet_information); + private: typedef std::map<uint32_t, RTCPHelp::RTCPReceiveInformation*> ReceivedInfoMap; @@ -241,6 +246,7 @@ protected: CriticalSectionWrapper* _criticalSectionFeedbacks; RtcpBandwidthObserver* const _cbRtcpBandwidthObserver; RtcpIntraFrameObserver* const _cbRtcpIntraFrameObserver; + TransportFeedbackObserver* const _cbTransportFeedbackObserver; CriticalSectionWrapper* _criticalSectionRTCPReceiver; uint32_t main_ssrc_; @@ -282,6 +288,9 @@ protected: RtcpPacketTypeCounter packet_type_counter_; RTCPUtility::NackStats nack_stats_; + + size_t num_skipped_packets_; + int64_t last_skipped_packets_warning_; }; } // namespace webrtc #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_H_ diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc index b86e5cc2d8..718990d10b 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc @@ -13,6 +13,7 @@ #include <assert.h> // assert #include <string.h> // memset +#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" namespace webrtc { @@ -36,8 +37,7 @@ RTCPPacketInformation::RTCPPacketInformation() rtp_timestamp(0), xr_originator_ssrc(0), xr_dlrr_item(false), - VoIPMetric(NULL) { -} + VoIPMetric(nullptr) {} RTCPPacketInformation::~RTCPPacketInformation() { diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h index 790fe819ef..37b7b88370 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h @@ -20,6 +20,9 @@ #include "webrtc/typedefs.h" namespace webrtc { +namespace rtcp { +class TransportFeedback; +} namespace RTCPHelp { @@ -84,6 +87,8 @@ public: bool xr_dlrr_item; RTCPVoIPMetric* VoIPMetric; + rtc::scoped_ptr<rtcp::TransportFeedback> transport_feedback_; + private: RTC_DISALLOW_COPY_AND_ASSIGN(RTCPPacketInformation); }; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index 6ef2a148fa..e09c29d72c 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -33,9 +33,7 @@ namespace { // Anonymous namespace; hide utility functions and classes. class TestTransport : public Transport, public NullRtpData { public: - explicit TestTransport() - : rtcp_receiver_(NULL) { - } + explicit TestTransport() : rtcp_receiver_(nullptr) {} void SetRTCPReceiver(RTCPReceiver* rtcp_receiver) { rtcp_receiver_ = rtcp_receiver; } @@ -78,8 +76,8 @@ class RtcpReceiverTest : public ::testing::Test { configuration.outgoing_transport = test_transport_; configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get(); rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration); - rtcp_receiver_ = new RTCPReceiver(&system_clock_, false, NULL, NULL, NULL, - rtp_rtcp_impl_); + rtcp_receiver_ = new RTCPReceiver(&system_clock_, false, nullptr, nullptr, + nullptr, nullptr, rtp_rtcp_impl_); test_transport_->SetRTCPReceiver(rtcp_receiver_); } ~RtcpReceiverTest() { @@ -362,7 +360,8 @@ TEST_F(RtcpReceiverTest, GetRtt) { rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs); // No report block received. - EXPECT_EQ(-1, rtcp_receiver_->RTT(kSenderSsrc, NULL, NULL, NULL, NULL)); + EXPECT_EQ( + -1, rtcp_receiver_->RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr)); rtcp::ReportBlock rb; rb.To(kSourceSsrc); @@ -374,10 +373,12 @@ TEST_F(RtcpReceiverTest, GetRtt) { EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC); EXPECT_EQ(kRtcpRr, rtcp_packet_info_.rtcpPacketTypeFlags); EXPECT_EQ(1u, rtcp_packet_info_.report_blocks.size()); - EXPECT_EQ(0, rtcp_receiver_->RTT(kSenderSsrc, NULL, NULL, NULL, NULL)); + EXPECT_EQ( + 0, rtcp_receiver_->RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr)); // Report block not received. - EXPECT_EQ(-1, rtcp_receiver_->RTT(kSenderSsrc + 1, NULL, NULL, NULL, NULL)); + EXPECT_EQ(-1, rtcp_receiver_->RTT(kSenderSsrc + 1, nullptr, nullptr, nullptr, + nullptr)); } TEST_F(RtcpReceiverTest, InjectIjWithNoItem) { @@ -589,7 +590,7 @@ TEST_F(RtcpReceiverTest, InjectXrVoipPacket) { xr.WithVoipMetric(&voip_metric); rtc::scoped_ptr<rtcp::RawPacket> packet(xr.Build()); EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); - ASSERT_TRUE(rtcp_packet_info_.VoIPMetric != NULL); + ASSERT_TRUE(rtcp_packet_info_.VoIPMetric != nullptr); EXPECT_EQ(kLossRate, rtcp_packet_info_.VoIPMetric->lossRate); EXPECT_EQ(kRtcpXrVoipMetric, rtcp_packet_info_.rtcpPacketTypeFlags); } @@ -843,7 +844,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) { TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) { // This call is expected to fail because no data has arrived. - EXPECT_EQ(-1, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); + EXPECT_EQ(-1, rtcp_receiver_->TMMBRReceived(0, 0, nullptr)); } TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) { @@ -864,7 +865,7 @@ TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) { rtc::scoped_ptr<rtcp::RawPacket> packet(sr.Build()); EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); - EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); + EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(0, 0, nullptr)); TMMBRSet candidate_set; candidate_set.VerifyAndAllocateSet(1); EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(1, 0, &candidate_set)); @@ -890,7 +891,7 @@ TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) { ssrcs.insert(kMediaFlowSsrc); rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs); EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); - EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); + EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, nullptr)); } TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) { @@ -911,7 +912,7 @@ TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) { rtc::scoped_ptr<rtcp::RawPacket> packet(sr.Build()); EXPECT_EQ(0, InjectRtcpPacket(packet->Buffer(), packet->Length())); - EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); + EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, nullptr)); } TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) { @@ -938,7 +939,7 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) { system_clock_.AdvanceTimeMilliseconds(5000); } // It is now starttime + 15. - EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); + EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, nullptr)); TMMBRSet candidate_set; candidate_set.VerifyAndAllocateSet(3); EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set)); @@ -947,7 +948,7 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) { // seconds, timing out the first packet. system_clock_.AdvanceTimeMilliseconds(12000); // Odd behaviour: Just counting them does not trigger the timeout. - EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL)); + EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, nullptr)); EXPECT_EQ(2, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set)); EXPECT_EQ(kSenderSsrc + 1, candidate_set.Ssrc(0)); } @@ -1008,7 +1009,7 @@ TEST_F(RtcpReceiverTest, Callbacks) { EXPECT_TRUE(callback.Matches(kSourceSsrc, kSequenceNumber, kFractionLoss, kCumulativeLoss, kJitter)); - rtcp_receiver_->RegisterRtcpStatisticsCallback(NULL); + rtcp_receiver_->RegisterRtcpStatisticsCallback(nullptr); // Add arbitrary numbers, callback should not be called (retain old values). rtcp::ReportBlock rb2; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h index e0195f1758..fa6468e519 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -33,9 +33,6 @@ namespace webrtc { class ModuleRtpRtcpImpl; class RTCPReceiver; -namespace rtcp { -class TransportFeedback; -} class NACKStringBuilder { public: NACKStringBuilder(); diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc index caffb6342c..6c1deb467e 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc @@ -8,7 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ +#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 <assert.h> #include <math.h> // ceil @@ -55,6 +57,7 @@ RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData, _ptrRTCPBlockEnd(NULL), _state(ParseState::State_TopLevel), _numberOfBlocks(0), + num_skipped_blocks_(0), _packetType(RTCPPacketTypes::kInvalid) { Validate(); } @@ -80,6 +83,9 @@ RTCPUtility::RTCPParserV2::Packet() const return _packet; } +rtcp::RtcpPacket* RTCPUtility::RTCPParserV2::ReleaseRtcpPacket() { + return rtcp_packet_.release(); +} RTCPUtility::RTCPPacketTypes RTCPUtility::RTCPParserV2::Begin() { @@ -147,7 +153,7 @@ RTCPUtility::RTCPParserV2::Iterate() IterateAppItem(); break; default: - assert(false); // Invalid state! + RTC_NOTREACHED() << "Invalid state!"; break; } } @@ -170,7 +176,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel() _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize(); if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd) { - // Bad block! + ++num_skipped_blocks_; return; } @@ -219,16 +225,15 @@ RTCPUtility::RTCPParserV2::IterateTopLevel() ParseIJ(); return; } - case PT_RTPFB: // Fall through! + case PT_RTPFB: + FALLTHROUGH(); case PT_PSFB: { - const bool ok = ParseFBCommon(header); - if (!ok) - { - // Nothing supported found, continue to next block! - break; - } - return; + if (!ParseFBCommon(header)) { + // Nothing supported found, continue to next block! + break; + } + return; } case PT_APP: { @@ -252,6 +257,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel() } default: // Not supported! Skip! + ++num_skipped_blocks_; EndCurrentBlock(); break; } @@ -1160,28 +1166,26 @@ bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType( } bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { - assert((header.packet_type == PT_RTPFB) || - (header.packet_type == PT_PSFB)); // Parser logic check + RTC_CHECK((header.packet_type == PT_RTPFB) || + (header.packet_type == PT_PSFB)); // Parser logic check const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; - if (length < 12) // 4 * 3, RFC4585 section 6.1 - { - EndCurrentBlock(); + // 4 * 3, RFC4585 section 6.1 + if (length < 12) { + LOG(LS_WARNING) + << "Invalid RTCP packet: Too little data (" << length + << " bytes) left in buffer to parse a 12 byte RTPFB/PSFB message."; return false; } _ptrRTCPData += 4; // Skip RTCP header - uint32_t senderSSRC = *_ptrRTCPData++ << 24; - senderSSRC += *_ptrRTCPData++ << 16; - senderSSRC += *_ptrRTCPData++ << 8; - senderSSRC += *_ptrRTCPData++; + uint32_t senderSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); + _ptrRTCPData += 4; - uint32_t mediaSSRC = *_ptrRTCPData++ << 24; - mediaSSRC += *_ptrRTCPData++ << 16; - mediaSSRC += *_ptrRTCPData++ << 8; - mediaSSRC += *_ptrRTCPData++; + uint32_t mediaSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData); + _ptrRTCPData += 4; if (header.packet_type == PT_RTPFB) { // Transport layer feedback @@ -1198,12 +1202,6 @@ bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { return true; } - case 2: - { - // used to be ACK is this code point, which is removed - // conficts with http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00 - break; - } case 3: { // TMMBR @@ -1236,10 +1234,23 @@ bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { // Note: No state transition, SR REQ is empty! return true; } + case 15: { + _packetType = RTCPPacketTypes::kTransportFeedback; + rtcp_packet_ = + rtcp::TransportFeedback::ParseFrom(_ptrRTCPData - 12, length); + // Since we parse the whole packet here, keep the TopLevel state and + // just end the current block. + if (rtcp_packet_.get()) { + EndCurrentBlock(); + return true; + } + break; + } default: break; } - EndCurrentBlock(); + // Unsupported RTPFB message. Skip and move to next block. + ++num_skipped_blocks_; return false; } else if (header.packet_type == PT_PSFB) { // Payload specific feedback @@ -1287,14 +1298,11 @@ bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) { break; } - EndCurrentBlock(); return false; } else { - assert(false); - - EndCurrentBlock(); + RTC_NOTREACHED(); return false; } } @@ -1654,6 +1662,10 @@ RTCPUtility::RTCPParserV2::ParseAPPItem() return true; } +size_t RTCPUtility::RTCPParserV2::NumSkippedBlocks() const { + return num_skipped_blocks_; +} + RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData, size_t rtcpDataLength) : _ptrBegin(rtcpData), diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.h b/webrtc/modules/rtp_rtcp/source/rtcp_utility.h index 73658a01f8..f05d512919 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.h @@ -13,11 +13,15 @@ #include <stddef.h> // size_t, ptrdiff_t +#include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h" #include "webrtc/typedefs.h" namespace webrtc { +namespace rtcp { +class RtcpPacket; +} namespace RTCPUtility { class NackStats { @@ -294,6 +298,9 @@ enum class RTCPPacketTypes { kApp, kAppItem, + + // draft-holmer-rmcat-transport-wide-cc-extensions + kTransportFeedback, }; struct RTCPRawPacket { @@ -359,10 +366,12 @@ class RTCPParserV2 { RTCPPacketTypes PacketType() const; const RTCPPacket& Packet() const; + rtcp::RtcpPacket* ReleaseRtcpPacket(); const RTCPRawPacket& RawPacket() const; ptrdiff_t LengthLeft() const; bool IsValid() const; + size_t NumSkippedBlocks() const; RTCPPacketTypes Begin(); RTCPPacketTypes Iterate(); @@ -454,9 +463,11 @@ class RTCPParserV2 { ParseState _state; uint8_t _numberOfBlocks; + size_t num_skipped_blocks_; RTCPPacketTypes _packetType; RTCPPacket _packet; + rtc::scoped_ptr<webrtc::rtcp::RtcpPacket> rtcp_packet_; }; class RTCPPacketIterator { diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index d941201cb1..ae4caf7bde 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -78,6 +78,7 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) configuration.rtcp_packet_type_counter_observer, configuration.bandwidth_callback, configuration.intra_frame_callback, + configuration.transport_feedback_callback, this), clock_(configuration.clock), audio_(configuration.audio), |