aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules
diff options
context:
space:
mode:
authorErik Språng <sprang@webrtc.org>2015-09-24 15:06:57 +0200
committerErik Språng <sprang@webrtc.org>2015-09-24 13:07:17 +0000
commit6b8d3551681f40b880507cecc88f478a12383cc7 (patch)
treeac12260207483555367f9f6ab93bee1528f37a1e /webrtc/modules
parent8c266e6baff043a1fa5c9134f46042908a376d5b (diff)
downloadwebrtc-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.gyp1
-rw-r--r--webrtc/modules/remote_bitrate_estimator/BUILD.gn4
-rw-r--r--webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc1
-rw-r--r--webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h3
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc10
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_packet.h4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc51
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver.h9
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc4
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h5
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc33
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_sender.h3
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_utility.cc80
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtcp_utility.h11
-rw-r--r--webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc1
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),