Move timestamp_extrapolator and rtp_to_ntp to system wrapper so that it can be shared by both audio and video engine.

BUG=3111
TEST=try bots
R=mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/13459004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6074 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp
index 444c665..d7e7cf8 100644
--- a/webrtc/modules/modules.gyp
+++ b/webrtc/modules/modules.gyp
@@ -180,7 +180,6 @@
             'remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc',
             'remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h',
             'remote_bitrate_estimator/remote_bitrate_estimators_test.cc',
-            'remote_bitrate_estimator/rtp_to_ntp_unittest.cc',
             'remote_bitrate_estimator/test/bwe_test_baselinefile.cc',
             'remote_bitrate_estimator/test/bwe_test_baselinefile.h',
             'remote_bitrate_estimator/test/bwe_test_fileutils.cc',
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
index 810da46..7292cae 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
@@ -21,10 +21,8 @@
       'sources': [
         'include/bwe_defines.h',
         'include/remote_bitrate_estimator.h',
-        'include/rtp_to_ntp.h',
         'rate_statistics.cc',
         'rate_statistics.h',
-        'rtp_to_ntp.cc',
       ], # source
     },
     {
diff --git a/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp_unittest.cc b/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp_unittest.cc
deleted file mode 100644
index aff314a..0000000
--- a/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp_unittest.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h"
-
-namespace webrtc {
-
-TEST(WrapAroundTests, NoWrap) {
-  EXPECT_EQ(0, synchronization::CheckForWrapArounds(0xFFFFFFFF, 0xFFFFFFFE));
-  EXPECT_EQ(0, synchronization::CheckForWrapArounds(1, 0));
-  EXPECT_EQ(0, synchronization::CheckForWrapArounds(0x00010000, 0x0000FFFF));
-}
-
-TEST(WrapAroundTests, ForwardWrap) {
-  EXPECT_EQ(1, synchronization::CheckForWrapArounds(0, 0xFFFFFFFF));
-  EXPECT_EQ(1, synchronization::CheckForWrapArounds(0, 0xFFFF0000));
-  EXPECT_EQ(1, synchronization::CheckForWrapArounds(0x0000FFFF, 0xFFFFFFFF));
-  EXPECT_EQ(1, synchronization::CheckForWrapArounds(0x0000FFFF, 0xFFFF0000));
-}
-
-TEST(WrapAroundTests, BackwardWrap) {
-  EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFFFFFF, 0));
-  EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFF0000, 0));
-  EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFFFFFF, 0x0000FFFF));
-  EXPECT_EQ(-1, synchronization::CheckForWrapArounds(0xFFFF0000, 0x0000FFFF));
-}
-
-TEST(WrapAroundTests, OldRtcpWrapped) {
-  synchronization::RtcpList rtcp;
-  uint32_t ntp_sec = 0;
-  uint32_t ntp_frac = 0;
-  uint32_t timestamp = 0;
-  const uint32_t kOneMsInNtpFrac = 4294967;
-  const uint32_t kTimestampTicksPerMs = 90;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp -= kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp -= kTimestampTicksPerMs;
-  int64_t timestamp_in_ms = -1;
-  // This expected to fail since it's highly unlikely that the older RTCP
-  // has a much smaller RTP timestamp than the newer.
-  EXPECT_FALSE(synchronization::RtpToNtpMs(timestamp, rtcp, &timestamp_in_ms));
-}
-
-TEST(WrapAroundTests, NewRtcpWrapped) {
-  synchronization::RtcpList rtcp;
-  uint32_t ntp_sec = 0;
-  uint32_t ntp_frac = 0;
-  uint32_t timestamp = 0xFFFFFFFF;
-  const uint32_t kOneMsInNtpFrac = 4294967;
-  const uint32_t kTimestampTicksPerMs = 90;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                         timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp += kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                         timestamp));
-  int64_t timestamp_in_ms = -1;
-  EXPECT_TRUE(synchronization::RtpToNtpMs(rtcp.back().rtp_timestamp, rtcp,
-                                          &timestamp_in_ms));
-  // Since this RTP packet has the same timestamp as the RTCP packet constructed
-  // at time 0 it should be mapped to 0 as well.
-  EXPECT_EQ(0, timestamp_in_ms);
-}
-
-TEST(WrapAroundTests, RtpWrapped) {
-  const uint32_t kOneMsInNtpFrac = 4294967;
-  const uint32_t kTimestampTicksPerMs = 90;
-  synchronization::RtcpList rtcp;
-  uint32_t ntp_sec = 0;
-  uint32_t ntp_frac = 0;
-  uint32_t timestamp = 0xFFFFFFFF - 2 * kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp += kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp += kTimestampTicksPerMs;
-  int64_t timestamp_in_ms = -1;
-  EXPECT_TRUE(synchronization::RtpToNtpMs(timestamp, rtcp,
-                                          &timestamp_in_ms));
-  // Since this RTP packet has the same timestamp as the RTCP packet constructed
-  // at time 0 it should be mapped to 0 as well.
-  EXPECT_EQ(2, timestamp_in_ms);
-}
-
-TEST(WrapAroundTests, OldRtp_RtcpsWrapped) {
-  const uint32_t kOneMsInNtpFrac = 4294967;
-  const uint32_t kTimestampTicksPerMs = 90;
-  synchronization::RtcpList rtcp;
-  uint32_t ntp_sec = 0;
-  uint32_t ntp_frac = 0;
-  uint32_t timestamp = 0;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp += kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp -= 2*kTimestampTicksPerMs;
-  int64_t timestamp_in_ms = -1;
-  EXPECT_FALSE(synchronization::RtpToNtpMs(timestamp, rtcp,
-                                           &timestamp_in_ms));
-}
-
-TEST(WrapAroundTests, OldRtp_NewRtcpWrapped) {
-  const uint32_t kOneMsInNtpFrac = 4294967;
-  const uint32_t kTimestampTicksPerMs = 90;
-  synchronization::RtcpList rtcp;
-  uint32_t ntp_sec = 0;
-  uint32_t ntp_frac = 0;
-  uint32_t timestamp = 0xFFFFFFFF;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp += kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp -= kTimestampTicksPerMs;
-  int64_t timestamp_in_ms = -1;
-  EXPECT_TRUE(synchronization::RtpToNtpMs(timestamp, rtcp,
-                                          &timestamp_in_ms));
-  // Constructed at the same time as the first RTCP and should therefore be
-  // mapped to zero.
-  EXPECT_EQ(0, timestamp_in_ms);
-}
-
-TEST(WrapAroundTests, OldRtp_OldRtcpWrapped) {
-  const uint32_t kOneMsInNtpFrac = 4294967;
-  const uint32_t kTimestampTicksPerMs = 90;
-  synchronization::RtcpList rtcp;
-  uint32_t ntp_sec = 0;
-  uint32_t ntp_frac = 0;
-  uint32_t timestamp = 0;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp -= kTimestampTicksPerMs;
-  rtcp.push_front(synchronization::RtcpMeasurement(ntp_sec, ntp_frac,
-                                                   timestamp));
-  ntp_frac += kOneMsInNtpFrac;
-  timestamp += 2*kTimestampTicksPerMs;
-  int64_t timestamp_in_ms = -1;
-  EXPECT_FALSE(synchronization::RtpToNtpMs(timestamp, rtcp,
-                                           &timestamp_in_ms));
-}
-};  // namespace webrtc
diff --git a/webrtc/modules/video_coding/main/source/Android.mk b/webrtc/modules/video_coding/main/source/Android.mk
index 9ebdbed..a8cf2d0 100644
--- a/webrtc/modules/video_coding/main/source/Android.mk
+++ b/webrtc/modules/video_coding/main/source/Android.mk
@@ -37,7 +37,6 @@
     receiver.cc \
     rtt_filter.cc \
     session_info.cc \
