Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(812)

Unified Diff: webrtc/modules/include/module_common_types.h

Issue 2813593003: Add TimestampUnwrapper and generalize the code (Closed)
Patch Set: Remove ctor Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | webrtc/modules/module_common_types_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/include/module_common_types.h
diff --git a/webrtc/modules/include/module_common_types.h b/webrtc/modules/include/module_common_types.h
index a16c9392a2ec62a3d46ae42a47223c092c141745..4976a2a2a163d98491449ae8947e2d43c45d9ac3 100644
--- a/webrtc/modules/include/module_common_types.h
+++ b/webrtc/modules/include/module_common_types.h
@@ -20,11 +20,12 @@
#include "webrtc/api/video/video_rotation.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/deprecation.h"
+#include "webrtc/base/optional.h"
#include "webrtc/base/safe_conversions.h"
#include "webrtc/common_types.h"
+#include "webrtc/modules/video_coding/codecs/h264/include/h264_globals.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_globals.h"
#include "webrtc/modules/video_coding/codecs/vp9/include/vp9_globals.h"
-#include "webrtc/modules/video_coding/codecs/h264/include/h264_globals.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -474,28 +475,30 @@ inline AudioFrame& AudioFrame::operator+=(const AudioFrame& rhs) {
return *this;
}
+template <typename U>
+inline bool IsNewer(U value, U prev_value) {
+ static_assert(!std::numeric_limits<U>::is_signed, "U must be unsigned");
+ // kBreakpoint is the half-way mark for the type U. For instance, for a
+ // uint16_t it will be 0x8000, and for a uint32_t, it will be 0x8000000.
+ constexpr U kBreakpoint = (std::numeric_limits<U>::max() >> 1) + 1;
+ // Distinguish between elements that are exactly kBreakpoint apart.
+ // If t1>t2 and |t1-t2| = kBreakpoint: IsNewer(t1,t2)=true,
+ // IsNewer(t2,t1)=false
+ // rather than having IsNewer(t1,t2) = IsNewer(t2,t1) = false.
+ if (value - prev_value == kBreakpoint) {
+ return value > prev_value;
+ }
+ return value != prev_value &&
+ static_cast<U>(value - prev_value) < kBreakpoint;
+}
+
inline bool IsNewerSequenceNumber(uint16_t sequence_number,
uint16_t prev_sequence_number) {
- // Distinguish between elements that are exactly 0x8000 apart.
- // If s1>s2 and |s1-s2| = 0x8000: IsNewer(s1,s2)=true, IsNewer(s2,s1)=false
- // rather than having IsNewer(s1,s2) = IsNewer(s2,s1) = false.
- if (static_cast<uint16_t>(sequence_number - prev_sequence_number) == 0x8000) {
- return sequence_number > prev_sequence_number;
- }
- return sequence_number != prev_sequence_number &&
- static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000;
+ return IsNewer(sequence_number, prev_sequence_number);
}
inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
- // Distinguish between elements that are exactly 0x80000000 apart.
- // If t1>t2 and |t1-t2| = 0x80000000: IsNewer(t1,t2)=true,
- // IsNewer(t2,t1)=false
- // rather than having IsNewer(t1,t2) = IsNewer(t2,t1) = false.
- if (static_cast<uint32_t>(timestamp - prev_timestamp) == 0x80000000) {
- return timestamp > prev_timestamp;
- }
- return timestamp != prev_timestamp &&
- static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000;
+ return IsNewer(timestamp, prev_timestamp);
}
inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,
@@ -509,46 +512,57 @@ inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) {
return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2;
}
-// Utility class to unwrap a sequence number to a larger type, for easier
-// handling large ranges. Note that sequence numbers will never be unwrapped
-// to a negative value.
-class SequenceNumberUnwrapper {
+// Utility class to unwrap a number to a larger type. The numbers will never be
+// unwrapped to a negative value.
+template <typename U>
+class Unwrapper {
+ static_assert(!std::numeric_limits<U>::is_signed, "U must be unsigned");
+ static_assert(std::numeric_limits<U>::max() <=
+ std::numeric_limits<uint32_t>::max(),
+ "U must not be wider than 32 bits");
+
public:
- SequenceNumberUnwrapper() : last_seq_(-1) {}
+ // Get the unwrapped value, but don't update the internal state.
+ int64_t UnwrapWithoutUpdate(U value) {
+ if (!last_value_)
+ return value;
- // Get the unwrapped sequence, but don't update the internal state.
- int64_t UnwrapWithoutUpdate(uint16_t sequence_number) {
- if (last_seq_ == -1)
- return sequence_number;
+ constexpr int64_t kMaxPlusOne =
+ static_cast<int64_t>(std::numeric_limits<U>::max()) + 1;
- uint16_t cropped_last = static_cast<uint16_t>(last_seq_);
- int64_t delta = sequence_number - cropped_last;
- if (IsNewerSequenceNumber(sequence_number, cropped_last)) {
+ U cropped_last = static_cast<U>(*last_value_);
+ int64_t delta = value - cropped_last;
+ if (IsNewer(value, cropped_last)) {
if (delta < 0)
- delta += (1 << 16); // Wrap forwards.
- } else if (delta > 0 && (last_seq_ + delta - (1 << 16)) >= 0) {
- // If sequence_number is older but delta is positive, this is a backwards
+ delta += kMaxPlusOne; // Wrap forwards.
+ } else if (delta > 0 && (*last_value_ + delta - kMaxPlusOne) >= 0) {
+ // If value is older but delta is positive, this is a backwards
// wrap-around. However, don't wrap backwards past 0 (unwrapped).
- delta -= (1 << 16);
+ delta -= kMaxPlusOne;
}
- return last_seq_ + delta;
+ return *last_value_ + delta;
}
- // Only update the internal state to the specified last (unwrapped) sequence.
- void UpdateLast(int64_t last_sequence) { last_seq_ = last_sequence; }
+ // Only update the internal state to the specified last (unwrapped) value.
+ void UpdateLast(int64_t last_value) {
+ last_value_ = rtc::Optional<int64_t>(last_value);
+ }
- // Unwrap the sequence number and update the internal state.
- int64_t Unwrap(uint16_t sequence_number) {
- int64_t unwrapped = UnwrapWithoutUpdate(sequence_number);
+ // Unwrap the value and update the internal state.
+ int64_t Unwrap(U value) {
+ int64_t unwrapped = UnwrapWithoutUpdate(value);
UpdateLast(unwrapped);
return unwrapped;
}
private:
- int64_t last_seq_;
+ rtc::Optional<int64_t> last_value_;
};
+using SequenceNumberUnwrapper = Unwrapper<uint16_t>;
+using TimestampUnwrapper = Unwrapper<uint32_t>;
+
struct PacedPacketInfo {
PacedPacketInfo() {}
PacedPacketInfo(int probe_cluster_id,
« no previous file with comments | « no previous file | webrtc/modules/module_common_types_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698