Index: media/cast/common/expanded_value_base.h |
diff --git a/media/cast/common/expanded_value_base.h b/media/cast/common/expanded_value_base.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1fbcd010ba8718d1ce740f01d4d5c1bbf93b7a80 |
--- /dev/null |
+++ b/media/cast/common/expanded_value_base.h |
@@ -0,0 +1,116 @@ |
+// 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_EXPANDED_VALUE_BASE_H_ |
+#define MEDIA_CAST_COMMON_EXPANDED_VALUE_BASE_H_ |
+ |
+#include <stdint.h> |
+ |
+#include <limits> |
+#include <sstream> |
+ |
+namespace media { |
+namespace cast { |
+ |
+// Abstract base template class for common "sequence value" data types such as |
+// RtpTimeTicks, FrameId, or PacketId which generally increment/decrement in |
Irfan
2015/12/09 21:24:27
Suggest expanding further here with some examples
miu
2015/12/10 00:38:36
Done. Elaborated on where to find usage info. Al
|
+// predictable amounts as media is streamed, and which often need to be reliably |
+// truncated and re-expanded for over-the-wire transmission. |
+// |
+// FullPrecisionInterger should be a signed integer POD type that is of |
Irfan
2015/12/09 21:24:27
Typo: FullPrecisionInteger
miu
2015/12/10 00:38:36
Done.
|
+// sufficiently high precision to never wrap-around in the system. Subclass is |
+// the the class inheriting the common functionality provided in this template, |
Irfan
2015/12/09 21:24:27
s/the the/the
miu
2015/12/10 00:38:36
Done.
|
+// and is used to provide operator overloads. The Subclass must friend this |
+// class to enable these operator overloads. |
+template <typename FullPrecisionInteger, class Subclass> |
+class ExpandedValueBase { |
+ static_assert(std::numeric_limits<FullPrecisionInteger>::is_signed, |
Irfan
2015/12/09 21:24:27
also do an integer check like below ?
miu
2015/12/10 00:38:36
Done.
|
+ "FullPrecisionInteger must be a signed integer."); |
+ |
+ public: |
+ bool is_zero() const { return value_ == 0; } |
Irfan
2015/12/09 21:24:27
we need this ?
miu
2015/12/10 00:38:36
Nope. Removed.
|
+ |
+ // Methods that return the lower bits of this value. This should only be used |
+ // for serializing/wire-formatting, and not to subvert the restricted set of |
+ // operators allowed on this data type. |
+ uint8_t lower_8_bits() const { return static_cast<uint8_t>(value_); } |
+ uint16_t lower_16_bits() const { return static_cast<uint16_t>(value_); } |
+ uint32_t lower_32_bits() const { return static_cast<uint32_t>(value_); } |
+ |
+ // Create a value whose lower bits are those of |x|, and whose upper bits are |
+ // determined relative to |this| value. The result is always within |
+ // |max_distance_for_expansion<ShortUnsigned>()| of |this| value. |
+ // |
+ // The purpose of this method is to re-instantiate an original value from its |
+ // truncated form, usually when deserializing off-the-wire. Therefore, it is |
+ // always important to call this method on an instance known to be close in |
+ // distance to |x|. |
+ template <typename ShortUnsigned> |
+ Subclass Expand(ShortUnsigned x) const { |
+ static_assert(!std::numeric_limits<ShortUnsigned>::is_signed, |
+ "|x| must be an unsigned integer."); |
+ static_assert(std::numeric_limits<ShortUnsigned>::is_integer, |
+ "|x| must be an unsigned integer."); |
+ static_assert(sizeof(ShortUnsigned) <= sizeof(FullPrecisionInteger), |
+ "|x| must fit within the FullPrecisionInteger."); |
+ |
+ if (sizeof(ShortUnsigned) < sizeof(FullPrecisionInteger)) { |
+ // Initially, the |result| is composed of upper bits from |value_| and |
+ // lower bits from |x|. |
+ const FullPrecisionInteger short_max = |
+ std::numeric_limits<ShortUnsigned>::max(); |
+ FullPrecisionInteger result = (value_ & ~short_max) | x; |
+ |
+ // Determine whether the shorter integer type encountered wrap-around, and |
+ // increment/decrement the upper bits by one to account for that. |
+ const FullPrecisionInteger diff = result - value_; |
+ const FullPrecisionInteger pivot = short_max / 2; |
Irfan
2015/12/09 21:24:27
pivot = max_distance_for_expansion ?
miu
2015/12/10 00:38:36
Done.
|
+ if (diff > pivot) |
+ result -= short_max + 1; |
+ else if (diff < -(pivot + 1)) |
+ result += short_max + 1; |
+ return Subclass(result); |
+ } else { |
+ return Subclass(x); |
+ } |
+ } |
+ |
+ // Comparison operators. |
+ bool operator==(Subclass rhs) const { return value_ == rhs.value_; } |
+ bool operator!=(Subclass rhs) const { return value_ != rhs.value_; } |
+ bool operator<(Subclass rhs) const { return value_ < rhs.value_; } |
+ bool operator>(Subclass rhs) const { return value_ > rhs.value_; } |
+ bool operator<=(Subclass rhs) const { return value_ <= rhs.value_; } |
+ bool operator>=(Subclass rhs) const { return value_ >= rhs.value_; } |
+ |
+ // (De)Serialize for transmission over IPC. Do not use these to subvert the |
+ // valid set of operators allowed by this class or its Subclass. |
+ uint64_t SerializeForIPC() const { |
+ static_assert(sizeof(uint64_t) >= sizeof(FullPrecisionInteger), |
+ "Cannot serialize FullPrecisionInteger into an uint64_t."); |
+ return static_cast<uint64_t>(value_); |
+ } |
+ static Subclass DeserializeForIPC(uint64_t serialized) { |
+ return Subclass(static_cast<FullPrecisionInteger>(serialized)); |
+ } |
+ |
+ // Design limit: Values that are truncated to the ShortUnsigned type must be |
+ // no more than this maximum distance from each other in order to ensure the |
+ // original value can be determined correctly. |
+ template <typename ShortUnsigned> |
+ static FullPrecisionInteger max_distance_for_expansion() { |
Irfan
2015/12/09 21:24:27
private ?
miu
2015/12/10 00:38:36
In a follow-up CL (where I introduce FrameId), I w
|
+ return std::numeric_limits<ShortUnsigned>::max() / 2; |
+ } |
+ |
+ protected: |
+ // Only subclasses are permitted to instantiate directly. |
+ explicit ExpandedValueBase(FullPrecisionInteger value) : value_(value) {} |
+ |
+ FullPrecisionInteger value_; |
+}; |
+ |
+} // namespace cast |
+} // namespace media |
+ |
+#endif // MEDIA_CAST_COMMON_EXPANDED_VALUE_BASE_H_ |