Wire up non-sender RTT for audio, and implement related standardized stats.
The implemented stats are: - https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime - https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-totalroundtriptime - https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptimemeasurements Bug: webrtc:12951, webrtc:12714 Change-Id: Ia362d5c4b0456140e32da79d40edc06ab9ce2a2c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/226956 Commit-Queue: Ivo Creusen <ivoc@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#34861}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
58157b5cd2
commit
fb0dca6c05
@ -303,6 +303,15 @@ int32_t RTCPReceiver::RTT(uint32_t remote_ssrc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
RTCPReceiver::NonSenderRttStats RTCPReceiver::GetNonSenderRTT() const {
|
||||
MutexLock lock(&rtcp_receiver_lock_);
|
||||
auto it = non_sender_rtts_.find(remote_ssrc_);
|
||||
if (it == non_sender_rtts_.end()) {
|
||||
return {};
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void RTCPReceiver::SetNonSenderRttMeasurement(bool enabled) {
|
||||
MutexLock lock(&rtcp_receiver_lock_);
|
||||
xr_rrtr_status_ = enabled;
|
||||
@ -435,6 +444,16 @@ bool RTCPReceiver::ParseCompoundPacket(rtc::ArrayView<const uint8_t> packet,
|
||||
MutexLock lock(&rtcp_receiver_lock_);
|
||||
|
||||
CommonHeader rtcp_block;
|
||||
// If a sender report is received but no DLRR, we need to reset the
|
||||
// roundTripTime stat according to the standard, see
|
||||
// https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime
|
||||
struct RtcpReceivedBlock {
|
||||
bool sender_report = false;
|
||||
bool dlrr = false;
|
||||
};
|
||||
// For each remote SSRC we store if we've received a sender report or a DLRR
|
||||
// block.
|
||||
flat_map<uint32_t, RtcpReceivedBlock> received_blocks;
|
||||
for (const uint8_t* next_block = packet.begin(); next_block != packet.end();
|
||||
next_block = rtcp_block.NextPacket()) {
|
||||
ptrdiff_t remaining_blocks_size = packet.end() - next_block;
|
||||
@ -455,6 +474,7 @@ bool RTCPReceiver::ParseCompoundPacket(rtc::ArrayView<const uint8_t> packet,
|
||||
switch (rtcp_block.type()) {
|
||||
case rtcp::SenderReport::kPacketType:
|
||||
HandleSenderReport(rtcp_block, packet_information);
|
||||
received_blocks[packet_information->remote_ssrc].sender_report = true;
|
||||
break;
|
||||
case rtcp::ReceiverReport::kPacketType:
|
||||
HandleReceiverReport(rtcp_block, packet_information);
|
||||
@ -463,7 +483,12 @@ bool RTCPReceiver::ParseCompoundPacket(rtc::ArrayView<const uint8_t> packet,
|
||||
HandleSdes(rtcp_block, packet_information);
|
||||
break;
|
||||
case rtcp::ExtendedReports::kPacketType:
|
||||
HandleXr(rtcp_block, packet_information);
|
||||
bool contains_dlrr;
|
||||
uint32_t ssrc;
|
||||
HandleXr(rtcp_block, packet_information, contains_dlrr, ssrc);
|
||||
if (contains_dlrr) {
|
||||
received_blocks[ssrc].dlrr = true;
|
||||
}
|
||||
break;
|
||||
case rtcp::Bye::kPacketType:
|
||||
HandleBye(rtcp_block);
|
||||
@ -515,6 +540,15 @@ bool RTCPReceiver::ParseCompoundPacket(rtc::ArrayView<const uint8_t> packet,
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& rb : received_blocks) {
|
||||
if (rb.second.sender_report && !rb.second.dlrr) {
|
||||
auto rtt_stats = non_sender_rtts_.find(rb.first);
|
||||
if (rtt_stats != non_sender_rtts_.end()) {
|
||||
rtt_stats->second.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (packet_type_counter_observer_) {
|
||||
packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
|
||||
main_ssrc_, packet_type_counter_);
|
||||
@ -832,18 +866,22 @@ void RTCPReceiver::HandleBye(const CommonHeader& rtcp_block) {
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXr(const CommonHeader& rtcp_block,
|
||||
PacketInformation* packet_information) {
|
||||
PacketInformation* packet_information,
|
||||
bool& contains_dlrr,
|
||||
uint32_t& ssrc) {
|
||||
rtcp::ExtendedReports xr;
|
||||
if (!xr.Parse(rtcp_block)) {
|
||||
++num_skipped_packets_;
|
||||
return;
|
||||
}
|
||||
ssrc = xr.sender_ssrc();
|
||||
contains_dlrr = !xr.dlrr().sub_blocks().empty();
|
||||
|
||||
if (xr.rrtr())
|
||||
HandleXrReceiveReferenceTime(xr.sender_ssrc(), *xr.rrtr());
|
||||
|
||||
for (const rtcp::ReceiveTimeInfo& time_info : xr.dlrr().sub_blocks())
|
||||
HandleXrDlrrReportBlock(time_info);
|
||||
HandleXrDlrrReportBlock(xr.sender_ssrc(), time_info);
|
||||
|
||||
if (xr.target_bitrate()) {
|
||||
HandleXrTargetBitrate(xr.sender_ssrc(), *xr.target_bitrate(),
|
||||
@ -872,7 +910,8 @@ void RTCPReceiver::HandleXrReceiveReferenceTime(uint32_t sender_ssrc,
|
||||
}
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXrDlrrReportBlock(const rtcp::ReceiveTimeInfo& rti) {
|
||||
void RTCPReceiver::HandleXrDlrrReportBlock(uint32_t sender_ssrc,
|
||||
const rtcp::ReceiveTimeInfo& rti) {
|
||||
if (!registered_ssrcs_.contains(rti.ssrc)) // Not to us.
|
||||
return;
|
||||
|
||||
@ -884,14 +923,21 @@ void RTCPReceiver::HandleXrDlrrReportBlock(const rtcp::ReceiveTimeInfo& rti) {
|
||||
uint32_t send_time_ntp = rti.last_rr;
|
||||
// RFC3611, section 4.5, LRR field discription states:
|
||||
// If no such block has been received, the field is set to zero.
|
||||
if (send_time_ntp == 0)
|
||||
if (send_time_ntp == 0) {
|
||||
auto rtt_stats = non_sender_rtts_.find(sender_ssrc);
|
||||
if (rtt_stats != non_sender_rtts_.end()) {
|
||||
rtt_stats->second.Invalidate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t delay_ntp = rti.delay_since_last_rr;
|
||||
uint32_t now_ntp = CompactNtp(clock_->CurrentNtpTime());
|
||||
|
||||
uint32_t rtt_ntp = now_ntp - delay_ntp - send_time_ntp;
|
||||
xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
|
||||
|
||||
non_sender_rtts_[sender_ssrc].Update(TimeDelta::Millis(xr_rr_rtt_ms_));
|
||||
}
|
||||
|
||||
void RTCPReceiver::HandleXrTargetBitrate(
|
||||
|
||||
Reference in New Issue
Block a user