From ee8cd20ec550f19a7c62c0d8dd509ca654750580 Mon Sep 17 00:00:00 2001 From: Per Kjellander Date: Wed, 10 Mar 2021 12:31:38 +0100 Subject: [PATCH] Add a mutex free implementation of webrtc::ReceiveStatistics The mutex is removed from the old existing implementation and instead a wrapper is implemented that ensure thread-safety. Both the thread-safe and unsafe version share the same implementation of the logic. There are two ways of construction: webrtc::ReceiveStatistics::Create - thread-safe version. webrtc::ReceiveStatistics::CreateUnLocked -thread-unsafe Bug: none Change-Id: Ica375919fda70180335c8f9ea666497811daf866 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/211240 Reviewed-by: Danil Chapovalov Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/master@{#33419} --- modules/rtp_rtcp/include/receive_statistics.h | 5 + .../source/receive_statistics_impl.cc | 89 ++++---- .../rtp_rtcp/source/receive_statistics_impl.h | 195 ++++++++++++++---- .../source/receive_statistics_unittest.cc | 51 +++-- 4 files changed, 225 insertions(+), 115 deletions(-) diff --git a/modules/rtp_rtcp/include/receive_statistics.h b/modules/rtp_rtcp/include/receive_statistics.h index 2cc3feab3a..ce87b99a42 100644 --- a/modules/rtp_rtcp/include/receive_statistics.h +++ b/modules/rtp_rtcp/include/receive_statistics.h @@ -55,7 +55,12 @@ class ReceiveStatistics : public ReceiveStatisticsProvider, public: ~ReceiveStatistics() override = default; + // Returns a thread-safe instance of ReceiveStatistics. + // https://chromium.googlesource.com/chromium/src/+/lkgr/docs/threading_and_tasks.md#threading-lexicon static std::unique_ptr Create(Clock* clock); + // Returns a thread-compatible instance of ReceiveStatistics. + static std::unique_ptr CreateThreadCompatible( + Clock* clock); // Returns a pointer to the statistician of an ssrc. virtual StreamStatistician* GetStatistician(uint32_t ssrc) const = 0; diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc index 6ec41a1eb0..4c399a107e 100644 --- a/modules/rtp_rtcp/source/receive_statistics_impl.cc +++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" @@ -100,7 +101,6 @@ bool StreamStatisticianImpl::UpdateOutOfOrder(const RtpPacketReceived& packet, } void StreamStatisticianImpl::UpdateCounters(const RtpPacketReceived& packet) { - MutexLock lock(&stream_lock_); RTC_DCHECK_EQ(ssrc_, packet.Ssrc()); int64_t now_ms = clock_->TimeInMilliseconds(); @@ -159,17 +159,14 @@ void StreamStatisticianImpl::UpdateJitter(const RtpPacketReceived& packet, void StreamStatisticianImpl::SetMaxReorderingThreshold( int max_reordering_threshold) { - MutexLock lock(&stream_lock_); max_reordering_threshold_ = max_reordering_threshold; } void StreamStatisticianImpl::EnableRetransmitDetection(bool enable) { - MutexLock lock(&stream_lock_); enable_retransmit_detection_ = enable; } RtpReceiveStats StreamStatisticianImpl::GetStats() const { - MutexLock lock(&stream_lock_); RtpReceiveStats stats; stats.packets_lost = cumulative_loss_; // TODO(nisse): Can we return a float instead? @@ -183,7 +180,6 @@ RtpReceiveStats StreamStatisticianImpl::GetStats() const { bool StreamStatisticianImpl::GetActiveStatisticsAndReset( RtcpStatistics* statistics) { - MutexLock lock(&stream_lock_); if (clock_->TimeInMilliseconds() - last_receive_time_ms_ >= kStatisticsTimeoutMs) { // Not active. @@ -192,9 +188,7 @@ bool StreamStatisticianImpl::GetActiveStatisticsAndReset( if (!ReceivedRtpPacket()) { return false; } - *statistics = CalculateRtcpStatistics(); - return true; } @@ -241,7 +235,6 @@ RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() { } absl::optional StreamStatisticianImpl::GetFractionLostInPercent() const { - MutexLock lock(&stream_lock_); if (!ReceivedRtpPacket()) { return absl::nullopt; } @@ -257,12 +250,10 @@ absl::optional StreamStatisticianImpl::GetFractionLostInPercent() const { StreamDataCounters StreamStatisticianImpl::GetReceiveStreamDataCounters() const { - MutexLock lock(&stream_lock_); return receive_counters_; } uint32_t StreamStatisticianImpl::BitrateReceived() const { - MutexLock lock(&stream_lock_); return incoming_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); } @@ -295,21 +286,33 @@ bool StreamStatisticianImpl::IsRetransmitOfOldPacket( } std::unique_ptr ReceiveStatistics::Create(Clock* clock) { - return std::make_unique(clock); + return std::make_unique( + clock, [](uint32_t ssrc, Clock* clock, int max_reordering_threshold) { + return std::make_unique( + ssrc, clock, max_reordering_threshold); + }); } -ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock) +std::unique_ptr ReceiveStatistics::CreateThreadCompatible( + Clock* clock) { + return std::make_unique( + clock, [](uint32_t ssrc, Clock* clock, int max_reordering_threshold) { + return std::make_unique( + ssrc, clock, max_reordering_threshold); + }); +} + +ReceiveStatisticsImpl::ReceiveStatisticsImpl( + Clock* clock, + std::function( + uint32_t ssrc, + Clock* clock, + int max_reordering_threshold)> stream_statistician_factory) : clock_(clock), + stream_statistician_factory_(std::move(stream_statistician_factory)), last_returned_ssrc_(0), max_reordering_threshold_(kDefaultMaxReorderingThreshold) {} -ReceiveStatisticsImpl::~ReceiveStatisticsImpl() { - while (!statisticians_.empty()) { - delete statisticians_.begin()->second; - statisticians_.erase(statisticians_.begin()); - } -} - void ReceiveStatisticsImpl::OnRtpPacket(const RtpPacketReceived& packet) { // StreamStatisticianImpl instance is created once and only destroyed when // this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has @@ -318,34 +321,28 @@ void ReceiveStatisticsImpl::OnRtpPacket(const RtpPacketReceived& packet) { GetOrCreateStatistician(packet.Ssrc())->UpdateCounters(packet); } -StreamStatisticianImpl* ReceiveStatisticsImpl::GetStatistician( +StreamStatistician* ReceiveStatisticsImpl::GetStatistician( uint32_t ssrc) const { - MutexLock lock(&receive_statistics_lock_); const auto& it = statisticians_.find(ssrc); if (it == statisticians_.end()) - return NULL; - return it->second; + return nullptr; + return it->second.get(); } -StreamStatisticianImpl* ReceiveStatisticsImpl::GetOrCreateStatistician( +StreamStatisticianImplInterface* ReceiveStatisticsImpl::GetOrCreateStatistician( uint32_t ssrc) { - MutexLock lock(&receive_statistics_lock_); - StreamStatisticianImpl*& impl = statisticians_[ssrc]; + std::unique_ptr& impl = statisticians_[ssrc]; if (impl == nullptr) { // new element - impl = new StreamStatisticianImpl(ssrc, clock_, max_reordering_threshold_); + impl = + stream_statistician_factory_(ssrc, clock_, max_reordering_threshold_); } - return impl; + return impl.get(); } void ReceiveStatisticsImpl::SetMaxReorderingThreshold( int max_reordering_threshold) { - std::map statisticians; - { - MutexLock lock(&receive_statistics_lock_); - max_reordering_threshold_ = max_reordering_threshold; - statisticians = statisticians_; - } - for (auto& statistician : statisticians) { + max_reordering_threshold_ = max_reordering_threshold; + for (auto& statistician : statisticians_) { statistician.second->SetMaxReorderingThreshold(max_reordering_threshold); } } @@ -364,15 +361,11 @@ void ReceiveStatisticsImpl::EnableRetransmitDetection(uint32_t ssrc, std::vector ReceiveStatisticsImpl::RtcpReportBlocks( size_t max_blocks) { - std::map statisticians; - { - MutexLock lock(&receive_statistics_lock_); - statisticians = statisticians_; - } std::vector result; - result.reserve(std::min(max_blocks, statisticians.size())); - auto add_report_block = [&result](uint32_t media_ssrc, - StreamStatisticianImpl* statistician) { + result.reserve(std::min(max_blocks, statisticians_.size())); + auto add_report_block = [&result]( + uint32_t media_ssrc, + StreamStatisticianImplInterface* statistician) { // Do we have receive statistics to send? RtcpStatistics stats; if (!statistician->GetActiveStatisticsAndReset(&stats)) @@ -390,13 +383,13 @@ std::vector ReceiveStatisticsImpl::RtcpReportBlocks( block.SetJitter(stats.jitter); }; - const auto start_it = statisticians.upper_bound(last_returned_ssrc_); + const auto start_it = statisticians_.upper_bound(last_returned_ssrc_); for (auto it = start_it; - result.size() < max_blocks && it != statisticians.end(); ++it) - add_report_block(it->first, it->second); - for (auto it = statisticians.begin(); + result.size() < max_blocks && it != statisticians_.end(); ++it) + add_report_block(it->first, it->second.get()); + for (auto it = statisticians_.begin(); result.size() < max_blocks && it != start_it; ++it) - add_report_block(it->first, it->second); + add_report_block(it->first, it->second.get()); if (!result.empty()) last_returned_ssrc_ = result.back().source_ssrc(); diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h index 41830b0b48..2456f93e9a 100644 --- a/modules/rtp_rtcp/source/receive_statistics_impl.h +++ b/modules/rtp_rtcp/source/receive_statistics_impl.h @@ -12,7 +12,10 @@ #define MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_ #include +#include #include +#include +#include #include #include "absl/types/optional.h" @@ -24,86 +27,141 @@ namespace webrtc { -class StreamStatisticianImpl : public StreamStatistician { +// Extends StreamStatistician with methods needed by the implementation. +class StreamStatisticianImplInterface : public StreamStatistician { + public: + virtual ~StreamStatisticianImplInterface() = default; + virtual bool GetActiveStatisticsAndReset(RtcpStatistics* statistics) = 0; + virtual void SetMaxReorderingThreshold(int max_reordering_threshold) = 0; + virtual void EnableRetransmitDetection(bool enable) = 0; + virtual void UpdateCounters(const RtpPacketReceived& packet) = 0; +}; + +// Thread-compatible implementation of StreamStatisticianImplInterface. +class StreamStatisticianImpl : public StreamStatisticianImplInterface { public: StreamStatisticianImpl(uint32_t ssrc, Clock* clock, int max_reordering_threshold); ~StreamStatisticianImpl() override; + // Implements StreamStatistician RtpReceiveStats GetStats() const override; - - bool GetActiveStatisticsAndReset(RtcpStatistics* statistics); absl::optional GetFractionLostInPercent() const override; StreamDataCounters GetReceiveStreamDataCounters() const override; uint32_t BitrateReceived() const override; - void SetMaxReorderingThreshold(int max_reordering_threshold); - void EnableRetransmitDetection(bool enable); - + // Implements StreamStatisticianImplInterface + bool GetActiveStatisticsAndReset(RtcpStatistics* statistics) override; + void SetMaxReorderingThreshold(int max_reordering_threshold) override; + void EnableRetransmitDetection(bool enable) override; // Updates StreamStatistician for incoming packets. - void UpdateCounters(const RtpPacketReceived& packet); + void UpdateCounters(const RtpPacketReceived& packet) override; private: bool IsRetransmitOfOldPacket(const RtpPacketReceived& packet, - int64_t now_ms) const - RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_); - RtcpStatistics CalculateRtcpStatistics() - RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_); - void UpdateJitter(const RtpPacketReceived& packet, int64_t receive_time_ms) - RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_); + 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. bool UpdateOutOfOrder(const RtpPacketReceived& packet, int64_t sequence_number, - int64_t now_ms) - RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_); + int64_t now_ms); // Checks if this StreamStatistician received any rtp packets. - bool ReceivedRtpPacket() const RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_) { - return received_seq_first_ >= 0; - } + bool ReceivedRtpPacket() const { return received_seq_first_ >= 0; } const uint32_t ssrc_; Clock* const clock_; - mutable Mutex stream_lock_; - RateStatistics incoming_bitrate_ RTC_GUARDED_BY(&stream_lock_); + RateStatistics incoming_bitrate_; // In number of packets or sequence numbers. - int max_reordering_threshold_ RTC_GUARDED_BY(&stream_lock_); - bool enable_retransmit_detection_ RTC_GUARDED_BY(&stream_lock_); + int max_reordering_threshold_; + bool enable_retransmit_detection_; // Stats on received RTP packets. - uint32_t jitter_q4_ RTC_GUARDED_BY(&stream_lock_); + uint32_t jitter_q4_; // Cumulative loss according to RFC 3550, which may be negative (and often is, // if packets are reordered and there are non-RTX retransmissions). - int32_t cumulative_loss_ RTC_GUARDED_BY(&stream_lock_); + int32_t cumulative_loss_; // Offset added to outgoing rtcp reports, to make ensure that the reported // cumulative loss is non-negative. Reports with negative values confuse some // senders, in particular, our own loss-based bandwidth estimator. - int32_t cumulative_loss_rtcp_offset_ RTC_GUARDED_BY(&stream_lock_); + int32_t cumulative_loss_rtcp_offset_; - int64_t last_receive_time_ms_ RTC_GUARDED_BY(&stream_lock_); - uint32_t last_received_timestamp_ RTC_GUARDED_BY(&stream_lock_); - SequenceNumberUnwrapper seq_unwrapper_ RTC_GUARDED_BY(&stream_lock_); - int64_t received_seq_first_ RTC_GUARDED_BY(&stream_lock_); - int64_t received_seq_max_ RTC_GUARDED_BY(&stream_lock_); + int64_t last_receive_time_ms_; + uint32_t last_received_timestamp_; + SequenceNumberUnwrapper seq_unwrapper_; + int64_t received_seq_first_; + int64_t received_seq_max_; // Assume that the other side restarted when there are two sequential packets // with large jump from received_seq_max_. - absl::optional received_seq_out_of_order_ - RTC_GUARDED_BY(&stream_lock_); + absl::optional received_seq_out_of_order_; // Current counter values. - StreamDataCounters receive_counters_ RTC_GUARDED_BY(&stream_lock_); + StreamDataCounters receive_counters_; // Counter values when we sent the last report. - int32_t last_report_cumulative_loss_ RTC_GUARDED_BY(&stream_lock_); - int64_t last_report_seq_max_ RTC_GUARDED_BY(&stream_lock_); + int32_t last_report_cumulative_loss_; + int64_t last_report_seq_max_; }; +// Thread-safe implementation of StreamStatisticianImplInterface. +class StreamStatisticianLocked : public StreamStatisticianImplInterface { + public: + StreamStatisticianLocked(uint32_t ssrc, + Clock* clock, + int max_reordering_threshold) + : impl_(ssrc, clock, max_reordering_threshold) {} + ~StreamStatisticianLocked() override = default; + + RtpReceiveStats GetStats() const override { + MutexLock lock(&stream_lock_); + return impl_.GetStats(); + } + absl::optional GetFractionLostInPercent() const override { + MutexLock lock(&stream_lock_); + return impl_.GetFractionLostInPercent(); + } + StreamDataCounters GetReceiveStreamDataCounters() const override { + MutexLock lock(&stream_lock_); + return impl_.GetReceiveStreamDataCounters(); + } + uint32_t BitrateReceived() const override { + MutexLock lock(&stream_lock_); + return impl_.BitrateReceived(); + } + bool GetActiveStatisticsAndReset(RtcpStatistics* statistics) override { + MutexLock lock(&stream_lock_); + return impl_.GetActiveStatisticsAndReset(statistics); + } + void SetMaxReorderingThreshold(int max_reordering_threshold) override { + MutexLock lock(&stream_lock_); + return impl_.SetMaxReorderingThreshold(max_reordering_threshold); + } + void EnableRetransmitDetection(bool enable) override { + MutexLock lock(&stream_lock_); + return impl_.EnableRetransmitDetection(enable); + } + void UpdateCounters(const RtpPacketReceived& packet) override { + MutexLock lock(&stream_lock_); + return impl_.UpdateCounters(packet); + } + + private: + mutable Mutex stream_lock_; + StreamStatisticianImpl impl_ RTC_GUARDED_BY(&stream_lock_); +}; + +// Thread-compatible implementation. class ReceiveStatisticsImpl : public ReceiveStatistics { public: - explicit ReceiveStatisticsImpl(Clock* clock); - - ~ReceiveStatisticsImpl() override; + ReceiveStatisticsImpl( + Clock* clock, + std::function( + uint32_t ssrc, + Clock* clock, + int max_reordering_threshold)> stream_statistician_factory); + ~ReceiveStatisticsImpl() override = default; // Implements ReceiveStatisticsProvider. std::vector RtcpReportBlocks(size_t max_blocks) override; @@ -112,22 +170,69 @@ class ReceiveStatisticsImpl : public ReceiveStatistics { void OnRtpPacket(const RtpPacketReceived& packet) override; // Implements ReceiveStatistics. - // Note: More specific return type for use in the implementation. - StreamStatisticianImpl* GetStatistician(uint32_t ssrc) const override; + StreamStatistician* GetStatistician(uint32_t ssrc) const override; void SetMaxReorderingThreshold(int max_reordering_threshold) override; void SetMaxReorderingThreshold(uint32_t ssrc, int max_reordering_threshold) override; void EnableRetransmitDetection(uint32_t ssrc, bool enable) override; private: - StreamStatisticianImpl* GetOrCreateStatistician(uint32_t ssrc); + StreamStatisticianImplInterface* GetOrCreateStatistician(uint32_t ssrc); Clock* const clock_; - mutable Mutex receive_statistics_lock_; + std::function( + uint32_t ssrc, + Clock* clock, + int max_reordering_threshold)> + stream_statistician_factory_; uint32_t last_returned_ssrc_; - int max_reordering_threshold_ RTC_GUARDED_BY(receive_statistics_lock_); - std::map statisticians_ - RTC_GUARDED_BY(receive_statistics_lock_); + int max_reordering_threshold_; + std::map> + statisticians_; }; + +// Thread-safe implementation wrapping access to ReceiveStatisticsImpl with a +// mutex. +class ReceiveStatisticsLocked : public ReceiveStatistics { + public: + explicit ReceiveStatisticsLocked( + Clock* clock, + std::function( + uint32_t ssrc, + Clock* clock, + int max_reordering_threshold)> stream_statitician_factory) + : impl_(clock, std::move(stream_statitician_factory)) {} + ~ReceiveStatisticsLocked() override = default; + std::vector RtcpReportBlocks(size_t max_blocks) override { + MutexLock lock(&receive_statistics_lock_); + return impl_.RtcpReportBlocks(max_blocks); + } + void OnRtpPacket(const RtpPacketReceived& packet) override { + MutexLock lock(&receive_statistics_lock_); + return impl_.OnRtpPacket(packet); + } + StreamStatistician* GetStatistician(uint32_t ssrc) const override { + MutexLock lock(&receive_statistics_lock_); + return impl_.GetStatistician(ssrc); + } + void SetMaxReorderingThreshold(int max_reordering_threshold) override { + MutexLock lock(&receive_statistics_lock_); + return impl_.SetMaxReorderingThreshold(max_reordering_threshold); + } + void SetMaxReorderingThreshold(uint32_t ssrc, + int max_reordering_threshold) override { + MutexLock lock(&receive_statistics_lock_); + return impl_.SetMaxReorderingThreshold(ssrc, max_reordering_threshold); + } + void EnableRetransmitDetection(uint32_t ssrc, bool enable) override { + MutexLock lock(&receive_statistics_lock_); + return impl_.EnableRetransmitDetection(ssrc, enable); + } + + private: + mutable Mutex receive_statistics_lock_; + ReceiveStatisticsImpl impl_ RTC_GUARDED_BY(&receive_statistics_lock_); +}; + } // namespace webrtc #endif // MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_ diff --git a/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/modules/rtp_rtcp/source/receive_statistics_unittest.cc index 053460e2ba..d40a743469 100644 --- a/modules/rtp_rtcp/source/receive_statistics_unittest.cc +++ b/modules/rtp_rtcp/source/receive_statistics_unittest.cc @@ -65,10 +65,13 @@ void IncrementSequenceNumber(RtpPacketReceived* packet) { IncrementSequenceNumber(packet, 1); } -class ReceiveStatisticsTest : public ::testing::Test { +class ReceiveStatisticsTest : public ::testing::TestWithParam { public: ReceiveStatisticsTest() - : clock_(0), receive_statistics_(ReceiveStatistics::Create(&clock_)) { + : clock_(0), + receive_statistics_( + GetParam() ? ReceiveStatistics::Create(&clock_) + : ReceiveStatistics::CreateThreadCompatible(&clock_)) { packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1); packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2); } @@ -80,7 +83,14 @@ class ReceiveStatisticsTest : public ::testing::Test { RtpPacketReceived packet2_; }; -TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) { +INSTANTIATE_TEST_SUITE_P(All, + ReceiveStatisticsTest, + ::testing::Bool(), + [](::testing::TestParamInfo info) { + return info.param ? "WithMutex" : "WithoutMutex"; + }); + +TEST_P(ReceiveStatisticsTest, TwoIncomingSsrcs) { receive_statistics_->OnRtpPacket(packet1_); IncrementSequenceNumber(&packet1_); receive_statistics_->OnRtpPacket(packet2_); @@ -133,7 +143,7 @@ TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) { EXPECT_EQ(3u, counters.transmitted.packets); } -TEST_F(ReceiveStatisticsTest, +TEST_P(ReceiveStatisticsTest, RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) { RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1); RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1); @@ -147,7 +157,7 @@ TEST_F(ReceiveStatisticsTest, EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2)); } -TEST_F(ReceiveStatisticsTest, +TEST_P(ReceiveStatisticsTest, RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) { RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1); RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1); @@ -174,7 +184,7 @@ TEST_F(ReceiveStatisticsTest, UnorderedElementsAre(kSsrc1, kSsrc2, kSsrc3, kSsrc4)); } -TEST_F(ReceiveStatisticsTest, ActiveStatisticians) { +TEST_P(ReceiveStatisticsTest, ActiveStatisticians) { receive_statistics_->OnRtpPacket(packet1_); IncrementSequenceNumber(&packet1_); clock_.AdvanceTimeMilliseconds(1000); @@ -206,7 +216,7 @@ TEST_F(ReceiveStatisticsTest, ActiveStatisticians) { EXPECT_EQ(2u, counters.transmitted.packets); } -TEST_F(ReceiveStatisticsTest, +TEST_P(ReceiveStatisticsTest, DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc) { // Creates a statistician object for the ssrc. receive_statistics_->EnableRetransmitDetection(kSsrc1, true); @@ -217,7 +227,7 @@ TEST_F(ReceiveStatisticsTest, EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size()); } -TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) { +TEST_P(ReceiveStatisticsTest, GetReceiveStreamDataCounters) { receive_statistics_->OnRtpPacket(packet1_); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); @@ -233,7 +243,7 @@ TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) { EXPECT_EQ(2u, counters.transmitted.packets); } -TEST_F(ReceiveStatisticsTest, SimpleLossComputation) { +TEST_P(ReceiveStatisticsTest, SimpleLossComputation) { packet1_.SetSequenceNumber(1); receive_statistics_->OnRtpPacket(packet1_); packet1_.SetSequenceNumber(3); @@ -256,7 +266,7 @@ TEST_F(ReceiveStatisticsTest, SimpleLossComputation) { EXPECT_EQ(20, statistician->GetFractionLostInPercent()); } -TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) { +TEST_P(ReceiveStatisticsTest, LossComputationWithReordering) { packet1_.SetSequenceNumber(1); receive_statistics_->OnRtpPacket(packet1_); packet1_.SetSequenceNumber(3); @@ -279,7 +289,7 @@ TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) { EXPECT_EQ(20, statistician->GetFractionLostInPercent()); } -TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) { +TEST_P(ReceiveStatisticsTest, LossComputationWithDuplicates) { // Lose 2 packets, but also receive 1 duplicate. Should actually count as // only 1 packet being lost. packet1_.SetSequenceNumber(1); @@ -304,7 +314,7 @@ TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) { EXPECT_EQ(20, statistician->GetFractionLostInPercent()); } -TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) { +TEST_P(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) { // First, test loss computation over a period that included a sequence number // rollover. packet1_.SetSequenceNumber(0xfffd); @@ -344,7 +354,7 @@ TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) { EXPECT_EQ(28, statistician->GetFractionLostInPercent()); } -TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) { +TEST_P(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) { receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); packet1_.SetSequenceNumber(0); @@ -377,7 +387,7 @@ TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) { EXPECT_EQ(0, statistician->GetFractionLostInPercent()); } -TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) { +TEST_P(ReceiveStatisticsTest, CountsLossAfterStreamRestart) { receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); packet1_.SetSequenceNumber(0); @@ -405,7 +415,7 @@ TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) { EXPECT_EQ(0, statistician->GetFractionLostInPercent()); } -TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) { +TEST_P(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) { receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); packet1_.SetSequenceNumber(0xffff - 401); @@ -428,7 +438,7 @@ TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) { EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); } -TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) { +TEST_P(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) { receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); packet1_.SetSequenceNumber(400); @@ -458,7 +468,7 @@ TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) { EXPECT_EQ(4u, report_blocks[0].extended_high_seq_num()); } -TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) { +TEST_P(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) { packet1_.SetSequenceNumber(0xffff); receive_statistics_->OnRtpPacket(packet1_); @@ -503,8 +513,7 @@ TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) { EXPECT_EQ(0x20001u, report_blocks[0].extended_high_seq_num()); } -TEST_F(ReceiveStatisticsTest, StreamDataCounters) { - receive_statistics_ = ReceiveStatistics::Create(&clock_); +TEST_P(ReceiveStatisticsTest, StreamDataCounters) { receive_statistics_->EnableRetransmitDetection(kSsrc1, true); const size_t kHeaderLength = 20; @@ -554,9 +563,7 @@ TEST_F(ReceiveStatisticsTest, StreamDataCounters) { EXPECT_EQ(counters.retransmitted.packets, 1u); } -TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) { - receive_statistics_ = ReceiveStatistics::Create(&clock_); - +TEST_P(ReceiveStatisticsTest, LastPacketReceivedTimestamp) { clock_.AdvanceTimeMilliseconds(42); receive_statistics_->OnRtpPacket(packet1_); StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)