stats: implement candidate-pair lastPacket(Sent|Received)Timestamp

https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-lastpacketsenttimestamp
https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-lastpacketreceivedtimestamp

which are useful together with the ice-restart-necessary logic mentioned
in
  https://w3c.github.io/webrtc-pc/#dictionary-rtcofferoptions-members

BUG=webrtc:14619

Change-Id: I4a8ab00a37fbd4af8b948720c83787cbdfc6b9a3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/281281
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#38534}
This commit is contained in:
Philipp Hancke 2022-11-01 17:03:01 +01:00 committed by WebRTC LUCI CQ
parent 9f06ef1cc3
commit 0487c5797a
9 changed files with 41 additions and 3 deletions

View File

@ -222,6 +222,8 @@ class RTC_EXPORT RTCIceCandidatePairStats final : public RTCStats {
RTCStatsMember<uint64_t> consent_requests_sent;
RTCStatsMember<uint64_t> packets_discarded_on_send;
RTCStatsMember<uint64_t> bytes_discarded_on_send;
RTCStatsMember<double> last_packet_received_timestamp;
RTCStatsMember<double> last_packet_sent_timestamp;
};
// https://w3c.github.io/webrtc-stats/#icecandidate-dict*

View File

@ -111,6 +111,7 @@ rtc_library("rtc_p2p") {
"../api/transport:field_trial_based_config",
"../api/transport:stun_types",
"../api/units:time_delta",
"../api/units:timestamp",
"../logging:ice_log",
"../rtc_base",
"../rtc_base:async_resolver_interface",

View File

@ -235,6 +235,7 @@ Connection::Connection(rtc::WeakPtr<Port> port,
last_ping_response_received_(0),
state_(IceCandidatePairState::WAITING),
time_created_ms_(rtc::TimeMillis()),
delta_internal_unix_epoch_ms_(rtc::TimeUTCMillis() - rtc::TimeMillis()),
field_trials_(&kDefaultFieldTrials),
rtt_estimate_(DEFAULT_RTT_ESTIMATE_HALF_TIME_MS) {
RTC_DCHECK_RUN_ON(network_thread_);
@ -1526,6 +1527,14 @@ ConnectionInfo Connection::stats() {
stats_.total_round_trip_time_ms = total_round_trip_time_ms_;
stats_.current_round_trip_time_ms = current_round_trip_time_ms_;
stats_.remote_candidate = remote_candidate();
if (last_data_received_ > 0) {
stats_.last_data_received = webrtc::Timestamp::Millis(
last_data_received_ + delta_internal_unix_epoch_ms_);
}
if (last_send_data_ > 0) {
stats_.last_data_sent = webrtc::Timestamp::Millis(
last_send_data_ + delta_internal_unix_epoch_ms_);
}
return stats_;
}

View File

@ -442,7 +442,8 @@ class Connection : public CandidatePairInterface {
IceCandidatePairState state_ RTC_GUARDED_BY(network_thread_);
// Time duration to switch from receiving to not receiving.
absl::optional<int> receiving_timeout_ RTC_GUARDED_BY(network_thread_);
int64_t time_created_ms_ RTC_GUARDED_BY(network_thread_);
const int64_t time_created_ms_ RTC_GUARDED_BY(network_thread_);
const int64_t delta_internal_unix_epoch_ms_ RTC_GUARDED_BY(network_thread_);
int num_pings_sent_ RTC_GUARDED_BY(network_thread_) = 0;
absl::optional<webrtc::IceCandidatePairDescription> log_description_

View File

@ -15,6 +15,7 @@
#include "absl/types/optional.h"
#include "api/candidate.h"
#include "api/units/timestamp.h"
namespace cricket {
@ -72,6 +73,10 @@ struct ConnectionInfo {
uint64_t total_round_trip_time_ms;
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
absl::optional<uint32_t> current_round_trip_time_ms;
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-lastpacketreceivedtimestamp
absl::optional<webrtc::Timestamp> last_data_received;
absl::optional<webrtc::Timestamp> last_data_sent;
};
// Information about all the candidate pairs of a channel.

View File

@ -1727,6 +1727,15 @@ void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
info.sent_ping_requests_total -
info.sent_ping_requests_before_first_response);
if (info.last_data_received) {
candidate_pair_stats->last_packet_received_timestamp =
static_cast<double>(info.last_data_received->ms());
}
if (info.last_data_sent) {
candidate_pair_stats->last_packet_sent_timestamp =
static_cast<double>(info.last_data_sent->ms());
}
report->AddStats(std::move(candidate_pair_stats));
}

View File

@ -1940,6 +1940,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
connection_info.state = cricket::IceCandidatePairState::IN_PROGRESS;
connection_info.priority = 5555;
connection_info.nominated = false;
connection_info.last_data_received = Timestamp::Millis(2500);
connection_info.last_data_sent = Timestamp::Millis(5200);
cricket::TransportChannelStats transport_channel_stats;
transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
@ -1974,6 +1976,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
expected_pair.responses_received = 4321;
expected_pair.responses_sent = 1000;
expected_pair.consent_requests_sent = (2222 - 2000);
expected_pair.last_packet_received_timestamp = 2500;
expected_pair.last_packet_sent_timestamp = 5200;
// `expected_pair.current_round_trip_time` should be undefined because the
// current RTT is not set.
// `expected_pair.available_[outgoing/incoming]_bitrate` should be undefined

View File

@ -516,6 +516,8 @@ class RTCStatsReportVerifier {
verifier.TestMemberIsNonNegative<uint64_t>(candidate_pair.responses_sent);
verifier.TestMemberIsNonNegative<uint64_t>(
candidate_pair.consent_requests_sent);
verifier.TestMemberIsDefined(candidate_pair.last_packet_received_timestamp);
verifier.TestMemberIsDefined(candidate_pair.last_packet_sent_timestamp);
return verifier.ExpectAllMembersSuccessfullyTested();
}

View File

@ -185,7 +185,9 @@ WEBRTC_RTCSTATS_IMPL(RTCIceCandidatePairStats, RTCStats, "candidate-pair",
&responses_sent,
&consent_requests_sent,
&packets_discarded_on_send,
&bytes_discarded_on_send)
&bytes_discarded_on_send,
&last_packet_received_timestamp,
&last_packet_sent_timestamp)
// clang-format on
RTCIceCandidatePairStats::RTCIceCandidatePairStats(const std::string& id,
@ -216,7 +218,9 @@ RTCIceCandidatePairStats::RTCIceCandidatePairStats(std::string&& id,
responses_sent("responsesSent"),
consent_requests_sent("consentRequestsSent"),
packets_discarded_on_send("packetsDiscardedOnSend"),
bytes_discarded_on_send("bytesDiscardedOnSend") {}
bytes_discarded_on_send("bytesDiscardedOnSend"),
last_packet_received_timestamp("lastPacketReceivedTimestamp"),
last_packet_sent_timestamp("lastPacketSentTimestamp") {}
RTCIceCandidatePairStats::RTCIceCandidatePairStats(
const RTCIceCandidatePairStats& other) = default;