diff options
-rw-r--r-- | modules/rtp_rtcp/BUILD.gn | 1 | ||||
-rw-r--r-- | modules/rtp_rtcp/include/remote_ntp_time_estimator.h | 3 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/remote_ntp_time_estimator.cc | 39 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc | 67 | ||||
-rw-r--r-- | system_wrappers/BUILD.gn | 5 | ||||
-rw-r--r-- | system_wrappers/include/rtp_to_ntp_estimator.h | 27 | ||||
-rw-r--r-- | system_wrappers/source/rtp_to_ntp_estimator.cc | 68 |
7 files changed, 31 insertions, 179 deletions
diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index c391d31690..9f9de961c5 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -197,7 +197,6 @@ rtc_static_library("rtp_rtcp") { "../../logging:rtc_event_log_api", "../../rtc_base:gtest_prod", "../../rtc_base:rtc_base_approved", - "../../rtc_base:rtc_numerics", "../../rtc_base:sequenced_task_checker", "../../system_wrappers", "../audio_coding:audio_format_conversion", diff --git a/modules/rtp_rtcp/include/remote_ntp_time_estimator.h b/modules/rtp_rtcp/include/remote_ntp_time_estimator.h index 98665155f2..ef0ccdf891 100644 --- a/modules/rtp_rtcp/include/remote_ntp_time_estimator.h +++ b/modules/rtp_rtcp/include/remote_ntp_time_estimator.h @@ -14,7 +14,6 @@ #include <memory> #include "rtc_base/constructormagic.h" -#include "rtc_base/numerics/moving_median_filter.h" #include "system_wrappers/include/rtp_to_ntp_estimator.h" namespace webrtc { @@ -44,10 +43,8 @@ class RemoteNtpTimeEstimator { private: Clock* clock_; std::unique_ptr<TimestampExtrapolator> ts_extrapolator_; - MovingMedianFilter<int64_t> ntp_clocks_offset_estimator_; RtpToNtpEstimator rtp_to_ntp_; int64_t last_timing_log_ms_; - const bool is_experiment_enabled_; RTC_DISALLOW_COPY_AND_ASSIGN(RemoteNtpTimeEstimator); }; diff --git a/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc b/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc index 7b049465bc..06f17a1463 100644 --- a/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc +++ b/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc @@ -12,28 +12,19 @@ #include "rtc_base/logging.h" #include "system_wrappers/include/clock.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/timestamp_extrapolator.h" namespace webrtc { -namespace { static const int kTimingLogIntervalMs = 10000; -static const int kClocksOffsetSmoothingWindow = 100; - -bool IsClockEstimationExperimentEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-ClockEstimation"); -} -} // namespace // TODO(wu): Refactor this class so that it can be shared with // vie_sync_module.cc. RemoteNtpTimeEstimator::RemoteNtpTimeEstimator(Clock* clock) : clock_(clock), ts_extrapolator_(new TimestampExtrapolator(clock_->TimeInMilliseconds())), - ntp_clocks_offset_estimator_(kClocksOffsetSmoothingWindow), - last_timing_log_ms_(-1), - is_experiment_enabled_(IsClockEstimationExperimentEnabled()) {} + last_timing_log_ms_(-1) { +} RemoteNtpTimeEstimator::~RemoteNtpTimeEstimator() {} @@ -50,18 +41,12 @@ bool RemoteNtpTimeEstimator::UpdateRtcpTimestamp(int64_t rtt, // No new RTCP SR since last time this function was called. return true; } - // Update extrapolator with the new arrival time. // The extrapolator assumes the TimeInMilliseconds time. int64_t receiver_arrival_time_ms = clock_->TimeInMilliseconds(); int64_t sender_send_time_ms = Clock::NtpToMs(ntp_secs, ntp_frac); int64_t sender_arrival_time_90k = (sender_send_time_ms + rtt / 2) * 90; ts_extrapolator_->Update(receiver_arrival_time_ms, sender_arrival_time_90k); - - int64_t sender_arrival_time_ms = sender_send_time_ms + rtt / 2; - int64_t remote_to_local_clocks_offset = - receiver_arrival_time_ms - sender_arrival_time_ms; - ntp_clocks_offset_estimator_.Insert(remote_to_local_clocks_offset); return true; } @@ -70,21 +55,13 @@ int64_t RemoteNtpTimeEstimator::Estimate(uint32_t rtp_timestamp) { if (!rtp_to_ntp_.Estimate(rtp_timestamp, &sender_capture_ntp_ms)) { return -1; } - - int64_t receiver_capture_ms; - - if (is_experiment_enabled_) { - int64_t remote_to_local_clocks_offset = - ntp_clocks_offset_estimator_.GetFilteredValue(); - receiver_capture_ms = sender_capture_ntp_ms + remote_to_local_clocks_offset; - } else { - uint32_t timestamp = sender_capture_ntp_ms * 90; - receiver_capture_ms = ts_extrapolator_->ExtrapolateLocalTime(timestamp); - } - int64_t now_ms = clock_->TimeInMilliseconds(); - int64_t ntp_offset = clock_->CurrentNtpInMilliseconds() - now_ms; + uint32_t timestamp = sender_capture_ntp_ms * 90; + int64_t receiver_capture_ms = + ts_extrapolator_->ExtrapolateLocalTime(timestamp); + int64_t ntp_offset = + clock_->CurrentNtpInMilliseconds() - clock_->TimeInMilliseconds(); int64_t receiver_capture_ntp_ms = receiver_capture_ms + ntp_offset; - + int64_t now_ms = clock_->TimeInMilliseconds(); if (now_ms - last_timing_log_ms_ > kTimingLogIntervalMs) { RTC_LOG(LS_INFO) << "RTP timestamp: " << rtp_timestamp << " in NTP clock: " << sender_capture_ntp_ms diff --git a/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc b/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc index 410085e1d1..9812f26db0 100644 --- a/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc +++ b/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc @@ -8,10 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h" #include "common_types.h" // NOLINT(build/include) +#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h" #include "system_wrappers/include/clock.h" -#include "test/field_trial.h" #include "test/gmock.h" #include "test/gtest.h" @@ -32,7 +31,7 @@ class RemoteNtpTimeEstimatorTest : public ::testing::Test { RemoteNtpTimeEstimatorTest() : local_clock_(kLocalClockInitialTimeMs * 1000), remote_clock_(kRemoteClockInitialTimeMs * 1000), - estimator_(new RemoteNtpTimeEstimator(&local_clock_)) {} + estimator_(&local_clock_) {} ~RemoteNtpTimeEstimatorTest() {} void AdvanceTimeMilliseconds(int64_t ms) { @@ -53,21 +52,11 @@ class RemoteNtpTimeEstimatorTest : public ::testing::Test { ReceiveRtcpSr(kTestRtt, rtcp_timestamp, ntp.seconds(), ntp.fractions()); } - void SendRtcpSrInaccurately(int64_t ntp_error_ms, - int64_t networking_delay_ms) { - uint32_t rtcp_timestamp = GetRemoteTimestamp(); - int64_t ntp_error_fractions = - ntp_error_ms * NtpTime::kFractionsPerSecond / 1000; - NtpTime ntp(static_cast<uint64_t>(remote_clock_.CurrentNtpTime()) + - ntp_error_fractions); - AdvanceTimeMilliseconds(kTestRtt / 2 + networking_delay_ms); - ReceiveRtcpSr(kTestRtt, rtcp_timestamp, ntp.seconds(), ntp.fractions()); - } - void UpdateRtcpTimestamp(int64_t rtt, uint32_t ntp_secs, uint32_t ntp_frac, uint32_t rtp_timestamp, bool expected_result) { - EXPECT_EQ(expected_result, estimator_->UpdateRtcpTimestamp( - rtt, ntp_secs, ntp_frac, rtp_timestamp)); + EXPECT_EQ(expected_result, + estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, + rtp_timestamp)); } void ReceiveRtcpSr(int64_t rtt, @@ -79,7 +68,7 @@ class RemoteNtpTimeEstimatorTest : public ::testing::Test { SimulatedClock local_clock_; SimulatedClock remote_clock_; - std::unique_ptr<RemoteNtpTimeEstimator> estimator_; + RemoteNtpTimeEstimator estimator_; }; TEST_F(RemoteNtpTimeEstimatorTest, Estimate) { @@ -97,54 +86,14 @@ TEST_F(RemoteNtpTimeEstimatorTest, Estimate) { // Local peer needs at least 2 RTCP SR to calculate the capture time. const int64_t kNotEnoughRtcpSr = -1; - EXPECT_EQ(kNotEnoughRtcpSr, estimator_->Estimate(rtp_timestamp)); + EXPECT_EQ(kNotEnoughRtcpSr, estimator_.Estimate(rtp_timestamp)); AdvanceTimeMilliseconds(800); // Remote sends second RTCP SR. SendRtcpSr(); // Local peer gets enough RTCP SR to calculate the capture time. - EXPECT_EQ(capture_ntp_time_ms, estimator_->Estimate(rtp_timestamp)); -} - -TEST_F(RemoteNtpTimeEstimatorTest, AveragesErrorsOut) { - test::ScopedFieldTrials override_field_trials( - "WebRTC-ClockEstimation/Enabled/"); - // Reset estimator_ because it checks experiment status during construction. - estimator_.reset(new RemoteNtpTimeEstimator(&local_clock_)); - - // Remote peer sends first 5 RTCP SR without errors. - AdvanceTimeMilliseconds(1000); - SendRtcpSr(); - AdvanceTimeMilliseconds(1000); - SendRtcpSr(); - AdvanceTimeMilliseconds(1000); - SendRtcpSr(); - AdvanceTimeMilliseconds(1000); - SendRtcpSr(); - AdvanceTimeMilliseconds(1000); - SendRtcpSr(); - - AdvanceTimeMilliseconds(15); - uint32_t rtp_timestamp = GetRemoteTimestamp(); - int64_t capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds(); - - // Local peer gets enough RTCP SR to calculate the capture time. - EXPECT_EQ(capture_ntp_time_ms, estimator_->Estimate(rtp_timestamp)); - - // Remote sends corrupted RTCP SRs - AdvanceTimeMilliseconds(1000); - SendRtcpSrInaccurately(10, 10); - AdvanceTimeMilliseconds(1000); - SendRtcpSrInaccurately(-20, 5); - - // New RTP packet to estimate timestamp. - AdvanceTimeMilliseconds(150); - rtp_timestamp = GetRemoteTimestamp(); - capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds(); - - // Errors should be averaged out. - EXPECT_EQ(capture_ntp_time_ms, estimator_->Estimate(rtp_timestamp)); + EXPECT_EQ(capture_ntp_time_ms, estimator_.Estimate(rtp_timestamp)); } } // namespace webrtc diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn index ca11b891aa..fb376fe3f6 100644 --- a/system_wrappers/BUILD.gn +++ b/system_wrappers/BUILD.gn @@ -101,10 +101,7 @@ rtc_static_library("system_wrappers") { suppressed_configs += [ "//build/config/clang:find_bad_constructs" ] } - deps += [ - "../rtc_base:rtc_base_approved", - "../rtc_base:rtc_numerics", - ] + deps += [ "../rtc_base:rtc_base_approved" ] } rtc_source_set("cpu_features_api") { diff --git a/system_wrappers/include/rtp_to_ntp_estimator.h b/system_wrappers/include/rtp_to_ntp_estimator.h index 3e858078e3..6aad545b16 100644 --- a/system_wrappers/include/rtp_to_ntp_estimator.h +++ b/system_wrappers/include/rtp_to_ntp_estimator.h @@ -15,7 +15,6 @@ #include "api/optional.h" #include "modules/include/module_common_types_public.h" -#include "rtc_base/numerics/moving_median_filter.h" #include "system_wrappers/include/ntp_time.h" #include "typedefs.h" // NOLINT(build/include) @@ -41,23 +40,8 @@ class RtpToNtpEstimator { // Estimated parameters from RTP and NTP timestamp pairs in |measurements_|. struct Parameters { - // Implicit conversion from int because MovingMedianFilter returns 0 - // internally if no samples are present. However, it should never happen as - // we don't ask smoothing_filter_ to return anything if there were no - // samples. - Parameters(const int& value) { // NOLINT - RTC_NOTREACHED(); - } - Parameters() : frequency_khz(0.0), offset_ms(0.0) {} - double frequency_khz; double offset_ms; - - // Needed to make it work inside MovingMedianFilter - bool operator<(const Parameters& other) const; - bool operator==(const Parameters& other) const; - bool operator<=(const Parameters& other) const; - bool operator!=(const Parameters& other) const; }; // Updates measurements with RTP/NTP timestamp pair from a RTCP sender report. @@ -71,8 +55,13 @@ class RtpToNtpEstimator { // Returns true on success, false otherwise. bool Estimate(int64_t rtp_timestamp, int64_t* rtp_timestamp_ms) const; - // Returns estimated rtp to ntp linear transform parameters. - const rtc::Optional<Parameters> params() const; + const rtc::Optional<Parameters> params() const { + rtc::Optional<Parameters> res; + if (params_calculated_) { + res.emplace(params_); + } + return res; + } static const int kMaxInvalidSamples = 3; @@ -82,10 +71,8 @@ class RtpToNtpEstimator { int consecutive_invalid_samples_; std::list<RtcpMeasurement> measurements_; Parameters params_; - MovingMedianFilter<Parameters> smoothing_filter_; bool params_calculated_; mutable TimestampUnwrapper unwrapper_; - const bool is_experiment_enabled_; }; } // namespace webrtc diff --git a/system_wrappers/source/rtp_to_ntp_estimator.cc b/system_wrappers/source/rtp_to_ntp_estimator.cc index 55cdfab402..cd33f32020 100644 --- a/system_wrappers/source/rtp_to_ntp_estimator.cc +++ b/system_wrappers/source/rtp_to_ntp_estimator.cc @@ -13,18 +13,11 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "system_wrappers/include/clock.h" -#include "system_wrappers/include/field_trial.h" namespace webrtc { namespace { // Number of RTCP SR reports to use to map between RTP and NTP. const size_t kNumRtcpReportsToUse = 2; -// Number of parameters samples used to smooth. -const size_t kNumSamplesToSmooth = 20; - -bool IsClockEstimationExperimentEnabled() { - return webrtc::field_trial::IsEnabled("WebRTC-ClockEstimation"); -} // Calculates the RTP timestamp frequency from two pairs of NTP/RTP timestamps. bool CalculateFrequency(int64_t ntp_ms1, @@ -50,28 +43,6 @@ bool Contains(const std::list<RtpToNtpEstimator::RtcpMeasurement>& measurements, } } // namespace -bool RtpToNtpEstimator::Parameters::operator<(const Parameters& other) const { - if (frequency_khz < other.frequency_khz - 1e-6) { - return true; - } else if (frequency_khz > other.frequency_khz + 1e-6) { - return false; - } else { - return offset_ms < other.offset_ms - 1e-6; - } -} - -bool RtpToNtpEstimator::Parameters::operator==(const Parameters& other) const { - return !(other < *this || *this < other); -} - -bool RtpToNtpEstimator::Parameters::operator!=(const Parameters& other) const { - return other < *this || *this < other; -} - -bool RtpToNtpEstimator::Parameters::operator<=(const Parameters& other) const { - return !(other < *this); -} - RtpToNtpEstimator::RtcpMeasurement::RtcpMeasurement(uint32_t ntp_secs, uint32_t ntp_frac, int64_t unwrapped_timestamp) @@ -88,18 +59,13 @@ bool RtpToNtpEstimator::RtcpMeasurement::IsEqual( // Class for converting an RTP timestamp to the NTP domain. RtpToNtpEstimator::RtpToNtpEstimator() - : consecutive_invalid_samples_(0), - smoothing_filter_(kNumSamplesToSmooth), - params_calculated_(false), - is_experiment_enabled_(IsClockEstimationExperimentEnabled()) {} - + : consecutive_invalid_samples_(0), params_calculated_(false) {} RtpToNtpEstimator::~RtpToNtpEstimator() {} void RtpToNtpEstimator::UpdateParameters() { if (measurements_.size() != kNumRtcpReportsToUse) return; - Parameters params; int64_t timestamp_new = measurements_.front().unwrapped_rtp_timestamp; int64_t timestamp_old = measurements_.back().unwrapped_rtp_timestamp; @@ -107,16 +73,11 @@ void RtpToNtpEstimator::UpdateParameters() { 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)) { + ¶ms_.frequency_khz)) { return; } - params.offset_ms = timestamp_new - params.frequency_khz * ntp_ms_new; + params_.offset_ms = timestamp_new - params_.frequency_khz * ntp_ms_new; params_calculated_ = true; - if (is_experiment_enabled_) { - smoothing_filter_.Insert(params); - } else { - params_ = params; - } } bool RtpToNtpEstimator::UpdateMeasurements(uint32_t ntp_secs, @@ -133,7 +94,6 @@ bool RtpToNtpEstimator::UpdateMeasurements(uint32_t ntp_secs, // RTCP SR report already added. return true; } - if (!new_measurement.ntp_time.Valid()) return false; @@ -162,7 +122,6 @@ bool RtpToNtpEstimator::UpdateMeasurements(uint32_t ntp_secs, RTC_LOG(LS_WARNING) << "Multiple consecutively invalid RTCP SR reports, " "clearing measurements."; measurements_.clear(); - smoothing_filter_.Reset(); params_calculated_ = false; } consecutive_invalid_samples_ = 0; @@ -186,15 +145,12 @@ bool RtpToNtpEstimator::Estimate(int64_t rtp_timestamp, int64_t rtp_timestamp_unwrapped = unwrapper_.Unwrap(rtp_timestamp); - Parameters params = - is_experiment_enabled_ ? smoothing_filter_.GetFilteredValue() : params_; - - // params_calculated_ should not be true unless ms params.frequency_khz has + // params_calculated_ should not be true unless ms params_.frequency_khz has // been calculated to something non zero. - RTC_DCHECK_NE(params.frequency_khz, 0.0); + RTC_DCHECK_NE(params_.frequency_khz, 0.0); double rtp_ms = - (static_cast<double>(rtp_timestamp_unwrapped) - params.offset_ms) / - params.frequency_khz + + (static_cast<double>(rtp_timestamp_unwrapped) - params_.offset_ms) / + params_.frequency_khz + 0.5f; if (rtp_ms < 0) @@ -203,14 +159,4 @@ bool RtpToNtpEstimator::Estimate(int64_t rtp_timestamp, *rtp_timestamp_ms = rtp_ms; return true; } - -const rtc::Optional<RtpToNtpEstimator::Parameters> RtpToNtpEstimator::params() - const { - rtc::Optional<Parameters> res; - if (params_calculated_) { - res.emplace(is_experiment_enabled_ ? smoothing_filter_.GetFilteredValue() - : params_); - } - return res; -} } // namespace webrtc |