Add histograms for Abs-Capture-Timestamp
Bug: webrtc:380712819 Change-Id: I5f56caffe33a257432551321f7c097c852b134dd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/368903 Reviewed-by: Johannes Kron <kron@webrtc.org> Commit-Queue: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43458}
This commit is contained in:
parent
05cf9c7235
commit
e9193d7031
@ -731,6 +731,7 @@ if (rtc_include_tests) {
|
|||||||
"../../rtc_base:timeutils",
|
"../../rtc_base:timeutils",
|
||||||
"../../rtc_base/network:ecn_marking",
|
"../../rtc_base/network:ecn_marking",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
|
"../../system_wrappers:metrics",
|
||||||
"../../test:explicit_key_value_config",
|
"../../test:explicit_key_value_config",
|
||||||
"../../test:mock_transport",
|
"../../test:mock_transport",
|
||||||
"../../test:rtp_test_utils",
|
"../../test:rtp_test_utils",
|
||||||
|
|||||||
@ -10,9 +10,18 @@
|
|||||||
|
|
||||||
#include "modules/rtp_rtcp/source/absolute_capture_time_interpolator.h"
|
#include "modules/rtp_rtcp/source/absolute_capture_time_interpolator.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "api/array_view.h"
|
||||||
|
#include "api/rtp_headers.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
|
#include "api/units/timestamp.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
#include "rtc_base/synchronization/mutex.h"
|
||||||
|
#include "system_wrappers/include/clock.h"
|
||||||
|
#include "system_wrappers/include/metrics.h"
|
||||||
|
#include "system_wrappers/include/ntp_time.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -36,6 +45,9 @@ AbsoluteCaptureTimeInterpolator::OnReceivePacket(
|
|||||||
int rtp_clock_frequency_hz,
|
int rtp_clock_frequency_hz,
|
||||||
const std::optional<AbsoluteCaptureTime>& received_extension) {
|
const std::optional<AbsoluteCaptureTime>& received_extension) {
|
||||||
const Timestamp receive_time = clock_->CurrentTime();
|
const Timestamp receive_time = clock_->CurrentTime();
|
||||||
|
if (!first_packet_time_) {
|
||||||
|
first_packet_time_ = receive_time;
|
||||||
|
}
|
||||||
|
|
||||||
MutexLock lock(&mutex_);
|
MutexLock lock(&mutex_);
|
||||||
|
|
||||||
@ -60,7 +72,40 @@ AbsoluteCaptureTimeInterpolator::OnReceivePacket(
|
|||||||
last_received_extension_ = *received_extension;
|
last_received_extension_ = *received_extension;
|
||||||
|
|
||||||
last_receive_time_ = receive_time;
|
last_receive_time_ = receive_time;
|
||||||
|
// Record statistics on the abs-capture-time extension
|
||||||
|
if (!first_extension_time_) {
|
||||||
|
RTC_HISTOGRAM_COUNTS_1M("WebRTC.Call.AbsCapture.ExtensionWait",
|
||||||
|
(receive_time - *first_packet_time_).ms());
|
||||||
|
first_extension_time_ = receive_time;
|
||||||
|
}
|
||||||
|
Timestamp capture_as_timestamp = Timestamp::Micros(
|
||||||
|
UQ32x32ToInt64Us(received_extension->absolute_capture_timestamp));
|
||||||
|
TimeDelta capture_delta = receive_time - capture_as_timestamp;
|
||||||
|
RTC_HISTOGRAM_COUNTS_1G("WebRTC.Call.AbsCapture.Delta",
|
||||||
|
abs(capture_delta.us()));
|
||||||
|
if (previous_capture_delta_) {
|
||||||
|
RTC_HISTOGRAM_COUNTS_1G(
|
||||||
|
"WebRTC.Call.AbsCapture.DeltaDeviation",
|
||||||
|
abs((capture_delta - *previous_capture_delta_).us()));
|
||||||
|
}
|
||||||
|
previous_capture_delta_ = capture_delta;
|
||||||
|
if (received_extension->estimated_capture_clock_offset) {
|
||||||
|
if (!first_offset_time_) {
|
||||||
|
RTC_HISTOGRAM_COUNTS_1M("WebRTC.Call.AbsCapture.OffsetWait",
|
||||||
|
(receive_time - *first_packet_time_).ms());
|
||||||
|
first_offset_time_ = receive_time;
|
||||||
|
}
|
||||||
|
TimeDelta offset_as_delta = TimeDelta::Micros(UQ32x32ToInt64Us(
|
||||||
|
*received_extension->estimated_capture_clock_offset));
|
||||||
|
RTC_HISTOGRAM_COUNTS_1G("WebRTC.Call.AbsCapture.Offset",
|
||||||
|
abs(offset_as_delta.us()));
|
||||||
|
if (previous_offset_as_delta_) {
|
||||||
|
RTC_HISTOGRAM_COUNTS_1G(
|
||||||
|
"WebRTC.Call.AbsCapture.OffsetDeviation",
|
||||||
|
abs((offset_as_delta - *previous_offset_as_delta_).us()));
|
||||||
|
}
|
||||||
|
previous_offset_as_delta_ = offset_as_delta;
|
||||||
|
}
|
||||||
return received_extension;
|
return received_extension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,9 @@
|
|||||||
#ifndef MODULES_RTP_RTCP_SOURCE_ABSOLUTE_CAPTURE_TIME_INTERPOLATOR_H_
|
#ifndef MODULES_RTP_RTCP_SOURCE_ABSOLUTE_CAPTURE_TIME_INTERPOLATOR_H_
|
||||||
#define MODULES_RTP_RTCP_SOURCE_ABSOLUTE_CAPTURE_TIME_INTERPOLATOR_H_
|
#define MODULES_RTP_RTCP_SOURCE_ABSOLUTE_CAPTURE_TIME_INTERPOLATOR_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/rtp_headers.h"
|
#include "api/rtp_headers.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
@ -80,6 +83,12 @@ class AbsoluteCaptureTimeInterpolator {
|
|||||||
uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(mutex_);
|
uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(mutex_);
|
||||||
int last_rtp_clock_frequency_hz_ RTC_GUARDED_BY(mutex_);
|
int last_rtp_clock_frequency_hz_ RTC_GUARDED_BY(mutex_);
|
||||||
AbsoluteCaptureTime last_received_extension_ RTC_GUARDED_BY(mutex_);
|
AbsoluteCaptureTime last_received_extension_ RTC_GUARDED_BY(mutex_);
|
||||||
|
// Variables used for statistics generation
|
||||||
|
std::optional<Timestamp> first_packet_time_;
|
||||||
|
std::optional<Timestamp> first_offset_time_;
|
||||||
|
std::optional<Timestamp> first_extension_time_;
|
||||||
|
std::optional<TimeDelta> previous_capture_delta_;
|
||||||
|
std::optional<TimeDelta> previous_offset_as_delta_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -10,8 +10,14 @@
|
|||||||
|
|
||||||
#include "modules/rtp_rtcp/source/absolute_capture_time_interpolator.h"
|
#include "modules/rtp_rtcp/source/absolute_capture_time_interpolator.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "api/rtp_headers.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
|
#include "system_wrappers/include/clock.h"
|
||||||
|
#include "system_wrappers/include/metrics.h"
|
||||||
#include "system_wrappers/include/ntp_time.h"
|
#include "system_wrappers/include/ntp_time.h"
|
||||||
#include "test/gmock.h"
|
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -342,4 +348,36 @@ TEST(AbsoluteCaptureTimeInterpolatorTest, SkipInterpolateIsSticky) {
|
|||||||
std::nullopt);
|
std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(AbsoluteCaptureTimeInterpolatorTest, MetricsAreUpdated) {
|
||||||
|
constexpr uint32_t kRtpTimestamp0 = 102030000;
|
||||||
|
constexpr uint32_t kSource = 1234;
|
||||||
|
constexpr uint32_t kFrequency = 1000;
|
||||||
|
SimulatedClock clock(0);
|
||||||
|
AbsoluteCaptureTimeInterpolator interpolator(&clock);
|
||||||
|
|
||||||
|
metrics::Reset();
|
||||||
|
// First packet has no extension.
|
||||||
|
interpolator.OnReceivePacket(kSource, kRtpTimestamp0, kFrequency,
|
||||||
|
std::nullopt);
|
||||||
|
EXPECT_METRIC_EQ(metrics::NumSamples("WebRTC.Call.AbsCapture.ExtensionWait"),
|
||||||
|
0);
|
||||||
|
|
||||||
|
// Second packet has extension, but no offset.
|
||||||
|
clock.AdvanceTimeMilliseconds(10);
|
||||||
|
interpolator.OnReceivePacket(
|
||||||
|
kSource, kRtpTimestamp0 + 10, kFrequency,
|
||||||
|
AbsoluteCaptureTime{Int64MsToUQ32x32(5000), std::nullopt});
|
||||||
|
EXPECT_METRIC_EQ(metrics::NumSamples("WebRTC.Call.AbsCapture.ExtensionWait"),
|
||||||
|
1);
|
||||||
|
|
||||||
|
// Third packet has extension with offset, value zero.
|
||||||
|
clock.AdvanceTimeMilliseconds(10);
|
||||||
|
interpolator.OnReceivePacket(
|
||||||
|
kSource, kRtpTimestamp0 + 20, kFrequency,
|
||||||
|
AbsoluteCaptureTime{Int64MsToUQ32x32(20), Int64MsToUQ32x32(0)});
|
||||||
|
EXPECT_METRIC_EQ(metrics::NumSamples("WebRTC.Call.AbsCapture.Delta"), 2);
|
||||||
|
EXPECT_METRIC_EQ(metrics::NumSamples("WebRTC.Call.AbsCapture.DeltaDeviation"),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -125,6 +125,12 @@ void NoOp(const Ts&...) {}
|
|||||||
#define RTC_HISTOGRAM_COUNTS_100000(name, sample) \
|
#define RTC_HISTOGRAM_COUNTS_100000(name, sample) \
|
||||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50)
|
RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50)
|
||||||
|
|
||||||
|
#define RTC_HISTOGRAM_COUNTS_1M(name, sample) \
|
||||||
|
RTC_HISTOGRAM_COUNTS(name, sample, 1, 1'000'000, 50)
|
||||||
|
|
||||||
|
#define RTC_HISTOGRAM_COUNTS_1G(name, sample) \
|
||||||
|
RTC_HISTOGRAM_COUNTS(name, sample, 1, 1'000'000'000, 50)
|
||||||
|
|
||||||
#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
|
#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
|
||||||
RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
|
RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
|
||||||
webrtc::metrics::HistogramFactoryGetCounts( \
|
webrtc::metrics::HistogramFactoryGetCounts( \
|
||||||
@ -300,6 +306,12 @@ void NoOp(const Ts&...) {}
|
|||||||
#define RTC_HISTOGRAM_COUNTS_100000(name, sample) \
|
#define RTC_HISTOGRAM_COUNTS_100000(name, sample) \
|
||||||
webrtc::metrics_impl::NoOp(name, sample)
|
webrtc::metrics_impl::NoOp(name, sample)
|
||||||
|
|
||||||
|
#define RTC_HISTOGRAM_COUNTS_1M(name, sample) \
|
||||||
|
webrtc::metrics_impl::NoOp(name, sample)
|
||||||
|
|
||||||
|
#define RTC_HISTOGRAM_COUNTS_1G(name, sample) \
|
||||||
|
webrtc::metrics_impl::NoOp(name, sample)
|
||||||
|
|
||||||
#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
|
#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
|
||||||
webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count)
|
webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count)
|
||||||
|
|
||||||
|
|||||||
@ -120,5 +120,11 @@ inline int64_t UQ32x32ToInt64Ms(uint64_t q32x32) {
|
|||||||
std::round(q32x32 * (1000.0 / NtpTime::kFractionsPerSecond)));
|
std::round(q32x32 * (1000.0 / NtpTime::kFractionsPerSecond)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts UQ32.32-formatted fixed-point seconds to `int64_t` microseconds.
|
||||||
|
inline int64_t UQ32x32ToInt64Us(uint64_t q32x32) {
|
||||||
|
return rtc::dchecked_cast<int64_t>(
|
||||||
|
std::round(q32x32 * (1'000'000.0 / NtpTime::kFractionsPerSecond)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // SYSTEM_WRAPPERS_INCLUDE_NTP_TIME_H_
|
#endif // SYSTEM_WRAPPERS_INCLUDE_NTP_TIME_H_
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user