Home | History | Annotate | Download | only in source
      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