Add statistics gathering for packet loss.
Adds a class used to classify whether packet loss events are a single packet or multiple packets as well as how many packets have been lost. Also exposes a new function in the RtpRtcp interface to retrieve these statistics. BUG= Review URL: https://codereview.webrtc.org/1198853004 Cr-Commit-Position: refs/heads/master@{#9568}
This commit is contained in:
@ -230,6 +230,7 @@
|
||||
'rtp_rtcp/source/fec_test_helper.h',
|
||||
'rtp_rtcp/source/h264_sps_parser_unittest.cc',
|
||||
'rtp_rtcp/source/nack_rtx_unittest.cc',
|
||||
'rtp_rtcp/source/packet_loss_stats_unittest.cc',
|
||||
'rtp_rtcp/source/producer_fec_unittest.cc',
|
||||
'rtp_rtcp/source/receive_statistics_unittest.cc',
|
||||
'rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc',
|
||||
|
@ -35,6 +35,8 @@ source_set("rtp_rtcp") {
|
||||
"source/h264_sps_parser.cc",
|
||||
"source/h264_sps_parser.h",
|
||||
"source/mock/mock_rtp_payload_strategy.h",
|
||||
"source/packet_loss_stats.cc",
|
||||
"source/packet_loss_stats.h",
|
||||
"source/producer_fec.cc",
|
||||
"source/producer_fec.h",
|
||||
"source/receive_statistics_impl.cc",
|
||||
|
@ -430,6 +430,14 @@ class RtpRtcp : public Module {
|
||||
StreamDataCounters* rtp_counters,
|
||||
StreamDataCounters* rtx_counters) const = 0;
|
||||
|
||||
/*
|
||||
* Get packet loss statistics for the RTP stream.
|
||||
*/
|
||||
virtual void GetRtpPacketLossStats(
|
||||
bool outgoing,
|
||||
uint32_t ssrc,
|
||||
struct RtpPacketLossStats* loss_stats) const = 0;
|
||||
|
||||
/*
|
||||
* Get received RTCP sender info
|
||||
*
|
||||
|
@ -350,5 +350,18 @@ class NullRtpAudioFeedback : public RtpAudioFeedback {
|
||||
const uint8_t volume) override {}
|
||||
};
|
||||
|
||||
// Statistics about packet loss for a single directional connection. All values
|
||||
// are totals since the connection initiated.
|
||||
struct RtpPacketLossStats {
|
||||
// The number of packets lost in events where no adjacent packets were also
|
||||
// lost.
|
||||
uint64_t single_packet_loss_count;
|
||||
// The number of events in which more than one adjacent packet was lost.
|
||||
uint64_t multiple_packet_loss_event_count;
|
||||
// The number of packets lost in events where more than one adjacent packet
|
||||
// was lost.
|
||||
uint64_t multiple_packet_loss_packet_count;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
|
||||
|
@ -165,6 +165,8 @@ class MockRtpRtcp : public RtpRtcp {
|
||||
int32_t(size_t *bytesSent, uint32_t *packetsSent));
|
||||
MOCK_CONST_METHOD2(GetSendStreamDataCounters,
|
||||
void(StreamDataCounters*, StreamDataCounters*));
|
||||
MOCK_CONST_METHOD3(GetRtpPacketLossStats,
|
||||
void(bool, uint32_t, struct RtpPacketLossStats*));
|
||||
MOCK_METHOD1(RemoteRTCPStat,
|
||||
int32_t(RTCPSenderInfo* senderInfo));
|
||||
MOCK_CONST_METHOD1(RemoteRTCPStat,
|
||||
|
@ -31,6 +31,8 @@
|
||||
'source/byte_io.h',
|
||||
'source/fec_receiver_impl.cc',
|
||||
'source/fec_receiver_impl.h',
|
||||
'source/packet_loss_stats.cc',
|
||||
'source/packet_loss_stats.h',
|
||||
'source/receive_statistics_impl.cc',
|
||||
'source/receive_statistics_impl.h',
|
||||
'source/remote_ntp_time_estimator.cc',
|
||||
|
137
webrtc/modules/rtp_rtcp/source/packet_loss_stats.cc
Normal file
137
webrtc/modules/rtp_rtcp/source/packet_loss_stats.cc
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/source/packet_loss_stats.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
// After this many packets are added, adding additional packets will cause the
|
||||
// oldest packets to be pruned from the buffer.
|
||||
static const int kBufferSize = 100;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
PacketLossStats::PacketLossStats()
|
||||
: single_loss_historic_count_(0),
|
||||
multiple_loss_historic_event_count_(0),
|
||||
multiple_loss_historic_packet_count_(0) {
|
||||
}
|
||||
|
||||
void PacketLossStats::AddLostPacket(uint16_t sequence_number) {
|
||||
// Detect sequence number wrap around.
|
||||
if (!lost_packets_buffer_.empty() &&
|
||||
static_cast<int>(*(lost_packets_buffer_.rbegin())) - sequence_number
|
||||
> 0x8000) {
|
||||
// The buffer contains large numbers and this is a small number.
|
||||
lost_packets_wrapped_buffer_.insert(sequence_number);
|
||||
} else {
|
||||
lost_packets_buffer_.insert(sequence_number);
|
||||
}
|
||||
if (lost_packets_wrapped_buffer_.size() + lost_packets_buffer_.size()
|
||||
> kBufferSize || (!lost_packets_wrapped_buffer_.empty() &&
|
||||
*(lost_packets_wrapped_buffer_.rbegin()) > 0x4000)) {
|
||||
PruneBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
int PacketLossStats::GetSingleLossCount() const {
|
||||
int single_loss_count, unused1, unused2;
|
||||
ComputeLossCounts(&single_loss_count, &unused1, &unused2);
|
||||
return single_loss_count;
|
||||
}
|
||||
|
||||
int PacketLossStats::GetMultipleLossEventCount() const {
|
||||
int event_count, unused1, unused2;
|
||||
ComputeLossCounts(&unused1, &event_count, &unused2);
|
||||
return event_count;
|
||||
}
|
||||
|
||||
int PacketLossStats::GetMultipleLossPacketCount() const {
|
||||
int packet_count, unused1, unused2;
|
||||
ComputeLossCounts(&unused1, &unused2, &packet_count);
|
||||
return packet_count;
|
||||
}
|
||||
|
||||
void PacketLossStats::ComputeLossCounts(
|
||||
int* out_single_loss_count,
|
||||
int* out_multiple_loss_event_count,
|
||||
int* out_multiple_loss_packet_count) const {
|
||||
*out_single_loss_count = single_loss_historic_count_;
|
||||
*out_multiple_loss_event_count = multiple_loss_historic_event_count_;
|
||||
*out_multiple_loss_packet_count = multiple_loss_historic_packet_count_;
|
||||
if (lost_packets_buffer_.empty()) {
|
||||
DCHECK(lost_packets_wrapped_buffer_.empty());
|
||||
return;
|
||||
}
|
||||
uint16_t last_num = 0;
|
||||
int sequential_count = 0;
|
||||
std::vector<const std::set<uint16_t>*> buffers;
|
||||
buffers.push_back(&lost_packets_buffer_);
|
||||
buffers.push_back(&lost_packets_wrapped_buffer_);
|
||||
for (auto buffer : buffers) {
|
||||
for (auto it = buffer->begin(); it != buffer->end(); ++it) {
|
||||
uint16_t current_num = *it;
|
||||
if (sequential_count > 0 && current_num != ((last_num + 1) & 0xFFFF)) {
|
||||
if (sequential_count == 1) {
|
||||
(*out_single_loss_count)++;
|
||||
} else {
|
||||
(*out_multiple_loss_event_count)++;
|
||||
*out_multiple_loss_packet_count += sequential_count;
|
||||
}
|
||||
sequential_count = 0;
|
||||
}
|
||||
sequential_count++;
|
||||
last_num = current_num;
|
||||
}
|
||||
}
|
||||
if (sequential_count == 1) {
|
||||
(*out_single_loss_count)++;
|
||||
} else if (sequential_count > 1) {
|
||||
(*out_multiple_loss_event_count)++;
|
||||
*out_multiple_loss_packet_count += sequential_count;
|
||||
}
|
||||
}
|
||||
|
||||
void PacketLossStats::PruneBuffer() {
|
||||
// Remove the oldest lost packet and any contiguous packets and move them
|
||||
// into the historic counts.
|
||||
auto it = lost_packets_buffer_.begin();
|
||||
uint16_t last_removed = 0;
|
||||
int remove_count = 0;
|
||||
// Count adjacent packets and continue counting if it is wrap around by
|
||||
// swapping in the wrapped buffer and letting our value wrap as well.
|
||||
while (remove_count == 0 || (!lost_packets_buffer_.empty() &&
|
||||
*it == ((last_removed + 1) & 0xFFFF))) {
|
||||
last_removed = *it;
|
||||
remove_count++;
|
||||
auto to_erase = it++;
|
||||
lost_packets_buffer_.erase(to_erase);
|
||||
if (lost_packets_buffer_.empty()) {
|
||||
lost_packets_buffer_.swap(lost_packets_wrapped_buffer_);
|
||||
it = lost_packets_buffer_.begin();
|
||||
}
|
||||
}
|
||||
if (remove_count > 1) {
|
||||
multiple_loss_historic_event_count_++;
|
||||
multiple_loss_historic_packet_count_ += remove_count;
|
||||
} else {
|
||||
single_loss_historic_count_++;
|
||||
}
|
||||
// Continue pruning if the wrapped buffer is beyond a threshold and there are
|
||||
// things left in the pre-wrapped buffer.
|
||||
if (!lost_packets_wrapped_buffer_.empty() &&
|
||||
*(lost_packets_wrapped_buffer_.rbegin()) > 0x4000) {
|
||||
PruneBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
57
webrtc/modules/rtp_rtcp/source/packet_loss_stats.h
Normal file
57
webrtc/modules/rtp_rtcp/source/packet_loss_stats.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_PACKET_LOSS_STATS_H_
|
||||
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_PACKET_LOSS_STATS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <set>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Keeps track of statistics of packet loss including whether losses are a
|
||||
// single packet or multiple packets in a row.
|
||||
class PacketLossStats {
|
||||
public:
|
||||
PacketLossStats();
|
||||
~PacketLossStats() {}
|
||||
|
||||
// Adds a lost packet to the stats by sequence number.
|
||||
void AddLostPacket(uint16_t sequence_number);
|
||||
|
||||
// Queries the number of packets that were lost by themselves, no neighboring
|
||||
// packets were lost.
|
||||
int GetSingleLossCount() const;
|
||||
|
||||
// Queries the number of times that multiple packets with sequential numbers
|
||||
// were lost. This is the number of events with more than one packet lost,
|
||||
// regardless of the size of the event;
|
||||
int GetMultipleLossEventCount() const;
|
||||
|
||||
// Queries the number of packets lost in multiple packet loss events. Combined
|
||||
// with the event count, this can be used to determine the average event size.
|
||||
int GetMultipleLossPacketCount() const;
|
||||
|
||||
private:
|
||||
std::set<uint16_t> lost_packets_buffer_;
|
||||
std::set<uint16_t> lost_packets_wrapped_buffer_;
|
||||
int single_loss_historic_count_;
|
||||
int multiple_loss_historic_event_count_;
|
||||
int multiple_loss_historic_packet_count_;
|
||||
|
||||
void ComputeLossCounts(int* out_single_loss_count,
|
||||
int* out_multiple_loss_event_count,
|
||||
int* out_multiple_loss_packet_count) const;
|
||||
void PruneBuffer();
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_PACKET_LOSS_STATS_H_
|
197
webrtc/modules/rtp_rtcp/source/packet_loss_stats_unittest.cc
Normal file
197
webrtc/modules/rtp_rtcp/source/packet_loss_stats_unittest.cc
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/packet_loss_stats.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class PacketLossStatsTest : public ::testing::Test {
|
||||
protected:
|
||||
PacketLossStats stats_;
|
||||
};
|
||||
|
||||
// Add a lost packet as every other packet, they should all count as single
|
||||
// losses.
|
||||
TEST_F(PacketLossStatsTest, EveryOtherPacket) {
|
||||
for (int i = 0; i < 1000; i += 2) {
|
||||
stats_.AddLostPacket(i);
|
||||
}
|
||||
EXPECT_EQ(500, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(0, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(0, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add a lost packet as every other packet, but such that the sequence numbers
|
||||
// will wrap around while they are being added.
|
||||
TEST_F(PacketLossStatsTest, EveryOtherPacketWrapped) {
|
||||
for (int i = 65500; i < 66500; i += 2) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
EXPECT_EQ(500, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(0, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(0, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add a lost packet as every other packet, but such that the sequence numbers
|
||||
// will wrap around close to the very end, such that the buffer contains packets
|
||||
// on either side of the wrapping.
|
||||
TEST_F(PacketLossStatsTest, EveryOtherPacketWrappedAtEnd) {
|
||||
for (int i = 64600; i < 65600; i += 2) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
EXPECT_EQ(500, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(0, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(0, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add a lost packet as the first three of every eight packets. Each set of
|
||||
// three should count as a multiple loss event and three multiple loss packets.
|
||||
TEST_F(PacketLossStatsTest, FirstThreeOfEight) {
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
if ((i & 7) < 3) {
|
||||
stats_.AddLostPacket(i);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(0, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(125, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(375, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add a lost packet as the first three of every eight packets such that the
|
||||
// sequence numbers wrap in the middle of adding them.
|
||||
TEST_F(PacketLossStatsTest, FirstThreeOfEightWrapped) {
|
||||
for (int i = 65500; i < 66500; ++i) {
|
||||
if ((i & 7) < 3) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(0, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(125, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(375, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add a lost packet as the first three of every eight packets such that the
|
||||
// sequence numbers wrap near the end of adding them and there are still numbers
|
||||
// in the buffer from before the wrapping.
|
||||
TEST_F(PacketLossStatsTest, FirstThreeOfEightWrappedAtEnd) {
|
||||
for (int i = 64600; i < 65600; ++i) {
|
||||
if ((i & 7) < 3) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(0, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(125, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(375, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets as the first three and the fifth of every eight packets. The
|
||||
// set of three should be multiple loss and the fifth should be single loss.
|
||||
TEST_F(PacketLossStatsTest, FirstThreeAndFifthOfEight) {
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
if ((i & 7) < 3 || (i & 7) == 4) {
|
||||
stats_.AddLostPacket(i);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(125, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(125, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(375, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets as the first three and the fifth of every eight packets such
|
||||
// that the sequence numbers wrap in the middle of adding them.
|
||||
TEST_F(PacketLossStatsTest, FirstThreeAndFifthOfEightWrapped) {
|
||||
for (int i = 65500; i < 66500; ++i) {
|
||||
if ((i & 7) < 3 || (i & 7) == 4) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(125, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(125, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(375, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets as the first three and the fifth of every eight packets such
|
||||
// that the sequence numbers wrap near the end of adding them and there are
|
||||
// packets from before the wrapping still in the buffer.
|
||||
TEST_F(PacketLossStatsTest, FirstThreeAndFifthOfEightWrappedAtEnd) {
|
||||
for (int i = 64600; i < 65600; ++i) {
|
||||
if ((i & 7) < 3 || (i & 7) == 4) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(125, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(125, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(375, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets such that there is a multiple loss event that continues
|
||||
// around the wrapping of sequence numbers.
|
||||
TEST_F(PacketLossStatsTest, MultipleLossEventWrapped) {
|
||||
for (int i = 60000; i < 60500; i += 2) {
|
||||
stats_.AddLostPacket(i);
|
||||
}
|
||||
for (int i = 65530; i < 65540; ++i) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
EXPECT_EQ(250, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(1, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(10, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets such that there is a multiple loss event that continues
|
||||
// around the wrapping of sequence numbers and then is pushed out of the buffer.
|
||||
TEST_F(PacketLossStatsTest, MultipleLossEventWrappedPushedOut) {
|
||||
for (int i = 60000; i < 60500; i += 2) {
|
||||
stats_.AddLostPacket(i);
|
||||
}
|
||||
for (int i = 65530; i < 65540; ++i) {
|
||||
stats_.AddLostPacket(i & 0xFFFF);
|
||||
}
|
||||
for (int i = 1000; i < 1500; i += 2) {
|
||||
stats_.AddLostPacket(i);
|
||||
}
|
||||
EXPECT_EQ(500, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(1, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(10, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets out of order and ensure that they still get counted
|
||||
// correctly as single or multiple loss events.
|
||||
TEST_F(PacketLossStatsTest, OutOfOrder) {
|
||||
for (int i = 0; i < 1000; i += 10) {
|
||||
stats_.AddLostPacket(i + 5);
|
||||
stats_.AddLostPacket(i + 7);
|
||||
stats_.AddLostPacket(i + 4);
|
||||
stats_.AddLostPacket(i + 1);
|
||||
stats_.AddLostPacket(i + 2);
|
||||
}
|
||||
EXPECT_EQ(100, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(200, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(400, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
// Add loss packets out of order and ensure that they still get counted
|
||||
// correctly as single or multiple loss events, and wrap in the middle of
|
||||
// adding.
|
||||
TEST_F(PacketLossStatsTest, OutOfOrderWrapped) {
|
||||
for (int i = 65000; i < 66000; i += 10) {
|
||||
stats_.AddLostPacket((i + 5) & 0xFFFF);
|
||||
stats_.AddLostPacket((i + 7) & 0xFFFF);
|
||||
stats_.AddLostPacket((i + 4) & 0xFFFF);
|
||||
stats_.AddLostPacket((i + 1) & 0xFFFF);
|
||||
stats_.AddLostPacket((i + 2) & 0xFFFF);
|
||||
}
|
||||
EXPECT_EQ(100, stats_.GetSingleLossCount());
|
||||
EXPECT_EQ(200, stats_.GetMultipleLossEventCount());
|
||||
EXPECT_EQ(400, stats_.GetMultipleLossPacketCount());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -604,6 +604,31 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters(
|
||||
rtp_sender_.GetDataCounters(rtp_counters, rtx_counters);
|
||||
}
|
||||
|
||||
void ModuleRtpRtcpImpl::GetRtpPacketLossStats(
|
||||
bool outgoing,
|
||||
uint32_t ssrc,
|
||||
struct RtpPacketLossStats* loss_stats) const {
|
||||
if (!loss_stats) return;
|
||||
const PacketLossStats* stats_source = NULL;
|
||||
if (outgoing) {
|
||||
if (SSRC() == ssrc) {
|
||||
stats_source = &send_loss_stats_;
|
||||
}
|
||||
} else {
|
||||
if (rtcp_receiver_.RemoteSSRC() == ssrc) {
|
||||
stats_source = &receive_loss_stats_;
|
||||
}
|
||||
}
|
||||
if (stats_source) {
|
||||
loss_stats->single_packet_loss_count =
|
||||
stats_source->GetSingleLossCount();
|
||||
loss_stats->multiple_packet_loss_event_count =
|
||||
stats_source->GetMultipleLossEventCount();
|
||||
loss_stats->multiple_packet_loss_packet_count =
|
||||
stats_source->GetMultipleLossPacketCount();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* sender_info) {
|
||||
return rtcp_receiver_.SenderInfoReceived(sender_info);
|
||||
}
|
||||
@ -677,6 +702,9 @@ int ModuleRtpRtcpImpl::SetSelectiveRetransmissions(uint8_t settings) {
|
||||
// Send a Negative acknowledgment packet.
|
||||
int32_t ModuleRtpRtcpImpl::SendNACK(const uint16_t* nack_list,
|
||||
const uint16_t size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
receive_loss_stats_.AddLostPacket(nack_list[i]);
|
||||
}
|
||||
uint16_t nack_length = size;
|
||||
uint16_t start_id = 0;
|
||||
int64_t now = clock_->TimeInMilliseconds();
|
||||
@ -892,6 +920,9 @@ bool ModuleRtpRtcpImpl::SendTimeOfXrRrReport(
|
||||
|
||||
void ModuleRtpRtcpImpl::OnReceivedNACK(
|
||||
const std::list<uint16_t>& nack_sequence_numbers) {
|
||||
for (uint16_t nack_sequence_number : nack_sequence_numbers) {
|
||||
send_loss_stats_.AddLostPacket(nack_sequence_number);
|
||||
}
|
||||
if (!rtp_sender_.StorePackets() ||
|
||||
nack_sequence_numbers.size() == 0) {
|
||||
return;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/packet_loss_stats.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
|
||||
@ -170,6 +171,11 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
|
||||
StreamDataCounters* rtp_counters,
|
||||
StreamDataCounters* rtx_counters) const override;
|
||||
|
||||
void GetRtpPacketLossStats(
|
||||
bool outgoing,
|
||||
uint32_t ssrc,
|
||||
struct RtpPacketLossStats* loss_stats) const override;
|
||||
|
||||
// Get received RTCP report, sender info.
|
||||
int32_t RemoteRTCPStat(RTCPSenderInfo* sender_info) override;
|
||||
|
||||
@ -374,6 +380,9 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
|
||||
|
||||
RtcpRttStats* rtt_stats_;
|
||||
|
||||
PacketLossStats send_loss_stats_;
|
||||
PacketLossStats receive_loss_stats_;
|
||||
|
||||
// The processed RTT from RtcpRttStats.
|
||||
rtc::scoped_ptr<CriticalSectionWrapper> critical_section_rtt_;
|
||||
int64_t rtt_ms_;
|
||||
|
Reference in New Issue
Block a user