From 1b3530b4df1dc5ef3a6c16b41d86dd910d24c573 Mon Sep 17 00:00:00 2001 From: sprang Date: Thu, 10 Mar 2016 01:32:53 -0800 Subject: [PATCH] Make rtc::TimestampWrapAroundHandler handle backwards wrapping Also fix a timestamp issue in video analyzer test. BUG=webrtc:5637, webrtc:5537 Review URL: https://codereview.webrtc.org/1779773002 Cr-Commit-Position: refs/heads/master@{#11938} --- webrtc/base/timeutils.cc | 22 +++++++++---- webrtc/base/timeutils_unittest.cc | 52 +++++++++++++++++++++++------- webrtc/video/video_quality_test.cc | 6 ++-- 3 files changed, 59 insertions(+), 21 deletions(-) diff --git a/webrtc/base/timeutils.cc b/webrtc/base/timeutils.cc index 24b04ee2ee..b7803aea10 100644 --- a/webrtc/base/timeutils.cc +++ b/webrtc/base/timeutils.cc @@ -193,17 +193,25 @@ int32_t TimeDiff(uint32_t later, uint32_t earlier) { } TimestampWrapAroundHandler::TimestampWrapAroundHandler() - : last_ts_(0), num_wrap_(0) {} + : last_ts_(0), num_wrap_(-1) {} int64_t TimestampWrapAroundHandler::Unwrap(uint32_t ts) { - if (ts < last_ts_) { - if (last_ts_ > 0xf0000000 && ts < 0x0fffffff) { - ++num_wrap_; - } + if (num_wrap_ == -1) { + last_ts_ = ts; + num_wrap_ = 0; + return ts; } + + if (ts < last_ts_) { + if (last_ts_ >= 0xf0000000 && ts < 0x0fffffff) + ++num_wrap_; + } else if ((ts - last_ts_) > 0xf0000000) { + // Backwards wrap. Unwrap with last wrap count and don't update last_ts_. + return ts + ((num_wrap_ - 1) << 32); + } + last_ts_ = ts; - int64_t unwrapped_ts = ts + (num_wrap_ << 32); - return unwrapped_ts; + return ts + (num_wrap_ << 32); } int64_t TmToSeconds(const std::tm& tm) { diff --git a/webrtc/base/timeutils_unittest.cc b/webrtc/base/timeutils_unittest.cc index 688658b32f..7e342d00fa 100644 --- a/webrtc/base/timeutils_unittest.cc +++ b/webrtc/base/timeutils_unittest.cc @@ -153,18 +153,48 @@ class TimestampWrapAroundHandlerTest : public testing::Test { }; TEST_F(TimestampWrapAroundHandlerTest, Unwrap) { - uint32_t ts = 0xfffffff2; - int64_t unwrapped_ts = ts; - EXPECT_EQ(ts, wraparound_handler_.Unwrap(ts)); + // Start value. + int64_t ts = 2; + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); + + // Wrap backwards. + ts = -2; + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); + + // Forward to 2 again. ts = 2; - unwrapped_ts += 0x10; - EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts)); - ts = 0xfffffff2; - unwrapped_ts += 0xfffffff0; - EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts)); - ts = 0; - unwrapped_ts += 0xe; - EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts)); + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); + + // Max positive skip ahead, until max value (0xffffffff). + for (uint32_t i = 0; i <= 0xf; ++i) { + ts = (i << 28) + 0x0fffffff; + EXPECT_EQ( + ts, wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); + } + + // Wrap around. + ts += 2; + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); + + // Max wrap backward... + ts -= 0x0fffffff; + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); + + // ...and back again. + ts += 0x0fffffff; + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); +} + +TEST_F(TimestampWrapAroundHandlerTest, NoNegativeStart) { + int64_t ts = 0xfffffff0; + EXPECT_EQ(ts, + wraparound_handler_.Unwrap(static_cast(ts & 0xffffffff))); } class TmToSeconds : public testing::Test { diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc index e43ddb16ce..c8829925e4 100644 --- a/webrtc/video/video_quality_test.cc +++ b/webrtc/video/video_quality_test.cc @@ -161,13 +161,13 @@ class VideoAnalyzer : public PacketReceiver, bool result = transport_->SendRtp(packet, length, options); { rtc::CritScope lock(&crit_); - int64_t timestamp = wrap_handler_.Unwrap(header.timestamp); if (rtp_timestamp_delta_ == 0) { - rtp_timestamp_delta_ = timestamp - first_send_frame_.timestamp(); + rtp_timestamp_delta_ = header.timestamp - first_send_frame_.timestamp(); first_send_frame_.Reset(); } - timestamp -= rtp_timestamp_delta_; + int64_t timestamp = + wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); send_times_[timestamp] = current_time; if (!transport_->DiscardedLastPacket() && header.ssrc == ssrc_to_analyze_) {