From dd14a955967b69bf1611ce2985a5457934b1fb1d Mon Sep 17 00:00:00 2001 From: Minyue Li Date: Tue, 10 Mar 2020 15:56:42 +0100 Subject: [PATCH] Allow TimestampAligner to translate timestamp without new observation of system clock. Bug: chromium:1054403 Change-Id: I32c622851fc0bed2c47ae142c743399acb91ae84 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169924 Commit-Queue: Minyue Li Reviewed-by: Karl Wiberg Reviewed-by: Niels Moller Cr-Commit-Position: refs/heads/master@{#30744} --- rtc_base/timestamp_aligner.cc | 11 ++++++++-- rtc_base/timestamp_aligner.h | 8 +++++++ rtc_base/timestamp_aligner_unittest.cc | 30 ++++++++++++++++++++------ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/rtc_base/timestamp_aligner.cc b/rtc_base/timestamp_aligner.cc index 8bbcdb5a6d..c9f8f9de33 100644 --- a/rtc_base/timestamp_aligner.cc +++ b/rtc_base/timestamp_aligner.cc @@ -23,15 +23,22 @@ TimestampAligner::TimestampAligner() : frames_seen_(0), offset_us_(0), clip_bias_us_(0), - prev_translated_time_us_(std::numeric_limits::min()) {} + prev_translated_time_us_(std::numeric_limits::min()), + prev_time_offset_us_(0) {} TimestampAligner::~TimestampAligner() {} int64_t TimestampAligner::TranslateTimestamp(int64_t capturer_time_us, int64_t system_time_us) { - return ClipTimestamp( + const int64_t translated_timestamp = ClipTimestamp( capturer_time_us + UpdateOffset(capturer_time_us, system_time_us), system_time_us); + prev_time_offset_us_ = translated_timestamp - capturer_time_us; + return translated_timestamp; +} + +int64_t TimestampAligner::TranslateTimestamp(int64_t capturer_time_us) const { + return capturer_time_us + prev_time_offset_us_; } int64_t TimestampAligner::UpdateOffset(int64_t capturer_time_us, diff --git a/rtc_base/timestamp_aligner.h b/rtc_base/timestamp_aligner.h index 48023ab44d..da45aa6d1f 100644 --- a/rtc_base/timestamp_aligner.h +++ b/rtc_base/timestamp_aligner.h @@ -45,6 +45,11 @@ class RTC_EXPORT TimestampAligner { // translated timestamp. int64_t TranslateTimestamp(int64_t capturer_time_us, int64_t system_time_us); + // Returns the translated timestamp without updating the states. This is to + // allow TimestampAligner to translate capturer time into system clock based + // on earlier observations. It won't guarantee monotonicity. + int64_t TranslateTimestamp(int64_t capturer_time_us) const; + protected: // Update the estimated offset between capturer's time and system monotonic // time. @@ -69,6 +74,9 @@ class RTC_EXPORT TimestampAligner { int64_t clip_bias_us_; // Used to ensure that translated timestamps are monotonous. int64_t prev_translated_time_us_; + // Offset between |prev_translated_time_us_| and the corresponding capturer + // time. + int64_t prev_time_offset_us_; RTC_DISALLOW_COPY_AND_ASSIGN(TimestampAligner); }; diff --git a/rtc_base/timestamp_aligner_unittest.cc b/rtc_base/timestamp_aligner_unittest.cc index 17d9e06ce5..df6207a22c 100644 --- a/rtc_base/timestamp_aligner_unittest.cc +++ b/rtc_base/timestamp_aligner_unittest.cc @@ -152,27 +152,27 @@ TEST(TimestampAlignerTest, ClipToMonotonous) { // {0, c1, c1 + c2}, we exhibit non-monotonous behaviour if and only // if c1 > s1 + 2 s2 + 4 c2. const int kNumSamples = 3; - const int64_t camera_time_us[kNumSamples] = {0, 80000, 90001}; - const int64_t system_time_us[kNumSamples] = {0, 10000, 20000}; + const int64_t kCaptureTimeUs[kNumSamples] = {0, 80000, 90001}; + const int64_t kSystemTimeUs[kNumSamples] = {0, 10000, 20000}; const int64_t expected_offset_us[kNumSamples] = {0, -35000, -46667}; // Non-monotonic translated timestamps can happen when only for // translated timestamps in the future. Which is tolerated if // |timestamp_aligner.clip_bias_us| is large enough. Instead of // changing that private member for this test, just add the bias to - // |system_time_us| when calling ClipTimestamp. + // |kSystemTimeUs| when calling ClipTimestamp. const int64_t kClipBiasUs = 100000; bool did_clip = false; int64_t prev_timestamp_us = std::numeric_limits::min(); for (int i = 0; i < kNumSamples; i++) { int64_t offset_us = - timestamp_aligner.UpdateOffset(camera_time_us[i], system_time_us[i]); + timestamp_aligner.UpdateOffset(kCaptureTimeUs[i], kSystemTimeUs[i]); EXPECT_EQ(offset_us, expected_offset_us[i]); - int64_t translated_timestamp_us = camera_time_us[i] + offset_us; + int64_t translated_timestamp_us = kCaptureTimeUs[i] + offset_us; int64_t clip_timestamp_us = timestamp_aligner.ClipTimestamp( - translated_timestamp_us, system_time_us[i] + kClipBiasUs); + translated_timestamp_us, kSystemTimeUs[i] + kClipBiasUs); if (translated_timestamp_us <= prev_timestamp_us) { did_clip = true; EXPECT_EQ(clip_timestamp_us, @@ -186,4 +186,22 @@ TEST(TimestampAlignerTest, ClipToMonotonous) { EXPECT_TRUE(did_clip); } +TEST(TimestampAlignerTest, TranslateTimestampWithoutStateUpdate) { + TimestampAligner timestamp_aligner; + + constexpr int kNumSamples = 4; + constexpr int64_t kCaptureTimeUs[kNumSamples] = {0, 80000, 90001, 100000}; + constexpr int64_t kSystemTimeUs[kNumSamples] = {0, 10000, 20000, 30000}; + constexpr int64_t kQueryCaptureTimeOffsetUs[kNumSamples] = {0, 123, -321, + 345}; + + for (int i = 0; i < kNumSamples; i++) { + int64_t reference_timestamp = timestamp_aligner.TranslateTimestamp( + kCaptureTimeUs[i], kSystemTimeUs[i]); + EXPECT_EQ(reference_timestamp - kQueryCaptureTimeOffsetUs[i], + timestamp_aligner.TranslateTimestamp( + kCaptureTimeUs[i] - kQueryCaptureTimeOffsetUs[i])); + } +} + } // namespace rtc