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}
diff --git a/system_wrappers/include/clock.h b/system_wrappers/include/clock.h
index 914fbda..62d2216 100644
--- a/system_wrappers/include/clock.h
+++ b/system_wrappers/include/clock.h
@@ -39,9 +39,23 @@
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 @@
// 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.
diff --git a/system_wrappers/source/clock.cc b/system_wrappers/source/clock.cc
index 2c3981a..77c1d36 100644
--- a/system_wrappers/source/clock.cc
+++ b/system_wrappers/source/clock.cc
@@ -93,6 +93,12 @@
: 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 @@
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);
}
diff --git a/test/drifting_clock.cc b/test/drifting_clock.cc
index 29b28dd..47c8e56 100644
--- a/test/drifting_clock.cc
+++ b/test/drifting_clock.cc
@@ -28,16 +28,15 @@
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);
}
diff --git a/test/drifting_clock.h b/test/drifting_clock.h
index 820b2f0..3471c00 100644
--- a/test/drifting_clock.h
+++ b/test/drifting_clock.h
@@ -30,11 +30,16 @@
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_;