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 <danilchap@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33419}
diff --git a/modules/rtp_rtcp/include/receive_statistics.h b/modules/rtp_rtcp/include/receive_statistics.h
index 2cc3fea..ce87b99 100644
--- a/modules/rtp_rtcp/include/receive_statistics.h
+++ b/modules/rtp_rtcp/include/receive_statistics.h
@@ -55,7 +55,12 @@
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<ReceiveStatistics> Create(Clock* clock);
+ // Returns a thread-compatible instance of ReceiveStatistics.
+ static std::unique_ptr<ReceiveStatistics> 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 6ec41a1..4c399a1 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -13,6 +13,7 @@
#include <cmath>
#include <cstdlib>
#include <memory>
+#include <utility>
#include <vector>
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
@@ -100,7 +101,6 @@
}
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::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 @@
bool StreamStatisticianImpl::GetActiveStatisticsAndReset(
RtcpStatistics* statistics) {
- MutexLock lock(&stream_lock_);
if (clock_->TimeInMilliseconds() - last_receive_time_ms_ >=
kStatisticsTimeoutMs) {
// Not active.
@@ -192,9 +188,7 @@
if (!ReceivedRtpPacket()) {
return false;
}
-
*statistics = CalculateRtcpStatistics();
-
return true;
}
@@ -241,7 +235,6 @@
}
absl::optional<int> StreamStatisticianImpl::GetFractionLostInPercent() const {
- MutexLock lock(&stream_lock_);
if (!ReceivedRtpPacket()) {
return absl::nullopt;
}
@@ -257,12 +250,10 @@
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 @@
}
std::unique_ptr<ReceiveStatistics> ReceiveStatistics::Create(Clock* clock) {
- return std::make_unique<ReceiveStatisticsImpl>(clock);
+ return std::make_unique<ReceiveStatisticsLocked>(
+ clock, [](uint32_t ssrc, Clock* clock, int max_reordering_threshold) {
+ return std::make_unique<StreamStatisticianLocked>(
+ ssrc, clock, max_reordering_threshold);
+ });
}
-ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock)
+std::unique_ptr<ReceiveStatistics> ReceiveStatistics::CreateThreadCompatible(
+ Clock* clock) {
+ return std::make_unique<ReceiveStatisticsImpl>(
+ clock, [](uint32_t ssrc, Clock* clock, int max_reordering_threshold) {
+ return std::make_unique<StreamStatisticianImpl>(
+ ssrc, clock, max_reordering_threshold);
+ });
+}
+
+ReceiveStatisticsImpl::ReceiveStatisticsImpl(
+ Clock* clock,
+ std::function<std::unique_ptr<StreamStatisticianImplInterface>(
+ 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 @@
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<StreamStatisticianImplInterface>& 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<uint32_t, StreamStatisticianImpl*> 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 @@
std::vector<rtcp::ReportBlock> ReceiveStatisticsImpl::RtcpReportBlocks(
size_t max_blocks) {
- std::map<uint32_t, StreamStatisticianImpl*> statisticians;
- {
- MutexLock lock(&receive_statistics_lock_);
- statisticians = statisticians_;
- }
std::vector<rtcp::ReportBlock> 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 @@
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 41830b0..2456f93 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 <algorithm>
+#include <functional>
#include <map>
+#include <memory>
+#include <utility>
#include <vector>
#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<int> 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<uint16_t> received_seq_out_of_order_
- RTC_GUARDED_BY(&stream_lock_);
+ absl::optional<uint16_t> 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<int> 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<std::unique_ptr<StreamStatisticianImplInterface>(
+ uint32_t ssrc,
+ Clock* clock,
+ int max_reordering_threshold)> stream_statistician_factory);
+ ~ReceiveStatisticsImpl() override = default;
// Implements ReceiveStatisticsProvider.
std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override;
@@ -112,22 +170,69 @@
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<std::unique_ptr<StreamStatisticianImplInterface>(
+ 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<uint32_t, StreamStatisticianImpl*> statisticians_
- RTC_GUARDED_BY(receive_statistics_lock_);
+ int max_reordering_threshold_;
+ std::map<uint32_t, std::unique_ptr<StreamStatisticianImplInterface>>
+ statisticians_;
};
+
+// Thread-safe implementation wrapping access to ReceiveStatisticsImpl with a
+// mutex.
+class ReceiveStatisticsLocked : public ReceiveStatistics {
+ public:
+ explicit ReceiveStatisticsLocked(
+ Clock* clock,
+ std::function<std::unique_ptr<StreamStatisticianImplInterface>(
+ uint32_t ssrc,
+ Clock* clock,
+ int max_reordering_threshold)> stream_statitician_factory)
+ : impl_(clock, std::move(stream_statitician_factory)) {}
+ ~ReceiveStatisticsLocked() override = default;
+ std::vector<rtcp::ReportBlock> 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 053460e..d40a743 100644
--- a/modules/rtp_rtcp/source/receive_statistics_unittest.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
@@ -65,10 +65,13 @@
IncrementSequenceNumber(packet, 1);
}
-class ReceiveStatisticsTest : public ::testing::Test {
+class ReceiveStatisticsTest : public ::testing::TestWithParam<bool> {
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 @@
RtpPacketReceived packet2_;
};
-TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
+INSTANTIATE_TEST_SUITE_P(All,
+ ReceiveStatisticsTest,
+ ::testing::Bool(),
+ [](::testing::TestParamInfo<bool> info) {
+ return info.param ? "WithMutex" : "WithoutMutex";
+ });
+
+TEST_P(ReceiveStatisticsTest, TwoIncomingSsrcs) {
receive_statistics_->OnRtpPacket(packet1_);
IncrementSequenceNumber(&packet1_);
receive_statistics_->OnRtpPacket(packet2_);
@@ -133,7 +143,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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)