blob: 6b13132f8a9eea2a0ddf6d3506d8fad67564e477 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CAST_STREAMING_NTP_TIME_H_
#define CAST_STREAMING_NTP_TIME_H_
#include <stdint.h>
#include "platform/api/time.h"
namespace openscreen {
namespace cast {
// NTP timestamps are 64-bit timestamps that consist of two 32-bit parts: 1) The
// number of seconds since 1 January 1900; and 2) The fraction of the second,
// where 0 maps to 0x00000000 and each unit increment represents another 2^-32
// seconds.
//
// Note that it is part of the design of NTP for the seconds part to roll around
// on 7 February 2036.
using NtpTimestamp = uint64_t;
// NTP fixed-point time math: Declare two std::chrono::duration types with the
// bit-width necessary to reliably perform all conversions to/from NTP format.
using NtpSeconds = std::chrono::duration<int64_t, std::chrono::seconds::period>;
using NtpFraction =
std::chrono::duration<int64_t, std::ratio<1, INT64_C(0x100000000)>>;
constexpr NtpSeconds NtpSecondsPart(NtpTimestamp timestamp) {
return NtpSeconds(timestamp >> 32);
}
constexpr NtpFraction NtpFractionPart(NtpTimestamp timestamp) {
return NtpFraction(timestamp & 0xffffffff);
}
constexpr NtpTimestamp AssembleNtpTimestamp(NtpSeconds seconds,
NtpFraction fraction) {
return (static_cast<uint64_t>(seconds.count()) << 32) |
static_cast<uint32_t>(fraction.count());
}
// Converts between Clock::time_points and NtpTimestamps. The class is
// instantiated with the current Clock time and the current wall clock time, and
// these are used to determine a fixed origin reference point for all
// conversions. Thus, to avoid introducing unintended timing-related behaviors,
// only one NtpTimeConverter instance should be used for converting all the NTP
// timestamps in the same streaming session.
class NtpTimeConverter {
public:
NtpTimeConverter(
Clock::time_point now,
std::chrono::seconds since_unix_epoch = GetWallTimeSinceUnixEpoch());
~NtpTimeConverter();
NtpTimestamp ToNtpTimestamp(Clock::time_point time_point) const;
Clock::time_point ToLocalTime(NtpTimestamp timestamp) const;
private:
// The time point on the platform clock's timeline that corresponds to
// approximately the same time point on the NTP timeline. Note that it is
// acceptable for the granularity of the NTP seconds value to be whole seconds
// here: Both a Cast Streaming Sender and Receiver will assume their clocks
// can be off (with respect to each other) by even a large amount; and all
// that matters is that time ticks forward at a reasonable pace from some
// initial point.
const Clock::time_point start_time_;
const NtpSeconds since_ntp_epoch_;
};
} // namespace cast
} // namespace openscreen
#endif // CAST_STREAMING_NTP_TIME_H_