Wire up RTCInboundRtpStreamStats.lastPacketReceivedTimestamp.
This collects this metric for both audio and video streams. https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp This is a follow-up to https://webrtc-review.googlesource.com/c/src/+/130479 which calculated this metric. This CL is purely plumbing from "StreamDataCounters::last_packet_received_timestamp_ms" to RTCInboundRtpStreamStats. Bug: webrtc:10449 Change-Id: I757ad19b5b8e84553da5edd4a75efa3e1fe30b56 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131397 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Åsa Persson <asapersson@webrtc.org> Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27628}
This commit is contained in:

committed by
Commit Bot

parent
3d11e2f81c
commit
01738c63aa
@ -397,6 +397,7 @@ class RTC_EXPORT RTCInboundRTPStreamStats final : public RTCRTPStreamStats {
|
||||
RTCStatsMember<uint32_t> packets_received;
|
||||
RTCStatsMember<uint64_t> bytes_received;
|
||||
RTCStatsMember<int32_t> packets_lost; // Signed per RFC 3550
|
||||
RTCStatsMember<double> last_packet_received_timestamp;
|
||||
// TODO(hbos): Collect and populate this value for both "audio" and "video",
|
||||
// currently not collected for "video". https://bugs.webrtc.org/7065
|
||||
RTCStatsMember<double> jitter;
|
||||
|
@ -190,6 +190,8 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
|
||||
stats.packets_lost = call_stats.cumulativeLost;
|
||||
stats.fraction_lost = Q8ToFloat(call_stats.fractionLost);
|
||||
stats.capture_start_ntp_time_ms = call_stats.capture_start_ntp_time_ms_;
|
||||
stats.last_packet_received_timestamp_ms =
|
||||
call_stats.last_packet_received_timestamp_ms;
|
||||
stats.codec_name = receive_codec->second.name;
|
||||
stats.codec_payload_type = receive_codec->first;
|
||||
stats.ext_seqnum = call_stats.extendedMax;
|
||||
|
@ -757,17 +757,23 @@ CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const {
|
||||
stats.rttMs = GetRTT();
|
||||
|
||||
// --- Data counters
|
||||
|
||||
size_t bytesReceived(0);
|
||||
uint32_t packetsReceived(0);
|
||||
|
||||
if (statistician) {
|
||||
statistician->GetDataCounters(&bytesReceived, &packetsReceived);
|
||||
StreamDataCounters data_counters;
|
||||
statistician->GetReceiveStreamDataCounters(&data_counters);
|
||||
// TODO(http://crbug.com/webrtc/10525): Bytes received should only include
|
||||
// payload bytes, not header and padding bytes.
|
||||
stats.bytesReceived = data_counters.transmitted.payload_bytes +
|
||||
data_counters.transmitted.header_bytes +
|
||||
data_counters.transmitted.padding_bytes;
|
||||
stats.packetsReceived = data_counters.transmitted.packets;
|
||||
stats.last_packet_received_timestamp_ms =
|
||||
data_counters.last_packet_received_timestamp_ms;
|
||||
} else {
|
||||
stats.bytesReceived = 0;
|
||||
stats.packetsReceived = 0;
|
||||
stats.last_packet_received_timestamp_ms = absl::nullopt;
|
||||
}
|
||||
|
||||
stats.bytesReceived = bytesReceived;
|
||||
stats.packetsReceived = packetsReceived;
|
||||
|
||||
// --- Timestamps
|
||||
{
|
||||
rtc::CritScope lock(&ts_stats_lock_);
|
||||
|
@ -59,6 +59,10 @@ struct CallReceiveStatistics {
|
||||
// The capture ntp time (in local timebase) of the first played out audio
|
||||
// frame.
|
||||
int64_t capture_start_ntp_time_ms_;
|
||||
// The timestamp at which the last packet was received, i.e. the time of the
|
||||
// local clock when it was received - not the RTP timestamp of that packet.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
|
||||
absl::optional<int64_t> last_packet_received_timestamp_ms;
|
||||
};
|
||||
|
||||
namespace voe {
|
||||
|
@ -73,6 +73,10 @@ class AudioReceiveStream {
|
||||
int32_t decoding_plc_cng = 0;
|
||||
int32_t decoding_muted_output = 0;
|
||||
int64_t capture_start_ntp_time_ms = 0;
|
||||
// The timestamp at which the last packet was received, i.e. the time of the
|
||||
// local clock when it was received - not the RTP timestamp of that packet.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
|
||||
absl::optional<int64_t> last_packet_received_timestamp_ms;
|
||||
uint64_t jitter_buffer_flushes = 0;
|
||||
double relative_packet_arrival_delay_seconds = 0.0;
|
||||
};
|
||||
|
@ -435,6 +435,10 @@ struct MediaReceiverInfo {
|
||||
int packets_rcvd = 0;
|
||||
int packets_lost = 0;
|
||||
float fraction_lost = 0.0f;
|
||||
// The timestamp at which the last packet was received, i.e. the time of the
|
||||
// local clock when it was received - not the RTP timestamp of that packet.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
|
||||
absl::optional<int64_t> last_packet_received_timestamp_ms;
|
||||
std::string codec_name;
|
||||
absl::optional<int> codec_payload_type;
|
||||
std::vector<SsrcReceiverInfo> local_stats;
|
||||
|
@ -2697,6 +2697,8 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
|
||||
info.frames_decoded = stats.frames_decoded;
|
||||
info.frames_rendered = stats.frames_rendered;
|
||||
info.qp_sum = stats.qp_sum;
|
||||
info.last_packet_received_timestamp_ms =
|
||||
stats.rtp_stats.last_packet_received_timestamp_ms;
|
||||
info.first_frame_received_to_decoded_ms =
|
||||
stats.first_frame_received_to_decoded_ms;
|
||||
info.interframe_delay_max_ms = stats.interframe_delay_max_ms;
|
||||
|
@ -2267,6 +2267,8 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
|
||||
rinfo.decoding_plc_cng = stats.decoding_plc_cng;
|
||||
rinfo.decoding_muted_output = stats.decoding_muted_output;
|
||||
rinfo.capture_start_ntp_time_ms = stats.capture_start_ntp_time_ms;
|
||||
rinfo.last_packet_received_timestamp_ms =
|
||||
stats.last_packet_received_timestamp_ms;
|
||||
rinfo.jitter_buffer_flushes = stats.jitter_buffer_flushes;
|
||||
rinfo.relative_packet_arrival_delay_seconds =
|
||||
stats.relative_packet_arrival_delay_seconds;
|
||||
|
@ -244,6 +244,12 @@ void SetInboundRTPStreamStatsFromVoiceReceiverInfo(
|
||||
rtc::kNumMillisecsPerSec;
|
||||
// |fir_count|, |pli_count| and |sli_count| are only valid for video and are
|
||||
// purposefully left undefined for audio.
|
||||
if (voice_receiver_info.last_packet_received_timestamp_ms) {
|
||||
inbound_audio->last_packet_received_timestamp =
|
||||
static_cast<double>(
|
||||
*voice_receiver_info.last_packet_received_timestamp_ms) /
|
||||
rtc::kNumMillisecsPerSec;
|
||||
}
|
||||
}
|
||||
|
||||
void SetInboundRTPStreamStatsFromVideoReceiverInfo(
|
||||
@ -267,6 +273,12 @@ void SetInboundRTPStreamStatsFromVideoReceiverInfo(
|
||||
inbound_video->frames_decoded = video_receiver_info.frames_decoded;
|
||||
if (video_receiver_info.qp_sum)
|
||||
inbound_video->qp_sum = *video_receiver_info.qp_sum;
|
||||
if (video_receiver_info.last_packet_received_timestamp_ms) {
|
||||
inbound_video->last_packet_received_timestamp =
|
||||
static_cast<double>(
|
||||
*video_receiver_info.last_packet_received_timestamp_ms) /
|
||||
rtc::kNumMillisecsPerSec;
|
||||
}
|
||||
// TODO(https://crbug.com/webrtc/10529): When info's |content_info| is
|
||||
// optional, support the "unspecified" value.
|
||||
if (video_receiver_info.content_type == VideoContentType::SCREENSHARE)
|
||||
|
@ -1625,6 +1625,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
|
||||
voice_media_info.receivers[0].codec_payload_type = 42;
|
||||
voice_media_info.receivers[0].jitter_ms = 4500;
|
||||
voice_media_info.receivers[0].fraction_lost = 5.5f;
|
||||
voice_media_info.receivers[0].last_packet_received_timestamp_ms =
|
||||
absl::nullopt;
|
||||
|
||||
RtpCodecParameters codec_parameters;
|
||||
codec_parameters.payload_type = 42;
|
||||
@ -1656,8 +1658,21 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
|
||||
expected_audio.packets_received = 2;
|
||||
expected_audio.bytes_received = 3;
|
||||
expected_audio.packets_lost = -1;
|
||||
// |expected_audio.last_packet_received_timestamp| should be undefined.
|
||||
expected_audio.jitter = 4.5;
|
||||
expected_audio.fraction_lost = 5.5;
|
||||
ASSERT_TRUE(report->Get(expected_audio.id()));
|
||||
EXPECT_EQ(
|
||||
report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
|
||||
expected_audio);
|
||||
|
||||
// Set previously undefined values and "GetStats" again.
|
||||
voice_media_info.receivers[0].last_packet_received_timestamp_ms = 3000;
|
||||
expected_audio.last_packet_received_timestamp = 3.0;
|
||||
voice_media_channel->SetStats(voice_media_info);
|
||||
|
||||
report = stats_->GetFreshStatsReport();
|
||||
|
||||
ASSERT_TRUE(report->Get(expected_audio.id()));
|
||||
EXPECT_EQ(
|
||||
report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
|
||||
@ -1684,6 +1699,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
||||
video_media_info.receivers[0].nacks_sent = 7;
|
||||
video_media_info.receivers[0].frames_decoded = 8;
|
||||
video_media_info.receivers[0].qp_sum = absl::nullopt;
|
||||
video_media_info.receivers[0].last_packet_received_timestamp_ms =
|
||||
absl::nullopt;
|
||||
video_media_info.receivers[0].content_type = VideoContentType::UNSPECIFIED;
|
||||
|
||||
RtpCodecParameters codec_parameters;
|
||||
@ -1719,6 +1736,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
||||
expected_video.fraction_lost = 4.5;
|
||||
expected_video.frames_decoded = 8;
|
||||
// |expected_video.qp_sum| should be undefined.
|
||||
// |expected_video.last_packet_received_timestamp| should be undefined.
|
||||
// |expected_video.content_type| should be undefined.
|
||||
|
||||
ASSERT_TRUE(report->Get(expected_video.id()));
|
||||
@ -1728,7 +1746,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
||||
|
||||
// Set previously undefined values and "GetStats" again.
|
||||
video_media_info.receivers[0].qp_sum = 9;
|
||||
video_media_info.receivers[0].last_packet_received_timestamp_ms = 1000;
|
||||
expected_video.qp_sum = 9;
|
||||
expected_video.last_packet_received_timestamp = 1.0;
|
||||
video_media_info.receivers[0].content_type = VideoContentType::SCREENSHARE;
|
||||
expected_video.content_type = "screenshare";
|
||||
video_media_channel->SetStats(video_media_info);
|
||||
|
@ -719,6 +719,7 @@ class RTCStatsReportVerifier {
|
||||
// packets_lost is defined as signed, but this should never happen in
|
||||
// this test. See RFC 3550.
|
||||
verifier.TestMemberIsNonNegative<int32_t>(inbound_stream.packets_lost);
|
||||
verifier.TestMemberIsDefined(inbound_stream.last_packet_received_timestamp);
|
||||
if (inbound_stream.media_type.is_defined() &&
|
||||
*inbound_stream.media_type == "video") {
|
||||
verifier.TestMemberIsUndefined(inbound_stream.jitter);
|
||||
|
@ -578,6 +578,7 @@ WEBRTC_RTCSTATS_IMPL(
|
||||
&packets_received,
|
||||
&bytes_received,
|
||||
&packets_lost,
|
||||
&last_packet_received_timestamp,
|
||||
&jitter,
|
||||
&fraction_lost,
|
||||
&round_trip_time,
|
||||
@ -605,6 +606,7 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string&& id,
|
||||
packets_received("packetsReceived"),
|
||||
bytes_received("bytesReceived"),
|
||||
packets_lost("packetsLost"),
|
||||
last_packet_received_timestamp("lastPacketReceivedTimestamp"),
|
||||
jitter("jitter"),
|
||||
fraction_lost("fractionLost"),
|
||||
round_trip_time("roundTripTime"),
|
||||
@ -627,6 +629,7 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
|
||||
packets_received(other.packets_received),
|
||||
bytes_received(other.bytes_received),
|
||||
packets_lost(other.packets_lost),
|
||||
last_packet_received_timestamp(other.last_packet_received_timestamp),
|
||||
jitter(other.jitter),
|
||||
fraction_lost(other.fraction_lost),
|
||||
round_trip_time(other.round_trip_time),
|
||||
|
Reference in New Issue
Block a user