Cleanup ReceiveStatistics collecting ReportBlock

avoid intermediate type RtcpStatistics,
Instead write to rtcp::ReportBlock directly.

Bug: webrtc:10678
Change-Id: Ia5f840d720e48d79cbbcb0c95cd221c87156205e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/218840
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34021}
This commit is contained in:
Danil Chapovalov
2021-05-17 14:22:02 +02:00
committed by WebRTC LUCI CQ
parent 4310375740
commit b27a9f9481
2 changed files with 42 additions and 52 deletions

View File

@ -17,6 +17,7 @@
#include <vector>
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
#include "modules/rtp_rtcp/source/time_util.h"
@ -47,6 +48,7 @@ StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc,
RateStatistics::kBpsScale),
max_reordering_threshold_(max_reordering_threshold),
enable_retransmit_detection_(false),
cumulative_loss_is_capped_(false),
jitter_q4_(0),
cumulative_loss_(0),
cumulative_loss_rtcp_offset_(0),
@ -189,22 +191,20 @@ RtpReceiveStats StreamStatisticianImpl::GetStats() const {
return stats;
}
bool StreamStatisticianImpl::GetActiveStatisticsAndReset(
RtcpStatistics* statistics) {
if (clock_->TimeInMilliseconds() - last_receive_time_ms_ >=
kStatisticsTimeoutMs) {
void StreamStatisticianImpl::MaybeAppendReportBlockAndReset(
std::vector<rtcp::ReportBlock>& report_blocks) {
int64_t now_ms = clock_->TimeInMilliseconds();
if (now_ms - last_receive_time_ms_ >= kStatisticsTimeoutMs) {
// Not active.
return false;
return;
}
if (!ReceivedRtpPacket()) {
return false;
return;
}
*statistics = CalculateRtcpStatistics();
return true;
}
RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
RtcpStatistics stats;
report_blocks.emplace_back();
rtcp::ReportBlock& stats = report_blocks.back();
stats.SetMediaSsrc(ssrc_);
// Calculate fraction lost.
int64_t exp_since_last = received_seq_max_ - last_report_seq_max_;
RTC_DCHECK_GE(exp_since_last, 0);
@ -212,37 +212,39 @@ RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
int32_t lost_since_last = cumulative_loss_ - last_report_cumulative_loss_;
if (exp_since_last > 0 && lost_since_last > 0) {
// Scale 0 to 255, where 255 is 100% loss.
stats.fraction_lost =
static_cast<uint8_t>(255 * lost_since_last / exp_since_last);
} else {
stats.fraction_lost = 0;
stats.SetFractionLost(255 * lost_since_last / exp_since_last);
}
// TODO(danilchap): Ensure |stats.packets_lost| is clamped to fit in a signed
// 24-bit value.
stats.packets_lost = cumulative_loss_ + cumulative_loss_rtcp_offset_;
if (stats.packets_lost < 0) {
int packets_lost = cumulative_loss_ + cumulative_loss_rtcp_offset_;
if (packets_lost < 0) {
// Clamp to zero. Work around to accomodate for senders that misbehave with
// negative cumulative loss.
stats.packets_lost = 0;
packets_lost = 0;
cumulative_loss_rtcp_offset_ = -cumulative_loss_;
}
stats.extended_highest_sequence_number =
static_cast<uint32_t>(received_seq_max_);
if (packets_lost > 0x7fffff) {
// Packets lost is a 24 bit signed field, and thus should be clamped, as
// described in https://datatracker.ietf.org/doc/html/rfc3550#appendix-A.3
if (!cumulative_loss_is_capped_) {
cumulative_loss_is_capped_ = true;
RTC_LOG(LS_WARNING) << "Cumulative loss reached maximum value for ssrc "
<< ssrc_;
}
packets_lost = 0x7fffff;
}
stats.SetCumulativeLost(packets_lost);
stats.SetExtHighestSeqNum(received_seq_max_);
// Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
stats.jitter = jitter_q4_ >> 4;
stats.SetJitter(jitter_q4_ >> 4);
// Only for report blocks in RTCP SR and RR.
last_report_cumulative_loss_ = cumulative_loss_;
last_report_seq_max_ = received_seq_max_;
BWE_TEST_LOGGING_PLOT_WITH_SSRC(1, "cumulative_loss_pkts",
clock_->TimeInMilliseconds(),
BWE_TEST_LOGGING_PLOT_WITH_SSRC(1, "cumulative_loss_pkts", now_ms,
cumulative_loss_, ssrc_);
BWE_TEST_LOGGING_PLOT_WITH_SSRC(
1, "received_seq_max_pkts", clock_->TimeInMilliseconds(),
(received_seq_max_ - received_seq_first_), ssrc_);
return stats;
BWE_TEST_LOGGING_PLOT_WITH_SSRC(1, "received_seq_max_pkts", now_ms,
(received_seq_max_ - received_seq_first_),
ssrc_);
}
absl::optional<int> StreamStatisticianImpl::GetFractionLostInPercent() const {
@ -382,23 +384,7 @@ std::vector<rtcp::ReportBlock> ReceiveStatisticsImpl::RtcpReportBlocks(
const uint32_t media_ssrc = all_ssrcs_[ssrc_idx];
auto statistician_it = statisticians_.find(media_ssrc);
RTC_DCHECK(statistician_it != statisticians_.end());
// Do we have receive statistics to send?
RtcpStatistics stats;
if (!statistician_it->second->GetActiveStatisticsAndReset(&stats))
continue;
result.emplace_back();
rtcp::ReportBlock& block = result.back();
block.SetMediaSsrc(media_ssrc);
block.SetFractionLost(stats.fraction_lost);
if (!block.SetCumulativeLost(stats.packets_lost)) {
RTC_LOG(LS_WARNING) << "Cumulative lost is oversized.";
result.pop_back();
continue;
}
block.SetExtHighestSeqNum(stats.extended_highest_sequence_number);
block.SetJitter(stats.jitter);
statistician_it->second->MaybeAppendReportBlockAndReset(result);
}
last_returned_ssrc_idx_ = ssrc_idx;
return result;

View File

@ -21,6 +21,7 @@
#include "absl/types/optional.h"
#include "modules/include/module_common_types_public.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "rtc_base/rate_statistics.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"
@ -31,7 +32,8 @@ namespace webrtc {
class StreamStatisticianImplInterface : public StreamStatistician {
public:
virtual ~StreamStatisticianImplInterface() = default;
virtual bool GetActiveStatisticsAndReset(RtcpStatistics* statistics) = 0;
virtual void MaybeAppendReportBlockAndReset(
std::vector<rtcp::ReportBlock>& report_blocks) = 0;
virtual void SetMaxReorderingThreshold(int max_reordering_threshold) = 0;
virtual void EnableRetransmitDetection(bool enable) = 0;
virtual void UpdateCounters(const RtpPacketReceived& packet) = 0;
@ -52,7 +54,8 @@ class StreamStatisticianImpl : public StreamStatisticianImplInterface {
uint32_t BitrateReceived() const override;
// Implements StreamStatisticianImplInterface
bool GetActiveStatisticsAndReset(RtcpStatistics* statistics) override;
void MaybeAppendReportBlockAndReset(
std::vector<rtcp::ReportBlock>& report_blocks) override;
void SetMaxReorderingThreshold(int max_reordering_threshold) override;
void EnableRetransmitDetection(bool enable) override;
// Updates StreamStatistician for incoming packets.
@ -61,7 +64,6 @@ class StreamStatisticianImpl : public StreamStatisticianImplInterface {
private:
bool IsRetransmitOfOldPacket(const RtpPacketReceived& packet,
int64_t now_ms) const;
RtcpStatistics CalculateRtcpStatistics();
void UpdateJitter(const RtpPacketReceived& packet, int64_t receive_time_ms);
// Updates StreamStatistician for out of order packets.
// Returns true if packet considered to be out of order.
@ -79,6 +81,7 @@ class StreamStatisticianImpl : public StreamStatisticianImplInterface {
// In number of packets or sequence numbers.
int max_reordering_threshold_;
bool enable_retransmit_detection_;
bool cumulative_loss_is_capped_;
// Stats on received RTP packets.
uint32_t jitter_q4_;
@ -132,9 +135,10 @@ class StreamStatisticianLocked : public StreamStatisticianImplInterface {
MutexLock lock(&stream_lock_);
return impl_.BitrateReceived();
}
bool GetActiveStatisticsAndReset(RtcpStatistics* statistics) override {
void MaybeAppendReportBlockAndReset(
std::vector<rtcp::ReportBlock>& report_blocks) override {
MutexLock lock(&stream_lock_);
return impl_.GetActiveStatisticsAndReset(statistics);
impl_.MaybeAppendReportBlockAndReset(report_blocks);
}
void SetMaxReorderingThreshold(int max_reordering_threshold) override {
MutexLock lock(&stream_lock_);