Add RTCP packet type counter (for getting statistics such as sent/received NACK and FIR).
Add counter to RTCP sender and RTCP receiver.
Add video api GetRtcpPacketTypes().
BUG=2638
R=mflodman@webrtc.org, stefan@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/8179004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5575 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
index c9fb492..4012a81 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -317,6 +317,12 @@
return 0;
}
+void RTCPReceiver::GetPacketTypeCounter(
+ RtcpPacketTypeCounter* packet_counter) const {
+ CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
+ *packet_counter = packet_type_counter_;
+}
+
int32_t
RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
RTCPUtility::RTCPParserV2* rtcpParser)
@@ -839,6 +845,10 @@
HandleNACKItem(rtcpPacket, rtcpPacketInformation);
pktType = rtcpParser.Iterate();
}
+
+ if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
+ ++packet_type_counter_.nack_packets;
+ }
}
// no need for critsect we have _criticalSectionRTCPReceiver
@@ -1028,6 +1038,7 @@
if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
+ ++packet_type_counter_.pli_packets;
// Received a signal that we need to send a new key frame.
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
}
@@ -1270,6 +1281,9 @@
if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
return;
}
+
+ ++packet_type_counter_.fir_packets;
+
// rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
// we don't know who this originate from
if (receiveInfo) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
index 637773d..ebffb7c 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -88,6 +88,8 @@
int32_t StatisticsReceived(
std::vector<RTCPReportBlock>* receiveBlocks) const;
+ void GetPacketTypeCounter(RtcpPacketTypeCounter* packet_counter) const;
+
// Returns true if we haven't received an RTCP RR for several RTCP
// intervals, but only triggers true once.
bool RtcpRrTimeout(int64_t rtcp_interval_ms);
@@ -266,6 +268,8 @@
int64_t _lastIncreasedSequenceNumberMs;
RtcpStatisticsCallback* stats_callback_;
+
+ RtcpPacketTypeCounter packet_type_counter_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
index a376df7..f3c33bf 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -156,10 +156,7 @@
xrSendReceiverReferenceTimeEnabled_(false),
_xrSendVoIPMetric(false),
- _xrVoIPMetric(),
- _nackCount(0),
- _pliCount(0),
- _fullIntraRequestCount(0)
+ _xrVoIPMetric()
{
memset(_CNAME, 0, sizeof(_CNAME));
memset(_lastSendReport, 0, sizeof(_lastSendReport));
@@ -239,10 +236,7 @@
memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime));
last_xr_rr_.clear();
- _nackCount = 0;
- _pliCount = 0;
- _fullIntraRequestCount = 0;
-
+ memset(&packet_type_counter_, 0, sizeof(packet_type_counter_));
return 0;
}
@@ -616,6 +610,12 @@
return true;
}
+void RTCPSender::GetPacketTypeCounter(
+ RtcpPacketTypeCounter* packet_counter) const {
+ CriticalSectionScoped lock(_criticalSectionRTCPSender);
+ *packet_counter = packet_type_counter_;
+}
+
int32_t RTCPSender::AddExternalReportBlock(
uint32_t SSRC,
const RTCPReportBlock* reportBlock) {
@@ -1919,8 +1919,9 @@
return position;
}
TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::PLI");
- _pliCount++;
- TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_PLICount", _SSRC, _pliCount);
+ ++packet_type_counter_.pli_packets;
+ TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_PLICount", _SSRC,
+ packet_type_counter_.pli_packets);
}
if(rtcpPacketTypeFlags & kRtcpFir)
{
@@ -1931,9 +1932,9 @@
return position;
}
TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::FIR");
- _fullIntraRequestCount++;
+ ++packet_type_counter_.fir_packets;
TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_FIRCount", _SSRC,
- _fullIntraRequestCount);
+ packet_type_counter_.fir_packets);
}
if(rtcpPacketTypeFlags & kRtcpSli)
{
@@ -2016,8 +2017,9 @@
}
TRACE_EVENT_INSTANT1("webrtc_rtp", "RTCPSender::NACK",
"nacks", TRACE_STR_COPY(nackString.c_str()));
- _nackCount++;
- TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_NACKCount", _SSRC, _nackCount);
+ ++packet_type_counter_.nack_packets;
+ TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_NACKCount", _SSRC,
+ packet_type_counter_.nack_packets);
}
if(rtcpPacketTypeFlags & kRtcpXrVoipMetric)
{
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
index 9ed5824..cbbc32a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
@@ -180,6 +180,8 @@
void SetTargetBitrate(unsigned int target_bitrate);
+ void GetPacketTypeCounter(RtcpPacketTypeCounter* packet_counter) const;
+
private:
int32_t SendToNetwork(const uint8_t* dataBuffer, const uint16_t length);
@@ -342,10 +344,7 @@
bool _xrSendVoIPMetric;
RTCPVoIPMetric _xrVoIPMetric;
- // Counters
- uint32_t _nackCount;
- uint32_t _pliCount;
- uint32_t _fullIntraRequestCount;
+ RtcpPacketTypeCounter packet_type_counter_;
};
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 9fdf3c8..b960941 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -983,6 +983,13 @@
return rtcp_sender_.RemoveExternalReportBlock(ssrc);
}
+void ModuleRtpRtcpImpl::GetRtcpPacketTypeCounters(
+ RtcpPacketTypeCounter* packets_sent,
+ RtcpPacketTypeCounter* packets_received) const {
+ rtcp_sender_.GetPacketTypeCounter(packets_sent);
+ rtcp_receiver_.GetPacketTypeCounter(packets_received);
+}
+
// (REMB) Receiver Estimated Max Bitrate.
bool ModuleRtpRtcpImpl::REMB() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "REMB()");
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 8f25c2f..34c4fa2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -197,10 +197,14 @@
// Set received RTCP report block.
virtual int32_t AddRTCPReportBlock(
- const uint32_t ssrc, const RTCPReportBlock* receive_block) OVERRIDE;
+ const uint32_t ssrc, const RTCPReportBlock* receive_block) OVERRIDE;
virtual int32_t RemoveRTCPReportBlock(const uint32_t ssrc) OVERRIDE;
+ virtual void GetRtcpPacketTypeCounters(
+ RtcpPacketTypeCounter* packets_sent,
+ RtcpPacketTypeCounter* packets_received) const OVERRIDE;
+
// (REMB) Receiver Estimated Max Bitrate.
virtual bool REMB() const OVERRIDE;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index 0f28854..42c7c40 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -80,10 +80,22 @@
transport_.SimulateNetworkDelay(kOneWayNetworkDelayMs, clock);
}
+
+ RtcpPacketTypeCounter packets_sent_;
+ RtcpPacketTypeCounter packets_received_;
scoped_ptr<ReceiveStatistics> receive_statistics_;
SendTransport transport_;
RtcpRttStatsTestImpl rtt_stats_;
scoped_ptr<ModuleRtpRtcpImpl> impl_;
+
+ RtcpPacketTypeCounter RtcpSent() {
+ impl_->GetRtcpPacketTypeCounters(&packets_sent_, &packets_received_);
+ return packets_sent_;
+ }
+ RtcpPacketTypeCounter RtcpReceived() {
+ impl_->GetRtcpPacketTypeCounters(&packets_sent_, &packets_received_);
+ return packets_received_;
+ }
};
} // namespace
@@ -172,4 +184,35 @@
EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.rtt_stats_.LastProcessedRtt());
EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms());
}
+
+TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_Nack) {
+ EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets);
+ EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
+ // Receive module sends a NACK.
+ const uint16_t kNackLength = 1;
+ uint16_t nack_list[kNackLength] = {123};
+ EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
+ EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
+
+ // Send module receives the NACK.
+ EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
+}
+
+TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_FirAndPli) {
+ EXPECT_EQ(0U, sender_.RtcpReceived().fir_packets);
+ EXPECT_EQ(0U, receiver_.RtcpSent().fir_packets);
+ // Receive module sends a FIR.
+ EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpFir));
+ EXPECT_EQ(1U, receiver_.RtcpSent().fir_packets);
+ // Send module receives the FIR.
+ EXPECT_EQ(1U, sender_.RtcpReceived().fir_packets);
+
+ // Receive module sends a FIR and PLI.
+ EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpFir | kRtcpPli));
+ EXPECT_EQ(2U, receiver_.RtcpSent().fir_packets);
+ EXPECT_EQ(1U, receiver_.RtcpSent().pli_packets);
+ // Send module receives the FIR and PLI.
+ EXPECT_EQ(2U, sender_.RtcpReceived().fir_packets);
+ EXPECT_EQ(1U, sender_.RtcpReceived().pli_packets);
+}
} // namespace webrtc