ntp_time_util.cc (2505B)
1 /* 2 * Copyright (c) 2016 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 "modules/rtp_rtcp/source/ntp_time_util.h" 12 13 #include <algorithm> 14 #include <cstdint> 15 16 #include "api/units/time_delta.h" 17 #include "rtc_base/numerics/divide_round.h" 18 #include "rtc_base/time_utils.h" 19 20 namespace webrtc { 21 22 uint32_t SaturatedToCompactNtp(TimeDelta delta) { 23 constexpr uint32_t kMaxCompactNtp = 0xFFFFFFFF; 24 constexpr int kCompactNtpInSecond = 0x10000; 25 if (delta <= TimeDelta::Zero()) 26 return 0; 27 if (delta.us() >= kMaxCompactNtp * kNumMicrosecsPerSec / kCompactNtpInSecond) 28 return kMaxCompactNtp; 29 // To convert to compact ntp need to divide by 1e6 to get seconds, 30 // then multiply by 0x10000 to get the final result. 31 // To avoid float operations, multiplication and division swapped. 32 return DivideRoundToNearest(delta.us() * kCompactNtpInSecond, 33 kNumMicrosecsPerSec); 34 } 35 36 TimeDelta CompactNtpIntervalToTimeDelta(uint32_t compact_ntp_interval) { 37 // Convert to 64bit value to avoid multiplication overflow. 38 int64_t value = int64_t{compact_ntp_interval}; 39 if (compact_ntp_interval > 0x8000'0000) { 40 value -= (int64_t{1} << 32); 41 } 42 // To convert to TimeDelta need to divide by 2^16 to get seconds, 43 // then multiply by 1'000'000 to get microseconds. To avoid float operations, 44 // multiplication and division are swapped. 45 int64_t us = DivideRoundToNearest(value * kNumMicrosecsPerSec, 1 << 16); 46 return TimeDelta::Micros(us); 47 } 48 49 TimeDelta CompactNtpRttToTimeDelta(uint32_t compact_ntp_interval) { 50 static constexpr TimeDelta kMinRtt = TimeDelta::Millis(1); 51 // Interval to convert expected to be positive, e.g. RTT or delay. 52 // Because interval can be derived from non-monotonic ntp clock, 53 // it might become negative that is indistinguishable from very large values. 54 // Since very large RTT/delay is less likely than non-monotonic ntp clock, 55 // such value is considered negative and converted to minimum value of 1ms. 56 // Small RTT value is considered too good to be true and increased to 1ms. 57 return std::max(CompactNtpIntervalToTimeDelta(compact_ntp_interval), kMinRtt); 58 } 59 } // namespace webrtc