OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef MEDIA_CAST_COMMON_EXPANDED_VALUE_BASE_H_ | |
6 #define MEDIA_CAST_COMMON_EXPANDED_VALUE_BASE_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <limits> | |
11 #include <sstream> | |
12 | |
13 namespace media { | |
14 namespace cast { | |
15 | |
16 // Abstract base template class for common "sequence value" data types such as | |
17 // 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
| |
18 // predictable amounts as media is streamed, and which often need to be reliably | |
19 // truncated and re-expanded for over-the-wire transmission. | |
20 // | |
21 // 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.
| |
22 // sufficiently high precision to never wrap-around in the system. Subclass is | |
23 // 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.
| |
24 // and is used to provide operator overloads. The Subclass must friend this | |
25 // class to enable these operator overloads. | |
26 template <typename FullPrecisionInteger, class Subclass> | |
27 class ExpandedValueBase { | |
28 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.
| |
29 "FullPrecisionInteger must be a signed integer."); | |
30 | |
31 public: | |
32 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.
| |
33 | |
34 // Methods that return the lower bits of this value. This should only be used | |
35 // for serializing/wire-formatting, and not to subvert the restricted set of | |
36 // operators allowed on this data type. | |
37 uint8_t lower_8_bits() const { return static_cast<uint8_t>(value_); } | |
38 uint16_t lower_16_bits() const { return static_cast<uint16_t>(value_); } | |
39 uint32_t lower_32_bits() const { return static_cast<uint32_t>(value_); } | |
40 | |
41 // Create a value whose lower bits are those of |x|, and whose upper bits are | |
42 // determined relative to |this| value. The result is always within | |
43 // |max_distance_for_expansion<ShortUnsigned>()| of |this| value. | |
44 // | |
45 // The purpose of this method is to re-instantiate an original value from its | |
46 // truncated form, usually when deserializing off-the-wire. Therefore, it is | |
47 // always important to call this method on an instance known to be close in | |
48 // distance to |x|. | |
49 template <typename ShortUnsigned> | |
50 Subclass Expand(ShortUnsigned x) const { | |
51 static_assert(!std::numeric_limits<ShortUnsigned>::is_signed, | |
52 "|x| must be an unsigned integer."); | |
53 static_assert(std::numeric_limits<ShortUnsigned>::is_integer, | |
54 "|x| must be an unsigned integer."); | |
55 static_assert(sizeof(ShortUnsigned) <= sizeof(FullPrecisionInteger), | |
56 "|x| must fit within the FullPrecisionInteger."); | |
57 | |
58 if (sizeof(ShortUnsigned) < sizeof(FullPrecisionInteger)) { | |
59 // Initially, the |result| is composed of upper bits from |value_| and | |
60 // lower bits from |x|. | |
61 const FullPrecisionInteger short_max = | |
62 std::numeric_limits<ShortUnsigned>::max(); | |
63 FullPrecisionInteger result = (value_ & ~short_max) | x; | |
64 | |
65 // Determine whether the shorter integer type encountered wrap-around, and | |
66 // increment/decrement the upper bits by one to account for that. | |
67 const FullPrecisionInteger diff = result - value_; | |
68 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.
| |
69 if (diff > pivot) | |
70 result -= short_max + 1; | |
71 else if (diff < -(pivot + 1)) | |
72 result += short_max + 1; | |
73 return Subclass(result); | |
74 } else { | |
75 return Subclass(x); | |
76 } | |
77 } | |
78 | |
79 // Comparison operators. | |
80 bool operator==(Subclass rhs) const { return value_ == rhs.value_; } | |
81 bool operator!=(Subclass rhs) const { return value_ != rhs.value_; } | |
82 bool operator<(Subclass rhs) const { return value_ < rhs.value_; } | |
83 bool operator>(Subclass rhs) const { return value_ > rhs.value_; } | |
84 bool operator<=(Subclass rhs) const { return value_ <= rhs.value_; } | |
85 bool operator>=(Subclass rhs) const { return value_ >= rhs.value_; } | |
86 | |
87 // (De)Serialize for transmission over IPC. Do not use these to subvert the | |
88 // valid set of operators allowed by this class or its Subclass. | |
89 uint64_t SerializeForIPC() const { | |
90 static_assert(sizeof(uint64_t) >= sizeof(FullPrecisionInteger), | |
91 "Cannot serialize FullPrecisionInteger into an uint64_t."); | |
92 return static_cast<uint64_t>(value_); | |
93 } | |
94 static Subclass DeserializeForIPC(uint64_t serialized) { | |
95 return Subclass(static_cast<FullPrecisionInteger>(serialized)); | |
96 } | |
97 | |
98 // Design limit: Values that are truncated to the ShortUnsigned type must be | |
99 // no more than this maximum distance from each other in order to ensure the | |
100 // original value can be determined correctly. | |
101 template <typename ShortUnsigned> | |
102 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
| |
103 return std::numeric_limits<ShortUnsigned>::max() / 2; | |
104 } | |
105 | |
106 protected: | |
107 // Only subclasses are permitted to instantiate directly. | |
108 explicit ExpandedValueBase(FullPrecisionInteger value) : value_(value) {} | |
109 | |
110 FullPrecisionInteger value_; | |
111 }; | |
112 | |
113 } // namespace cast | |
114 } // namespace media | |
115 | |
116 #endif // MEDIA_CAST_COMMON_EXPANDED_VALUE_BASE_H_ | |
OLD | NEW |