From 950e231b634299fe1ba9787d6be9700e401d1bef Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 24 Jul 2023 12:44:05 +0200 Subject: [PATCH] In RtpRtcp use BitrateTracker instead of RateStatistics to measure bitrate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BitrateTracker uses RateStatistics underneath, thus algorithm is the same, but it provides Timestamp/TimeDelta friendly interface Bug: webrtc:13757 Change-Id: I9f2fcb3d498b2a137b531b94b660d15aa273c4bf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/312600 Reviewed-by: Erik Språng Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#40465} --- modules/rtp_rtcp/BUILD.gn | 3 ++- modules/rtp_rtcp/include/flexfec_sender.h | 4 ++-- .../deprecated/deprecated_rtp_sender_egress.cc | 12 +++++------- .../deprecated/deprecated_rtp_sender_egress.h | 4 ++-- modules/rtp_rtcp/source/flexfec_sender.cc | 7 +++---- modules/rtp_rtcp/source/receive_statistics_impl.cc | 9 +++++---- modules/rtp_rtcp/source/receive_statistics_impl.h | 4 ++-- modules/rtp_rtcp/source/rtp_sender.h | 1 - modules/rtp_rtcp/source/rtp_sender_egress.cc | 13 +++++-------- modules/rtp_rtcp/source/rtp_sender_egress.h | 4 ++-- modules/rtp_rtcp/source/rtp_sender_video.cc | 10 ++++------ modules/rtp_rtcp/source/rtp_sender_video.h | 3 ++- modules/rtp_rtcp/source/ulpfec_generator.cc | 9 ++++----- modules/rtp_rtcp/source/ulpfec_generator.h | 4 ++-- 14 files changed, 40 insertions(+), 47 deletions(-) diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index 2d2cf53a94..96c43bded3 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -305,6 +305,7 @@ rtc_library("rtp_rtcp") { "../../logging:rtc_event_rtp_rtcp", "../../modules/audio_coding:audio_coding_module_typedefs", "../../rtc_base:bit_buffer", + "../../rtc_base:bitrate_tracker", "../../rtc_base:bitstream_reader", "../../rtc_base:buffer", "../../rtc_base:byte_buffer", @@ -365,11 +366,11 @@ rtc_source_set("rtp_rtcp_legacy") { "../../api/units:timestamp", "../../api/video:video_bitrate_allocation", "../../logging:rtc_event_rtp_rtcp", + "../../rtc_base:bitrate_tracker", "../../rtc_base:checks", "../../rtc_base:gtest_prod", "../../rtc_base:logging", "../../rtc_base:macromagic", - "../../rtc_base:rate_statistics", "../../rtc_base/synchronization:mutex", "../../system_wrappers", "../remote_bitrate_estimator", diff --git a/modules/rtp_rtcp/include/flexfec_sender.h b/modules/rtp_rtcp/include/flexfec_sender.h index b61781a480..8f21ab7517 100644 --- a/modules/rtp_rtcp/include/flexfec_sender.h +++ b/modules/rtp_rtcp/include/flexfec_sender.h @@ -24,8 +24,8 @@ #include "modules/rtp_rtcp/source/rtp_header_extension_size.h" #include "modules/rtp_rtcp/source/ulpfec_generator.h" #include "modules/rtp_rtcp/source/video_fec_generator.h" +#include "rtc_base/bitrate_tracker.h" #include "rtc_base/random.h" -#include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" namespace webrtc { @@ -96,7 +96,7 @@ class FlexfecSender : public VideoFecGenerator { const size_t header_extensions_size_; mutable Mutex mutex_; - RateStatistics fec_bitrate_ RTC_GUARDED_BY(mutex_); + BitrateTracker fec_bitrate_ RTC_GUARDED_BY(mutex_); }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc index 1dc9111640..5ef1372355 100644 --- a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc +++ b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc @@ -24,7 +24,7 @@ namespace webrtc { namespace { constexpr uint32_t kTimestampTicksPerMs = 90; constexpr int kSendSideDelayWindowMs = 1000; -constexpr int kBitrateStatisticsWindowMs = 1000; +constexpr TimeDelta kBitrateStatisticsWindow = TimeDelta::Seconds(1); constexpr size_t kRtpSequenceNumberMapMaxEntries = 1 << 13; } // namespace @@ -82,8 +82,7 @@ DEPRECATED_RtpSenderEgress::DEPRECATED_RtpSenderEgress( timestamp_offset_(0), max_delay_it_(send_delays_.end()), sum_delays_ms_(0), - send_rates_(kNumMediaTypes, - {kBitrateStatisticsWindowMs, RateStatistics::kBpsScale}), + send_rates_(kNumMediaTypes, BitrateTracker(kBitrateStatisticsWindow)), rtp_sequence_number_map_(need_rtp_packet_infos_ ? std::make_unique( kRtpSequenceNumberMapMaxEntries) @@ -221,12 +220,11 @@ RtpSendRates DEPRECATED_RtpSenderEgress::GetSendRates() const { } RtpSendRates DEPRECATED_RtpSenderEgress::GetSendRatesLocked() const { - const int64_t now_ms = clock_->TimeInMilliseconds(); + const Timestamp now = clock_->CurrentTime(); RtpSendRates current_rates; for (size_t i = 0; i < kNumMediaTypes; ++i) { RtpPacketMediaType type = static_cast(i); - current_rates[type] = - DataRate::BitsPerSec(send_rates_[i].Rate(now_ms).value_or(0)); + current_rates[type] = send_rates_[i].Rate(now).value_or(DataRate::Zero()); } return current_rates; } @@ -453,7 +451,7 @@ void DEPRECATED_RtpSenderEgress::UpdateRtpStats(const RtpPacketToSend& packet) { RTC_DCHECK(packet.packet_type().has_value()); send_rates_[static_cast(*packet.packet_type())].Update(packet.size(), - now.ms()); + now); if (rtp_stats_callback_) { rtp_stats_callback_->DataCountersUpdated(*counters, packet.Ssrc()); diff --git a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h index 609a90d4fe..e786d90c2f 100644 --- a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h +++ b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.h @@ -25,7 +25,7 @@ #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "rtc_base/rate_statistics.h" +#include "rtc_base/bitrate_tracker.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -136,7 +136,7 @@ class DEPRECATED_RtpSenderEgress { StreamDataCounters rtp_stats_ RTC_GUARDED_BY(lock_); StreamDataCounters rtx_rtp_stats_ RTC_GUARDED_BY(lock_); // One element per value in RtpPacketMediaType, with index matching value. - std::vector send_rates_ RTC_GUARDED_BY(lock_); + std::vector send_rates_ RTC_GUARDED_BY(lock_); // Maps sent packets' sequence numbers to a tuple consisting of: // 1. The timestamp, without the randomizing offset mandated by the RFC. diff --git a/modules/rtp_rtcp/source/flexfec_sender.cc b/modules/rtp_rtcp/source/flexfec_sender.cc index c8bac0114d..3a98778d16 100644 --- a/modules/rtp_rtcp/source/flexfec_sender.cc +++ b/modules/rtp_rtcp/source/flexfec_sender.cc @@ -99,7 +99,7 @@ FlexfecSender::FlexfecSender( RegisterSupportedExtensions(rtp_header_extensions)), header_extensions_size_( RtpHeaderExtensionSize(extension_sizes, rtp_header_extension_map_)), - fec_bitrate_(/*max_window_size_ms=*/1000, RateStatistics::kBpsScale) { + fec_bitrate_(/*max_window_size=*/TimeDelta::Seconds(1)) { // This object should not have been instantiated if FlexFEC is disabled. RTC_DCHECK_GE(payload_type, 0); RTC_DCHECK_LE(payload_type, 127); @@ -179,7 +179,7 @@ std::vector> FlexfecSender::GetFecPackets() { } MutexLock lock(&mutex_); - fec_bitrate_.Update(total_fec_data_bytes, now.ms()); + fec_bitrate_.Update(total_fec_data_bytes, now); return fec_packets_to_send; } @@ -191,8 +191,7 @@ size_t FlexfecSender::MaxPacketOverhead() const { DataRate FlexfecSender::CurrentFecRate() const { MutexLock lock(&mutex_); - return DataRate::BitsPerSec( - fec_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0)); + return fec_bitrate_.Rate(clock_->CurrentTime()).value_or(DataRate::Zero()); } absl::optional FlexfecSender::GetRtpState() { diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc index 5ae5d2d8c5..ebf520bc0f 100644 --- a/modules/rtp_rtcp/source/receive_statistics_impl.cc +++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc @@ -47,8 +47,7 @@ StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc, : ssrc_(ssrc), clock_(clock), delta_internal_unix_epoch_(UnixEpochDelta(*clock_)), - incoming_bitrate_(kStatisticsProcessInterval.ms(), - RateStatistics::kBpsScale), + incoming_bitrate_(/*max_window_size=*/kStatisticsProcessInterval), max_reordering_threshold_(max_reordering_threshold), enable_retransmit_detection_(false), cumulative_loss_is_capped_(false), @@ -117,7 +116,7 @@ void StreamStatisticianImpl::UpdateCounters(const RtpPacketReceived& packet) { RTC_DCHECK_EQ(ssrc_, packet.Ssrc()); Timestamp now = clock_->CurrentTime(); - incoming_bitrate_.Update(packet.size(), now.ms()); + incoming_bitrate_.Update(packet.size(), now); receive_counters_.transmitted.AddPacket(packet); --cumulative_loss_; @@ -310,7 +309,9 @@ StreamDataCounters StreamStatisticianImpl::GetReceiveStreamDataCounters() } uint32_t StreamStatisticianImpl::BitrateReceived() const { - return incoming_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); + return incoming_bitrate_.Rate(clock_->CurrentTime()) + .value_or(DataRate::Zero()) + .bps(); } bool StreamStatisticianImpl::IsRetransmitOfOldPacket( diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h index 8ec7c96c17..ccac2d55d6 100644 --- a/modules/rtp_rtcp/source/receive_statistics_impl.h +++ b/modules/rtp_rtcp/source/receive_statistics_impl.h @@ -22,9 +22,9 @@ #include "api/units/timestamp.h" #include "modules/rtp_rtcp/include/receive_statistics.h" #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" +#include "rtc_base/bitrate_tracker.h" #include "rtc_base/containers/flat_map.h" #include "rtc_base/numerics/sequence_number_unwrapper.h" -#include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" @@ -80,7 +80,7 @@ class StreamStatisticianImpl : public StreamStatisticianImplInterface { Clock* const clock_; // Delta used to map internal timestamps to Unix epoch ones. const TimeDelta delta_internal_unix_epoch_; - RateStatistics incoming_bitrate_; + BitrateTracker incoming_bitrate_; // In number of packets or sequence numbers. int max_reordering_threshold_; bool enable_retransmit_detection_; diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h index 158d073b7a..633a69b34f 100644 --- a/modules/rtp_rtcp/source/rtp_sender.h +++ b/modules/rtp_rtcp/source/rtp_sender.h @@ -30,7 +30,6 @@ #include "modules/rtp_rtcp/source/rtp_rtcp_config.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "rtc_base/random.h" -#include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.cc b/modules/rtp_rtcp/source/rtp_sender_egress.cc index 1d4eca5a79..2e022cec37 100644 --- a/modules/rtp_rtcp/source/rtp_sender_egress.cc +++ b/modules/rtp_rtcp/source/rtp_sender_egress.cc @@ -24,10 +24,9 @@ namespace webrtc { namespace { constexpr uint32_t kTimestampTicksPerMs = 90; constexpr TimeDelta kSendSideDelayWindow = TimeDelta::Seconds(1); -constexpr int kBitrateStatisticsWindowMs = 1000; +constexpr TimeDelta kBitrateStatisticsWindow = TimeDelta::Seconds(1); constexpr size_t kRtpSequenceNumberMapMaxEntries = 1 << 13; -constexpr TimeDelta kUpdateInterval = - TimeDelta::Millis(kBitrateStatisticsWindowMs); +constexpr TimeDelta kUpdateInterval = kBitrateStatisticsWindow; } // namespace RtpSenderEgress::NonPacedPacketSender::NonPacedPacketSender( @@ -106,8 +105,7 @@ RtpSenderEgress::RtpSenderEgress(const RtpRtcpInterface::Configuration& config, timestamp_offset_(0), max_delay_it_(send_delays_.end()), sum_delays_(TimeDelta::Zero()), - send_rates_(kNumMediaTypes, - {kBitrateStatisticsWindowMs, RateStatistics::kBpsScale}), + send_rates_(kNumMediaTypes, BitrateTracker(kBitrateStatisticsWindow)), rtp_sequence_number_map_(need_rtp_packet_infos_ ? std::make_unique( kRtpSequenceNumberMapMaxEntries) @@ -304,8 +302,7 @@ RtpSendRates RtpSenderEgress::GetSendRates(Timestamp now) const { RtpSendRates current_rates; for (size_t i = 0; i < kNumMediaTypes; ++i) { RtpPacketMediaType type = static_cast(i); - current_rates[type] = - DataRate::BitsPerSec(send_rates_[i].Rate(now.ms()).value_or(0)); + current_rates[type] = send_rates_[i].Rate(now).value_or(DataRate::Zero()); } return current_rates; } @@ -564,7 +561,7 @@ void RtpSenderEgress::UpdateRtpStats(Timestamp now, } counters->transmitted.Add(counter); - send_rates_[static_cast(packet_type)].Update(packet_size, now.ms()); + send_rates_[static_cast(packet_type)].Update(packet_size, now); if (bitrate_callback_) { send_rates = GetSendRates(now); } diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.h b/modules/rtp_rtcp/source/rtp_sender_egress.h index 7bb8f80efd..3e5b2b21c3 100644 --- a/modules/rtp_rtcp/source/rtp_sender_egress.h +++ b/modules/rtp_rtcp/source/rtp_sender_egress.h @@ -32,7 +32,7 @@ #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "rtc_base/rate_statistics.h" +#include "rtc_base/bitrate_tracker.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/system/no_unique_address.h" #include "rtc_base/task_utils/repeating_task.h" @@ -170,7 +170,7 @@ class RtpSenderEgress { StreamDataCounters rtp_stats_ RTC_GUARDED_BY(worker_queue_); StreamDataCounters rtx_rtp_stats_ RTC_GUARDED_BY(worker_queue_); // One element per value in RtpPacketMediaType, with index matching value. - std::vector send_rates_ RTC_GUARDED_BY(worker_queue_); + std::vector send_rates_ RTC_GUARDED_BY(worker_queue_); absl::optional> pending_fec_params_ RTC_GUARDED_BY(worker_queue_); diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc index dd64064add..dc37475df0 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -141,7 +141,7 @@ RTPSenderVideo::RTPSenderVideo(const Config& config) red_payload_type_(config.red_payload_type), fec_type_(config.fec_type), fec_overhead_bytes_(config.fec_overhead_bytes), - post_encode_overhead_bitrate_(1000, RateStatistics::kBpsScale), + post_encode_overhead_bitrate_(/*max_window_size=*/TimeDelta::Seconds(1)), frame_encryptor_(config.frame_encryptor), require_frame_encryption_(config.require_frame_encryption), generic_descriptor_auth_experiment_(!absl::StartsWith( @@ -181,8 +181,7 @@ void RTPSenderVideo::LogAndSendToNetwork( // unpacketized. if (packetized_payload_size >= encoder_output_size) { post_encode_overhead_bitrate_.Update( - packetized_payload_size - encoder_output_size, - clock_->TimeInMilliseconds()); + packetized_payload_size - encoder_output_size, clock_->CurrentTime()); } } @@ -801,9 +800,8 @@ bool RTPSenderVideo::SendEncodedImage(int payload_type, DataRate RTPSenderVideo::PostEncodeOverhead() const { MutexLock lock(&stats_mutex_); - return DataRate::BitsPerSec( - post_encode_overhead_bitrate_.Rate(clock_->TimeInMilliseconds()) - .value_or(0)); + return post_encode_overhead_bitrate_.Rate(clock_->CurrentTime()) + .value_or(DataRate::Zero()); } bool RTPSenderVideo::AllowRetransmission( diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h index 2d955acf1a..80ad6165d0 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.h +++ b/modules/rtp_rtcp/source/rtp_sender_video.h @@ -35,6 +35,7 @@ #include "modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h" #include "modules/rtp_rtcp/source/rtp_video_header.h" #include "modules/rtp_rtcp/source/video_fec_generator.h" +#include "rtc_base/bitrate_tracker.h" #include "rtc_base/one_time_event.h" #include "rtc_base/race_checker.h" #include "rtc_base/rate_statistics.h" @@ -248,7 +249,7 @@ class RTPSenderVideo : public RTPVideoFrameSenderInterface { const size_t fec_overhead_bytes_; // Per packet max FEC overhead. mutable Mutex stats_mutex_; - RateStatistics post_encode_overhead_bitrate_ RTC_GUARDED_BY(stats_mutex_); + BitrateTracker post_encode_overhead_bitrate_ RTC_GUARDED_BY(stats_mutex_); std::map frame_stats_by_temporal_layer_ RTC_GUARDED_BY(stats_mutex_); diff --git a/modules/rtp_rtcp/source/ulpfec_generator.cc b/modules/rtp_rtcp/source/ulpfec_generator.cc index 20402fc4d3..cae659cdd7 100644 --- a/modules/rtp_rtcp/source/ulpfec_generator.cc +++ b/modules/rtp_rtcp/source/ulpfec_generator.cc @@ -77,7 +77,7 @@ UlpfecGenerator::UlpfecGenerator(int red_payload_type, num_protected_frames_(0), min_num_media_packets_(1), media_contains_keyframe_(false), - fec_bitrate_(/*max_window_size_ms=*/1000, RateStatistics::kBpsScale) {} + fec_bitrate_(/*max_window_size=*/TimeDelta::Seconds(1)) {} // Used by FlexFecSender, payload types are unused. UlpfecGenerator::UlpfecGenerator(std::unique_ptr fec, @@ -89,7 +89,7 @@ UlpfecGenerator::UlpfecGenerator(std::unique_ptr fec, num_protected_frames_(0), min_num_media_packets_(1), media_contains_keyframe_(false), - fec_bitrate_(/*max_window_size_ms=*/1000, RateStatistics::kBpsScale) {} + fec_bitrate_(/*max_window_size=*/TimeDelta::Seconds(1)) {} UlpfecGenerator::~UlpfecGenerator() = default; @@ -235,15 +235,14 @@ std::vector> UlpfecGenerator::GetFecPackets() { ResetState(); MutexLock lock(&mutex_); - fec_bitrate_.Update(total_fec_size_bytes, clock_->TimeInMilliseconds()); + fec_bitrate_.Update(total_fec_size_bytes, clock_->CurrentTime()); return fec_packets; } DataRate UlpfecGenerator::CurrentFecRate() const { MutexLock lock(&mutex_); - return DataRate::BitsPerSec( - fec_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0)); + return fec_bitrate_.Rate(clock_->CurrentTime()).value_or(DataRate::Zero()); } int UlpfecGenerator::Overhead() const { diff --git a/modules/rtp_rtcp/source/ulpfec_generator.h b/modules/rtp_rtcp/source/ulpfec_generator.h index 88a8b459e6..0058847357 100644 --- a/modules/rtp_rtcp/source/ulpfec_generator.h +++ b/modules/rtp_rtcp/source/ulpfec_generator.h @@ -21,8 +21,8 @@ #include "modules/include/module_fec_types.h" #include "modules/rtp_rtcp/source/forward_error_correction.h" #include "modules/rtp_rtcp/source/video_fec_generator.h" +#include "rtc_base/bitrate_tracker.h" #include "rtc_base/race_checker.h" -#include "rtc_base/rate_statistics.h" #include "rtc_base/synchronization/mutex.h" namespace webrtc { @@ -115,7 +115,7 @@ class UlpfecGenerator : public VideoFecGenerator { mutable Mutex mutex_; absl::optional pending_params_ RTC_GUARDED_BY(mutex_); - RateStatistics fec_bitrate_ RTC_GUARDED_BY(mutex_); + BitrateTracker fec_bitrate_ RTC_GUARDED_BY(mutex_); }; } // namespace webrtc