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 <minyue@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30744}
This commit is contained in:
Minyue Li
2020-03-10 15:56:42 +01:00
committed by Commit Bot
parent 1230c8568e
commit dd14a95596
3 changed files with 41 additions and 8 deletions

View File

@ -23,15 +23,22 @@ TimestampAligner::TimestampAligner()
: frames_seen_(0), : frames_seen_(0),
offset_us_(0), offset_us_(0),
clip_bias_us_(0), clip_bias_us_(0),
prev_translated_time_us_(std::numeric_limits<int64_t>::min()) {} prev_translated_time_us_(std::numeric_limits<int64_t>::min()),
prev_time_offset_us_(0) {}
TimestampAligner::~TimestampAligner() {} TimestampAligner::~TimestampAligner() {}
int64_t TimestampAligner::TranslateTimestamp(int64_t capturer_time_us, int64_t TimestampAligner::TranslateTimestamp(int64_t capturer_time_us,
int64_t system_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), capturer_time_us + UpdateOffset(capturer_time_us, system_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, int64_t TimestampAligner::UpdateOffset(int64_t capturer_time_us,

View File

@ -45,6 +45,11 @@ class RTC_EXPORT TimestampAligner {
// translated timestamp. // translated timestamp.
int64_t TranslateTimestamp(int64_t capturer_time_us, int64_t system_time_us); 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: protected:
// Update the estimated offset between capturer's time and system monotonic // Update the estimated offset between capturer's time and system monotonic
// time. // time.
@ -69,6 +74,9 @@ class RTC_EXPORT TimestampAligner {
int64_t clip_bias_us_; int64_t clip_bias_us_;
// Used to ensure that translated timestamps are monotonous. // Used to ensure that translated timestamps are monotonous.
int64_t prev_translated_time_us_; 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); RTC_DISALLOW_COPY_AND_ASSIGN(TimestampAligner);
}; };

View File

@ -152,27 +152,27 @@ TEST(TimestampAlignerTest, ClipToMonotonous) {
// {0, c1, c1 + c2}, we exhibit non-monotonous behaviour if and only // {0, c1, c1 + c2}, we exhibit non-monotonous behaviour if and only
// if c1 > s1 + 2 s2 + 4 c2. // if c1 > s1 + 2 s2 + 4 c2.
const int kNumSamples = 3; const int kNumSamples = 3;
const int64_t camera_time_us[kNumSamples] = {0, 80000, 90001}; const int64_t kCaptureTimeUs[kNumSamples] = {0, 80000, 90001};
const int64_t system_time_us[kNumSamples] = {0, 10000, 20000}; const int64_t kSystemTimeUs[kNumSamples] = {0, 10000, 20000};
const int64_t expected_offset_us[kNumSamples] = {0, -35000, -46667}; const int64_t expected_offset_us[kNumSamples] = {0, -35000, -46667};
// Non-monotonic translated timestamps can happen when only for // Non-monotonic translated timestamps can happen when only for
// translated timestamps in the future. Which is tolerated if // translated timestamps in the future. Which is tolerated if
// |timestamp_aligner.clip_bias_us| is large enough. Instead of // |timestamp_aligner.clip_bias_us| is large enough. Instead of
// changing that private member for this test, just add the bias to // 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; const int64_t kClipBiasUs = 100000;
bool did_clip = false; bool did_clip = false;
int64_t prev_timestamp_us = std::numeric_limits<int64_t>::min(); int64_t prev_timestamp_us = std::numeric_limits<int64_t>::min();
for (int i = 0; i < kNumSamples; i++) { for (int i = 0; i < kNumSamples; i++) {
int64_t offset_us = 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]); 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( 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) { if (translated_timestamp_us <= prev_timestamp_us) {
did_clip = true; did_clip = true;
EXPECT_EQ(clip_timestamp_us, EXPECT_EQ(clip_timestamp_us,
@ -186,4 +186,22 @@ TEST(TimestampAlignerTest, ClipToMonotonous) {
EXPECT_TRUE(did_clip); 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 } // namespace rtc