Index: media/cast/common/rtp_time.h |
diff --git a/media/cast/common/rtp_time.h b/media/cast/common/rtp_time.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..79e625b6ed2e94ee80e2b8fabcdfbd0616aa35ea |
--- /dev/null |
+++ b/media/cast/common/rtp_time.h |
@@ -0,0 +1,197 @@ |
+// Copyright 2015 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 MEDIA_CAST_COMMON_RTP_TIME_H_ |
+#define MEDIA_CAST_COMMON_RTP_TIME_H_ |
+ |
+#include <stdint.h> |
+ |
+#include <limits> |
+#include <sstream> |
+ |
+#include "base/time/time.h" |
+#include "media/cast/common/expanded_value_base.h" |
+ |
+namespace media { |
+namespace 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 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 (floor'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. |
+// DLOG(INFO) << "The RTP time offset is " << ten_seconds_later; |
+// |
+// // Convert (approximately!) between RTP timebase and microsecond timebase: |
+// base::TimeDelta nine_seconds_offset = |
+// (ten_seconds_later - one_second_later).ToTimeDelta(kAudioSamplingRate); |
+// RtpTimeDelta nine_seconds_rtp = |
+// RtpTimeDelta::FromTimeDelta(nine_seconds_offset, kAudioSamplingRate); |
+class RtpTimeDelta : public ExpandedValueBase<int64_t, RtpTimeDelta> { |
+ public: |
+ RtpTimeDelta() : ExpandedValueBase(0) {} |
+ |
+ // Arithmetic operators (with other deltas). |
+ RtpTimeDelta operator+(RtpTimeDelta rhs) const { |
+ return RtpTimeDelta(value_ + rhs.value_); |
+ } |
+ RtpTimeDelta operator-(RtpTimeDelta rhs) const { |
+ return RtpTimeDelta(value_ - rhs.value_); |
+ } |
+ RtpTimeDelta& operator+=(RtpTimeDelta rhs) { return (*this = (*this + rhs)); } |
+ RtpTimeDelta& operator-=(RtpTimeDelta rhs) { return (*this = (*this - rhs)); } |
+ RtpTimeDelta operator-() const { return RtpTimeDelta(-value_); } |
+ |
+ // Multiplicative operators (with other deltas). |
+ int64_t operator/(RtpTimeDelta rhs) const { return value_ / rhs.value_; } |
+ RtpTimeDelta operator%(RtpTimeDelta rhs) const { |
+ return RtpTimeDelta(value_ % rhs.value_); |
+ } |
+ RtpTimeDelta& operator%=(RtpTimeDelta rhs) { return (*this = (*this % rhs)); } |
+ |
+ // Multiplicative operators (with integer types). |
+ template <typename IntType> |
+ RtpTimeDelta operator*(IntType rhs) const { |
+ static_assert(std::numeric_limits<IntType>::is_integer, |
+ "|rhs| must be a POD integer type"); |
+ return RtpTimeDelta(value_ * rhs); |
+ } |
+ template <typename IntType> |
+ RtpTimeDelta operator/(IntType rhs) const { |
+ static_assert(std::numeric_limits<IntType>::is_integer, |
+ "|rhs| must be a POD integer type"); |
+ return RtpTimeDelta(value_ / rhs); |
+ } |
+ template <typename IntType> |
+ RtpTimeDelta& operator*=(IntType rhs) { return (*this = (*this * rhs)); } |
+ template <typename IntType> |
+ RtpTimeDelta& operator/=(IntType rhs) { return (*this = (*this / rhs)); } |
+ |
+ // Maps this RtpTimeDelta to an approximate TimeDelta using the given |
+ // RTP timebase. Assumes a zero-valued TimeDelta corresponds to a zero-valued |
+ // RtpTimeDelta. |
+ base::TimeDelta ToTimeDelta(int rtp_timebase) const; |
+ |
+ // Maps the TimeDelta to an approximate RtpTimeDelta using the given RTP |
+ // timebase. Assumes a zero-valued TimeDelta corresponds to a zero-valued |
+ // RtpTimeDelta. |
+ static RtpTimeDelta FromTimeDelta(base::TimeDelta delta, int rtp_timebase); |
+ |
+ // Construct a RtpTimeDelta from an exact number of ticks. |
+ static RtpTimeDelta FromTicks(int64_t ticks); |
+ |
+ private: |
+ friend class ExpandedValueBase<int64_t, RtpTimeDelta>; |
+ friend class RtpTimeTicks; |
+ friend std::ostream& operator<<(std::ostream& out, const RtpTimeDelta rhs); |
+ |
+ explicit RtpTimeDelta(int64_t ticks) : ExpandedValueBase(ticks) {} |
+ |
+ int64_t value() const { return value_; } |
+}; |
+ |
+// 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 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. |
+// DLOG(INFO) << "The RTP timestamp is " << at_four_seconds; |
+// |
+// // Convert (approximately!) between RTP timebase and media timestamps in |
+// // microsecond timebase: |
+// base::TimeDelta four_seconds_timestamp = |
+// at_four_seconds.ToTimeDelta(kAudioSamplingRate); |
+// video_frame->set_timestamp(four_seconds_timestamp); |
+// RtpTimeTicks four_seconds_rtp = RtpTimeDelta::FromTimeDelta( |
+// video_frame->timestamp(), kAudioSamplingRate); |
+class RtpTimeTicks : public ExpandedValueBase<int64_t, RtpTimeTicks> { |
+ public: |
+ RtpTimeTicks() : ExpandedValueBase(0) {} |
+ |
+ // Compute the difference between two RtpTimeTickses. |
+ RtpTimeDelta operator-(RtpTimeTicks rhs) const { |
+ return RtpTimeDelta(value_ - rhs.value_); |
+ } |
+ |
+ // Return a new RtpTimeTicks before or after this one. |
+ RtpTimeTicks operator+(RtpTimeDelta rhs) const { |
+ return RtpTimeTicks(value_ + rhs.value()); |
+ } |
+ RtpTimeTicks operator-(RtpTimeDelta rhs) const { |
+ return RtpTimeTicks(value_ - rhs.value()); |
+ } |
+ RtpTimeTicks& operator+=(RtpTimeDelta rhs) { return (*this = (*this + rhs)); } |
+ RtpTimeTicks& operator-=(RtpTimeDelta rhs) { return (*this = (*this - rhs)); } |
+ |
+ // Maps this RtpTimeTicks to an approximate TimeDelta using the given |
+ // RTP timebase. Assumes a zero-valued TimeDelta corresponds to a zero-valued |
+ // RtpTimeTicks. |
+ base::TimeDelta ToTimeDelta(int rtp_timebase) const; |
+ |
+ // Maps the TimeDelta to an approximate RtpTimeTicks using the given RTP |
+ // timebase. Assumes a zero-valued TimeDelta corresponds to a zero-valued |
+ // RtpTimeTicks. |
+ static RtpTimeTicks FromTimeDelta(base::TimeDelta delta, int rtp_timebase); |
+ |
+ private: |
+ friend class ExpandedValueBase<int64_t, RtpTimeTicks>; |
+ friend std::ostream& operator<<(std::ostream& out, const RtpTimeTicks rhs); |
+ |
+ explicit RtpTimeTicks(int64_t value) : ExpandedValueBase(value) {} |
+ |
+ int64_t value() const { return value_; } |
+}; |
+ |
+} // namespace cast |
+} // namespace media |
+ |
+#endif // MEDIA_CAST_COMMON_RTP_TIME_H_ |