Delete StreamDataCountersCallback from ReceiveStatistics
Bug: webrtc:10679 Change-Id: Ife6a4f598c5b70478244b15fc884f6a424d1505b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148521 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28841}
This commit is contained in:
@ -57,10 +57,9 @@ class ReceiveStatistics : public ReceiveStatisticsProvider,
|
|||||||
public:
|
public:
|
||||||
~ReceiveStatistics() override = default;
|
~ReceiveStatistics() override = default;
|
||||||
|
|
||||||
static std::unique_ptr<ReceiveStatistics> Create(Clock* clock) {
|
static std::unique_ptr<ReceiveStatistics> Create(Clock* clock);
|
||||||
return Create(clock, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
RTC_DEPRECATED
|
||||||
static std::unique_ptr<ReceiveStatistics> Create(
|
static std::unique_ptr<ReceiveStatistics> Create(
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
StreamDataCountersCallback* rtp_callback);
|
StreamDataCountersCallback* rtp_callback);
|
||||||
|
@ -30,11 +30,9 @@ const int64_t kStatisticsProcessIntervalMs = 1000;
|
|||||||
|
|
||||||
StreamStatistician::~StreamStatistician() {}
|
StreamStatistician::~StreamStatistician() {}
|
||||||
|
|
||||||
StreamStatisticianImpl::StreamStatisticianImpl(
|
StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc,
|
||||||
uint32_t ssrc,
|
Clock* clock,
|
||||||
Clock* clock,
|
int max_reordering_threshold)
|
||||||
int max_reordering_threshold,
|
|
||||||
StreamDataCountersCallback* rtp_callback)
|
|
||||||
: ssrc_(ssrc),
|
: ssrc_(ssrc),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
incoming_bitrate_(kStatisticsProcessIntervalMs,
|
incoming_bitrate_(kStatisticsProcessIntervalMs,
|
||||||
@ -49,15 +47,12 @@ StreamStatisticianImpl::StreamStatisticianImpl(
|
|||||||
received_seq_max_(-1),
|
received_seq_max_(-1),
|
||||||
last_report_inorder_packets_(0),
|
last_report_inorder_packets_(0),
|
||||||
last_report_old_packets_(0),
|
last_report_old_packets_(0),
|
||||||
last_report_seq_max_(-1),
|
last_report_seq_max_(-1) {}
|
||||||
rtp_callback_(rtp_callback) {}
|
|
||||||
|
|
||||||
StreamStatisticianImpl::~StreamStatisticianImpl() = default;
|
StreamStatisticianImpl::~StreamStatisticianImpl() = default;
|
||||||
|
|
||||||
void StreamStatisticianImpl::OnRtpPacket(const RtpPacketReceived& packet) {
|
void StreamStatisticianImpl::OnRtpPacket(const RtpPacketReceived& packet) {
|
||||||
StreamDataCounters counters = UpdateCounters(packet);
|
UpdateCounters(packet);
|
||||||
if (rtp_callback_)
|
|
||||||
rtp_callback_->DataCountersUpdated(counters, ssrc_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StreamStatisticianImpl::UpdateOutOfOrder(const RtpPacketReceived& packet,
|
bool StreamStatisticianImpl::UpdateOutOfOrder(const RtpPacketReceived& packet,
|
||||||
@ -156,14 +151,8 @@ void StreamStatisticianImpl::UpdateJitter(const RtpPacketReceived& packet,
|
|||||||
|
|
||||||
void StreamStatisticianImpl::FecPacketReceived(
|
void StreamStatisticianImpl::FecPacketReceived(
|
||||||
const RtpPacketReceived& packet) {
|
const RtpPacketReceived& packet) {
|
||||||
StreamDataCounters counters;
|
rtc::CritScope cs(&stream_lock_);
|
||||||
{
|
receive_counters_.fec.AddPacket(packet);
|
||||||
rtc::CritScope cs(&stream_lock_);
|
|
||||||
receive_counters_.fec.AddPacket(packet);
|
|
||||||
counters = receive_counters_;
|
|
||||||
}
|
|
||||||
if (rtp_callback_)
|
|
||||||
rtp_callback_->DataCountersUpdated(counters, ssrc_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamStatisticianImpl::SetMaxReorderingThreshold(
|
void StreamStatisticianImpl::SetMaxReorderingThreshold(
|
||||||
@ -332,10 +321,15 @@ bool StreamStatisticianImpl::IsRetransmitOfOldPacket(
|
|||||||
return time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms;
|
return time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(Clock* clock) {
|
||||||
|
return absl::make_unique<ReceiveStatisticsImpl>(clock);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(
|
std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
StreamDataCountersCallback* rtp_callback) {
|
StreamDataCountersCallback* rtp_callback) {
|
||||||
return absl::make_unique<ReceiveStatisticsImpl>(clock, rtp_callback);
|
RTC_CHECK(rtp_callback == nullptr);
|
||||||
|
return Create(clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(
|
std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(
|
||||||
@ -343,16 +337,14 @@ std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(
|
|||||||
RtcpStatisticsCallback* rtcp_callback,
|
RtcpStatisticsCallback* rtcp_callback,
|
||||||
StreamDataCountersCallback* rtp_callback) {
|
StreamDataCountersCallback* rtp_callback) {
|
||||||
RTC_CHECK(rtcp_callback == nullptr);
|
RTC_CHECK(rtcp_callback == nullptr);
|
||||||
return Create(clock, rtp_callback);
|
RTC_CHECK(rtp_callback == nullptr);
|
||||||
|
return Create(clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceiveStatisticsImpl::ReceiveStatisticsImpl(
|
ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock)
|
||||||
Clock* clock,
|
|
||||||
StreamDataCountersCallback* rtp_callback)
|
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
last_returned_ssrc_(0),
|
last_returned_ssrc_(0),
|
||||||
max_reordering_threshold_(kDefaultMaxReorderingThreshold),
|
max_reordering_threshold_(kDefaultMaxReorderingThreshold) {}
|
||||||
rtp_stats_callback_(rtp_callback) {}
|
|
||||||
|
|
||||||
ReceiveStatisticsImpl::~ReceiveStatisticsImpl() {
|
ReceiveStatisticsImpl::~ReceiveStatisticsImpl() {
|
||||||
while (!statisticians_.empty()) {
|
while (!statisticians_.empty()) {
|
||||||
@ -391,8 +383,7 @@ StreamStatisticianImpl* ReceiveStatisticsImpl::GetOrCreateStatistician(
|
|||||||
rtc::CritScope cs(&receive_statistics_lock_);
|
rtc::CritScope cs(&receive_statistics_lock_);
|
||||||
StreamStatisticianImpl*& impl = statisticians_[ssrc];
|
StreamStatisticianImpl*& impl = statisticians_[ssrc];
|
||||||
if (impl == nullptr) { // new element
|
if (impl == nullptr) { // new element
|
||||||
impl = new StreamStatisticianImpl(ssrc, clock_, max_reordering_threshold_,
|
impl = new StreamStatisticianImpl(ssrc, clock_, max_reordering_threshold_);
|
||||||
rtp_stats_callback_);
|
|
||||||
}
|
}
|
||||||
return impl;
|
return impl;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,7 @@ class StreamStatisticianImpl : public StreamStatistician,
|
|||||||
public:
|
public:
|
||||||
StreamStatisticianImpl(uint32_t ssrc,
|
StreamStatisticianImpl(uint32_t ssrc,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
int max_reordering_threshold,
|
int max_reordering_threshold);
|
||||||
StreamDataCountersCallback* rtp_callback);
|
|
||||||
~StreamStatisticianImpl() override;
|
~StreamStatisticianImpl() override;
|
||||||
|
|
||||||
// |reset| here and in next method restarts calculation of fraction_lost stat.
|
// |reset| here and in next method restarts calculation of fraction_lost stat.
|
||||||
@ -98,15 +97,11 @@ class StreamStatisticianImpl : public StreamStatistician,
|
|||||||
uint32_t last_report_old_packets_ RTC_GUARDED_BY(&stream_lock_);
|
uint32_t last_report_old_packets_ RTC_GUARDED_BY(&stream_lock_);
|
||||||
int64_t last_report_seq_max_ RTC_GUARDED_BY(&stream_lock_);
|
int64_t last_report_seq_max_ RTC_GUARDED_BY(&stream_lock_);
|
||||||
RtcpStatistics last_reported_statistics_ RTC_GUARDED_BY(&stream_lock_);
|
RtcpStatistics last_reported_statistics_ RTC_GUARDED_BY(&stream_lock_);
|
||||||
|
|
||||||
// stream_lock_ shouldn't be held when calling callbacks.
|
|
||||||
StreamDataCountersCallback* const rtp_callback_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReceiveStatisticsImpl : public ReceiveStatistics {
|
class ReceiveStatisticsImpl : public ReceiveStatistics {
|
||||||
public:
|
public:
|
||||||
ReceiveStatisticsImpl(Clock* clock,
|
explicit ReceiveStatisticsImpl(Clock* clock);
|
||||||
StreamDataCountersCallback* rtp_callback);
|
|
||||||
|
|
||||||
~ReceiveStatisticsImpl() override;
|
~ReceiveStatisticsImpl() override;
|
||||||
|
|
||||||
@ -134,8 +129,6 @@ class ReceiveStatisticsImpl : public ReceiveStatistics {
|
|||||||
int max_reordering_threshold_ RTC_GUARDED_BY(receive_statistics_lock_);
|
int max_reordering_threshold_ RTC_GUARDED_BY(receive_statistics_lock_);
|
||||||
std::map<uint32_t, StreamStatisticianImpl*> statisticians_
|
std::map<uint32_t, StreamStatisticianImpl*> statisticians_
|
||||||
RTC_GUARDED_BY(receive_statistics_lock_);
|
RTC_GUARDED_BY(receive_statistics_lock_);
|
||||||
|
|
||||||
StreamDataCountersCallback* const rtp_stats_callback_;
|
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
|
#endif // MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
|
||||||
|
@ -68,8 +68,7 @@ void IncrementSequenceNumber(RtpPacketReceived* packet) {
|
|||||||
class ReceiveStatisticsTest : public ::testing::Test {
|
class ReceiveStatisticsTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
ReceiveStatisticsTest()
|
ReceiveStatisticsTest()
|
||||||
: clock_(0),
|
: clock_(0), receive_statistics_(ReceiveStatistics::Create(&clock_)) {
|
||||||
receive_statistics_(ReceiveStatistics::Create(&clock_, nullptr)) {
|
|
||||||
packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
|
packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
|
||||||
packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
|
packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
|
||||||
}
|
}
|
||||||
@ -460,45 +459,8 @@ TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
|
|||||||
EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number);
|
EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RtpTestCallback : public StreamDataCountersCallback {
|
TEST_F(ReceiveStatisticsTest, StreamDataCounters) {
|
||||||
public:
|
receive_statistics_ = ReceiveStatistics::Create(&clock_);
|
||||||
RtpTestCallback()
|
|
||||||
: StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {}
|
|
||||||
~RtpTestCallback() override = default;
|
|
||||||
|
|
||||||
void DataCountersUpdated(const StreamDataCounters& counters,
|
|
||||||
uint32_t ssrc) override {
|
|
||||||
ssrc_ = ssrc;
|
|
||||||
stats_ = counters;
|
|
||||||
++num_calls_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MatchPacketCounter(const RtpPacketCounter& expected,
|
|
||||||
const RtpPacketCounter& actual) {
|
|
||||||
EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
|
|
||||||
EXPECT_EQ(expected.header_bytes, actual.header_bytes);
|
|
||||||
EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
|
|
||||||
EXPECT_EQ(expected.packets, actual.packets);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Matches(uint32_t num_calls,
|
|
||||||
uint32_t ssrc,
|
|
||||||
const StreamDataCounters& expected) {
|
|
||||||
EXPECT_EQ(num_calls, num_calls_);
|
|
||||||
EXPECT_EQ(ssrc, ssrc_);
|
|
||||||
MatchPacketCounter(expected.transmitted, stats_.transmitted);
|
|
||||||
MatchPacketCounter(expected.retransmitted, stats_.retransmitted);
|
|
||||||
MatchPacketCounter(expected.fec, stats_.fec);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t num_calls_;
|
|
||||||
uint32_t ssrc_;
|
|
||||||
StreamDataCounters stats_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
|
|
||||||
RtpTestCallback callback;
|
|
||||||
receive_statistics_ = ReceiveStatistics::Create(&clock_, &callback);
|
|
||||||
receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
|
receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
|
||||||
|
|
||||||
const size_t kHeaderLength = 20;
|
const size_t kHeaderLength = 20;
|
||||||
@ -508,17 +470,17 @@ TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
|
|||||||
RtpPacketReceived packet1 =
|
RtpPacketReceived packet1 =
|
||||||
CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
|
CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
|
||||||
receive_statistics_->OnRtpPacket(packet1);
|
receive_statistics_->OnRtpPacket(packet1);
|
||||||
StreamDataCounters expected;
|
StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
expected.transmitted.payload_bytes = kPacketSize1;
|
->GetReceiveStreamDataCounters();
|
||||||
expected.transmitted.header_bytes = kHeaderLength;
|
EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
|
||||||
expected.transmitted.padding_bytes = 0;
|
EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
|
||||||
expected.transmitted.packets = 1;
|
EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
|
||||||
expected.retransmitted.payload_bytes = 0;
|
EXPECT_EQ(counters.transmitted.packets, 1u);
|
||||||
expected.retransmitted.header_bytes = 0;
|
EXPECT_EQ(counters.retransmitted.payload_bytes, 0u);
|
||||||
expected.retransmitted.padding_bytes = 0;
|
EXPECT_EQ(counters.retransmitted.header_bytes, 0u);
|
||||||
expected.retransmitted.packets = 0;
|
EXPECT_EQ(counters.retransmitted.padding_bytes, 0u);
|
||||||
expected.fec.packets = 0;
|
EXPECT_EQ(counters.retransmitted.packets, 0u);
|
||||||
callback.Matches(1, kSsrc1, expected);
|
EXPECT_EQ(counters.fec.packets, 0u);
|
||||||
|
|
||||||
// Another packet of size kPacketSize1 with 9 bytes padding.
|
// Another packet of size kPacketSize1 with 9 bytes padding.
|
||||||
RtpPacketReceived packet2 =
|
RtpPacketReceived packet2 =
|
||||||
@ -526,77 +488,89 @@ TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
|
|||||||
packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
|
packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
|
||||||
clock_.AdvanceTimeMilliseconds(5);
|
clock_.AdvanceTimeMilliseconds(5);
|
||||||
receive_statistics_->OnRtpPacket(packet2);
|
receive_statistics_->OnRtpPacket(packet2);
|
||||||
expected.transmitted.payload_bytes = kPacketSize1 * 2;
|
counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
expected.transmitted.header_bytes = kHeaderLength * 2;
|
->GetReceiveStreamDataCounters();
|
||||||
expected.transmitted.padding_bytes = kPaddingLength;
|
EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 2);
|
||||||
expected.transmitted.packets = 2;
|
EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 2);
|
||||||
callback.Matches(2, kSsrc1, expected);
|
EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength);
|
||||||
|
EXPECT_EQ(counters.transmitted.packets, 2u);
|
||||||
|
|
||||||
clock_.AdvanceTimeMilliseconds(5);
|
clock_.AdvanceTimeMilliseconds(5);
|
||||||
// Retransmit last packet.
|
// Retransmit last packet.
|
||||||
receive_statistics_->OnRtpPacket(packet2);
|
receive_statistics_->OnRtpPacket(packet2);
|
||||||
expected.transmitted.payload_bytes = kPacketSize1 * 3;
|
counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
expected.transmitted.header_bytes = kHeaderLength * 3;
|
->GetReceiveStreamDataCounters();
|
||||||
expected.transmitted.padding_bytes = kPaddingLength * 2;
|
EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 3);
|
||||||
expected.transmitted.packets = 3;
|
EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 3);
|
||||||
expected.retransmitted.payload_bytes = kPacketSize1;
|
EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength * 2);
|
||||||
expected.retransmitted.header_bytes = kHeaderLength;
|
EXPECT_EQ(counters.transmitted.packets, 3u);
|
||||||
expected.retransmitted.padding_bytes = kPaddingLength;
|
EXPECT_EQ(counters.retransmitted.payload_bytes, kPacketSize1);
|
||||||
expected.retransmitted.packets = 1;
|
EXPECT_EQ(counters.retransmitted.header_bytes, kHeaderLength);
|
||||||
callback.Matches(3, kSsrc1, expected);
|
EXPECT_EQ(counters.retransmitted.padding_bytes, kPaddingLength);
|
||||||
|
EXPECT_EQ(counters.retransmitted.packets, 1u);
|
||||||
|
|
||||||
// One FEC packet.
|
// One FEC packet.
|
||||||
packet1.SetSequenceNumber(packet2.SequenceNumber() + 1);
|
packet1.SetSequenceNumber(packet2.SequenceNumber() + 1);
|
||||||
clock_.AdvanceTimeMilliseconds(5);
|
clock_.AdvanceTimeMilliseconds(5);
|
||||||
receive_statistics_->OnRtpPacket(packet1);
|
receive_statistics_->OnRtpPacket(packet1);
|
||||||
receive_statistics_->FecPacketReceived(packet1);
|
receive_statistics_->FecPacketReceived(packet1);
|
||||||
expected.transmitted.payload_bytes = kPacketSize1 * 4;
|
counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
expected.transmitted.header_bytes = kHeaderLength * 4;
|
->GetReceiveStreamDataCounters();
|
||||||
expected.transmitted.packets = 4;
|
EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 4);
|
||||||
expected.fec.payload_bytes = kPacketSize1;
|
EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 4);
|
||||||
expected.fec.header_bytes = kHeaderLength;
|
EXPECT_EQ(counters.transmitted.packets, 4u);
|
||||||
expected.fec.packets = 1;
|
EXPECT_EQ(counters.fec.payload_bytes, kPacketSize1);
|
||||||
callback.Matches(5, kSsrc1, expected);
|
EXPECT_EQ(counters.fec.header_bytes, kHeaderLength);
|
||||||
|
EXPECT_EQ(counters.fec.packets, 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
|
TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
|
||||||
RtpTestCallback callback;
|
receive_statistics_ = ReceiveStatistics::Create(&clock_);
|
||||||
receive_statistics_ = ReceiveStatistics::Create(&clock_, &callback);
|
|
||||||
|
|
||||||
clock_.AdvanceTimeMilliseconds(42);
|
clock_.AdvanceTimeMilliseconds(42);
|
||||||
receive_statistics_->OnRtpPacket(packet1_);
|
receive_statistics_->OnRtpPacket(packet1_);
|
||||||
EXPECT_EQ(42, callback.stats_.last_packet_received_timestamp_ms);
|
StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
|
->GetReceiveStreamDataCounters();
|
||||||
|
|
||||||
|
EXPECT_EQ(42, counters.last_packet_received_timestamp_ms);
|
||||||
|
|
||||||
clock_.AdvanceTimeMilliseconds(3);
|
clock_.AdvanceTimeMilliseconds(3);
|
||||||
receive_statistics_->OnRtpPacket(packet1_);
|
receive_statistics_->OnRtpPacket(packet1_);
|
||||||
EXPECT_EQ(45, callback.stats_.last_packet_received_timestamp_ms);
|
counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
|
->GetReceiveStreamDataCounters();
|
||||||
|
EXPECT_EQ(45, counters.last_packet_received_timestamp_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
|
TEST_F(ReceiveStatisticsTest, FecFirst) {
|
||||||
RtpTestCallback callback;
|
receive_statistics_ = ReceiveStatistics::Create(&clock_);
|
||||||
receive_statistics_ = ReceiveStatistics::Create(&clock_, &callback);
|
|
||||||
|
|
||||||
const uint32_t kHeaderLength = 20;
|
const uint32_t kHeaderLength = 20;
|
||||||
RtpPacketReceived packet =
|
RtpPacketReceived packet =
|
||||||
CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
|
CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
|
||||||
// If first packet is FEC, ignore it.
|
// If first packet is FEC, ignore it.
|
||||||
receive_statistics_->FecPacketReceived(packet);
|
receive_statistics_->FecPacketReceived(packet);
|
||||||
EXPECT_EQ(0u, callback.num_calls_);
|
|
||||||
|
EXPECT_EQ(receive_statistics_->GetStatistician(kSsrc1), nullptr);
|
||||||
|
|
||||||
receive_statistics_->OnRtpPacket(packet);
|
receive_statistics_->OnRtpPacket(packet);
|
||||||
StreamDataCounters expected;
|
StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
expected.transmitted.payload_bytes = kPacketSize1;
|
->GetReceiveStreamDataCounters();
|
||||||
expected.transmitted.header_bytes = kHeaderLength;
|
EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
|
||||||
expected.transmitted.padding_bytes = 0;
|
EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
|
||||||
expected.transmitted.packets = 1;
|
EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
|
||||||
expected.fec.packets = 0;
|
EXPECT_EQ(counters.transmitted.packets, 1u);
|
||||||
callback.Matches(1, kSsrc1, expected);
|
EXPECT_EQ(counters.fec.packets, 0u);
|
||||||
|
|
||||||
receive_statistics_->FecPacketReceived(packet);
|
receive_statistics_->FecPacketReceived(packet);
|
||||||
expected.fec.payload_bytes = kPacketSize1;
|
counters = receive_statistics_->GetStatistician(kSsrc1)
|
||||||
expected.fec.header_bytes = kHeaderLength;
|
->GetReceiveStreamDataCounters();
|
||||||
expected.fec.packets = 1;
|
EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
|
||||||
callback.Matches(2, kSsrc1, expected);
|
EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
|
||||||
|
EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
|
||||||
|
EXPECT_EQ(counters.transmitted.packets, 1u);
|
||||||
|
EXPECT_EQ(counters.fec.payload_bytes, kPacketSize1);
|
||||||
|
EXPECT_EQ(counters.fec.header_bytes, kHeaderLength);
|
||||||
|
EXPECT_EQ(counters.fec.packets, 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -118,15 +118,12 @@ ReceiveStatisticsProxy::ReceiveStatisticsProxy(
|
|||||||
decode_thread_.Detach();
|
decode_thread_.Detach();
|
||||||
network_thread_.Detach();
|
network_thread_.Detach();
|
||||||
stats_.ssrc = config_.rtp.remote_ssrc;
|
stats_.ssrc = config_.rtp.remote_ssrc;
|
||||||
// TODO(brandtr): Replace |rtx_stats_| with a single instance of
|
|
||||||
// StreamDataCounters.
|
|
||||||
if (config_.rtp.rtx_ssrc) {
|
|
||||||
rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveStatisticsProxy::UpdateHistograms(
|
void ReceiveStatisticsProxy::UpdateHistograms(
|
||||||
absl::optional<int> fraction_lost) {
|
absl::optional<int> fraction_lost,
|
||||||
|
const StreamDataCounters& rtp_stats,
|
||||||
|
const StreamDataCounters* rtx_stats) {
|
||||||
// Not actually running on the decoder thread, but must be called after
|
// Not actually running on the decoder thread, but must be called after
|
||||||
// DecoderThreadStopped, which detaches the thread checker. It is therefore
|
// DecoderThreadStopped, which detaches the thread checker. It is therefore
|
||||||
// safe to access |qp_counters_|, which were updated on the decode thread
|
// safe to access |qp_counters_|, which were updated on the decode thread
|
||||||
@ -404,42 +401,42 @@ void ReceiveStatisticsProxy::UpdateHistograms(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamDataCounters rtp = stats_.rtp_stats;
|
StreamDataCounters rtp_rtx_stats = rtp_stats;
|
||||||
StreamDataCounters rtx;
|
if (rtx_stats)
|
||||||
for (auto it : rtx_stats_)
|
rtp_rtx_stats.Add(*rtx_stats);
|
||||||
rtx.Add(it.second);
|
|
||||||
StreamDataCounters rtp_rtx = rtp;
|
|
||||||
rtp_rtx.Add(rtx);
|
|
||||||
int64_t elapsed_sec =
|
int64_t elapsed_sec =
|
||||||
rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000;
|
rtp_rtx_stats.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) /
|
||||||
|
1000;
|
||||||
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
||||||
RTC_HISTOGRAM_COUNTS_10000(
|
RTC_HISTOGRAM_COUNTS_10000(
|
||||||
"WebRTC.Video.BitrateReceivedInKbps",
|
"WebRTC.Video.BitrateReceivedInKbps",
|
||||||
static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
|
static_cast<int>(rtp_rtx_stats.transmitted.TotalBytes() * 8 /
|
||||||
1000));
|
elapsed_sec / 1000));
|
||||||
int media_bitrate_kbs =
|
int media_bitrate_kbs = static_cast<int>(rtp_stats.MediaPayloadBytes() * 8 /
|
||||||
static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000);
|
elapsed_sec / 1000);
|
||||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.MediaBitrateReceivedInKbps",
|
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.MediaBitrateReceivedInKbps",
|
||||||
media_bitrate_kbs);
|
media_bitrate_kbs);
|
||||||
log_stream << "WebRTC.Video.MediaBitrateReceivedInKbps "
|
log_stream << "WebRTC.Video.MediaBitrateReceivedInKbps "
|
||||||
<< media_bitrate_kbs << '\n';
|
<< media_bitrate_kbs << '\n';
|
||||||
RTC_HISTOGRAM_COUNTS_10000(
|
RTC_HISTOGRAM_COUNTS_10000(
|
||||||
"WebRTC.Video.PaddingBitrateReceivedInKbps",
|
"WebRTC.Video.PaddingBitrateReceivedInKbps",
|
||||||
static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
|
static_cast<int>(rtp_rtx_stats.transmitted.padding_bytes * 8 /
|
||||||
1000));
|
elapsed_sec / 1000));
|
||||||
RTC_HISTOGRAM_COUNTS_10000(
|
RTC_HISTOGRAM_COUNTS_10000(
|
||||||
"WebRTC.Video.RetransmittedBitrateReceivedInKbps",
|
"WebRTC.Video.RetransmittedBitrateReceivedInKbps",
|
||||||
static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec /
|
static_cast<int>(rtp_rtx_stats.retransmitted.TotalBytes() * 8 /
|
||||||
1000));
|
elapsed_sec / 1000));
|
||||||
if (!rtx_stats_.empty()) {
|
if (rtx_stats) {
|
||||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateReceivedInKbps",
|
RTC_HISTOGRAM_COUNTS_10000(
|
||||||
static_cast<int>(rtx.transmitted.TotalBytes() *
|
"WebRTC.Video.RtxBitrateReceivedInKbps",
|
||||||
8 / elapsed_sec / 1000));
|
static_cast<int>(rtx_stats->transmitted.TotalBytes() * 8 /
|
||||||
|
elapsed_sec / 1000));
|
||||||
}
|
}
|
||||||
if (config_.rtp.ulpfec_payload_type != -1) {
|
if (config_.rtp.ulpfec_payload_type != -1) {
|
||||||
RTC_HISTOGRAM_COUNTS_10000(
|
RTC_HISTOGRAM_COUNTS_10000(
|
||||||
"WebRTC.Video.FecBitrateReceivedInKbps",
|
"WebRTC.Video.FecBitrateReceivedInKbps",
|
||||||
static_cast<int>(rtp_rtx.fec.TotalBytes() * 8 / elapsed_sec / 1000));
|
static_cast<int>(rtp_rtx_stats.fec.TotalBytes() * 8 / elapsed_sec /
|
||||||
|
1000));
|
||||||
}
|
}
|
||||||
const RtcpPacketTypeCounter& counters = stats_.rtcp_packet_type_counts;
|
const RtcpPacketTypeCounter& counters = stats_.rtcp_packet_type_counts;
|
||||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute",
|
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute",
|
||||||
@ -667,22 +664,6 @@ void ReceiveStatisticsProxy::OnCname(uint32_t ssrc, absl::string_view cname) {
|
|||||||
stats_.c_name = std::string(cname);
|
stats_.c_name = std::string(cname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveStatisticsProxy::DataCountersUpdated(
|
|
||||||
const webrtc::StreamDataCounters& counters,
|
|
||||||
uint32_t ssrc) {
|
|
||||||
rtc::CritScope lock(&crit_);
|
|
||||||
if (ssrc == stats_.ssrc) {
|
|
||||||
stats_.rtp_stats = counters;
|
|
||||||
} else {
|
|
||||||
auto it = rtx_stats_.find(ssrc);
|
|
||||||
if (it != rtx_stats_.end()) {
|
|
||||||
it->second = counters;
|
|
||||||
} else {
|
|
||||||
RTC_NOTREACHED() << "Unexpected stream ssrc: " << ssrc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReceiveStatisticsProxy::OnDecodedFrame(const VideoFrame& frame,
|
void ReceiveStatisticsProxy::OnDecodedFrame(const VideoFrame& frame,
|
||||||
absl::optional<uint8_t> qp,
|
absl::optional<uint8_t> qp,
|
||||||
int32_t decode_time_ms,
|
int32_t decode_time_ms,
|
||||||
|
@ -39,7 +39,6 @@ struct CodecSpecificInfo;
|
|||||||
class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
|
class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
|
||||||
public RtcpCnameCallback,
|
public RtcpCnameCallback,
|
||||||
public RtcpPacketTypeCounterObserver,
|
public RtcpPacketTypeCounterObserver,
|
||||||
public StreamDataCountersCallback,
|
|
||||||
public CallStatsObserver {
|
public CallStatsObserver {
|
||||||
public:
|
public:
|
||||||
ReceiveStatisticsProxy(const VideoReceiveStream::Config* config,
|
ReceiveStatisticsProxy(const VideoReceiveStream::Config* config,
|
||||||
@ -84,9 +83,6 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
|
|||||||
void RtcpPacketTypesCounterUpdated(
|
void RtcpPacketTypesCounterUpdated(
|
||||||
uint32_t ssrc,
|
uint32_t ssrc,
|
||||||
const RtcpPacketTypeCounter& packet_counter) override;
|
const RtcpPacketTypeCounter& packet_counter) override;
|
||||||
// Overrides StreamDataCountersCallback.
|
|
||||||
void DataCountersUpdated(const webrtc::StreamDataCounters& counters,
|
|
||||||
uint32_t ssrc) override;
|
|
||||||
|
|
||||||
// Implements CallStatsObserver.
|
// Implements CallStatsObserver.
|
||||||
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
|
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
|
||||||
@ -98,7 +94,9 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
|
|||||||
|
|
||||||
// Produce histograms. Must be called after DecoderThreadStopped(), typically
|
// Produce histograms. Must be called after DecoderThreadStopped(), typically
|
||||||
// at the end of the call.
|
// at the end of the call.
|
||||||
void UpdateHistograms(absl::optional<int> fraction_lost);
|
void UpdateHistograms(absl::optional<int> fraction_lost,
|
||||||
|
const StreamDataCounters& rtp_stats,
|
||||||
|
const StreamDataCounters* rtx_stats);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct QpCounters {
|
struct QpCounters {
|
||||||
@ -147,6 +145,7 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
|
|||||||
rtc::SampleCounter qp_sample_ RTC_GUARDED_BY(crit_);
|
rtc::SampleCounter qp_sample_ RTC_GUARDED_BY(crit_);
|
||||||
int num_bad_states_ RTC_GUARDED_BY(crit_);
|
int num_bad_states_ RTC_GUARDED_BY(crit_);
|
||||||
int num_certain_states_ RTC_GUARDED_BY(crit_);
|
int num_certain_states_ RTC_GUARDED_BY(crit_);
|
||||||
|
// Note: The |stats_.rtp_stats| member is not used or populated by this class.
|
||||||
mutable VideoReceiveStream::Stats stats_ RTC_GUARDED_BY(crit_);
|
mutable VideoReceiveStream::Stats stats_ RTC_GUARDED_BY(crit_);
|
||||||
RateStatistics decode_fps_estimator_ RTC_GUARDED_BY(crit_);
|
RateStatistics decode_fps_estimator_ RTC_GUARDED_BY(crit_);
|
||||||
RateStatistics renders_fps_estimator_ RTC_GUARDED_BY(crit_);
|
RateStatistics renders_fps_estimator_ RTC_GUARDED_BY(crit_);
|
||||||
@ -166,7 +165,6 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
|
|||||||
RTC_GUARDED_BY(crit_);
|
RTC_GUARDED_BY(crit_);
|
||||||
MaxCounter freq_offset_counter_ RTC_GUARDED_BY(crit_);
|
MaxCounter freq_offset_counter_ RTC_GUARDED_BY(crit_);
|
||||||
QpCounters qp_counters_ RTC_GUARDED_BY(decode_thread_);
|
QpCounters qp_counters_ RTC_GUARDED_BY(decode_thread_);
|
||||||
std::map<uint32_t, StreamDataCounters> rtx_stats_ RTC_GUARDED_BY(crit_);
|
|
||||||
int64_t avg_rtt_ms_ RTC_GUARDED_BY(crit_);
|
int64_t avg_rtt_ms_ RTC_GUARDED_BY(crit_);
|
||||||
mutable std::map<int64_t, size_t> frame_window_ RTC_GUARDED_BY(&crit_);
|
mutable std::map<int64_t, size_t> frame_window_ RTC_GUARDED_BY(&crit_);
|
||||||
VideoContentType last_content_type_ RTC_GUARDED_BY(&crit_);
|
VideoContentType last_content_type_ RTC_GUARDED_BY(&crit_);
|
||||||
|
@ -53,12 +53,6 @@ class ReceiveStatisticsProxyTest : public ::testing::Test {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertFirstRtpPacket(uint32_t ssrc) {
|
|
||||||
StreamDataCounters counters;
|
|
||||||
counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
|
|
||||||
statistics_proxy_->DataCountersUpdated(counters, ssrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoFrame CreateFrame(int width, int height) {
|
VideoFrame CreateFrame(int width, int height) {
|
||||||
return CreateVideoFrame(width, height, 0);
|
return CreateVideoFrame(width, height, 0);
|
||||||
}
|
}
|
||||||
@ -103,7 +97,8 @@ TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsReported) {
|
|||||||
VideoContentType::UNSPECIFIED);
|
VideoContentType::UNSPECIFIED);
|
||||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||||
}
|
}
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps));
|
||||||
}
|
}
|
||||||
@ -117,7 +112,8 @@ TEST_F(ReceiveStatisticsProxyTest, DecodedFpsIsNotReportedForTooFewSamples) {
|
|||||||
VideoContentType::UNSPECIFIED);
|
VideoContentType::UNSPECIFIED);
|
||||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||||
}
|
}
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,7 +521,8 @@ TEST_F(ReceiveStatisticsProxyTest, LifetimeHistogramIsUpdated) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
|
fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
|
||||||
// Need at least one frame to report stream lifetime.
|
// Need at least one frame to report stream lifetime.
|
||||||
statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
|
statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1,
|
EXPECT_EQ(1,
|
||||||
metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
|
metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
|
||||||
@ -537,7 +534,8 @@ TEST_F(ReceiveStatisticsProxyTest,
|
|||||||
const int64_t kTimeSec = 3;
|
const int64_t kTimeSec = 3;
|
||||||
fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
|
fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
|
||||||
// No frames received.
|
// No frames received.
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0,
|
EXPECT_EQ(0,
|
||||||
metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
|
metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
|
||||||
}
|
}
|
||||||
@ -552,7 +550,6 @@ TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
|
|||||||
|
|
||||||
StreamDataCounters counters;
|
StreamDataCounters counters;
|
||||||
counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
|
counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
|
||||||
statistics_proxy_->DataCountersUpdated(counters, config_.rtp.remote_ssrc);
|
|
||||||
|
|
||||||
webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
|
webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
|
||||||
|
|
||||||
@ -560,7 +557,7 @@ TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kBadFameIntervalMs);
|
fake_clock_.AdvanceTimeMilliseconds(kBadFameIntervalMs);
|
||||||
statistics_proxy_->OnRenderedFrame(frame);
|
statistics_proxy_->OnRenderedFrame(frame);
|
||||||
}
|
}
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, counters, nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
|
||||||
|
|
||||||
@ -573,7 +570,7 @@ TEST_F(ReceiveStatisticsProxyTest, BadCallHistogramsAreUpdated) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
|
TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
|
||||||
statistics_proxy_->UpdateHistograms(10);
|
statistics_proxy_->UpdateHistograms(10, StreamDataCounters(), nullptr);
|
||||||
EXPECT_EQ(0,
|
EXPECT_EQ(0,
|
||||||
metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
|
metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
|
||||||
|
|
||||||
@ -582,7 +579,7 @@ TEST_F(ReceiveStatisticsProxyTest, PacketLossHistogramIsUpdated) {
|
|||||||
|
|
||||||
// Min run time has passed.
|
// Min run time has passed.
|
||||||
fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
|
fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
|
||||||
statistics_proxy_->UpdateHistograms(10);
|
statistics_proxy_->UpdateHistograms(10, StreamDataCounters(), nullptr);
|
||||||
EXPECT_EQ(1,
|
EXPECT_EQ(1,
|
||||||
metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
|
metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@ -603,7 +600,8 @@ TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) {
|
|||||||
const double kFreqKhz = 90.0;
|
const double kFreqKhz = 90.0;
|
||||||
for (int i = 0; i < kMinRequiredSamples; ++i)
|
for (int i = 0; i < kMinRequiredSamples; ++i)
|
||||||
statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
|
statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
|
||||||
EXPECT_EQ(1,
|
EXPECT_EQ(1,
|
||||||
metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
|
metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
|
||||||
@ -622,7 +620,8 @@ TEST_F(ReceiveStatisticsProxyTest, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
|
fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
|
||||||
// Process interval passed, max diff: 4.
|
// Process interval passed, max diff: 4.
|
||||||
statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
|
statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz);
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
// Average reported: (2 + 4) / 2 = 3.
|
// Average reported: (2 + 4) / 2 = 3.
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
|
||||||
@ -634,7 +633,8 @@ TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsUpdated) {
|
|||||||
for (int i = 0; i < kMinRequiredSamples; ++i)
|
for (int i = 0; i < kMinRequiredSamples; ++i)
|
||||||
statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
|
statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
|
||||||
}
|
}
|
||||||
@ -645,7 +645,8 @@ TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
|
|||||||
for (int i = 0; i < kMinRequiredSamples - 1; ++i)
|
for (int i = 0; i < kMinRequiredSamples - 1; ++i)
|
||||||
statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
|
statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +654,8 @@ TEST_F(ReceiveStatisticsProxyTest, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
|
|||||||
for (int i = 0; i < kMinRequiredSamples; ++i)
|
for (int i = 0; i < kMinRequiredSamples; ++i)
|
||||||
statistics_proxy_->OnPreDecode(kVideoCodecVP8, -1);
|
statistics_proxy_->OnPreDecode(kVideoCodecVP8, -1);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +672,8 @@ TEST_F(ReceiveStatisticsProxyTest,
|
|||||||
EXPECT_EQ(kMinRequiredSamples - 1,
|
EXPECT_EQ(kMinRequiredSamples - 1,
|
||||||
statistics_proxy_->GetStats().frame_counts.delta_frames);
|
statistics_proxy_->GetStats().frame_counts.delta_frames);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +690,8 @@ TEST_F(ReceiveStatisticsProxyTest,
|
|||||||
EXPECT_EQ(kMinRequiredSamples,
|
EXPECT_EQ(kMinRequiredSamples,
|
||||||
statistics_proxy_->GetStats().frame_counts.delta_frames);
|
statistics_proxy_->GetStats().frame_counts.delta_frames);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
|
||||||
EXPECT_EQ(1,
|
EXPECT_EQ(1,
|
||||||
metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
|
metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
|
||||||
@ -709,7 +713,8 @@ TEST_F(ReceiveStatisticsProxyTest, KeyFrameHistogramIsUpdated) {
|
|||||||
EXPECT_EQ(kMinRequiredSamples,
|
EXPECT_EQ(kMinRequiredSamples,
|
||||||
statistics_proxy_->GetStats().frame_counts.delta_frames);
|
statistics_proxy_->GetStats().frame_counts.delta_frames);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
|
1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
|
||||||
@ -729,7 +734,8 @@ TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsNotUpdatedForTooFewSamples) {
|
|||||||
kMinPlayoutDelayMs, kRenderDelayMs);
|
kMinPlayoutDelayMs, kRenderDelayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
|
||||||
@ -751,7 +757,8 @@ TEST_F(ReceiveStatisticsProxyTest, TimingHistogramsAreUpdated) {
|
|||||||
kMinPlayoutDelayMs, kRenderDelayMs);
|
kMinPlayoutDelayMs, kRenderDelayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
|
||||||
@ -807,7 +814,8 @@ TEST_F(ReceiveStatisticsProxyTest,
|
|||||||
for (int i = 0; i < kMinRequiredSamples - 1; ++i)
|
for (int i = 0; i < kMinRequiredSamples - 1; ++i)
|
||||||
statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
|
statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
|
||||||
@ -818,7 +826,8 @@ TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) {
|
|||||||
for (int i = 0; i < kMinRequiredSamples; ++i)
|
for (int i = 0; i < kMinRequiredSamples; ++i)
|
||||||
statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
|
statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight));
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
|
||||||
@ -840,7 +849,8 @@ TEST_F(ReceiveStatisticsProxyTest, ZeroDelayReportedIfFrameNotDelayed) {
|
|||||||
|
|
||||||
// Min run time has passed.
|
// Min run time has passed.
|
||||||
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 0));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 0));
|
||||||
EXPECT_EQ(0, metrics::NumSamples(
|
EXPECT_EQ(0, metrics::NumSamples(
|
||||||
@ -860,7 +870,8 @@ TEST_F(ReceiveStatisticsProxyTest,
|
|||||||
// Min run time has not passed.
|
// Min run time has not passed.
|
||||||
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
|
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
|
||||||
1);
|
1);
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples(
|
EXPECT_EQ(0, metrics::NumSamples(
|
||||||
"WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
|
"WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
|
||||||
@ -874,7 +885,8 @@ TEST_F(ReceiveStatisticsProxyTest,
|
|||||||
|
|
||||||
// Min run time has passed. No rendered frames.
|
// Min run time has passed. No rendered frames.
|
||||||
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples(
|
EXPECT_EQ(0, metrics::NumSamples(
|
||||||
"WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
|
"WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
|
||||||
@ -891,7 +903,8 @@ TEST_F(ReceiveStatisticsProxyTest, DelayReportedIfFrameIsDelayed) {
|
|||||||
|
|
||||||
// Min run time has passed.
|
// Min run time has passed.
|
||||||
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 100));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 100));
|
||||||
EXPECT_EQ(1, metrics::NumSamples(
|
EXPECT_EQ(1, metrics::NumSamples(
|
||||||
@ -914,7 +927,8 @@ TEST_F(ReceiveStatisticsProxyTest, AverageDelayOfDelayedFramesIsReported) {
|
|||||||
|
|
||||||
// Min run time has passed.
|
// Min run time has passed.
|
||||||
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 50));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 50));
|
||||||
EXPECT_EQ(1, metrics::NumSamples(
|
EXPECT_EQ(1, metrics::NumSamples(
|
||||||
@ -925,21 +939,24 @@ TEST_F(ReceiveStatisticsProxyTest, AverageDelayOfDelayedFramesIsReported) {
|
|||||||
|
|
||||||
TEST_F(ReceiveStatisticsProxyTest,
|
TEST_F(ReceiveStatisticsProxyTest,
|
||||||
RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
|
RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
|
||||||
InsertFirstRtpPacket(kRemoteSsrc);
|
StreamDataCounters data_counters;
|
||||||
|
data_counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
|
||||||
|
|
||||||
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
|
fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
|
||||||
1);
|
1);
|
||||||
|
|
||||||
RtcpPacketTypeCounter counter;
|
RtcpPacketTypeCounter counter;
|
||||||
statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
|
statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
|
TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
|
||||||
InsertFirstRtpPacket(kRemoteSsrc);
|
StreamDataCounters data_counters;
|
||||||
|
data_counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
|
||||||
fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
|
fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
|
||||||
|
|
||||||
const uint32_t kFirPackets = 100;
|
const uint32_t kFirPackets = 100;
|
||||||
@ -952,7 +969,7 @@ TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
|
|||||||
counter.nack_packets = kNackPackets;
|
counter.nack_packets = kNackPackets;
|
||||||
statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
|
statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
|
||||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
|
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
|
||||||
@ -1044,7 +1061,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, InterFrameDelaysAreReported) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
const int kExpectedInterFrame =
|
const int kExpectedInterFrame =
|
||||||
(kInterFrameDelayMs * (kMinRequiredSamples - 1) +
|
(kInterFrameDelayMs * (kMinRequiredSamples - 1) +
|
||||||
kInterFrameDelayMs * 2) /
|
kInterFrameDelayMs * 2) /
|
||||||
@ -1083,7 +1101,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent,
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(10 * kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(10 * kInterFrameDelayMs);
|
||||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
const int kExpectedInterFrame = kInterFrameDelayMs * 2;
|
const int kExpectedInterFrame = kInterFrameDelayMs * 2;
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||||
EXPECT_EQ(kExpectedInterFrame,
|
EXPECT_EQ(kExpectedInterFrame,
|
||||||
@ -1108,7 +1127,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent,
|
|||||||
|
|
||||||
// |kMinRequiredSamples| samples, and thereby intervals, is required. That
|
// |kMinRequiredSamples| samples, and thereby intervals, is required. That
|
||||||
// means we're one frame short of having a valid data set.
|
// means we're one frame short of having a valid data set.
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
|
||||||
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
|
EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@ -1137,7 +1157,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, MaxInterFrameDelayOnlyWithPause) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
|
1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
|
||||||
@ -1176,7 +1197,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, FreezesAreReported) {
|
|||||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
||||||
statistics_proxy_->OnRenderedFrame(frame);
|
statistics_proxy_->OnRenderedFrame(frame);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
const int kExpectedTimeBetweenFreezes =
|
const int kExpectedTimeBetweenFreezes =
|
||||||
kInterFrameDelayMs * (kMinRequiredSamples - 1);
|
kInterFrameDelayMs * (kMinRequiredSamples - 1);
|
||||||
const int kExpectedNumberFreezesPerMinute = 60 * 1000 / kCallDurationMs;
|
const int kExpectedNumberFreezesPerMinute = 60 * 1000 / kCallDurationMs;
|
||||||
@ -1226,7 +1248,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, HarmonicFrameRateIsReported) {
|
|||||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
|
||||||
statistics_proxy_->OnRenderedFrame(frame);
|
statistics_proxy_->OnRenderedFrame(frame);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
double kSumSquaredFrameDurationSecs =
|
double kSumSquaredFrameDurationSecs =
|
||||||
(kMinRequiredSamples - 1) *
|
(kMinRequiredSamples - 1) *
|
||||||
(kFrameDurationMs / 1000.0 * kFrameDurationMs / 1000.0);
|
(kFrameDurationMs / 1000.0 * kFrameDurationMs / 1000.0);
|
||||||
@ -1266,7 +1289,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, PausesAreIgnored) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
// Average of two playback intervals.
|
// Average of two playback intervals.
|
||||||
const int kExpectedTimeBetweenFreezes =
|
const int kExpectedTimeBetweenFreezes =
|
||||||
kInterFrameDelayMs * kMinRequiredSamples * 2;
|
kInterFrameDelayMs * kMinRequiredSamples * 2;
|
||||||
@ -1299,7 +1323,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, ManyPausesAtTheBeginning) {
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
// No freezes should be detected, as all long inter-frame delays were pauses.
|
// No freezes should be detected, as all long inter-frame delays were pauses.
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||||
EXPECT_EQ(-1, metrics::MinSample(
|
EXPECT_EQ(-1, metrics::MinSample(
|
||||||
@ -1331,7 +1356,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, TimeInHdReported) {
|
|||||||
// Extra last frame.
|
// Extra last frame.
|
||||||
statistics_proxy_->OnRenderedFrame(frame_sd);
|
statistics_proxy_->OnRenderedFrame(frame_sd);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
const int kExpectedTimeInHdPercents = 33;
|
const int kExpectedTimeInHdPercents = 33;
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@ -1365,7 +1391,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, TimeInBlockyVideoReported) {
|
|||||||
statistics_proxy_->OnDecodedFrame(frame, kHighQp, 0, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, kHighQp, 0, content_type_);
|
||||||
statistics_proxy_->OnRenderedFrame(frame);
|
statistics_proxy_->OnRenderedFrame(frame);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
const int kExpectedTimeInHdPercents = 66;
|
const int kExpectedTimeInHdPercents = 66;
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||||
EXPECT_EQ(kExpectedTimeInHdPercents,
|
EXPECT_EQ(kExpectedTimeInHdPercents,
|
||||||
@ -1398,7 +1425,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, DownscalesReported) {
|
|||||||
statistics_proxy_->OnRenderedFrame(frame_ld);
|
statistics_proxy_->OnRenderedFrame(frame_ld);
|
||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||||
|
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
const int kExpectedDownscales = 30; // 2 per 4 seconds = 30 per minute.
|
const int kExpectedDownscales = 30; // 2 per 4 seconds = 30 per minute.
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@ -1423,7 +1451,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, DecodeTimeReported) {
|
|||||||
statistics_proxy_->OnDecodedFrame(frame, kLowQp, kDecodeMs, content_type_);
|
statistics_proxy_->OnDecodedFrame(frame, kLowQp, kDecodeMs, content_type_);
|
||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||||
}
|
}
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
|
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1447,7 +1476,8 @@ TEST_P(ReceiveStatisticsProxyTestWithContent,
|
|||||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
|
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
|
||||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type);
|
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type);
|
||||||
}
|
}
|
||||||
statistics_proxy_->UpdateHistograms(absl::nullopt);
|
statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
|
||||||
|
nullptr);
|
||||||
|
|
||||||
if (videocontenttypehelpers::IsScreenshare(content_type)) {
|
if (videocontenttypehelpers::IsScreenshare(content_type)) {
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
|
@ -193,7 +193,7 @@ VideoReceiveStream::VideoReceiveStream(
|
|||||||
call_stats_(call_stats),
|
call_stats_(call_stats),
|
||||||
source_tracker_(clock_),
|
source_tracker_(clock_),
|
||||||
stats_proxy_(&config_, clock_),
|
stats_proxy_(&config_, clock_),
|
||||||
rtp_receive_statistics_(ReceiveStatistics::Create(clock_, &stats_proxy_)),
|
rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
|
||||||
timing_(timing),
|
timing_(timing),
|
||||||
video_receiver_(clock_, timing_.get()),
|
video_receiver_(clock_, timing_.get()),
|
||||||
rtp_video_stream_receiver_(clock_,
|
rtp_video_stream_receiver_(clock_,
|
||||||
@ -464,6 +464,7 @@ VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
|
|||||||
rtp_receive_statistics_->GetStatistician(stats.ssrc);
|
rtp_receive_statistics_->GetStatistician(stats.ssrc);
|
||||||
if (statistician) {
|
if (statistician) {
|
||||||
statistician->GetStatistics(&stats.rtcp_stats, /*reset=*/false);
|
statistician->GetStatistics(&stats.rtcp_stats, /*reset=*/false);
|
||||||
|
stats.rtp_stats = statistician->GetReceiveStreamDataCounters();
|
||||||
stats.total_bitrate_bps = statistician->BitrateReceived();
|
stats.total_bitrate_bps = statistician->BitrateReceived();
|
||||||
}
|
}
|
||||||
if (config_.rtp.rtx_ssrc) {
|
if (config_.rtp.rtx_ssrc) {
|
||||||
@ -477,12 +478,24 @@ VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
|
|||||||
|
|
||||||
void VideoReceiveStream::UpdateHistograms() {
|
void VideoReceiveStream::UpdateHistograms() {
|
||||||
absl::optional<int> fraction_lost;
|
absl::optional<int> fraction_lost;
|
||||||
|
StreamDataCounters rtp_stats;
|
||||||
StreamStatistician* statistician =
|
StreamStatistician* statistician =
|
||||||
rtp_receive_statistics_->GetStatistician(config_.rtp.remote_ssrc);
|
rtp_receive_statistics_->GetStatistician(config_.rtp.remote_ssrc);
|
||||||
if (statistician) {
|
if (statistician) {
|
||||||
fraction_lost = statistician->GetFractionLostInPercent();
|
fraction_lost = statistician->GetFractionLostInPercent();
|
||||||
|
rtp_stats = statistician->GetReceiveStreamDataCounters();
|
||||||
}
|
}
|
||||||
stats_proxy_.UpdateHistograms(fraction_lost);
|
if (config_.rtp.rtx_ssrc) {
|
||||||
|
StreamStatistician* rtx_statistician =
|
||||||
|
rtp_receive_statistics_->GetStatistician(config_.rtp.rtx_ssrc);
|
||||||
|
if (rtx_statistician) {
|
||||||
|
StreamDataCounters rtx_stats =
|
||||||
|
rtx_statistician->GetReceiveStreamDataCounters();
|
||||||
|
stats_proxy_.UpdateHistograms(fraction_lost, rtp_stats, &rtx_stats);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stats_proxy_.UpdateHistograms(fraction_lost, rtp_stats, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoReceiveStream::AddSecondarySink(RtpPacketSinkInterface* sink) {
|
void VideoReceiveStream::AddSecondarySink(RtpPacketSinkInterface* sink) {
|
||||||
|
Reference in New Issue
Block a user