1 /* 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h" 12 13 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 14 #include "webrtc/system_wrappers/interface/clock.h" 15 #include "webrtc/system_wrappers/interface/timestamp_extrapolator.h" 16 17 namespace webrtc { 18 19 // TODO(wu): Refactor this class so that it can be shared with 20 // vie_sync_module.cc. 21 RemoteNtpTimeEstimator::RemoteNtpTimeEstimator(Clock* clock) 22 : clock_(clock), 23 ts_extrapolator_( 24 new TimestampExtrapolator(clock_->TimeInMilliseconds())) { 25 } 26 27 RemoteNtpTimeEstimator::~RemoteNtpTimeEstimator() {} 28 29 bool RemoteNtpTimeEstimator::UpdateRtcpTimestamp(uint32_t ssrc, 30 RtpRtcp* rtp_rtcp) { 31 assert(rtp_rtcp); 32 uint16_t rtt = 0; 33 rtp_rtcp->RTT(ssrc, &rtt, NULL, NULL, NULL); 34 if (rtt == 0) { 35 // Waiting for valid rtt. 36 return true; 37 } 38 // Update RTCP list 39 uint32_t ntp_secs = 0; 40 uint32_t ntp_frac = 0; 41 uint32_t rtp_timestamp = 0; 42 if (0 != rtp_rtcp->RemoteNTP(&ntp_secs, 43 &ntp_frac, 44 NULL, 45 NULL, 46 &rtp_timestamp)) { 47 // Waiting for RTCP. 48 return true; 49 } 50 bool new_rtcp_sr = false; 51 if (!UpdateRtcpList( 52 ntp_secs, ntp_frac, rtp_timestamp, &rtcp_list_, &new_rtcp_sr)) { 53 return false; 54 } 55 if (!new_rtcp_sr) { 56 // No new RTCP SR since last time this function was called. 57 return true; 58 } 59 // Update extrapolator with the new arrival time. 60 // The extrapolator assumes the TimeInMilliseconds time. 61 int64_t receiver_arrival_time_ms = clock_->TimeInMilliseconds(); 62 int64_t sender_send_time_ms = Clock::NtpToMs(ntp_secs, ntp_frac); 63 int64_t sender_arrival_time_90k = (sender_send_time_ms + rtt / 2) * 90; 64 ts_extrapolator_->Update(receiver_arrival_time_ms, sender_arrival_time_90k); 65 return true; 66 } 67 68 int64_t RemoteNtpTimeEstimator::Estimate(uint32_t rtp_timestamp) { 69 if (rtcp_list_.size() < 2) { 70 // We need two RTCP SR reports to calculate NTP. 71 return -1; 72 } 73 int64_t sender_capture_ntp_ms = 0; 74 if (!RtpToNtpMs(rtp_timestamp, rtcp_list_, &sender_capture_ntp_ms)) { 75 return -1; 76 } 77 uint32_t timestamp = sender_capture_ntp_ms * 90; 78 int64_t receiver_capture_ms = 79 ts_extrapolator_->ExtrapolateLocalTime(timestamp); 80 int64_t ntp_offset = 81 clock_->CurrentNtpInMilliseconds() - clock_->TimeInMilliseconds(); 82 return receiver_capture_ms + ntp_offset; 83 } 84 85 } // namespace webrtc 86