-    timestamp_extrapolator.cc \
     timestamp_map.cc \
     timing.cc \
     video_coding_impl.cc
@@ -56,7 +55,7 @@
     $(LOCAL_PATH)/../../../../common_video/vplib/main/interface \
     $(LOCAL_PATH)/../../../../common_video/interface \
     $(LOCAL_PATH)/../../utility/include \
-    $(LOCAL_PATH)/../../../../system_wrappers/interface 
+    $(LOCAL_PATH)/../../../../system_wrappers/interface
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
diff --git a/webrtc/modules/video_coding/main/source/timing.cc b/webrtc/modules/video_coding/main/source/timing.cc
index dd82187..af0e35c 100644
--- a/webrtc/modules/video_coding/main/source/timing.cc
+++ b/webrtc/modules/video_coding/main/source/timing.cc
@@ -10,12 +10,10 @@
 
 #include "webrtc/modules/video_coding/main/source/timing.h"
 
-
 #include "webrtc/modules/video_coding/main/source/internal_defines.h"
 #include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h"
-#include "webrtc/modules/video_coding/main/source/timestamp_extrapolator.h"
 #include "webrtc/system_wrappers/interface/clock.h"
-
+#include "webrtc/system_wrappers/interface/timestamp_extrapolator.h"
 
 
 namespace webrtc {
@@ -35,8 +33,7 @@
       prev_frame_timestamp_(0) {
   if (master_timing == NULL) {
     master_ = true;
-    ts_extrapolator_ =
-        new VCMTimestampExtrapolator(clock_->TimeInMilliseconds());
+    ts_extrapolator_ = new TimestampExtrapolator(clock_->TimeInMilliseconds());
   } else {
     ts_extrapolator_ = master_timing->ts_extrapolator_;
   }
diff --git a/webrtc/modules/video_coding/main/source/timing.h b/webrtc/modules/video_coding/main/source/timing.h
index fcb0402..1dca5e6 100644
--- a/webrtc/modules/video_coding/main/source/timing.h
+++ b/webrtc/modules/video_coding/main/source/timing.h
@@ -18,7 +18,7 @@
 namespace webrtc {
 
 class Clock;
-class VCMTimestampExtrapolator;
+class TimestampExtrapolator;
 
 class VCMTiming {
  public:
@@ -101,7 +101,7 @@
   CriticalSectionWrapper* crit_sect_;
   Clock* clock_;
   bool master_;
-  VCMTimestampExtrapolator* ts_extrapolator_;
+  TimestampExtrapolator* ts_extrapolator_;
   VCMCodecTimer codec_timer_;
   uint32_t render_delay_ms_;
   uint32_t min_playout_delay_ms_;
diff --git a/webrtc/modules/video_coding/main/source/video_coding.gypi b/webrtc/modules/video_coding/main/source/video_coding.gypi
index b4f6cb7..f19a585 100644
--- a/webrtc/modules/video_coding/main/source/video_coding.gypi
+++ b/webrtc/modules/video_coding/main/source/video_coding.gypi
@@ -48,7 +48,6 @@
         'receiver.h',
         'rtt_filter.h',
         'session_info.h',
-        'timestamp_extrapolator.h',
         'timestamp_map.h',
         'timing.h',
         'video_coding_impl.h',
@@ -72,7 +71,6 @@
         'receiver.cc',
         'rtt_filter.cc',
         'session_info.cc',
-        'timestamp_extrapolator.cc',
         'timestamp_map.cc',
         'timing.cc',
         'video_coding_impl.cc',
diff --git a/webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h b/webrtc/system_wrappers/interface/rtp_to_ntp.h
similarity index 84%
rename from webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h
rename to webrtc/system_wrappers/interface/rtp_to_ntp.h
index 08a4d46..dfc25cd 100644
--- a/webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h
+++ b/webrtc/system_wrappers/interface/rtp_to_ntp.h
@@ -8,8 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_RTP_TO_NTP_H_
-#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_RTP_TO_NTP_H_
+#ifndef SYSTEM_WRAPPERS_INTERFACE_RTP_TO_NTP_H_
+#define SYSTEM_WRAPPERS_INTERFACE_RTP_TO_NTP_H_
 
 #include <list>
 
@@ -17,8 +17,6 @@
 
 namespace webrtc {
 
-namespace synchronization {
-
 struct RtcpMeasurement {
   RtcpMeasurement();
   RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, uint32_t timestamp);
@@ -46,7 +44,7 @@
 // Returns 1 there has been a forward wrap around, 0 if there has been no wrap
 // around and -1 if there has been a backwards wrap around (i.e. reordering).
 int CheckForWrapArounds(uint32_t rtp_timestamp, uint32_t rtcp_rtp_timestamp);
-}  // namespace synchronization
+
 }  // namespace webrtc
 
-#endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_RTP_TO_NTP_H_
+#endif  // SYSTEM_WRAPPERS_INTERFACE_RTP_TO_NTP_H_
diff --git a/webrtc/modules/video_coding/main/source/timestamp_extrapolator.h b/webrtc/system_wrappers/interface/timestamp_extrapolator.h
similarity index 82%
rename from webrtc/modules/video_coding/main/source/timestamp_extrapolator.h
rename to webrtc/system_wrappers/interface/timestamp_extrapolator.h
index 151e4de..d067198 100644
--- a/webrtc/modules/video_coding/main/source/timestamp_extrapolator.h
+++ b/webrtc/system_wrappers/interface/timestamp_extrapolator.h
@@ -8,8 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#ifndef WEBRTC_MODULES_VIDEO_CODING_TIMESTAMP_EXTRAPOLATOR_H_
-#define WEBRTC_MODULES_VIDEO_CODING_TIMESTAMP_EXTRAPOLATOR_H_
+#ifndef SYSTEM_WRAPPERS_INTERFACE_TIMESTAMP_EXTRAPOLATOR_H_
+#define SYSTEM_WRAPPERS_INTERFACE_TIMESTAMP_EXTRAPOLATOR_H_
 
 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
 #include "webrtc/typedefs.h"
@@ -17,11 +17,11 @@
 namespace webrtc
 {
 
-class VCMTimestampExtrapolator
+class TimestampExtrapolator
 {
 public:
-    explicit VCMTimestampExtrapolator(int64_t start_ms);
-    ~VCMTimestampExtrapolator();
+    explicit TimestampExtrapolator(int64_t start_ms);
+    ~TimestampExtrapolator();
     void Update(int64_t tMs, uint32_t ts90khz);
     int64_t ExtrapolateLocalTime(uint32_t timestamp90khz);
     void Reset(int64_t start_ms);
@@ -53,4 +53,4 @@
 
 }  // namespace webrtc
 
-#endif // WEBRTC_MODULES_VIDEO_CODING_TIMESTAMP_EXTRAPOLATOR_H_
+#endif // SYSTEM_WRAPPERS_INTERFACE_TIMESTAMP_EXTRAPOLATOR_H_
diff --git a/webrtc/system_wrappers/source/Android.mk b/webrtc/system_wrappers/source/Android.mk
index f48019d..4767e72 100644
--- a/webrtc/system_wrappers/source/Android.mk
+++ b/webrtc/system_wrappers/source/Android.mk
@@ -35,11 +35,13 @@
     condition_variable_posix.cc \
     critical_section_posix.cc \
     event_posix.cc \
+    rtp_to_ntp.cc \
     sleep.cc \
     thread_posix.cc \
     tick_util.cc \
+    timestamp_extrapolator.cc \
     trace_posix.cc \
-    rw_lock_posix.cc 
+    rw_lock_posix.cc
 
 LOCAL_CFLAGS := \
     $(MY_WEBRTC_COMMON_DEFS)
diff --git a/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp.cc b/webrtc/system_wrappers/source/rtp_to_ntp.cc
similarity index 93%
rename from webrtc/modules/remote_bitrate_estimator/rtp_to_ntp.cc
rename to webrtc/system_wrappers/source/rtp_to_ntp.cc
index 775cd0d..d6b7b14 100644
--- a/webrtc/modules/remote_bitrate_estimator/rtp_to_ntp.cc
+++ b/webrtc/system_wrappers/source/rtp_to_ntp.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h"
+#include "webrtc/system_wrappers/interface/rtp_to_ntp.h"
 
 #include "webrtc/system_wrappers/interface/clock.h"
 
@@ -16,8 +16,6 @@
 
 namespace webrtc {
 
-namespace synchronization {
-
 RtcpMeasurement::RtcpMeasurement()
     : ntp_secs(0), ntp_frac(0), rtp_timestamp(0) {}
 
@@ -47,8 +45,7 @@
                              uint32_t old_timestamp,
                              int64_t* compensated_timestamp) {
   assert(compensated_timestamp);
-  int64_t wraps = synchronization::CheckForWrapArounds(new_timestamp,
-                                                       old_timestamp);
+  int64_t wraps = CheckForWrapArounds(new_timestamp, old_timestamp);
   if (wraps < 0) {
     // Reordering, don't use this packet.
     return false;
@@ -96,7 +93,7 @@
 // |rtp_timestamp_in_ms|. This function compensates for wrap arounds in RTP
 // timestamps and returns false if it can't do the conversion due to reordering.
 bool RtpToNtpMs(int64_t rtp_timestamp,
-                const synchronization::RtcpList& rtcp,
+                const RtcpList& rtcp,
                 int64_t* rtp_timestamp_in_ms) {
   assert(rtcp.size() == 2);
   int64_t rtcp_ntp_ms_new = Clock::NtpToMs(rtcp.front().ntp_secs,
@@ -149,5 +146,5 @@
   }
   return 0;
 }
-}  // namespace synchronization
+
 }  // namespace webrtc
diff --git a/webrtc/system_wrappers/source/rtp_to_ntp_unittest.cc b/webrtc/system_wrappers/source/rtp_to_ntp_unittest.cc
new file mode 100644
index 0000000..a4d75ae
--- /dev/null
+++ b/webrtc/system_wrappers/source/rtp_to_ntp_unittest.cc
@@ -0,0 +1,146 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/system_wrappers/interface/rtp_to_ntp.h"
+
+namespace webrtc {
+
+TEST(WrapAroundTests, NoWrap) {
+  EXPECT_EQ(0, CheckForWrapArounds(0xFFFFFFFF, 0xFFFFFFFE));
+  EXPECT_EQ(0, CheckForWrapArounds(1, 0));
+  EXPECT_EQ(0, CheckForWrapArounds(0x00010000, 0x0000FFFF));
+}
+
+TEST(WrapAroundTests, ForwardWrap) {
+  EXPECT_EQ(1, CheckForWrapArounds(0, 0xFFFFFFFF));
+  EXPECT_EQ(1, CheckForWrapArounds(0, 0xFFFF0000));
+  EXPECT_EQ(1, CheckForWrapArounds(0x0000FFFF, 0xFFFFFFFF));
+  EXPECT_EQ(1, CheckForWrapArounds(0x0000FFFF, 0xFFFF0000));
+}
+
+TEST(WrapAroundTests, BackwardWrap) {
+  EXPECT_EQ(-1, CheckForWrapArounds(0xFFFFFFFF, 0));
+  EXPECT_EQ(-1, CheckForWrapArounds(0xFFFF0000, 0));
+  EXPECT_EQ(-1, CheckForWrapArounds(0xFFFFFFFF, 0x0000FFFF));
+  EXPECT_EQ(-1, CheckForWrapArounds(0xFFFF0000, 0x0000FFFF));
+}
+
+TEST(WrapAroundTests, OldRtcpWrapped) {
+  RtcpList rtcp;
+  uint32_t ntp_sec = 0;
+  uint32_t ntp_frac = 0;
+  uint32_t timestamp = 0;
+  const uint32_t kOneMsInNtpFrac = 4294967;
+  const uint32_t kTimestampTicksPerMs = 90;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp -= kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp -= kTimestampTicksPerMs;
+  int64_t timestamp_in_ms = -1;
+  // This expected to fail since it's highly unlikely that the older RTCP
+  // has a much smaller RTP timestamp than the newer.
+  EXPECT_FALSE(RtpToNtpMs(timestamp, rtcp, &timestamp_in_ms));
+}
+
+TEST(WrapAroundTests, NewRtcpWrapped) {
+  RtcpList rtcp;
+  uint32_t ntp_sec = 0;
+  uint32_t ntp_frac = 0;
+  uint32_t timestamp = 0xFFFFFFFF;
+  const uint32_t kOneMsInNtpFrac = 4294967;
+  const uint32_t kTimestampTicksPerMs = 90;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp += kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  int64_t timestamp_in_ms = -1;
+  EXPECT_TRUE(RtpToNtpMs(rtcp.back().rtp_timestamp, rtcp, &timestamp_in_ms));
+  // Since this RTP packet has the same timestamp as the RTCP packet constructed
+  // at time 0 it should be mapped to 0 as well.
+  EXPECT_EQ(0, timestamp_in_ms);
+}
+
+TEST(WrapAroundTests, RtpWrapped) {
+  const uint32_t kOneMsInNtpFrac = 4294967;
+  const uint32_t kTimestampTicksPerMs = 90;
+  RtcpList rtcp;
+  uint32_t ntp_sec = 0;
+  uint32_t ntp_frac = 0;
+  uint32_t timestamp = 0xFFFFFFFF - 2 * kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp += kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp += kTimestampTicksPerMs;
+  int64_t timestamp_in_ms = -1;
+  EXPECT_TRUE(RtpToNtpMs(timestamp, rtcp, &timestamp_in_ms));
+  // Since this RTP packet has the same timestamp as the RTCP packet constructed
+  // at time 0 it should be mapped to 0 as well.
+  EXPECT_EQ(2, timestamp_in_ms);
+}
+
+TEST(WrapAroundTests, OldRtp_RtcpsWrapped) {
+  const uint32_t kOneMsInNtpFrac = 4294967;
+  const uint32_t kTimestampTicksPerMs = 90;
+  RtcpList rtcp;
+  uint32_t ntp_sec = 0;
+  uint32_t ntp_frac = 0;
+  uint32_t timestamp = 0;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp += kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp -= 2*kTimestampTicksPerMs;
+  int64_t timestamp_in_ms = -1;
+  EXPECT_FALSE(RtpToNtpMs(timestamp, rtcp, &timestamp_in_ms));
+}
+
+TEST(WrapAroundTests, OldRtp_NewRtcpWrapped) {
+  const uint32_t kOneMsInNtpFrac = 4294967;
+  const uint32_t kTimestampTicksPerMs = 90;
+  RtcpList rtcp;
+  uint32_t ntp_sec = 0;
+  uint32_t ntp_frac = 0;
+  uint32_t timestamp = 0xFFFFFFFF;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp += kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp -= kTimestampTicksPerMs;
+  int64_t timestamp_in_ms = -1;
+  EXPECT_TRUE(RtpToNtpMs(timestamp, rtcp, &timestamp_in_ms));
+  // Constructed at the same time as the first RTCP and should therefore be
+  // mapped to zero.
+  EXPECT_EQ(0, timestamp_in_ms);
+}
+
+TEST(WrapAroundTests, OldRtp_OldRtcpWrapped) {
+  const uint32_t kOneMsInNtpFrac = 4294967;
+  const uint32_t kTimestampTicksPerMs = 90;
+  RtcpList rtcp;
+  uint32_t ntp_sec = 0;
+  uint32_t ntp_frac = 0;
+  uint32_t timestamp = 0;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp -= kTimestampTicksPerMs;
+  rtcp.push_front(RtcpMeasurement(ntp_sec, ntp_frac, timestamp));
+  ntp_frac += kOneMsInNtpFrac;
+  timestamp += 2*kTimestampTicksPerMs;
+  int64_t timestamp_in_ms = -1;
+  EXPECT_FALSE(RtpToNtpMs(timestamp, rtcp, &timestamp_in_ms));
+}
+};  // namespace webrtc
diff --git a/webrtc/system_wrappers/source/system_wrappers.gyp b/webrtc/system_wrappers/source/system_wrappers.gyp
index 2deefaa..36d4d9c 100644
--- a/webrtc/system_wrappers/source/system_wrappers.gyp
+++ b/webrtc/system_wrappers/source/system_wrappers.gyp
@@ -40,6 +40,7 @@
         '../interface/logcat_trace_context.h',
         '../interface/logging.h',
         '../interface/ref_count.h',
+        '../interface/rtp_to_ntp.h',
         '../interface/rw_lock_wrapper.h',
         '../interface/scoped_ptr.h',
         '../interface/scoped_refptr.h',
@@ -52,6 +53,7 @@
         '../interface/thread_annotations.h',
         '../interface/thread_wrapper.h',
         '../interface/tick_util.h',
+        '../interface/timestamp_extrapolator.h',
         '../interface/trace.h',
         '../interface/trace_event.h',
         '../interface/utf_util_win.h',
@@ -87,6 +89,7 @@
         'file_impl.h',
         'logcat_trace_context.cc',
         'logging.cc',
+        'rtp_to_ntp.cc',
         'rw_lock.cc',
         'rw_lock_generic.cc',
         'rw_lock_generic.h',
@@ -103,6 +106,7 @@
         'thread_posix.h',
         'thread_win.cc',
         'thread_win.h',
+        'timestamp_extrapolator.cc',
         'trace_impl.cc',
         'trace_impl.h',
         'trace_posix.cc',
diff --git a/webrtc/system_wrappers/source/system_wrappers_tests.gyp b/webrtc/system_wrappers/source/system_wrappers_tests.gyp
index 91ff028..59eef36 100644
--- a/webrtc/system_wrappers/source/system_wrappers_tests.gyp
+++ b/webrtc/system_wrappers/source/system_wrappers_tests.gyp
@@ -29,6 +29,7 @@
         'data_log_helpers_unittest.cc',
         'data_log_c_helpers_unittest.c',
         'data_log_c_helpers_unittest.h',
+        'rtp_to_ntp_unittest.cc',
         'scoped_vector_unittest.cc',
         'stringize_macros_unittest.cc',
         'stl_util_unittest.cc',
diff --git a/webrtc/modules/video_coding/main/source/timestamp_extrapolator.cc b/webrtc/system_wrappers/source/timestamp_extrapolator.cc
similarity index 92%
rename from webrtc/modules/video_coding/main/source/timestamp_extrapolator.cc
rename to webrtc/system_wrappers/source/timestamp_extrapolator.cc
index bde2f0a..afd212b 100644
--- a/webrtc/modules/video_coding/main/source/timestamp_extrapolator.cc
+++ b/webrtc/system_wrappers/source/timestamp_extrapolator.cc
@@ -8,13 +8,13 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "webrtc/modules/video_coding/main/source/timestamp_extrapolator.h"
+#include "webrtc/system_wrappers/interface/timestamp_extrapolator.h"
 
 #include <algorithm>
 
 namespace webrtc {
 
-VCMTimestampExtrapolator::VCMTimestampExtrapolator(int64_t start_ms)
+TimestampExtrapolator::TimestampExtrapolator(int64_t start_ms)
     : _rwLock(RWLockWrapper::CreateRWLock()),
       _startMs(0),
       _firstTimestamp(0),
@@ -34,13 +34,12 @@
     Reset(start_ms);
 }
 
-VCMTimestampExtrapolator::~VCMTimestampExtrapolator()
+TimestampExtrapolator::~TimestampExtrapolator()
 {
     delete _rwLock;
 }
 
-void
-VCMTimestampExtrapolator::Reset(int64_t start_ms)
+void TimestampExtrapolator::Reset(int64_t start_ms)
 {
     WriteLockScoped wl(*_rwLock);
     _startMs = start_ms;
@@ -61,7 +60,7 @@
 }
 
 void
-VCMTimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz)
+TimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz)
 {
 
     _rwLock->AcquireLockExclusive();
@@ -143,7 +142,7 @@
 }
 
 int64_t
-VCMTimestampExtrapolator::ExtrapolateLocalTime(uint32_t timestamp90khz)
+TimestampExtrapolator::ExtrapolateLocalTime(uint32_t timestamp90khz)
 {
     ReadLockScoped rl(*_rwLock);
     int64_t localTimeMs = 0;
@@ -181,7 +180,7 @@
 // Investigates if the timestamp clock has overflowed since the last timestamp and
 // keeps track of the number of wrap arounds since reset.
 void
-VCMTimestampExtrapolator::CheckForWrapArounds(uint32_t ts90khz)
+TimestampExtrapolator::CheckForWrapArounds(uint32_t ts90khz)
 {
     if (_prevWrapTimestamp == -1)
     {
@@ -210,7 +209,7 @@
 }
 
 bool
-VCMTimestampExtrapolator::DelayChangeDetection(double error)
+TimestampExtrapolator::DelayChangeDetection(double error)
 {
     // CUSUM detection of sudden delay changes
     error = (error > 0) ? std::min(error, _accMaxError) :
diff --git a/webrtc/video/call_perf_tests.cc b/webrtc/video/call_perf_tests.cc
index 85f21da..9830dd1 100644
--- a/webrtc/video/call_perf_tests.cc
+++ b/webrtc/video/call_perf_tests.cc
@@ -17,10 +17,10 @@
 
 #include "webrtc/call.h"
 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/rtp_to_ntp.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/system_wrappers/interface/thread_annotations.h"
 #include "webrtc/test/direct_transport.h"
@@ -105,7 +105,7 @@
          packet_type = parser.Iterate()) {
       if (packet_type == RTCPUtility::kRtcpSrCode) {
         const RTCPUtility::RTCPPacket& packet = parser.Packet();
-        synchronization::RtcpMeasurement ntp_rtp_pair(
+        RtcpMeasurement ntp_rtp_pair(
             packet.SR.NTPMostSignificant,
             packet.SR.NTPLeastSignificant,
             packet.SR.RTPTimestamp);
@@ -122,16 +122,16 @@
       // TODO(stefan): We can't EXPECT_TRUE on this call due to a bug in the
       // RTCP sender where it sends RTCP SR before any RTP packets, which leads
       // to a bogus NTP/RTP mapping.
-      synchronization::RtpToNtpMs(timestamp, ntp_rtp_pairs_, &timestamp_in_ms);
+      RtpToNtpMs(timestamp, ntp_rtp_pairs_, &timestamp_in_ms);
       return timestamp_in_ms;
     }
     return -1;
   }
 
  private:
-  void StoreNtpRtpPair(synchronization::RtcpMeasurement ntp_rtp_pair) {
+  void StoreNtpRtpPair(RtcpMeasurement ntp_rtp_pair) {
     CriticalSectionScoped lock(crit_.get());
-    for (synchronization::RtcpList::iterator it = ntp_rtp_pairs_.begin();
+    for (RtcpList::iterator it = ntp_rtp_pairs_.begin();
          it != ntp_rtp_pairs_.end();
          ++it) {
       if (ntp_rtp_pair.ntp_secs == it->ntp_secs &&
@@ -149,7 +149,7 @@
   }
 
   const scoped_ptr<CriticalSectionWrapper> crit_;
-  synchronization::RtcpList ntp_rtp_pairs_ GUARDED_BY(crit_);
+  RtcpList ntp_rtp_pairs_ GUARDED_BY(crit_);
 };
 
 class VideoRtcpAndSyncObserver : public SyncRtcpObserver, public VideoRenderer {
diff --git a/webrtc/video_engine/stream_synchronization.cc b/webrtc/video_engine/stream_synchronization.cc
index a877c7f..8f72fa9 100644
--- a/webrtc/video_engine/stream_synchronization.cc
+++ b/webrtc/video_engine/stream_synchronization.cc
@@ -64,15 +64,15 @@
     return false;
   }
   int64_t audio_last_capture_time_ms;
-  if (!synchronization::RtpToNtpMs(audio_measurement.latest_timestamp,
-                                   audio_measurement.rtcp,
-                                   &audio_last_capture_time_ms)) {
+  if (!RtpToNtpMs(audio_measurement.latest_timestamp,
+                  audio_measurement.rtcp,
+                  &audio_last_capture_time_ms)) {
     return false;
   }
   int64_t video_last_capture_time_ms;
-  if (!synchronization::RtpToNtpMs(video_measurement.latest_timestamp,
-                                   video_measurement.rtcp,
-                                   &video_last_capture_time_ms)) {
+  if (!RtpToNtpMs(video_measurement.latest_timestamp,
+                  video_measurement.rtcp,
+                  &video_last_capture_time_ms)) {
     return false;
   }
   if (video_last_capture_time_ms < 0) {
diff --git a/webrtc/video_engine/stream_synchronization.h b/webrtc/video_engine/stream_synchronization.h
index 078b938..5fa9536d17 100644
--- a/webrtc/video_engine/stream_synchronization.h
+++ b/webrtc/video_engine/stream_synchronization.h
@@ -13,7 +13,7 @@
 
 #include <list>
 
-#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h"
+#include "webrtc/system_wrappers/interface/rtp_to_ntp.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
@@ -24,7 +24,7 @@
  public:
   struct Measurements {
     Measurements() : rtcp(), latest_receive_time_ms(0), latest_timestamp(0) {}
-    synchronization::RtcpList rtcp;
+    RtcpList rtcp;
     int64_t latest_receive_time_ms;
     uint32_t latest_timestamp;
   };
diff --git a/webrtc/video_engine/stream_synchronization_unittest.cc b/webrtc/video_engine/stream_synchronization_unittest.cc
index 8876485..7136f1e 100644
--- a/webrtc/video_engine/stream_synchronization_unittest.cc
+++ b/webrtc/video_engine/stream_synchronization_unittest.cc
@@ -33,9 +33,8 @@
       : kNtpJan1970(2208988800UL),
         time_now_ms_(offset) {}
 
-    synchronization::RtcpMeasurement GenerateRtcp(int frequency,
-                                                  uint32_t offset) const {
-    synchronization::RtcpMeasurement rtcp;
+  RtcpMeasurement GenerateRtcp(int frequency, uint32_t offset) const {
+    RtcpMeasurement rtcp;
     NowNtp(&rtcp.ntp_secs, &rtcp.ntp_frac);
     rtcp.rtp_timestamp = NowRtp(frequency, offset);
     return rtcp;
diff --git a/webrtc/video_engine/vie_receiver.cc b/webrtc/video_engine/vie_receiver.cc
index 2775ac9..ce6bdf2 100644
--- a/webrtc/video_engine/vie_receiver.cc
+++ b/webrtc/video_engine/vie_receiver.cc
@@ -21,10 +21,10 @@
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/utility/interface/rtp_dump.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
-#include "webrtc/modules/video_coding/main/source/timestamp_extrapolator.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/system_wrappers/interface/logging.h"
 #include "webrtc/system_wrappers/interface/tick_util.h"
+#include "webrtc/system_wrappers/interface/timestamp_extrapolator.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
 namespace webrtc {
@@ -49,7 +49,7 @@
       remote_bitrate_estimator_(remote_bitrate_estimator),
       clock_(Clock::GetRealTimeClock()),
       ts_extrapolator_(
-          new VCMTimestampExtrapolator(clock_->TimeInMilliseconds())),
+          new TimestampExtrapolator(clock_->TimeInMilliseconds())),
       rtp_dump_(NULL),
       receiving_(false),
       restored_packet_in_use_(false),
@@ -194,9 +194,9 @@
   }
 
   int64_t sender_capture_ntp_ms = 0;
-  if (!synchronization::RtpToNtpMs(rtp_header->header.timestamp,
-                                   rtcp_list_,
-                                   &sender_capture_ntp_ms)) {
+  if (!RtpToNtpMs(rtp_header->header.timestamp,
+                  rtcp_list_,
+                  &sender_capture_ntp_ms)) {
     return;
   }
   uint32_t timestamp = sender_capture_ntp_ms * 90;
@@ -390,8 +390,11 @@
   }
 
   bool new_rtcp_sr = false;
-  if (!synchronization::UpdateRtcpList(
-      ntp_secs, ntp_frac, rtp_timestamp, &rtcp_list_, &new_rtcp_sr)) {
+  if (!UpdateRtcpList(ntp_secs,
+                      ntp_frac,
+                      rtp_timestamp,
+                      &rtcp_list_,
+                      &new_rtcp_sr)) {
     return false;
   }
 
diff --git a/webrtc/video_engine/vie_receiver.h b/webrtc/video_engine/vie_receiver.h
index c85975c..bd753ae 100644
--- a/webrtc/video_engine/vie_receiver.h
+++ b/webrtc/video_engine/vie_receiver.h
@@ -14,17 +14,14 @@
 #include <list>
 
 #include "webrtc/engine_configurations.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/rtp_to_ntp.h"
 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/system_wrappers/interface/rtp_to_ntp.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/typedefs.h"
 #include "webrtc/video_engine/include/vie_network.h"
 #include "webrtc/video_engine/vie_defines.h"
 
-// TODO(wu): Move rtp_to_ntp.h and timestamp_extrapolator.h to somewhere that
-// can be shared between audio and video.
-
 namespace webrtc {
 
 class CriticalSectionWrapper;
@@ -36,7 +33,7 @@
 class RTPPayloadRegistry;
 class RtpReceiver;
 class RtpRtcp;
-class VCMTimestampExtrapolator;
+class TimestampExtrapolator;
 class VideoCodingModule;
 struct ReceiveBandwidthEstimatorStats;
 
@@ -124,8 +121,8 @@
   RemoteBitrateEstimator* remote_bitrate_estimator_;
 
   Clock* clock_;
-  scoped_ptr<VCMTimestampExtrapolator> ts_extrapolator_;
-  synchronization::RtcpList rtcp_list_;
+  scoped_ptr<TimestampExtrapolator> ts_extrapolator_;
+  RtcpList rtcp_list_;
 
   RtpDump* rtp_dump_;
   bool receiving_;
diff --git a/webrtc/video_engine/vie_sync_module.cc b/webrtc/video_engine/vie_sync_module.cc
index b7c74a7..31a7a6d 100644
--- a/webrtc/video_engine/vie_sync_module.cc
+++ b/webrtc/video_engine/vie_sync_module.cc
@@ -43,7 +43,7 @@
   }
 
   bool new_rtcp_sr = false;
-  if (!synchronization::UpdateRtcpList(
+  if (!UpdateRtcpList(
       ntp_secs, ntp_frac, rtp_timestamp, &stream->rtcp, &new_rtcp_sr)) {
     return -1;
   }