In ReportBlockData expose RTCP report block properties directly
These accessors would allow to deprecated report_block() accessor and then would allow to remove redundant RTCPReportBlock and ReportBlock types converging on single ReportBlockData type to pass that information across WebRTC components helpers like fraction_lost() and jitter() would also allow to unify conversion of the rtp specific format into more common way of represent such information Bug: None Change-Id: I3c97f96affcf83b529095899bd63af007f8b4014 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/303880 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39975}
This commit is contained in:
parent
b03c4a5437
commit
d3eddff30c
@ -10,10 +10,15 @@
|
||||
|
||||
#include "modules/rtp_rtcp/include/report_block_data.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TimeDelta ReportBlockData::AvgRtt() const {
|
||||
return num_rtts_ > 0 ? sum_rtt_ / num_rtts_ : TimeDelta::Zero();
|
||||
TimeDelta ReportBlockData::jitter(int rtp_clock_rate_hz) const {
|
||||
RTC_DCHECK_GT(rtp_clock_rate_hz, 0);
|
||||
// Conversion to TimeDelta and division are swapped to avoid conversion
|
||||
// to/from floating point types.
|
||||
return TimeDelta::Seconds(jitter()) / rtp_clock_rate_hz;
|
||||
}
|
||||
|
||||
void ReportBlockData::SetReportBlock(uint32_t sender_ssrc,
|
||||
|
||||
@ -18,6 +18,9 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Represents fields and derived information received in RTCP report block
|
||||
// attached to RTCP sender report or RTCP receiver report, as described in
|
||||
// https://www.rfc-editor.org/rfc/rfc3550#section-6.4.1
|
||||
class ReportBlockData {
|
||||
public:
|
||||
ReportBlockData() = default;
|
||||
@ -25,6 +28,50 @@ class ReportBlockData {
|
||||
ReportBlockData(const ReportBlockData&) = default;
|
||||
ReportBlockData& operator=(const ReportBlockData&) = default;
|
||||
|
||||
// The SSRC identifier for the originator of this report block,
|
||||
// i.e. remote receiver of the RTP stream.
|
||||
uint32_t sender_ssrc() const { return report_block_.sender_ssrc; }
|
||||
|
||||
// The SSRC identifier of the source to which the information in this
|
||||
// reception report block pertains, i.e. local sender of the RTP stream.
|
||||
uint32_t source_ssrc() const { return report_block_.source_ssrc; }
|
||||
|
||||
// The fraction of RTP data packets from 'source_ssrc()' lost since the
|
||||
// previous report block was sent.
|
||||
// Fraction loss in range [0.0, 1.0].
|
||||
float fraction_lost() const { return fraction_lost_raw() / 256.0; }
|
||||
|
||||
// Fraction loss as was written in the raw packet: range is [0, 255] where 0
|
||||
// represents no loss, and 255 represents 99.6% loss (255/256 * 100%).
|
||||
uint8_t fraction_lost_raw() const { return report_block_.fraction_lost; }
|
||||
|
||||
// The total number of RTP data packets from 'source_ssrc()' that have been
|
||||
// lost since the beginning of reception. This number is defined to be the
|
||||
// number of packets expected less the number of packets actually received,
|
||||
// where the number of packets received includes any which are late or
|
||||
// duplicates. Thus, packets that arrive late are not counted as lost, and the
|
||||
// loss may be negative if there are duplicates.
|
||||
int cumulative_lost() const { return report_block_.packets_lost; }
|
||||
|
||||
// The low 16 bits contain the highest sequence number received in an RTP data
|
||||
// packet from 'source_ssrc()', and the most significant 16 bits extend that
|
||||
// sequence number with the corresponding count of sequence number cycles.
|
||||
uint32_t extended_highest_sequence_number() const {
|
||||
return report_block_.extended_highest_sequence_number;
|
||||
}
|
||||
|
||||
// An estimate of the statistical variance of the RTP data packet interarrival
|
||||
// time, measured in RTP timestamp units. The interarrival jitter J is defined
|
||||
// to be the mean deviation (smoothed absolute value) of the difference D in
|
||||
// packet spacing at the receiver compared to the sender for a pair of
|
||||
// packets.
|
||||
uint32_t jitter() const { return report_block_.jitter; }
|
||||
|
||||
// Jitter converted to common time units.
|
||||
TimeDelta jitter(int rtp_clock_rate_hz) const;
|
||||
|
||||
// TODO(danilchap): Deprecate in favor of using ReportBlockData accessors
|
||||
// directly.
|
||||
const RTCPReportBlock& report_block() const { return report_block_; }
|
||||
|
||||
[[deprecated]] int64_t report_block_timestamp_utc_us() const {
|
||||
@ -34,11 +81,14 @@ class ReportBlockData {
|
||||
[[deprecated]] int64_t min_rtt_ms() const { return min_rtt_.ms(); }
|
||||
[[deprecated]] int64_t max_rtt_ms() const { return max_rtt_.ms(); }
|
||||
[[deprecated]] int64_t sum_rtt_ms() const { return sum_rtt_.ms(); }
|
||||
[[deprecated]] double AvgRttMs() const { return AvgRtt().ms<double>(); }
|
||||
|
||||
// Time in utc epoch (Jan 1st, 1970) the report block was received.
|
||||
Timestamp report_block_timestamp_utc() const {
|
||||
return report_block_timestamp_utc_;
|
||||
}
|
||||
|
||||
// Round Trip Time measurments for given (sender_ssrc, source_ssrc) pair.
|
||||
// Min, max, sum, number of measurements are since beginning of the call.
|
||||
TimeDelta last_rtt() const { return last_rtt_; }
|
||||
TimeDelta min_rtt() const { return min_rtt_; }
|
||||
TimeDelta max_rtt() const { return max_rtt_; }
|
||||
@ -46,11 +96,9 @@ class ReportBlockData {
|
||||
size_t num_rtts() const { return num_rtts_; }
|
||||
bool has_rtt() const { return num_rtts_ != 0; }
|
||||
|
||||
TimeDelta AvgRtt() const;
|
||||
|
||||
void SetReportBlock(uint32_t sender_ssrc,
|
||||
const rtcp::ReportBlock& report_block,
|
||||
Timestamp report_block_timestamp_utc_us);
|
||||
Timestamp report_block_timestamp_utc);
|
||||
void AddRoundTripTimeSample(TimeDelta rtt);
|
||||
|
||||
private:
|
||||
|
||||
@ -612,7 +612,7 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block,
|
||||
ReportBlockData* report_block_data =
|
||||
&received_report_blocks_[report_block.source_ssrc()];
|
||||
if (report_block.extended_high_seq_num() >
|
||||
report_block_data->report_block().extended_highest_sequence_number) {
|
||||
report_block_data->extended_highest_sequence_number()) {
|
||||
// We have successfully delivered new RTP packets to the remote side after
|
||||
// the last RR was sent from the remote side.
|
||||
last_increased_sequence_number_ = last_received_rb_;
|
||||
@ -806,7 +806,7 @@ bool RTCPReceiver::HandleBye(const CommonHeader& rtcp_block) {
|
||||
// Clear our lists.
|
||||
rtts_.erase(bye.sender_ssrc());
|
||||
EraseIf(received_report_blocks_, [&](const auto& elem) {
|
||||
return elem.second.report_block().sender_ssrc == bye.sender_ssrc();
|
||||
return elem.second.sender_ssrc() == bye.sender_ssrc();
|
||||
});
|
||||
|
||||
TmmbrInformation* tmmbr_info = GetTmmbrInformation(bye.sender_ssrc());
|
||||
|
||||
@ -441,12 +441,10 @@ TEST(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
|
||||
receiver.IncomingPacket(rr1.Build());
|
||||
|
||||
EXPECT_EQ(now, receiver.LastReceivedReportBlockMs());
|
||||
EXPECT_THAT(receiver.GetLatestReportBlockData(),
|
||||
UnorderedElementsAre(
|
||||
Property(&ReportBlockData::report_block,
|
||||
Field(&RTCPReportBlock::fraction_lost, 0)),
|
||||
Property(&ReportBlockData::report_block,
|
||||
Field(&RTCPReportBlock::fraction_lost, 10))));
|
||||
EXPECT_THAT(
|
||||
receiver.GetLatestReportBlockData(),
|
||||
UnorderedElementsAre(Property(&ReportBlockData::fraction_lost_raw, 0),
|
||||
Property(&ReportBlockData::fraction_lost_raw, 10)));
|
||||
|
||||
// Insert next receiver report with same ssrc but new values.
|
||||
rtcp::ReportBlock rb3;
|
||||
@ -478,20 +476,16 @@ TEST(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
|
||||
EXPECT_THAT(
|
||||
receiver.GetLatestReportBlockData(),
|
||||
UnorderedElementsAre(
|
||||
Property(
|
||||
&ReportBlockData::report_block,
|
||||
AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
|
||||
Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
|
||||
Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
|
||||
Field(&RTCPReportBlock::extended_highest_sequence_number,
|
||||
kSequenceNumbers[0]))),
|
||||
Property(
|
||||
&ReportBlockData::report_block,
|
||||
AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
|
||||
Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
|
||||
Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
|
||||
Field(&RTCPReportBlock::extended_highest_sequence_number,
|
||||
kSequenceNumbers[1])))));
|
||||
AllOf(Property(&ReportBlockData::source_ssrc, kReceiverMainSsrc),
|
||||
Property(&ReportBlockData::fraction_lost_raw, kFracLost[0]),
|
||||
Property(&ReportBlockData::cumulative_lost, kCumLost[0]),
|
||||
Property(&ReportBlockData::extended_highest_sequence_number,
|
||||
kSequenceNumbers[0])),
|
||||
AllOf(Property(&ReportBlockData::source_ssrc, kReceiverExtraSsrc),
|
||||
Property(&ReportBlockData::fraction_lost_raw, kFracLost[1]),
|
||||
Property(&ReportBlockData::cumulative_lost, kCumLost[1]),
|
||||
Property(&ReportBlockData::extended_highest_sequence_number,
|
||||
kSequenceNumbers[1]))));
|
||||
}
|
||||
|
||||
TEST(RtcpReceiverTest,
|
||||
@ -522,16 +516,14 @@ TEST(RtcpReceiverTest,
|
||||
|
||||
EXPECT_EQ(now, receiver.LastReceivedReportBlockMs());
|
||||
|
||||
EXPECT_THAT(
|
||||
receiver.GetLatestReportBlockData(),
|
||||
ElementsAre(Property(
|
||||
&ReportBlockData::report_block,
|
||||
AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
|
||||
Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
|
||||
Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
|
||||
Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
|
||||
Field(&RTCPReportBlock::extended_highest_sequence_number,
|
||||
kSequenceNumbers[0])))));
|
||||
EXPECT_THAT(receiver.GetLatestReportBlockData(),
|
||||
ElementsAre(AllOf(
|
||||
Property(&ReportBlockData::source_ssrc, kReceiverMainSsrc),
|
||||
Property(&ReportBlockData::sender_ssrc, kSenderSsrc),
|
||||
Property(&ReportBlockData::fraction_lost_raw, kFracLost[0]),
|
||||
Property(&ReportBlockData::cumulative_lost, kCumLost[0]),
|
||||
Property(&ReportBlockData::extended_highest_sequence_number,
|
||||
kSequenceNumbers[0]))));
|
||||
|
||||
rtcp::ReportBlock rb2;
|
||||
rb2.SetMediaSsrc(kReceiverMainSsrc);
|
||||
@ -547,16 +539,14 @@ TEST(RtcpReceiverTest,
|
||||
OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
|
||||
receiver.IncomingPacket(rr2.Build());
|
||||
|
||||
EXPECT_THAT(
|
||||
receiver.GetLatestReportBlockData(),
|
||||
UnorderedElementsAre(Property(
|
||||
&ReportBlockData::report_block,
|
||||
AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
|
||||
Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
|
||||
Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
|
||||
Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
|
||||
Field(&RTCPReportBlock::extended_highest_sequence_number,
|
||||
kSequenceNumbers[1])))));
|
||||
EXPECT_THAT(receiver.GetLatestReportBlockData(),
|
||||
UnorderedElementsAre(AllOf(
|
||||
Property(&ReportBlockData::source_ssrc, kReceiverMainSsrc),
|
||||
Property(&ReportBlockData::sender_ssrc, kSenderSsrc2),
|
||||
Property(&ReportBlockData::fraction_lost_raw, kFracLost[1]),
|
||||
Property(&ReportBlockData::cumulative_lost, kCumLost[1]),
|
||||
Property(&ReportBlockData::extended_highest_sequence_number,
|
||||
kSequenceNumbers[1]))));
|
||||
}
|
||||
|
||||
TEST(RtcpReceiverTest, GetRtt) {
|
||||
@ -1573,19 +1563,18 @@ TEST(RtcpReceiverTest,
|
||||
rtcp_report.SetSenderSsrc(kSenderSsrc);
|
||||
rtcp_report.AddReportBlock(rtcp_block);
|
||||
EXPECT_CALL(observer, OnReportBlockDataUpdated)
|
||||
.WillOnce([&](ReportBlockData report_block_data) {
|
||||
const auto& report_block = report_block_data.report_block();
|
||||
EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc);
|
||||
EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc);
|
||||
EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost);
|
||||
EXPECT_EQ(rtcp_block.cumulative_lost(), report_block.packets_lost);
|
||||
.WillOnce([&](ReportBlockData report_block) {
|
||||
EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc());
|
||||
EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc());
|
||||
EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost_raw());
|
||||
EXPECT_EQ(rtcp_block.cumulative_lost(), report_block.cumulative_lost());
|
||||
EXPECT_EQ(rtcp_block.extended_high_seq_num(),
|
||||
report_block.extended_highest_sequence_number);
|
||||
EXPECT_EQ(rtcp_block.jitter(), report_block.jitter);
|
||||
EXPECT_EQ(report_block_data.report_block_timestamp_utc(),
|
||||
report_block.extended_highest_sequence_number());
|
||||
EXPECT_EQ(rtcp_block.jitter(), report_block.jitter());
|
||||
EXPECT_EQ(report_block.report_block_timestamp_utc(),
|
||||
Timestamp::Millis(kNtpNowMs));
|
||||
// No RTT is calculated in this test.
|
||||
EXPECT_EQ(0u, report_block_data.num_rtts());
|
||||
EXPECT_EQ(0u, report_block.num_rtts());
|
||||
});
|
||||
EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
|
||||
EXPECT_CALL(mocks.bandwidth_observer, OnReceivedRtcpReceiverReport);
|
||||
@ -1627,8 +1616,7 @@ TEST(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
|
||||
InSequence sequence;
|
||||
EXPECT_CALL(observer, OnReportBlockDataUpdated)
|
||||
.WillOnce([&](ReportBlockData report_block_data) {
|
||||
EXPECT_EQ(kReceiverMainSsrc,
|
||||
report_block_data.report_block().source_ssrc);
|
||||
EXPECT_EQ(kReceiverMainSsrc, report_block_data.source_ssrc());
|
||||
EXPECT_EQ(1u, report_block_data.num_rtts());
|
||||
EXPECT_EQ(kRtt, report_block_data.min_rtt());
|
||||
EXPECT_EQ(kRtt, report_block_data.max_rtt());
|
||||
@ -1637,8 +1625,7 @@ TEST(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
|
||||
});
|
||||
EXPECT_CALL(observer, OnReportBlockDataUpdated)
|
||||
.WillOnce([](ReportBlockData report_block_data) {
|
||||
EXPECT_EQ(kReceiverExtraSsrc,
|
||||
report_block_data.report_block().source_ssrc);
|
||||
EXPECT_EQ(kReceiverExtraSsrc, report_block_data.source_ssrc());
|
||||
EXPECT_EQ(0u, report_block_data.num_rtts());
|
||||
});
|
||||
receiver.IncomingPacket(sr.Build());
|
||||
@ -1664,11 +1651,9 @@ TEST(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
|
||||
|
||||
auto report_block_datas = receiver.GetLatestReportBlockData();
|
||||
ASSERT_THAT(report_block_datas, SizeIs(1));
|
||||
EXPECT_EQ(kReceiverMainSsrc,
|
||||
report_block_datas[0].report_block().source_ssrc);
|
||||
EXPECT_EQ(
|
||||
kSequenceNumber,
|
||||
report_block_datas[0].report_block().extended_highest_sequence_number);
|
||||
EXPECT_EQ(kReceiverMainSsrc, report_block_datas[0].source_ssrc());
|
||||
EXPECT_EQ(kSequenceNumber,
|
||||
report_block_datas[0].extended_highest_sequence_number());
|
||||
}
|
||||
|
||||
TEST(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
|
||||
@ -1706,11 +1691,9 @@ TEST(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
|
||||
// Only the latest block should be returned.
|
||||
auto report_block_datas = receiver.GetLatestReportBlockData();
|
||||
ASSERT_THAT(report_block_datas, SizeIs(1));
|
||||
EXPECT_EQ(kReceiverMainSsrc,
|
||||
report_block_datas[0].report_block().source_ssrc);
|
||||
EXPECT_EQ(
|
||||
kSequenceNumber2,
|
||||
report_block_datas[0].report_block().extended_highest_sequence_number);
|
||||
EXPECT_EQ(kReceiverMainSsrc, report_block_datas[0].source_ssrc());
|
||||
EXPECT_EQ(kSequenceNumber2,
|
||||
report_block_datas[0].extended_highest_sequence_number());
|
||||
}
|
||||
|
||||
TEST(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
|
||||
@ -1747,16 +1730,12 @@ TEST(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
|
||||
// Both report blocks should be returned.
|
||||
auto report_block_datas = receiver.GetLatestReportBlockData();
|
||||
ASSERT_THAT(report_block_datas, SizeIs(2));
|
||||
EXPECT_EQ(kReceiverMainSsrc,
|
||||
report_block_datas[0].report_block().source_ssrc);
|
||||
EXPECT_EQ(
|
||||
kSequenceNumber1,
|
||||
report_block_datas[0].report_block().extended_highest_sequence_number);
|
||||
EXPECT_EQ(kReceiverExtraSsrc,
|
||||
report_block_datas[1].report_block().source_ssrc);
|
||||
EXPECT_EQ(
|
||||
kSequenceNumber2,
|
||||
report_block_datas[1].report_block().extended_highest_sequence_number);
|
||||
EXPECT_EQ(kReceiverMainSsrc, report_block_datas[0].source_ssrc());
|
||||
EXPECT_EQ(kSequenceNumber1,
|
||||
report_block_datas[0].extended_highest_sequence_number());
|
||||
EXPECT_EQ(kReceiverExtraSsrc, report_block_datas[1].source_ssrc());
|
||||
EXPECT_EQ(kSequenceNumber2,
|
||||
report_block_datas[1].extended_highest_sequence_number());
|
||||
}
|
||||
|
||||
TEST(RtcpReceiverTest, ReceivesTransportFeedback) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user