chromium/third_party/openscreen/src/cast/streaming/rtp_time.h

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CAST_STREAMING_RTP_TIME_H_
#define CAST_STREAMING_RTP_TIME_H_

#include <stdint.h>

#include <chrono>
#include <cmath>
#include <limits>
#include <sstream>
#include <type_traits>

#include "cast/streaming/impl/expanded_value_base.h"
#include "platform/api/time.h"
#include "util/saturate_cast.h"

namespace openscreen::cast {

// Forward declarations (see below).
class RtpTimeDelta;
class RtpTimeTicks;

// Convenience operator overloads for logging.
std::ostream& operator<<(std::ostream& out, const RtpTimeDelta rhs);
std::ostream& operator<<(std::ostream& out, const RtpTimeTicks rhs);

// The difference between two RtpTimeTicks values.  This data type is modeled
// off of Chromium's base::TimeDelta, and used for performing compiler-checked
// arithmetic with RtpTimeTicks.
//
// This data type wraps a value, providing only the meaningful set of math
// operations that may be performed on the value.  RtpTimeDeltas may be
// added/subtracted with other RtpTimeDeltas to produce a RtpTimeDelta holding
// the sum/difference.  RtpTimeDeltas may also be multiplied or divided by
// integer amounts.  Finally, RtpTimeDeltas may be divided by other
// RtpTimeDeltas to compute a number of periods (trunc'ed to an integer), or
// modulo each other to determine a time period remainder.
//
// The base class provides bit truncation/extension features for
// wire-formatting, and also the comparison operators.
//
// Usage example:
//
//   // Time math.
//   RtpTimeDelta zero;
//   RtpTimeDelta one_second_later =
//       zero + RtpTimeDelta::FromTicks(kAudioSamplingRate);
//   RtpTimeDelta ten_seconds_later = one_second_later * 10;
//   int64_t ten_periods = ten_seconds_later / one_second_later;
//
//   // Logging convenience.
//   OSP_DLOG_INFO << "The RTP time offset is " << ten_seconds_later;
//
//   // Convert (approximately!) between RTP timebase and microsecond timebase:
//   RtpTimeDelta nine_seconds_in_rtp = ten_seconds_later - one_second_later;
//   using std::chrono::microseconds;
//   microseconds nine_seconds_duration =
//       nine_seconds_in_rtp.ToDuration<microseconds>(kAudioSamplingRate);
//   RtpTimeDelta two_seconds_in_rtp =
//       RtpTimeDelta::FromDuration(std::chrono::seconds(2),
//                                  kAudioSamplingRate);
class RtpTimeDelta : public ExpandedValueBase<int64_t, RtpTimeDelta> {};

// A media timestamp whose timebase matches the periodicity of the content
// (e.g., for audio, the timebase would be the sampling frequency).  This data
// type is modeled off of Chromium's base::TimeTicks.
//
// This data type wraps a value, providing only the meaningful set of math
// operations that may be performed on the value.  The difference between two
// RtpTimeTicks is a RtpTimeDelta.  Likewise, adding or subtracting a
// RtpTimeTicks with a RtpTimeDelta produces an off-set RtpTimeTicks.
//
// The base class provides bit truncation/extension features for
// wire-formatting, and also the comparison operators.
//
// Usage example:
//
//   // Time math.
//   RtpTimeTicks origin;
//   RtpTimeTicks at_one_second =
//       origin + RtpTimeDelta::FromTicks(kAudioSamplingRate);
//   RtpTimeTicks at_two_seconds =
//       at_one_second + RtpTimeDelta::FromTicks(kAudioSamplingRate);
//   RtpTimeDelta elasped_in_between = at_two_seconds - at_one_second;
//   RtpTimeDelta thrice_as_much_elasped = elasped_in_between * 3;
//   RtpTimeTicks at_four_seconds = at_one_second + thrice_as_much_elasped;
//
//   // Logging convenience.
//   OSP_DLOG_INFO << "The RTP timestamp is " << at_four_seconds;
//
//   // Convert (approximately!) between RTP timebase and stream time offsets in
//   // microsecond timebase:
//   using std::chrono::microseconds;
//   microseconds four_seconds_since_stream_start =
//       at_four_seconds.ToTimeSinceOrigin<microseconds>(kAudioSamplingRate);
//   RtpTimeTicks at_three_seconds = RtpTimeDelta::FromTimeSinceOrigin(
//       std::chrono::seconds(3), kAudioSamplingRate);
class RtpTimeTicks : public ExpandedValueBase<int64_t, RtpTimeTicks> {};

}  // namespace openscreen::cast

#endif  // CAST_STREAMING_RTP_TIME_H_