Chromium Code Reviews| 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_ |