Expose jitter in time in addition to in samples.

RFC 3550 specifies samples to be the unit while https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict* specifies time. This avoids the need to convert to time in code that reads the jitter value from RtpReceiveStats.

Bug: webrtc:13757
Change-Id: I972996971c58b686babd621ff4e0f5790fdf2cb1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/279281
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Tomas Lundqvist <tomasl@google.com>
Cr-Commit-Position: refs/heads/main@{#38419}
This commit is contained in:
Tomas Lundqvist
2022-10-17 14:44:52 +00:00
committed by WebRTC LUCI CQ
parent f0e65bab0e
commit b50599b7b5
4 changed files with 47 additions and 3 deletions

View File

@ -25,6 +25,7 @@
#include "api/audio_codecs/audio_format.h"
#include "api/rtp_headers.h"
#include "api/transport/network_types.h"
#include "api/units/time_delta.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h"
#include "system_wrappers/include/clock.h"
@ -442,7 +443,10 @@ struct RtpReceiveStats {
// RTCReceivedRtpStreamStats dictionary, see
// https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict*
int32_t packets_lost = 0;
// Interarrival jitter in samples.
uint32_t jitter = 0;
// Interarrival jitter in time.
webrtc::TimeDelta interarrival_jitter = webrtc::TimeDelta::Zero();
// Timestamp and counters exposed in RTCInboundRtpStreamStats, see
// https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*

View File

@ -16,6 +16,7 @@
#include <utility>
#include <vector>
#include "api/units/time_delta.h"
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
@ -33,8 +34,7 @@ constexpr int64_t kStatisticsProcessIntervalMs = 1000;
StreamStatistician::~StreamStatistician() {}
StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc,
Clock* clock,
StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc, Clock* clock,
int max_reordering_threshold)
: ssrc_(ssrc),
clock_(clock),
@ -54,7 +54,8 @@ StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc,
received_seq_first_(-1),
received_seq_max_(-1),
last_report_cumulative_loss_(0),
last_report_seq_max_(-1) {}
last_report_seq_max_(-1),
last_payload_type_frequency_(0) {}
StreamStatisticianImpl::~StreamStatisticianImpl() = default;
@ -141,6 +142,7 @@ void StreamStatisticianImpl::UpdateCounters(const RtpPacketReceived& packet) {
}
last_received_timestamp_ = packet.Timestamp();
last_receive_time_ms_ = now_ms;
last_payload_type_frequency_ = packet.payload_type_frequency();
}
void StreamStatisticianImpl::UpdateJitter(const RtpPacketReceived& packet,
@ -178,6 +180,12 @@ RtpReceiveStats StreamStatisticianImpl::GetStats() const {
stats.packets_lost = cumulative_loss_;
// Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
stats.jitter = jitter_q4_ >> 4;
if (last_payload_type_frequency_ > 0) {
// Divide value in fractional seconds by frequency to get jitter in
// fractional seconds.
stats.interarrival_jitter =
webrtc::TimeDelta::Seconds(stats.jitter) / last_payload_type_frequency_;
}
if (receive_counters_.last_packet_received_timestamp_ms.has_value()) {
stats.last_packet_received_timestamp_ms =
*receive_counters_.last_packet_received_timestamp_ms +

View File

@ -108,6 +108,9 @@ class StreamStatisticianImpl : public StreamStatisticianImplInterface {
// Counter values when we sent the last report.
int32_t last_report_cumulative_loss_;
int64_t last_report_seq_max_;
// The sample frequency of the last received packet.
int last_payload_type_frequency_;
};
// Thread-safe implementation of StreamStatisticianImplInterface.

View File

@ -10,9 +10,11 @@
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include <cstdint>
#include <memory>
#include <vector>
#include "api/units/time_delta.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/random.h"
#include "system_wrappers/include/clock.h"
@ -578,5 +580,32 @@ TEST_P(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
EXPECT_EQ(45, counters.last_packet_received_timestamp_ms);
}
TEST_P(ReceiveStatisticsTest, SimpleJitterComputation) {
const int kMsPerPacket = 20;
const int kCodecSampleRate = 48'000;
const int kSamplesPerPacket = kMsPerPacket * kCodecSampleRate / 1'000;
const int kLateArrivalDeltaMs = 100;
const int kLateArrivalDeltaSamples =
kLateArrivalDeltaMs * kCodecSampleRate / 1'000;
packet1_.set_payload_type_frequency(kCodecSampleRate);
packet1_.SetSequenceNumber(1);
packet1_.SetTimestamp(0);
receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(2);
packet1_.SetTimestamp(kSamplesPerPacket);
// Arrives 100 ms late.
clock_.AdvanceTimeMilliseconds(kMsPerPacket + kLateArrivalDeltaMs);
receive_statistics_->OnRtpPacket(packet1_);
StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1);
// See jitter caluculation in https://www.rfc-editor.org/rfc/rfc3550 6.4.1.
const uint32_t expected_jitter = (kLateArrivalDeltaSamples) / 16;
EXPECT_EQ(expected_jitter, statistician->GetStats().jitter);
EXPECT_EQ(webrtc::TimeDelta::Seconds(expected_jitter) / kCodecSampleRate,
statistician->GetStats().interarrival_jitter);
}
} // namespace
} // namespace webrtc