Add the ability to convert a timestamp to NTP time.

The timestamps returned by the clocks do not have an epoch. Each clock
should be able to convert a timestamp it returns to an NTP time.
The default implementation for querying for an NTP time is converting
the current timestamp.

This is favored over returning the offset between the relative and the
NTP time because there is a field trial that makes the real clock revert
to using system dependent methods for getting the NTP time.

Bug: webrtc:11327
Change-Id: Ia139b2744b407cae94420bf9112212ec577efb16
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219687
Reviewed-by: Minyue Li <minyue@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Paul Hallak <phallak@google.com>
Cr-Commit-Position: refs/heads/master@{#34071}
This commit is contained in:
Paul Hallak
2021-05-20 17:21:49 +02:00
committed by WebRTC LUCI CQ
parent 0cff39137b
commit b59e9045bf
4 changed files with 38 additions and 14 deletions

View File

@ -39,9 +39,23 @@ class RTC_EXPORT Clock {
int64_t TimeInMicroseconds() { return CurrentTime().us(); }
// Retrieve an NTP absolute timestamp (with an epoch of Jan 1, 1900).
virtual NtpTime CurrentNtpTime() = 0;
// TODO(bugs.webrtc.org/11327): Make this non-virtual once
// "WebRTC-SystemIndependentNtpTimeKillSwitch" is removed.
virtual NtpTime CurrentNtpTime() {
return ConvertTimestampToNtpTime(CurrentTime());
}
int64_t CurrentNtpInMilliseconds() { return CurrentNtpTime().ToMs(); }
// Converts between a relative timestamp returned by this clock, to NTP time.
// TODO(bugs.webrtc.org/11327): Make this method pure virtual,
// and delete default dummy implementation.
virtual NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) {
return NtpTime();
}
int64_t ConvertTimestampToNtpTimeInMilliseconds(int64_t timestamp_ms) {
return ConvertTimestampToNtpTime(Timestamp::Millis(timestamp_ms)).ToMs();
}
// Returns an instance of the real-time system clock implementation.
static Clock* GetRealTimeClock();
};
@ -56,7 +70,7 @@ class SimulatedClock : public Clock {
// Return a timestamp with an epoch of Jan 1, 1970.
Timestamp CurrentTime() override;
NtpTime CurrentNtpTime() override;
NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override;
// Advance the simulated clock with a given number of milliseconds or
// microseconds.

View File

@ -93,6 +93,12 @@ class RealTimeClock : public Clock {
: SystemDependentNtpTime();
}
NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override {
// This method does not check |use_system_independent_ntp_time_| because
// all callers never used the old behavior of |CurrentNtpTime|.
return TimeMicrosToNtp(timestamp.us());
}
protected:
virtual timeval CurrentTimeVal() = 0;
@ -276,11 +282,11 @@ Timestamp SimulatedClock::CurrentTime() {
return Timestamp::Micros(time_us_.load(std::memory_order_relaxed));
}
NtpTime SimulatedClock::CurrentNtpTime() {
int64_t now_ms = TimeInMilliseconds();
uint32_t seconds = (now_ms / 1000) + kNtpJan1970;
uint32_t fractions =
static_cast<uint32_t>((now_ms % 1000) * kMagicNtpFractionalUnit / 1000);
NtpTime SimulatedClock::ConvertTimestampToNtpTime(Timestamp timestamp) {
int64_t now_us = timestamp.us();
uint32_t seconds = (now_us / 1'000'000) + kNtpJan1970;
uint32_t fractions = static_cast<uint32_t>(
(now_us % 1'000'000) * kMagicNtpFractionalUnit / 1'000'000);
return NtpTime(seconds, fractions);
}

View File

@ -28,16 +28,15 @@ TimeDelta DriftingClock::Drift() const {
return (now - start_time_) * drift_;
}
Timestamp DriftingClock::CurrentTime() {
return clock_->CurrentTime() + Drift() / 1000.;
Timestamp DriftingClock::Drift(Timestamp timestamp) const {
return timestamp + Drift() / 1000.;
}
NtpTime DriftingClock::CurrentNtpTime() {
NtpTime DriftingClock::Drift(NtpTime ntp_time) const {
// NTP precision is 1/2^32 seconds, i.e. 2^32 ntp fractions = 1 second.
const double kNtpFracPerMicroSecond = 4294.967296; // = 2^32 / 10^6
NtpTime ntp = clock_->CurrentNtpTime();
uint64_t total_fractions = static_cast<uint64_t>(ntp);
uint64_t total_fractions = static_cast<uint64_t>(ntp_time);
total_fractions += Drift().us() * kNtpFracPerMicroSecond;
return NtpTime(total_fractions);
}

View File

@ -30,11 +30,16 @@ class DriftingClock : public Clock {
return 1.0f - percent / 100.0f;
}
Timestamp CurrentTime() override;
NtpTime CurrentNtpTime() override;
Timestamp CurrentTime() override { return Drift(clock_->CurrentTime()); }
NtpTime CurrentNtpTime() override { return Drift(clock_->CurrentNtpTime()); }
NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override {
return Drift(clock_->ConvertTimestampToNtpTime(timestamp));
}
private:
TimeDelta Drift() const;
Timestamp Drift(Timestamp timestamp) const;
NtpTime Drift(NtpTime ntp_time) const;
Clock* const clock_;
const float drift_;