| 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,
|
|
|