Make class of static functions in rtp_to_ntp.h:
- UpdateRtcpList
- RtpToNtp
class RtpToNtpEstimator
- UpdateMeasurements
- Estimate
List with rtcp measurements is now private.
BUG=none
Review-Url: https://codereview.webrtc.org/2574133003
Cr-Commit-Position: refs/heads/master@{#15762}
diff --git a/webrtc/call/call_perf_tests.cc b/webrtc/call/call_perf_tests.cc
index e03c26d..782b45c 100644
--- a/webrtc/call/call_perf_tests.cc
+++ b/webrtc/call/call_perf_tests.cc
@@ -24,7 +24,6 @@
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/metrics_default.h"
-#include "webrtc/system_wrappers/include/rtp_to_ntp.h"
#include "webrtc/test/call_test.h"
#include "webrtc/test/direct_transport.h"
#include "webrtc/test/drifting_clock.h"
diff --git a/webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h b/webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
index cab488f..118df4c 100644
--- a/webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
+++ b/webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h
@@ -14,7 +14,7 @@
#include <memory>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/system_wrappers/include/rtp_to_ntp.h"
+#include "webrtc/system_wrappers/include/rtp_to_ntp_estimator.h"
namespace webrtc {
@@ -43,7 +43,7 @@
private:
Clock* clock_;
std::unique_ptr<TimestampExtrapolator> ts_extrapolator_;
- RtcpMeasurements rtcp_list_;
+ RtpToNtpEstimator rtp_to_ntp_;
int64_t last_timing_log_ms_;
RTC_DISALLOW_COPY_AND_ASSIGN(RemoteNtpTimeEstimator);
};
diff --git a/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc b/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
index 69a8f23..c78a8bc 100644
--- a/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
+++ b/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc
@@ -33,8 +33,8 @@
uint32_t ntp_frac,
uint32_t rtcp_timestamp) {
bool new_rtcp_sr = false;
- if (!UpdateRtcpList(
- ntp_secs, ntp_frac, rtcp_timestamp, &rtcp_list_, &new_rtcp_sr)) {
+ if (!rtp_to_ntp_.UpdateMeasurements(ntp_secs, ntp_frac, rtcp_timestamp,
+ &new_rtcp_sr)) {
return false;
}
if (!new_rtcp_sr) {
@@ -52,7 +52,7 @@
int64_t RemoteNtpTimeEstimator::Estimate(uint32_t rtp_timestamp) {
int64_t sender_capture_ntp_ms = 0;
- if (!RtpToNtpMs(rtp_timestamp, rtcp_list_, &sender_capture_ntp_ms)) {
+ if (!rtp_to_ntp_.Estimate(rtp_timestamp, &sender_capture_ntp_ms)) {
return -1;
}
uint32_t timestamp = sender_capture_ntp_ms * 90;
diff --git a/webrtc/system_wrappers/BUILD.gn b/webrtc/system_wrappers/BUILD.gn
index 7f56fd8..745867b 100644
--- a/webrtc/system_wrappers/BUILD.gn
+++ b/webrtc/system_wrappers/BUILD.gn
@@ -28,7 +28,7 @@
"include/logging.h",
"include/metrics.h",
"include/ntp_time.h",
- "include/rtp_to_ntp.h",
+ "include/rtp_to_ntp_estimator.h",
"include/rw_lock_wrapper.h",
"include/sleep.h",
"include/static_instance.h",
@@ -50,7 +50,7 @@
"source/event_timer_win.h",
"source/file_impl.cc",
"source/logging.cc",
- "source/rtp_to_ntp.cc",
+ "source/rtp_to_ntp_estimator.cc",
"source/rw_lock.cc",
"source/rw_lock_posix.cc",
"source/rw_lock_posix.h",
@@ -179,7 +179,7 @@
"source/metrics_default_unittest.cc",
"source/metrics_unittest.cc",
"source/ntp_time_unittest.cc",
- "source/rtp_to_ntp_unittest.cc",
+ "source/rtp_to_ntp_estimator_unittest.cc",
"source/stringize_macros_unittest.cc",
]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
diff --git a/webrtc/system_wrappers/include/rtp_to_ntp.h b/webrtc/system_wrappers/include/rtp_to_ntp.h
deleted file mode 100644
index c1e7ab6..0000000
--- a/webrtc/system_wrappers/include/rtp_to_ntp.h
+++ /dev/null
@@ -1,71 +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.
- */
-
-#ifndef SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_H_
-#define SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_H_
-
-#include <list>
-
-#include "webrtc/system_wrappers/include/ntp_time.h"
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-
-struct RtcpMeasurement {
- RtcpMeasurement();
- RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, uint32_t timestamp);
- bool IsEqual(const RtcpMeasurement& other) const;
-
- NtpTime ntp_time;
- uint32_t rtp_timestamp;
-};
-
-struct RtcpMeasurements {
- RtcpMeasurements();
- ~RtcpMeasurements();
- bool Contains(const RtcpMeasurement& other) const;
- bool IsValid(const RtcpMeasurement& other) const;
- void UpdateParameters();
-
- // Estimated parameters from RTP and NTP timestamp pairs in |list|.
- struct RtpToNtpParameters {
- double frequency_khz = 0.0;
- double offset_ms = 0.0;
- bool calculated = false;
- };
-
- std::list<RtcpMeasurement> list;
- RtpToNtpParameters params;
-};
-
-// Updates |list| in |rtcp_measurements| with timestamps from the RTCP SR.
-// |new_rtcp_sr| will be set to true if these are the timestamps which have
-// never be added to |list|.
-// |rtcp_measurements.params| are estimated from the RTP and NTP timestamp pairs
-// in the |list| when a new RTCP SR is inserted.
-bool UpdateRtcpList(uint32_t ntp_secs,
- uint32_t ntp_frac,
- uint32_t rtp_timestamp,
- RtcpMeasurements* rtcp_measurements,
- bool* new_rtcp_sr);
-
-// Converts an RTP timestamp to the NTP domain in milliseconds using the
-// estimated |rtcp_measurements.params|.
-bool RtpToNtpMs(int64_t rtp_timestamp,
- const RtcpMeasurements& rtcp_measurements,
- int64_t* rtp_timestamp_in_ms);
-
-// 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 webrtc
-
-#endif // SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_H_
diff --git a/webrtc/system_wrappers/include/rtp_to_ntp_estimator.h b/webrtc/system_wrappers/include/rtp_to_ntp_estimator.h
new file mode 100644
index 0000000..a17428b
--- /dev/null
+++ b/webrtc/system_wrappers/include/rtp_to_ntp_estimator.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_
+#define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_
+
+#include <list>
+
+#include "webrtc/system_wrappers/include/ntp_time.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+// Class for converting an RTP timestamp to the NTP domain in milliseconds.
+// The class needs to be trained with (at least 2) RTP/NTP timestamp pairs from
+// RTCP sender reports before the convertion can be done.
+class RtpToNtpEstimator {
+ public:
+ RtpToNtpEstimator();
+ ~RtpToNtpEstimator();
+
+ // RTP and NTP timestamp pair from a RTCP SR report.
+ struct RtcpMeasurement {
+ RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, uint32_t timestamp);
+ bool IsEqual(const RtcpMeasurement& other) const;
+
+ NtpTime ntp_time;
+ uint32_t rtp_timestamp;
+ };
+
+ // Estimated parameters from RTP and NTP timestamp pairs in |measurements_|.
+ struct Parameters {
+ double frequency_khz = 0.0;
+ double offset_ms = 0.0;
+ bool calculated = false;
+ };
+
+ // Updates measurements with RTP/NTP timestamp pair from a RTCP sender report.
+ // |new_rtcp_sr| is set to true if a new report is added.
+ bool UpdateMeasurements(uint32_t ntp_secs,
+ uint32_t ntp_frac,
+ uint32_t rtp_timestamp,
+ bool* new_rtcp_sr);
+
+ // Converts an RTP timestamp to the NTP domain in milliseconds.
+ // Returns true on success, false otherwise.
+ bool Estimate(int64_t rtp_timestamp, int64_t* rtp_timestamp_ms) const;
+
+ const Parameters& params() const { return params_; }
+
+ private:
+ void UpdateParameters();
+
+ std::list<RtcpMeasurement> measurements_;
+ Parameters params_;
+};
+
+// Returns:
+// 1: forward wrap around.
+// 0: no wrap around.
+// -1: backwards wrap around (i.e. reordering).
+int CheckForWrapArounds(uint32_t new_timestamp, uint32_t old_timestamp);
+
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_
diff --git a/webrtc/system_wrappers/source/rtp_to_ntp.cc b/webrtc/system_wrappers/source/rtp_to_ntp.cc
deleted file mode 100644
index cbd5020..0000000
--- a/webrtc/system_wrappers/source/rtp_to_ntp.cc
+++ /dev/null
@@ -1,195 +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 "webrtc/system_wrappers/include/rtp_to_ntp.h"
-
-#include "webrtc/base/logging.h"
-#include "webrtc/system_wrappers/include/clock.h"
-
-namespace webrtc {
-namespace {
-// Number of RTCP SR reports to use to map between RTP and NTP.
-const size_t kNumRtcpReportsToUse = 2;
-
-// Calculates the RTP timestamp frequency from two pairs of NTP/RTP timestamps.
-bool CalculateFrequency(int64_t rtcp_ntp_ms1,
- uint32_t rtp_timestamp1,
- int64_t rtcp_ntp_ms2,
- uint32_t rtp_timestamp2,
- double* frequency_khz) {
- if (rtcp_ntp_ms1 <= rtcp_ntp_ms2) {
- return false;
- }
- *frequency_khz = static_cast<double>(rtp_timestamp1 - rtp_timestamp2) /
- static_cast<double>(rtcp_ntp_ms1 - rtcp_ntp_ms2);
- return true;
-}
-
-// Detects if there has been a wraparound between |old_timestamp| and
-// |new_timestamp|, and compensates by adding 2^32 if that is the case.
-bool CompensateForWrapAround(uint32_t new_timestamp,
- uint32_t old_timestamp,
- int64_t* compensated_timestamp) {
- int64_t wraps = CheckForWrapArounds(new_timestamp, old_timestamp);
- if (wraps < 0) {
- // Reordering, don't use this packet.
- return false;
- }
- *compensated_timestamp = new_timestamp + (wraps << 32);
- return true;
-}
-} // namespace
-
-// Class holding RTP and NTP timestamp from a RTCP SR report.
-RtcpMeasurement::RtcpMeasurement() : ntp_time(0, 0), rtp_timestamp(0) {}
-
-RtcpMeasurement::RtcpMeasurement(uint32_t ntp_secs,
- uint32_t ntp_frac,
- uint32_t timestamp)
- : ntp_time(ntp_secs, ntp_frac), rtp_timestamp(timestamp) {}
-
-bool RtcpMeasurement::IsEqual(const RtcpMeasurement& other) const {
- // Use || since two equal timestamps will result in zero frequency and in
- // RtpToNtpMs, |rtp_timestamp_ms| is estimated by dividing by the frequency.
- return (ntp_time == other.ntp_time) || (rtp_timestamp == other.rtp_timestamp);
-}
-
-// Class holding list of RTP and NTP timestamp pairs.
-RtcpMeasurements::RtcpMeasurements() {}
-RtcpMeasurements::~RtcpMeasurements() {}
-
-bool RtcpMeasurements::Contains(const RtcpMeasurement& other) const {
- for (const auto& it : list) {
- if (it.IsEqual(other))
- return true;
- }
- return false;
-}
-
-bool RtcpMeasurements::IsValid(const RtcpMeasurement& other) const {
- if (!other.ntp_time.Valid())
- return false;
-
- int64_t ntp_ms_new = other.ntp_time.ToMs();
- for (const auto& it : list) {
- if (ntp_ms_new <= it.ntp_time.ToMs()) {
- // Old report.
- return false;
- }
- int64_t timestamp_new = other.rtp_timestamp;
- if (!CompensateForWrapAround(timestamp_new, it.rtp_timestamp,
- ×tamp_new)) {
- return false;
- }
- if (timestamp_new <= it.rtp_timestamp) {
- LOG(LS_WARNING) << "Newer RTCP SR report with older RTP timestamp.";
- return false;
- }
- }
- return true;
-}
-
-void RtcpMeasurements::UpdateParameters() {
- if (list.size() != kNumRtcpReportsToUse)
- return;
-
- int64_t timestamp_new = list.front().rtp_timestamp;
- int64_t timestamp_old = list.back().rtp_timestamp;
- if (!CompensateForWrapAround(timestamp_new, timestamp_old, ×tamp_new))
- return;
-
- int64_t ntp_ms_new = list.front().ntp_time.ToMs();
- int64_t ntp_ms_old = list.back().ntp_time.ToMs();
-
- if (!CalculateFrequency(ntp_ms_new, timestamp_new, ntp_ms_old, timestamp_old,
- ¶ms.frequency_khz)) {
- return;
- }
- params.offset_ms = timestamp_new - params.frequency_khz * ntp_ms_new;
- params.calculated = true;
-}
-
-// Updates list holding NTP and RTP timestamp pairs.
-bool UpdateRtcpList(uint32_t ntp_secs,
- uint32_t ntp_frac,
- uint32_t rtp_timestamp,
- RtcpMeasurements* rtcp_measurements,
- bool* new_rtcp_sr) {
- *new_rtcp_sr = false;
-
- RtcpMeasurement measurement(ntp_secs, ntp_frac, rtp_timestamp);
- if (rtcp_measurements->Contains(measurement)) {
- // RTCP SR report already added.
- return true;
- }
-
- if (!rtcp_measurements->IsValid(measurement)) {
- // Old report or invalid parameters.
- return false;
- }
-
- // Insert new RTCP SR report.
- if (rtcp_measurements->list.size() == kNumRtcpReportsToUse)
- rtcp_measurements->list.pop_back();
-
- rtcp_measurements->list.push_front(measurement);
- *new_rtcp_sr = true;
-
- // List updated, calculate new parameters.
- rtcp_measurements->UpdateParameters();
- return true;
-}
-
-// Converts |rtp_timestamp| to the NTP time base using the NTP and RTP timestamp
-// pairs in |rtcp|. The converted timestamp is returned in
-// |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 RtcpMeasurements& rtcp,
- int64_t* rtp_timestamp_in_ms) {
- if (!rtcp.params.calculated || rtcp.list.empty())
- return false;
-
- uint32_t rtcp_timestamp_old = rtcp.list.back().rtp_timestamp;
- int64_t rtp_timestamp_unwrapped;
- if (!CompensateForWrapAround(rtp_timestamp, rtcp_timestamp_old,
- &rtp_timestamp_unwrapped)) {
- return false;
- }
-
- double rtp_timestamp_ms =
- (static_cast<double>(rtp_timestamp_unwrapped) - rtcp.params.offset_ms) /
- rtcp.params.frequency_khz +
- 0.5f;
- if (rtp_timestamp_ms < 0) {
- return false;
- }
- *rtp_timestamp_in_ms = rtp_timestamp_ms;
- return true;
-}
-
-int CheckForWrapArounds(uint32_t new_timestamp, uint32_t old_timestamp) {
- if (new_timestamp < old_timestamp) {
- // This difference should be less than -2^31 if we have had a wrap around
- // (e.g. |new_timestamp| = 1, |rtcp_rtp_timestamp| = 2^32 - 1). Since it is
- // cast to a int32_t, it should be positive.
- if (static_cast<int32_t>(new_timestamp - old_timestamp) > 0) {
- // Forward wrap around.
- return 1;
- }
- } else if (static_cast<int32_t>(old_timestamp - new_timestamp) > 0) {
- // This difference should be less than -2^31 if we have had a backward wrap
- // around. Since it is cast to a int32_t, it should be positive.
- return -1;
- }
- return 0;
-}
-
-} // namespace webrtc
diff --git a/webrtc/system_wrappers/source/rtp_to_ntp_estimator.cc b/webrtc/system_wrappers/source/rtp_to_ntp_estimator.cc
new file mode 100644
index 0000000..339635e
--- /dev/null
+++ b/webrtc/system_wrappers/source/rtp_to_ntp_estimator.cc
@@ -0,0 +1,188 @@
+/*
+ * 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 "webrtc/system_wrappers/include/rtp_to_ntp_estimator.h"
+
+#include "webrtc/base/logging.h"
+#include "webrtc/system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace {
+// Number of RTCP SR reports to use to map between RTP and NTP.
+const size_t kNumRtcpReportsToUse = 2;
+
+// Calculates the RTP timestamp frequency from two pairs of NTP/RTP timestamps.
+bool CalculateFrequency(int64_t ntp_ms1,
+ uint32_t rtp_timestamp1,
+ int64_t ntp_ms2,
+ uint32_t rtp_timestamp2,
+ double* frequency_khz) {
+ if (ntp_ms1 <= ntp_ms2)
+ return false;
+
+ *frequency_khz = static_cast<double>(rtp_timestamp1 - rtp_timestamp2) /
+ static_cast<double>(ntp_ms1 - ntp_ms2);
+ return true;
+}
+
+// Detects if there has been a wraparound between |old_timestamp| and
+// |new_timestamp|, and compensates by adding 2^32 if that is the case.
+bool CompensateForWrapAround(uint32_t new_timestamp,
+ uint32_t old_timestamp,
+ int64_t* compensated_timestamp) {
+ int64_t wraps = CheckForWrapArounds(new_timestamp, old_timestamp);
+ if (wraps < 0) {
+ // Reordering, don't use this packet.
+ return false;
+ }
+ *compensated_timestamp = new_timestamp + (wraps << 32);
+ return true;
+}
+
+bool Contains(const std::list<RtpToNtpEstimator::RtcpMeasurement>& measurements,
+ const RtpToNtpEstimator::RtcpMeasurement& other) {
+ for (const auto& measurement : measurements) {
+ if (measurement.IsEqual(other))
+ return true;
+ }
+ return false;
+}
+
+bool IsValid(const std::list<RtpToNtpEstimator::RtcpMeasurement>& measurements,
+ const RtpToNtpEstimator::RtcpMeasurement& other) {
+ if (!other.ntp_time.Valid())
+ return false;
+
+ int64_t ntp_ms_new = other.ntp_time.ToMs();
+ for (const auto& measurement : measurements) {
+ if (ntp_ms_new <= measurement.ntp_time.ToMs()) {
+ // Old report.
+ return false;
+ }
+ int64_t timestamp_new = other.rtp_timestamp;
+ if (!CompensateForWrapAround(timestamp_new, measurement.rtp_timestamp,
+ ×tamp_new)) {
+ return false;
+ }
+ if (timestamp_new <= measurement.rtp_timestamp) {
+ LOG(LS_WARNING) << "Newer RTCP SR report with older RTP timestamp.";
+ return false;
+ }
+ }
+ return true;
+}
+} // namespace
+
+RtpToNtpEstimator::RtcpMeasurement::RtcpMeasurement(uint32_t ntp_secs,
+ uint32_t ntp_frac,
+ uint32_t timestamp)
+ : ntp_time(ntp_secs, ntp_frac), rtp_timestamp(timestamp) {}
+
+bool RtpToNtpEstimator::RtcpMeasurement::IsEqual(
+ const RtcpMeasurement& other) const {
+ // Use || since two equal timestamps will result in zero frequency and in
+ // RtpToNtpMs, |rtp_timestamp_ms| is estimated by dividing by the frequency.
+ return (ntp_time == other.ntp_time) || (rtp_timestamp == other.rtp_timestamp);
+}
+
+// Class for converting an RTP timestamp to the NTP domain.
+RtpToNtpEstimator::RtpToNtpEstimator() {}
+RtpToNtpEstimator::~RtpToNtpEstimator() {}
+
+void RtpToNtpEstimator::UpdateParameters() {
+ if (measurements_.size() != kNumRtcpReportsToUse)
+ return;
+
+ int64_t timestamp_new = measurements_.front().rtp_timestamp;
+ int64_t timestamp_old = measurements_.back().rtp_timestamp;
+ if (!CompensateForWrapAround(timestamp_new, timestamp_old, ×tamp_new))
+ return;
+
+ int64_t ntp_ms_new = measurements_.front().ntp_time.ToMs();
+ int64_t ntp_ms_old = measurements_.back().ntp_time.ToMs();
+
+ if (!CalculateFrequency(ntp_ms_new, timestamp_new, ntp_ms_old, timestamp_old,
+ ¶ms_.frequency_khz)) {
+ return;
+ }
+ params_.offset_ms = timestamp_new - params_.frequency_khz * ntp_ms_new;
+ params_.calculated = true;
+}
+
+bool RtpToNtpEstimator::UpdateMeasurements(uint32_t ntp_secs,
+ uint32_t ntp_frac,
+ uint32_t rtp_timestamp,
+ bool* new_rtcp_sr) {
+ *new_rtcp_sr = false;
+
+ RtcpMeasurement measurement(ntp_secs, ntp_frac, rtp_timestamp);
+ if (Contains(measurements_, measurement)) {
+ // RTCP SR report already added.
+ return true;
+ }
+ if (!IsValid(measurements_, measurement)) {
+ // Old report or invalid parameters.
+ return false;
+ }
+
+ // Insert new RTCP SR report.
+ if (measurements_.size() == kNumRtcpReportsToUse)
+ measurements_.pop_back();
+
+ measurements_.push_front(measurement);
+ *new_rtcp_sr = true;
+
+ // List updated, calculate new parameters.
+ UpdateParameters();
+ return true;
+}
+
+bool RtpToNtpEstimator::Estimate(int64_t rtp_timestamp,
+ int64_t* rtp_timestamp_ms) const {
+ if (!params_.calculated || measurements_.empty())
+ return false;
+
+ uint32_t rtp_timestamp_old = measurements_.back().rtp_timestamp;
+ int64_t rtp_timestamp_unwrapped;
+ if (!CompensateForWrapAround(rtp_timestamp, rtp_timestamp_old,
+ &rtp_timestamp_unwrapped)) {
+ return false;
+ }
+
+ double rtp_ms =
+ (static_cast<double>(rtp_timestamp_unwrapped) - params_.offset_ms) /
+ params_.frequency_khz +
+ 0.5f;
+
+ if (rtp_ms < 0)
+ return false;
+
+ *rtp_timestamp_ms = rtp_ms;
+ return true;
+}
+
+int CheckForWrapArounds(uint32_t new_timestamp, uint32_t old_timestamp) {
+ if (new_timestamp < old_timestamp) {
+ // This difference should be less than -2^31 if we have had a wrap around
+ // (e.g. |new_timestamp| = 1, |rtcp_rtp_timestamp| = 2^32 - 1). Since it is
+ // cast to a int32_t, it should be positive.
+ if (static_cast<int32_t>(new_timestamp - old_timestamp) > 0) {
+ // Forward wrap around.
+ return 1;
+ }
+ } else if (static_cast<int32_t>(old_timestamp - new_timestamp) > 0) {
+ // This difference should be less than -2^31 if we have had a backward wrap
+ // around. Since it is cast to a int32_t, it should be positive.
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace webrtc
diff --git a/webrtc/system_wrappers/source/rtp_to_ntp_estimator_unittest.cc b/webrtc/system_wrappers/source/rtp_to_ntp_estimator_unittest.cc
new file mode 100644
index 0000000..09b47b4
--- /dev/null
+++ b/webrtc/system_wrappers/source/rtp_to_ntp_estimator_unittest.cc
@@ -0,0 +1,252 @@
+/*
+ * 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 "webrtc/system_wrappers/include/rtp_to_ntp_estimator.h"
+#include "webrtc/test/gtest.h"
+
+namespace webrtc {
+namespace {
+const uint32_t kOneMsInNtpFrac = 4294967;
+const uint32_t kTimestampTicksPerMs = 90;
+} // namespace
+
+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_OldRtpTimestamp) {
+ RtpToNtpEstimator estimator;
+ bool new_sr;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 1;
+ uint32_t timestamp = 0;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp -= kTimestampTicksPerMs;
+ // Expected to fail since the older RTCP has a smaller RTP timestamp than the
+ // newer (old:0, new:4294967206).
+ EXPECT_FALSE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+}
+
+TEST(WrapAroundTests, NewRtcpWrapped) {
+ RtpToNtpEstimator estimator;
+ bool new_sr;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 1;
+ uint32_t timestamp = 0xFFFFFFFF;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ int64_t timestamp_ms = -1;
+ EXPECT_TRUE(estimator.Estimate(0xFFFFFFFF, ×tamp_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_ms);
+}
+
+TEST(WrapAroundTests, RtpWrapped) {
+ RtpToNtpEstimator estimator;
+ bool new_sr;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 1;
+ uint32_t timestamp = 0xFFFFFFFF - 2 * kTimestampTicksPerMs;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+
+ int64_t timestamp_ms = -1;
+ EXPECT_TRUE(estimator.Estimate(0xFFFFFFFF - 2 * kTimestampTicksPerMs,
+ ×tamp_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_ms);
+ // Two kTimestampTicksPerMs advanced.
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
+ EXPECT_EQ(2, timestamp_ms);
+ // Wrapped rtp.
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
+ EXPECT_EQ(3, timestamp_ms);
+}
+
+TEST(WrapAroundTests, OldRtp_RtcpsWrapped) {
+ RtpToNtpEstimator estimator;
+ bool new_sr;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 1;
+ uint32_t timestamp = 0;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ timestamp -= 2 * kTimestampTicksPerMs;
+ int64_t timestamp_ms = -1;
+ EXPECT_FALSE(estimator.Estimate(timestamp, ×tamp_ms));
+}
+
+TEST(WrapAroundTests, OldRtp_NewRtcpWrapped) {
+ RtpToNtpEstimator estimator;
+ bool new_sr;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 1;
+ uint32_t timestamp = 0xFFFFFFFF;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ timestamp -= kTimestampTicksPerMs;
+ int64_t timestamp_ms = -1;
+ EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
+ // Constructed at the same time as the first RTCP and should therefore be
+ // mapped to zero.
+ EXPECT_EQ(0, timestamp_ms);
+}
+
+TEST(UpdateRtcpMeasurementTests, FailsForZeroNtp) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 0;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_FALSE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_FALSE(new_sr);
+}
+
+TEST(UpdateRtcpMeasurementTests, FailsForEqualNtp) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 699925050;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(new_sr);
+ // Ntp time already added, list not updated.
+ ++timestamp;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_FALSE(new_sr);
+}
+
+TEST(UpdateRtcpMeasurementTests, FailsForOldNtp) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 1;
+ uint32_t ntp_frac = 699925050;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(new_sr);
+ // Old ntp time, list not updated.
+ ntp_frac -= kOneMsInNtpFrac;
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_FALSE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+}
+
+TEST(UpdateRtcpMeasurementTests, FailsForEqualTimestamp) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 2;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(new_sr);
+ // Timestamp already added, list not updated.
+ ++ntp_frac;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_FALSE(new_sr);
+}
+
+TEST(UpdateRtcpMeasurementTests, FailsForOldRtpTimestamp) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 0;
+ uint32_t ntp_frac = 2;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(new_sr);
+ // Old timestamp, list not updated.
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp -= kTimestampTicksPerMs;
+ EXPECT_FALSE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_FALSE(new_sr);
+}
+
+TEST(UpdateRtcpMeasurementTests, VerifyParameters) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 1;
+ uint32_t ntp_frac = 2;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(new_sr);
+ EXPECT_FALSE(estimator.params().calculated);
+ // Add second report, parameters should be calculated.
+ ntp_frac += kOneMsInNtpFrac;
+ timestamp += kTimestampTicksPerMs;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(estimator.params().calculated);
+ EXPECT_DOUBLE_EQ(90.0, estimator.params().frequency_khz);
+ EXPECT_NE(0.0, estimator.params().offset_ms);
+}
+
+TEST(RtpToNtpTests, FailsForNoParameters) {
+ RtpToNtpEstimator estimator;
+ uint32_t ntp_sec = 1;
+ uint32_t ntp_frac = 2;
+ uint32_t timestamp = 0x12345678;
+ bool new_sr;
+ EXPECT_TRUE(
+ estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
+ EXPECT_TRUE(new_sr);
+ // Parameters are not calculated, conversion of RTP to NTP time should fail.
+ EXPECT_FALSE(estimator.params().calculated);
+ int64_t timestamp_ms = -1;
+ EXPECT_FALSE(estimator.Estimate(timestamp, ×tamp_ms));
+}
+
+}; // namespace webrtc
diff --git a/webrtc/system_wrappers/source/rtp_to_ntp_unittest.cc b/webrtc/system_wrappers/source/rtp_to_ntp_unittest.cc
deleted file mode 100644
index bdaaa7d..0000000
--- a/webrtc/system_wrappers/source/rtp_to_ntp_unittest.cc
+++ /dev/null
@@ -1,273 +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 "webrtc/system_wrappers/include/rtp_to_ntp.h"
-#include "webrtc/test/gtest.h"
-
-namespace webrtc {
-namespace {
-const uint32_t kOneMsInNtpFrac = 4294967;
-const uint32_t kTimestampTicksPerMs = 90;
-} // namespace
-
-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_OldRtpTimestamp) {
- RtcpMeasurements rtcp;
- bool new_sr;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 1;
- uint32_t timestamp = 0;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- ntp_frac += kOneMsInNtpFrac;
- timestamp -= kTimestampTicksPerMs;
- // Expected to fail since the older RTCP has a smaller RTP timestamp than the
- // newer (old:0, new:4294967206).
- EXPECT_FALSE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
-}
-
-TEST(WrapAroundTests, NewRtcpWrapped) {
- RtcpMeasurements rtcp;
- bool new_sr;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 1;
- uint32_t timestamp = 0xFFFFFFFF;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- ntp_frac += kOneMsInNtpFrac;
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- int64_t timestamp_ms = -1;
- EXPECT_TRUE(RtpToNtpMs(rtcp.list.back().rtp_timestamp, rtcp, ×tamp_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_ms);
-}
-
-TEST(WrapAroundTests, RtpWrapped) {
- RtcpMeasurements rtcp;
- bool new_sr;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 1;
- uint32_t timestamp = 0xFFFFFFFF - 2 * kTimestampTicksPerMs;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- ntp_frac += kOneMsInNtpFrac;
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
-
- int64_t timestamp_ms = -1;
- EXPECT_TRUE(RtpToNtpMs(rtcp.list.back().rtp_timestamp, rtcp, ×tamp_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_ms);
- // Two kTimestampTicksPerMs advanced.
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(RtpToNtpMs(timestamp, rtcp, ×tamp_ms));
- EXPECT_EQ(2, timestamp_ms);
- // Wrapped rtp.
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(RtpToNtpMs(timestamp, rtcp, ×tamp_ms));
- EXPECT_EQ(3, timestamp_ms);
-}
-
-TEST(WrapAroundTests, OldRtp_RtcpsWrapped) {
- RtcpMeasurements rtcp;
- bool new_sr;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 1;
- uint32_t timestamp = 0;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- ntp_frac += kOneMsInNtpFrac;
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- timestamp -= 2*kTimestampTicksPerMs;
- int64_t timestamp_ms = -1;
- EXPECT_FALSE(RtpToNtpMs(timestamp, rtcp, ×tamp_ms));
-}
-
-TEST(WrapAroundTests, OldRtp_NewRtcpWrapped) {
- RtcpMeasurements rtcp;
- bool new_sr;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 1;
- uint32_t timestamp = 0xFFFFFFFF;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- ntp_frac += kOneMsInNtpFrac;
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- timestamp -= kTimestampTicksPerMs;
- int64_t timestamp_ms = -1;
- EXPECT_TRUE(RtpToNtpMs(timestamp, rtcp, ×tamp_ms));
- // Constructed at the same time as the first RTCP and should therefore be
- // mapped to zero.
- EXPECT_EQ(0, timestamp_ms);
-}
-
-TEST(UpdateRtcpListTests, InjectRtcpSr) {
- const uint32_t kNtpSec = 10;
- const uint32_t kNtpFrac = 12345;
- const uint32_t kTs = 0x12345678;
- bool new_sr;
- RtcpMeasurements rtcp;
- EXPECT_TRUE(UpdateRtcpList(kNtpSec, kNtpFrac, kTs, &rtcp, &new_sr));
- EXPECT_TRUE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
- EXPECT_EQ(kNtpSec, rtcp.list.front().ntp_time.seconds());
- EXPECT_EQ(kNtpFrac, rtcp.list.front().ntp_time.fractions());
- EXPECT_EQ(kTs, rtcp.list.front().rtp_timestamp);
- // Add second report.
- EXPECT_TRUE(UpdateRtcpList(kNtpSec, kNtpFrac + kOneMsInNtpFrac, kTs + 1,
- &rtcp, &new_sr));
- EXPECT_EQ(2u, rtcp.list.size());
- EXPECT_EQ(kTs + 1, rtcp.list.front().rtp_timestamp);
- EXPECT_EQ(kTs + 0, rtcp.list.back().rtp_timestamp);
- // List should contain last two reports.
- EXPECT_TRUE(UpdateRtcpList(kNtpSec, kNtpFrac + 2 * kOneMsInNtpFrac, kTs + 2,
- &rtcp, &new_sr));
- EXPECT_EQ(2u, rtcp.list.size());
- EXPECT_EQ(kTs + 2, rtcp.list.front().rtp_timestamp);
- EXPECT_EQ(kTs + 1, rtcp.list.back().rtp_timestamp);
-}
-
-TEST(UpdateRtcpListTests, FailsForZeroNtp) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 0;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_FALSE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_FALSE(new_sr);
- EXPECT_EQ(0u, rtcp.list.size());
-}
-
-TEST(UpdateRtcpListTests, FailsForEqualNtp) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 699925050;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_TRUE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
- // Ntp time already added, list not updated.
- ++timestamp;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_FALSE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
-}
-
-TEST(UpdateRtcpListTests, FailsForOldNtp) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 1;
- uint32_t ntp_frac = 699925050;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_TRUE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
- // Old ntp time, list not updated.
- ntp_frac -= kOneMsInNtpFrac;
- timestamp += kTimestampTicksPerMs;
- EXPECT_FALSE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_EQ(1u, rtcp.list.size());
-}
-
-TEST(UpdateRtcpListTests, FailsForEqualTimestamp) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 2;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_TRUE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
- // Timestamp already added, list not updated.
- ++ntp_frac;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_FALSE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
-}
-
-TEST(UpdateRtcpListTests, FailsForOldRtpTimestamp) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 0;
- uint32_t ntp_frac = 2;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_TRUE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
- // Old timestamp, list not updated.
- ntp_frac += kOneMsInNtpFrac;
- timestamp -= kTimestampTicksPerMs;
- EXPECT_FALSE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_FALSE(new_sr);
- EXPECT_EQ(1u, rtcp.list.size());
-}
-
-TEST(UpdateRtcpListTests, VerifyParameters) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 1;
- uint32_t ntp_frac = 2;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_TRUE(new_sr);
- EXPECT_FALSE(rtcp.params.calculated);
- // Add second report, parameters should be calculated.
- ntp_frac += kOneMsInNtpFrac;
- timestamp += kTimestampTicksPerMs;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_TRUE(rtcp.params.calculated);
- EXPECT_DOUBLE_EQ(90.0, rtcp.params.frequency_khz);
- EXPECT_NE(0.0, rtcp.params.offset_ms);
-}
-
-TEST(RtpToNtpTests, FailsForEmptyList) {
- RtcpMeasurements rtcp;
- rtcp.params.calculated = true;
- // List is empty, conversion of RTP to NTP time should fail.
- EXPECT_EQ(0u, rtcp.list.size());
- int64_t timestamp_ms = -1;
- EXPECT_FALSE(RtpToNtpMs(0, rtcp, ×tamp_ms));
-}
-
-TEST(RtpToNtpTests, FailsForNoParameters) {
- RtcpMeasurements rtcp;
- uint32_t ntp_sec = 1;
- uint32_t ntp_frac = 2;
- uint32_t timestamp = 0x12345678;
- bool new_sr;
- EXPECT_TRUE(UpdateRtcpList(ntp_sec, ntp_frac, timestamp, &rtcp, &new_sr));
- EXPECT_EQ(1u, rtcp.list.size());
- // Parameters are not calculated, conversion of RTP to NTP time should fail.
- EXPECT_FALSE(rtcp.params.calculated);
- int64_t timestamp_ms = -1;
- EXPECT_FALSE(RtpToNtpMs(timestamp, rtcp, ×tamp_ms));
-}
-
-}; // namespace webrtc
diff --git a/webrtc/video/rtp_streams_synchronizer.cc b/webrtc/video/rtp_streams_synchronizer.cc
index d7fd949..0d026b3 100644
--- a/webrtc/video/rtp_streams_synchronizer.cc
+++ b/webrtc/video/rtp_streams_synchronizer.cc
@@ -41,8 +41,8 @@
}
bool new_rtcp_sr = false;
- if (!UpdateRtcpList(ntp_secs, ntp_frac, rtp_timestamp, &stream->rtcp,
- &new_rtcp_sr)) {
+ if (!stream->rtp_to_ntp.UpdateMeasurements(ntp_secs, ntp_frac, rtp_timestamp,
+ &new_rtcp_sr)) {
return false;
}
@@ -183,14 +183,14 @@
}
int64_t latest_audio_ntp;
- if (!RtpToNtpMs(playout_timestamp, audio_measurement_.rtcp,
- &latest_audio_ntp)) {
+ if (!audio_measurement_.rtp_to_ntp.Estimate(playout_timestamp,
+ &latest_audio_ntp)) {
return false;
}
int64_t latest_video_ntp;
- if (!RtpToNtpMs(frame.timestamp(), video_measurement_.rtcp,
- &latest_video_ntp)) {
+ if (!video_measurement_.rtp_to_ntp.Estimate(frame.timestamp(),
+ &latest_video_ntp)) {
return false;
}
@@ -200,7 +200,7 @@
latest_video_ntp += time_to_render_ms;
*stream_offset_ms = latest_audio_ntp - latest_video_ntp;
- *estimated_freq_khz = video_measurement_.rtcp.params.frequency_khz;
+ *estimated_freq_khz = video_measurement_.rtp_to_ntp.params().frequency_khz;
return true;
}
diff --git a/webrtc/video/stream_synchronization.cc b/webrtc/video/stream_synchronization.cc
index ff38973..145922c 100644
--- a/webrtc/video/stream_synchronization.cc
+++ b/webrtc/video/stream_synchronization.cc
@@ -40,15 +40,13 @@
int* relative_delay_ms) {
assert(relative_delay_ms);
int64_t audio_last_capture_time_ms;
- if (!RtpToNtpMs(audio_measurement.latest_timestamp,
- audio_measurement.rtcp,
- &audio_last_capture_time_ms)) {
+ if (!audio_measurement.rtp_to_ntp.Estimate(audio_measurement.latest_timestamp,
+ &audio_last_capture_time_ms)) {
return false;
}
int64_t video_last_capture_time_ms;
- if (!RtpToNtpMs(video_measurement.latest_timestamp,
- video_measurement.rtcp,
- &video_last_capture_time_ms)) {
+ if (!video_measurement.rtp_to_ntp.Estimate(video_measurement.latest_timestamp,
+ &video_last_capture_time_ms)) {
return false;
}
if (video_last_capture_time_ms < 0) {
diff --git a/webrtc/video/stream_synchronization.h b/webrtc/video/stream_synchronization.h
index c700ee3..0b1ad4f 100644
--- a/webrtc/video/stream_synchronization.h
+++ b/webrtc/video/stream_synchronization.h
@@ -13,7 +13,7 @@
#include <list>
-#include "webrtc/system_wrappers/include/rtp_to_ntp.h"
+#include "webrtc/system_wrappers/include/rtp_to_ntp_estimator.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -21,8 +21,8 @@
class StreamSynchronization {
public:
struct Measurements {
- Measurements() : rtcp(), latest_receive_time_ms(0), latest_timestamp(0) {}
- RtcpMeasurements rtcp;
+ Measurements() : latest_receive_time_ms(0), latest_timestamp(0) {}
+ RtpToNtpEstimator rtp_to_ntp;
int64_t latest_receive_time_ms;
uint32_t latest_timestamp;
};
diff --git a/webrtc/video/stream_synchronization_unittest.cc b/webrtc/video/stream_synchronization_unittest.cc
index 770bbf6..d5607a8 100644
--- a/webrtc/video/stream_synchronization_unittest.cc
+++ b/webrtc/video/stream_synchronization_unittest.cc
@@ -34,13 +34,6 @@
: kNtpJan1970(2208988800UL),
time_now_ms_(offset) {}
- RtcpMeasurement GenerateRtcp(int frequency, uint32_t offset) const {
- RtcpMeasurement rtcp;
- rtcp.ntp_time = GetNowNtp();
- rtcp.rtp_timestamp = GetNowRtp(frequency, offset);
- return rtcp;
- }
-
NtpTime GetNowNtp() const {
uint32_t ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
int64_t remainder_ms = time_now_ms_ % 1000;
@@ -104,29 +97,29 @@
StreamSynchronization::Measurements audio;
StreamSynchronization::Measurements video;
// Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
- RtcpMeasurement rtcp =
- send_time_->GenerateRtcp(audio_frequency, audio_offset);
- EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_time.seconds(),
- rtcp.ntp_time.fractions(), rtcp.rtp_timestamp,
- &audio.rtcp, &new_sr));
+ NtpTime ntp_time = send_time_->GetNowNtp();
+ uint32_t rtp_timestamp =
+ send_time_->GetNowRtp(audio_frequency, audio_offset);
+ EXPECT_TRUE(audio.rtp_to_ntp.UpdateMeasurements(
+ ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
send_time_->IncreaseTimeMs(100);
receive_time_->IncreaseTimeMs(100);
- rtcp = send_time_->GenerateRtcp(video_frequency, video_offset);
- EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_time.seconds(),
- rtcp.ntp_time.fractions(), rtcp.rtp_timestamp,
- &video.rtcp, &new_sr));
+ ntp_time = send_time_->GetNowNtp();
+ rtp_timestamp = send_time_->GetNowRtp(video_frequency, video_offset);
+ EXPECT_TRUE(video.rtp_to_ntp.UpdateMeasurements(
+ ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
send_time_->IncreaseTimeMs(900);
receive_time_->IncreaseTimeMs(900);
- rtcp = send_time_->GenerateRtcp(audio_frequency, audio_offset);
- EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_time.seconds(),
- rtcp.ntp_time.fractions(), rtcp.rtp_timestamp,
- &audio.rtcp, &new_sr));
+ ntp_time = send_time_->GetNowNtp();
+ rtp_timestamp = send_time_->GetNowRtp(audio_frequency, audio_offset);
+ EXPECT_TRUE(audio.rtp_to_ntp.UpdateMeasurements(
+ ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
send_time_->IncreaseTimeMs(100);
receive_time_->IncreaseTimeMs(100);
- rtcp = send_time_->GenerateRtcp(video_frequency, video_offset);
- EXPECT_TRUE(UpdateRtcpList(rtcp.ntp_time.seconds(),
- rtcp.ntp_time.fractions(), rtcp.rtp_timestamp,
- &video.rtcp, &new_sr));
+ ntp_time = send_time_->GetNowNtp();
+ rtp_timestamp = send_time_->GetNowRtp(video_frequency, video_offset);
+ EXPECT_TRUE(video.rtp_to_ntp.UpdateMeasurements(
+ ntp_time.seconds(), ntp_time.fractions(), rtp_timestamp, &new_sr));
send_time_->IncreaseTimeMs(900);
receive_time_->IncreaseTimeMs(900);