mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
[Unwrap] Prepare SequenceNumberUnwrapper for migrations
This is in prep for the migration of all unwrappers to SequenceNumberUnwrapper as a standard implementation. This moves the SeqNumUnwapper to its own header and adds 2 methods to SeqNumUnwrapper which are defined by other unwrappers: * PeekUnwrap * Reset It also adds two implementations for RtpTimestamps and RtpSequenceNumbers. Bug: webrtc:13982 Change-Id: I5baefb2de1db92fe1bb600760bd63b71e9310eb5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/288742 Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Auto-Submit: Evan Shrubsole <eshr@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39030}
This commit is contained in:
parent
17c4ca8fb3
commit
097fc347ec
21 changed files with 257 additions and 153 deletions
|
@ -185,6 +185,7 @@ rtc_library("rtp_video_frame_assembler") {
|
||||||
"../../modules/video_coding:packet_buffer",
|
"../../modules/video_coding:packet_buffer",
|
||||||
"../../modules/video_coding:video_coding",
|
"../../modules/video_coding:video_coding",
|
||||||
"../../rtc_base:logging",
|
"../../rtc_base:logging",
|
||||||
|
"../../rtc_base:rtc_numerics",
|
||||||
]
|
]
|
||||||
|
|
||||||
absl_deps = [
|
absl_deps = [
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "modules/video_coding/packet_buffer.h"
|
#include "modules/video_coding/packet_buffer.h"
|
||||||
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include "rtc_base/copy_on_write_buffer.h"
|
#include "rtc_base/copy_on_write_buffer.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/numerics/safe_conversions.h"
|
#include "rtc_base/numerics/safe_conversions.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/protobuf_utils.h"
|
#include "rtc_base/protobuf_utils.h"
|
||||||
#include "rtc_base/system/file_wrapper.h"
|
#include "rtc_base/system/file_wrapper.h"
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "modules/remote_bitrate_estimator/packet_arrival_map.h"
|
#include "modules/remote_bitrate_estimator/packet_arrival_map.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/synchronization/mutex.h"
|
#include "rtc_base/synchronization/mutex.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
|
#include "modules/video_coding/svc/scalable_video_controller_no_layering.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "third_party/libaom/source/libaom/aom/aom_codec.h"
|
#include "third_party/libaom/source/libaom/aom/aom_codec.h"
|
||||||
#include "third_party/libaom/source/libaom/aom/aom_encoder.h"
|
#include "third_party/libaom/source/libaom/aom/aom_encoder.h"
|
||||||
#include "third_party/libaom/source/libaom/aom/aomcx.h"
|
#include "third_party/libaom/source/libaom/aom/aomcx.h"
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "modules/video_coding/packet_buffer.h"
|
#include "modules/video_coding/packet_buffer.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "common_video/h264/h264_common.h"
|
#include "common_video/h264/h264_common.h"
|
||||||
#include "modules/video_coding/frame_object.h"
|
#include "modules/video_coding/frame_object.h"
|
||||||
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/random.h"
|
#include "rtc_base/random.h"
|
||||||
#include "test/field_trial.h"
|
#include "test/field_trial.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "absl/container/inlined_vector.h"
|
#include "absl/container/inlined_vector.h"
|
||||||
#include "modules/video_coding/frame_object.h"
|
#include "modules/video_coding/frame_object.h"
|
||||||
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "absl/container/inlined_vector.h"
|
#include "absl/container/inlined_vector.h"
|
||||||
#include "modules/video_coding/frame_object.h"
|
#include "modules/video_coding/frame_object.h"
|
||||||
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "absl/container/inlined_vector.h"
|
#include "absl/container/inlined_vector.h"
|
||||||
#include "modules/video_coding/frame_object.h"
|
#include "modules/video_coding/frame_object.h"
|
||||||
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "absl/container/inlined_vector.h"
|
#include "absl/container/inlined_vector.h"
|
||||||
#include "modules/video_coding/frame_object.h"
|
#include "modules/video_coding/frame_object.h"
|
||||||
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
|
|
@ -775,6 +775,7 @@ rtc_library("rtc_numerics") {
|
||||||
"numerics/moving_percentile_filter.h",
|
"numerics/moving_percentile_filter.h",
|
||||||
"numerics/percentile_filter.h",
|
"numerics/percentile_filter.h",
|
||||||
"numerics/running_statistics.h",
|
"numerics/running_statistics.h",
|
||||||
|
"numerics/sequence_number_unwrapper.h",
|
||||||
"numerics/sequence_number_util.h",
|
"numerics/sequence_number_util.h",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
|
@ -1696,6 +1697,7 @@ if (rtc_include_tests) {
|
||||||
"numerics/moving_percentile_filter_unittest.cc",
|
"numerics/moving_percentile_filter_unittest.cc",
|
||||||
"numerics/percentile_filter_unittest.cc",
|
"numerics/percentile_filter_unittest.cc",
|
||||||
"numerics/running_statistics_unittest.cc",
|
"numerics/running_statistics_unittest.cc",
|
||||||
|
"numerics/sequence_number_unwrapper_unittest.cc",
|
||||||
"numerics/sequence_number_util_unittest.cc",
|
"numerics/sequence_number_util_unittest.cc",
|
||||||
"numerics/sequence_numbers_conformance_test.cc",
|
"numerics/sequence_numbers_conformance_test.cc",
|
||||||
]
|
]
|
||||||
|
|
80
rtc_base/numerics/sequence_number_unwrapper.h
Normal file
80
rtc_base/numerics/sequence_number_unwrapper.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTC_BASE_NUMERICS_SEQUENCE_NUMBER_UNWRAPPER_H_
|
||||||
|
#define RTC_BASE_NUMERICS_SEQUENCE_NUMBER_UNWRAPPER_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "absl/types/optional.h"
|
||||||
|
#include "rtc_base/numerics/sequence_number_util.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// A sequence number unwrapper where the first unwrapped value equals the
|
||||||
|
// first value being unwrapped.
|
||||||
|
template <typename T, T M = 0>
|
||||||
|
class SeqNumUnwrapper {
|
||||||
|
static_assert(
|
||||||
|
std::is_unsigned<T>::value &&
|
||||||
|
std::numeric_limits<T>::max() < std::numeric_limits<int64_t>::max(),
|
||||||
|
"Type unwrapped must be an unsigned integer smaller than int64_t.");
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Unwraps `value` and updates the internal state of the unwrapper.
|
||||||
|
int64_t Unwrap(T value) {
|
||||||
|
if (!last_value_) {
|
||||||
|
last_unwrapped_ = {value};
|
||||||
|
} else {
|
||||||
|
last_unwrapped_ += Delta(*last_value_, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
last_value_ = value;
|
||||||
|
return last_unwrapped_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the `value` without updating the internal state of the unwrapper.
|
||||||
|
int64_t PeekUnwrap(T value) const {
|
||||||
|
if (!last_value_) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return last_unwrapped_ + Delta(*last_value_, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resets the unwrapper to its initial state. Unwrapped sequence numbers will
|
||||||
|
// being at 0 after resetting.
|
||||||
|
void Reset() {
|
||||||
|
last_unwrapped_ = 0;
|
||||||
|
last_value_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int64_t Delta(T last_value, T new_value) {
|
||||||
|
constexpr int64_t kBackwardAdjustment =
|
||||||
|
M == 0 ? int64_t{std::numeric_limits<T>::max()} + 1 : M;
|
||||||
|
int64_t result = ForwardDiff<T, M>(last_value, new_value);
|
||||||
|
if (!AheadOrAt<T, M>(new_value, last_value)) {
|
||||||
|
result -= kBackwardAdjustment;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t last_unwrapped_ = 0;
|
||||||
|
absl::optional<T> last_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using RtpTimestampUnwrapper = SeqNumUnwrapper<uint32_t>;
|
||||||
|
using RtpSequenceNumberUnwrapper = SeqNumUnwrapper<uint16_t>;
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // RTC_BASE_NUMERICS_SEQUENCE_NUMBER_UNWRAPPER_H_
|
146
rtc_base/numerics/sequence_number_unwrapper_unittest.cc
Normal file
146
rtc_base/numerics/sequence_number_unwrapper_unittest.cc
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "test/gtest.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, PreserveStartValue) {
|
||||||
|
SeqNumUnwrapper<uint8_t> unwrapper;
|
||||||
|
EXPECT_EQ(123, unwrapper.Unwrap(123));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, ForwardWrap) {
|
||||||
|
SeqNumUnwrapper<uint8_t> unwrapper;
|
||||||
|
EXPECT_EQ(255, unwrapper.Unwrap(255));
|
||||||
|
EXPECT_EQ(256, unwrapper.Unwrap(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, ForwardWrapWithDivisor) {
|
||||||
|
SeqNumUnwrapper<uint8_t, 33> unwrapper;
|
||||||
|
EXPECT_EQ(30, unwrapper.Unwrap(30));
|
||||||
|
EXPECT_EQ(36, unwrapper.Unwrap(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, BackWardWrap) {
|
||||||
|
SeqNumUnwrapper<uint8_t> unwrapper;
|
||||||
|
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
||||||
|
EXPECT_EQ(-2, unwrapper.Unwrap(254));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, BackWardWrapWithDivisor) {
|
||||||
|
SeqNumUnwrapper<uint8_t, 33> unwrapper;
|
||||||
|
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
||||||
|
EXPECT_EQ(-2, unwrapper.Unwrap(31));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, Unwrap) {
|
||||||
|
SeqNumUnwrapper<uint16_t> unwrapper;
|
||||||
|
const uint16_t kMax = std::numeric_limits<uint16_t>::max();
|
||||||
|
const uint16_t kMaxDist = kMax / 2 + 1;
|
||||||
|
|
||||||
|
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
||||||
|
EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
|
||||||
|
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
||||||
|
|
||||||
|
EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
|
||||||
|
EXPECT_EQ(kMax, unwrapper.Unwrap(kMax));
|
||||||
|
EXPECT_EQ(kMax + 1, unwrapper.Unwrap(0));
|
||||||
|
EXPECT_EQ(kMax, unwrapper.Unwrap(kMax));
|
||||||
|
EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
|
||||||
|
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, UnwrapOddDivisor) {
|
||||||
|
SeqNumUnwrapper<uint8_t, 11> unwrapper;
|
||||||
|
|
||||||
|
EXPECT_EQ(10, unwrapper.Unwrap(10));
|
||||||
|
EXPECT_EQ(11, unwrapper.Unwrap(0));
|
||||||
|
EXPECT_EQ(16, unwrapper.Unwrap(5));
|
||||||
|
EXPECT_EQ(21, unwrapper.Unwrap(10));
|
||||||
|
EXPECT_EQ(22, unwrapper.Unwrap(0));
|
||||||
|
EXPECT_EQ(17, unwrapper.Unwrap(6));
|
||||||
|
EXPECT_EQ(12, unwrapper.Unwrap(1));
|
||||||
|
EXPECT_EQ(7, unwrapper.Unwrap(7));
|
||||||
|
EXPECT_EQ(2, unwrapper.Unwrap(2));
|
||||||
|
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, ManyForwardWraps) {
|
||||||
|
const int kLargeNumber = 4711;
|
||||||
|
const int kMaxStep = kLargeNumber / 2;
|
||||||
|
const int kNumWraps = 100;
|
||||||
|
SeqNumUnwrapper<uint16_t, kLargeNumber> unwrapper;
|
||||||
|
|
||||||
|
uint16_t next_unwrap = 0;
|
||||||
|
int64_t expected = 0;
|
||||||
|
for (int i = 0; i < kNumWraps * 2 + 1; ++i) {
|
||||||
|
EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap));
|
||||||
|
expected += kMaxStep;
|
||||||
|
next_unwrap = (next_unwrap + kMaxStep) % kLargeNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, ManyBackwardWraps) {
|
||||||
|
const int kLargeNumber = 4711;
|
||||||
|
const int kMaxStep = kLargeNumber / 2;
|
||||||
|
const int kNumWraps = 100;
|
||||||
|
SeqNumUnwrapper<uint16_t, kLargeNumber> unwrapper;
|
||||||
|
|
||||||
|
uint16_t next_unwrap = 0;
|
||||||
|
int64_t expected = 0;
|
||||||
|
for (uint16_t i = 0; i < kNumWraps * 2 + 1; ++i) {
|
||||||
|
EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap));
|
||||||
|
expected -= kMaxStep;
|
||||||
|
next_unwrap = (next_unwrap + kMaxStep + 1) % kLargeNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, Reset) {
|
||||||
|
const uint16_t kMax = std::numeric_limits<uint16_t>::max();
|
||||||
|
const uint16_t kMaxStep = kMax / 2;
|
||||||
|
SeqNumUnwrapper<uint16_t> unwrapper;
|
||||||
|
EXPECT_EQ(10, unwrapper.Unwrap(10));
|
||||||
|
EXPECT_EQ(kMaxStep + 10, unwrapper.Unwrap(kMaxStep + 10));
|
||||||
|
|
||||||
|
EXPECT_EQ(kMax + 3, unwrapper.PeekUnwrap(2));
|
||||||
|
unwrapper.Reset();
|
||||||
|
// After Reset() the range is reset back to the start.
|
||||||
|
EXPECT_EQ(2, unwrapper.PeekUnwrap(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SeqNumUnwrapper, PeekUnwrap) {
|
||||||
|
const uint16_t kMax = std::numeric_limits<uint16_t>::max();
|
||||||
|
const uint16_t kMaxStep = kMax / 2;
|
||||||
|
const uint16_t kMaxDist = kMaxStep + 1;
|
||||||
|
SeqNumUnwrapper<uint16_t> unwrapper;
|
||||||
|
// No previous unwraps, so PeekUnwrap(x) == x.
|
||||||
|
EXPECT_EQ(10, unwrapper.PeekUnwrap(10));
|
||||||
|
EXPECT_EQ(kMaxDist + 10, unwrapper.PeekUnwrap(kMaxDist + 10));
|
||||||
|
|
||||||
|
EXPECT_EQ(10, unwrapper.Unwrap(10));
|
||||||
|
EXPECT_EQ(12, unwrapper.PeekUnwrap(12));
|
||||||
|
// State should not have updated, so kMaxDist + 12 should be negative.
|
||||||
|
EXPECT_EQ(-kMaxDist + 12, unwrapper.Unwrap(kMaxDist + 12));
|
||||||
|
|
||||||
|
// Test PeekUnwrap after around.
|
||||||
|
unwrapper.Reset();
|
||||||
|
EXPECT_EQ(kMaxStep, unwrapper.Unwrap(kMaxStep));
|
||||||
|
EXPECT_EQ(2 * kMaxStep, unwrapper.Unwrap(2 * kMaxStep));
|
||||||
|
EXPECT_EQ(kMax + 1, unwrapper.PeekUnwrap(0));
|
||||||
|
// Wrap back to last range.
|
||||||
|
EXPECT_EQ(kMax - 3, unwrapper.PeekUnwrap(kMax - 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
|
@ -16,8 +16,6 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
|
||||||
#include "rtc_base/checks.h"
|
|
||||||
#include "rtc_base/numerics/mod_ops.h"
|
#include "rtc_base/numerics/mod_ops.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
@ -82,38 +80,6 @@ struct DescendingSeqNumComp {
|
||||||
bool operator()(T a, T b) const { return AheadOf<T, M>(b, a); }
|
bool operator()(T a, T b) const { return AheadOf<T, M>(b, a); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// A sequence number unwrapper where the first unwrapped value equals the
|
|
||||||
// first value being unwrapped.
|
|
||||||
template <typename T, T M = 0>
|
|
||||||
class SeqNumUnwrapper {
|
|
||||||
static_assert(
|
|
||||||
std::is_unsigned<T>::value &&
|
|
||||||
std::numeric_limits<T>::max() < std::numeric_limits<int64_t>::max(),
|
|
||||||
"Type unwrapped must be an unsigned integer smaller than int64_t.");
|
|
||||||
|
|
||||||
public:
|
|
||||||
int64_t Unwrap(T value) {
|
|
||||||
if (!last_value_) {
|
|
||||||
last_unwrapped_ = {value};
|
|
||||||
} else {
|
|
||||||
last_unwrapped_ += ForwardDiff<T, M>(*last_value_, value);
|
|
||||||
|
|
||||||
if (!AheadOrAt<T, M>(value, *last_value_)) {
|
|
||||||
constexpr int64_t kBackwardAdjustment =
|
|
||||||
M == 0 ? int64_t{std::numeric_limits<T>::max()} + 1 : M;
|
|
||||||
last_unwrapped_ -= kBackwardAdjustment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_value_ = value;
|
|
||||||
return last_unwrapped_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int64_t last_unwrapped_ = 0;
|
|
||||||
absl::optional<T> last_value_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // RTC_BASE_NUMERICS_SEQUENCE_NUMBER_UTIL_H_
|
#endif // RTC_BASE_NUMERICS_SEQUENCE_NUMBER_UTIL_H_
|
||||||
|
|
|
@ -212,95 +212,4 @@ TEST_F(TestSeqNumUtil, SeqNumComparatorWithDivisor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, PreserveStartValue) {
|
|
||||||
SeqNumUnwrapper<uint8_t> unwrapper;
|
|
||||||
EXPECT_EQ(123, unwrapper.Unwrap(123));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, ForwardWrap) {
|
|
||||||
SeqNumUnwrapper<uint8_t> unwrapper;
|
|
||||||
EXPECT_EQ(255, unwrapper.Unwrap(255));
|
|
||||||
EXPECT_EQ(256, unwrapper.Unwrap(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, ForwardWrapWithDivisor) {
|
|
||||||
SeqNumUnwrapper<uint8_t, 33> unwrapper;
|
|
||||||
EXPECT_EQ(30, unwrapper.Unwrap(30));
|
|
||||||
EXPECT_EQ(36, unwrapper.Unwrap(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, BackWardWrap) {
|
|
||||||
SeqNumUnwrapper<uint8_t> unwrapper;
|
|
||||||
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
|
||||||
EXPECT_EQ(-2, unwrapper.Unwrap(254));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, BackWardWrapWithDivisor) {
|
|
||||||
SeqNumUnwrapper<uint8_t, 33> unwrapper;
|
|
||||||
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
|
||||||
EXPECT_EQ(-2, unwrapper.Unwrap(31));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, Unwrap) {
|
|
||||||
SeqNumUnwrapper<uint16_t> unwrapper;
|
|
||||||
const uint16_t kMax = std::numeric_limits<uint16_t>::max();
|
|
||||||
const uint16_t kMaxDist = kMax / 2 + 1;
|
|
||||||
|
|
||||||
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
|
||||||
EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
|
|
||||||
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
|
||||||
|
|
||||||
EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
|
|
||||||
EXPECT_EQ(kMax, unwrapper.Unwrap(kMax));
|
|
||||||
EXPECT_EQ(kMax + 1, unwrapper.Unwrap(0));
|
|
||||||
EXPECT_EQ(kMax, unwrapper.Unwrap(kMax));
|
|
||||||
EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist));
|
|
||||||
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, UnwrapOddDivisor) {
|
|
||||||
SeqNumUnwrapper<uint8_t, 11> unwrapper;
|
|
||||||
|
|
||||||
EXPECT_EQ(10, unwrapper.Unwrap(10));
|
|
||||||
EXPECT_EQ(11, unwrapper.Unwrap(0));
|
|
||||||
EXPECT_EQ(16, unwrapper.Unwrap(5));
|
|
||||||
EXPECT_EQ(21, unwrapper.Unwrap(10));
|
|
||||||
EXPECT_EQ(22, unwrapper.Unwrap(0));
|
|
||||||
EXPECT_EQ(17, unwrapper.Unwrap(6));
|
|
||||||
EXPECT_EQ(12, unwrapper.Unwrap(1));
|
|
||||||
EXPECT_EQ(7, unwrapper.Unwrap(7));
|
|
||||||
EXPECT_EQ(2, unwrapper.Unwrap(2));
|
|
||||||
EXPECT_EQ(0, unwrapper.Unwrap(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, ManyForwardWraps) {
|
|
||||||
const int kLargeNumber = 4711;
|
|
||||||
const int kMaxStep = kLargeNumber / 2;
|
|
||||||
const int kNumWraps = 100;
|
|
||||||
SeqNumUnwrapper<uint16_t, kLargeNumber> unwrapper;
|
|
||||||
|
|
||||||
uint16_t next_unwrap = 0;
|
|
||||||
int64_t expected = 0;
|
|
||||||
for (int i = 0; i < kNumWraps * 2 + 1; ++i) {
|
|
||||||
EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap));
|
|
||||||
expected += kMaxStep;
|
|
||||||
next_unwrap = (next_unwrap + kMaxStep) % kLargeNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(SeqNumUnwrapper, ManyBackwardWraps) {
|
|
||||||
const int kLargeNumber = 4711;
|
|
||||||
const int kMaxStep = kLargeNumber / 2;
|
|
||||||
const int kNumWraps = 100;
|
|
||||||
SeqNumUnwrapper<uint16_t, kLargeNumber> unwrapper;
|
|
||||||
|
|
||||||
uint16_t next_unwrap = 0;
|
|
||||||
int64_t expected = 0;
|
|
||||||
for (uint16_t i = 0; i < kNumWraps * 2 + 1; ++i) {
|
|
||||||
EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap));
|
|
||||||
expected -= kMaxStep;
|
|
||||||
next_unwrap = (next_unwrap + kMaxStep + 1) % kLargeNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "modules/include/module_common_types_public.h"
|
#include "modules/include/module_common_types_public.h"
|
||||||
#include "net/dcsctp/common/sequence_numbers.h"
|
#include "net/dcsctp/common/sequence_numbers.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/strong_alias.h"
|
#include "rtc_base/strong_alias.h"
|
||||||
#include "rtc_base/time_utils.h"
|
#include "rtc_base/time_utils.h"
|
||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
|
@ -26,7 +26,7 @@ namespace {
|
||||||
using ::testing::Test;
|
using ::testing::Test;
|
||||||
|
|
||||||
using dcsctp::UnwrappedSequenceNumber;
|
using dcsctp::UnwrappedSequenceNumber;
|
||||||
using Wrapped = webrtc::StrongAlias<class WrappedTag, uint32_t>;
|
using Wrapped = StrongAlias<class WrappedTag, uint32_t>;
|
||||||
using TestSequence = UnwrappedSequenceNumber<Wrapped>;
|
using TestSequence = UnwrappedSequenceNumber<Wrapped>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -84,9 +84,9 @@ TYPED_TEST_P(UnwrapperConformanceFixture, PositiveWrapAround) {
|
||||||
|
|
||||||
TYPED_TEST_P(UnwrapperConformanceFixture, NegativeUnwrap) {
|
TYPED_TEST_P(UnwrapperConformanceFixture, NegativeUnwrap) {
|
||||||
using UnwrapperT = decltype(this->ref_unwrapper_);
|
using UnwrapperT = decltype(this->ref_unwrapper_);
|
||||||
// webrtc::TimestampUnwrapper known to not handle negative numbers.
|
// TimestampUnwrapper known to not handle negative numbers.
|
||||||
// rtc::TimestampWrapAroundHandler does not wrap around correctly.
|
// rtc::TimestampWrapAroundHandler does not wrap around correctly.
|
||||||
if constexpr (std::is_same<UnwrapperT, webrtc::TimestampUnwrapper>() ||
|
if constexpr (std::is_same<UnwrapperT, TimestampUnwrapper>() ||
|
||||||
std::is_same<UnwrapperT, rtc::TimestampWrapAroundHandler>()) {
|
std::is_same<UnwrapperT, rtc::TimestampWrapAroundHandler>()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -134,10 +134,10 @@ TYPED_TEST_P(UnwrapperConformanceFixture, WrapBoundaries) {
|
||||||
|
|
||||||
TYPED_TEST_P(UnwrapperConformanceFixture, MultipleNegativeWrapArounds) {
|
TYPED_TEST_P(UnwrapperConformanceFixture, MultipleNegativeWrapArounds) {
|
||||||
using UnwrapperT = decltype(this->ref_unwrapper_);
|
using UnwrapperT = decltype(this->ref_unwrapper_);
|
||||||
// webrtc::TimestampUnwrapper known to not handle negative numbers.
|
// TimestampUnwrapper known to not handle negative numbers.
|
||||||
// webrtc::SequenceNumberUnwrapper can only wrap negative once.
|
// SequenceNumberUnwrapper can only wrap negative once.
|
||||||
// rtc::TimestampWrapAroundHandler does not wrap around correctly.
|
// rtc::TimestampWrapAroundHandler does not wrap around correctly.
|
||||||
if constexpr (std::is_same<UnwrapperT, webrtc::TimestampUnwrapper>() ||
|
if constexpr (std::is_same<UnwrapperT, TimestampUnwrapper>() ||
|
||||||
std::is_same<UnwrapperT,
|
std::is_same<UnwrapperT,
|
||||||
UnwrapperHelper<TestSequence::Unwrapper>>() ||
|
UnwrapperHelper<TestSequence::Unwrapper>>() ||
|
||||||
std::is_same<UnwrapperT, rtc::TimestampWrapAroundHandler>()) {
|
std::is_same<UnwrapperT, rtc::TimestampWrapAroundHandler>()) {
|
||||||
|
@ -164,11 +164,11 @@ REGISTER_TYPED_TEST_SUITE_P(UnwrapperConformanceFixture,
|
||||||
constexpr int64_t k15BitMax = (int64_t{1} << 15) - 1;
|
constexpr int64_t k15BitMax = (int64_t{1} << 15) - 1;
|
||||||
using UnwrapperTypes = ::testing::Types<
|
using UnwrapperTypes = ::testing::Types<
|
||||||
FixtureParams<rtc::TimestampWrapAroundHandler>,
|
FixtureParams<rtc::TimestampWrapAroundHandler>,
|
||||||
FixtureParams<webrtc::TimestampUnwrapper>,
|
FixtureParams<TimestampUnwrapper>,
|
||||||
FixtureParams<webrtc::SeqNumUnwrapper<uint32_t>>,
|
FixtureParams<RtpTimestampUnwrapper>,
|
||||||
FixtureParams<UnwrapperHelper<TestSequence::Unwrapper>>,
|
FixtureParams<UnwrapperHelper<TestSequence::Unwrapper>>,
|
||||||
// SeqNumUnwrapper supports arbitrary limits.
|
// SeqNumUnwrapper supports arbitrary limits.
|
||||||
FixtureParams<webrtc::SeqNumUnwrapper<uint32_t, k15BitMax + 1>, k15BitMax>>;
|
FixtureParams<SeqNumUnwrapper<uint32_t, k15BitMax + 1>, k15BitMax>>;
|
||||||
|
|
||||||
class TestNames {
|
class TestNames {
|
||||||
public:
|
public:
|
||||||
|
@ -177,15 +177,13 @@ class TestNames {
|
||||||
if constexpr (std::is_same<typename T::Unwrapper,
|
if constexpr (std::is_same<typename T::Unwrapper,
|
||||||
rtc::TimestampWrapAroundHandler>())
|
rtc::TimestampWrapAroundHandler>())
|
||||||
return "TimestampWrapAroundHandler";
|
return "TimestampWrapAroundHandler";
|
||||||
if constexpr (std::is_same<typename T::Unwrapper,
|
if constexpr (std::is_same<typename T::Unwrapper, TimestampUnwrapper>())
|
||||||
webrtc::TimestampUnwrapper>())
|
|
||||||
return "TimestampUnwrapper";
|
return "TimestampUnwrapper";
|
||||||
if constexpr (std::is_same<typename T::Unwrapper,
|
if constexpr (std::is_same<typename T::Unwrapper,
|
||||||
webrtc::SeqNumUnwrapper<uint32_t>>())
|
SeqNumUnwrapper<uint32_t>>())
|
||||||
return "SeqNumUnwrapper";
|
return "SeqNumUnwrapper";
|
||||||
if constexpr (std::is_same<
|
if constexpr (std::is_same<typename T::Unwrapper,
|
||||||
typename T::Unwrapper,
|
SeqNumUnwrapper<uint32_t, k15BitMax + 1>>())
|
||||||
webrtc::SeqNumUnwrapper<uint32_t, k15BitMax + 1>>())
|
|
||||||
return "SeqNumUnwrapper15bit";
|
return "SeqNumUnwrapper15bit";
|
||||||
if constexpr (std::is_same<typename T::Unwrapper,
|
if constexpr (std::is_same<typename T::Unwrapper,
|
||||||
UnwrapperHelper<TestSequence::Unwrapper>>())
|
UnwrapperHelper<TestSequence::Unwrapper>>())
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "logging/rtc_event_log/rtc_event_processor.h"
|
#include "logging/rtc_event_log/rtc_event_processor.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/strings/string_builder.h"
|
#include "rtc_base/strings/string_builder.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
|
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/rate_statistics.h"
|
#include "rtc_base/rate_statistics.h"
|
||||||
#include "rtc_base/strings/string_builder.h"
|
#include "rtc_base/strings/string_builder.h"
|
||||||
#include "rtc_tools/rtc_event_log_visualizer/log_simulation.h"
|
#include "rtc_tools/rtc_event_log_visualizer/log_simulation.h"
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
#include "api/video/encoded_frame.h"
|
#include "api/video/encoded_frame.h"
|
||||||
#include "api/video/frame_buffer.h"
|
#include "api/video/frame_buffer.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "test/fuzzers/fuzz_data_helper.h"
|
#include "test/fuzzers/fuzz_data_helper.h"
|
||||||
#include "test/scoped_key_value_config.h"
|
#include "test/scoped_key_value_config.h"
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "modules/video_coding/packet_buffer.h"
|
#include "modules/video_coding/packet_buffer.h"
|
||||||
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
#include "modules/video_coding/rtp_frame_reference_finder.h"
|
||||||
#include "rtc_base/experiments/field_trial_parser.h"
|
#include "rtc_base/experiments/field_trial_parser.h"
|
||||||
#include "rtc_base/numerics/sequence_number_util.h"
|
#include "rtc_base/numerics/sequence_number_unwrapper.h"
|
||||||
#include "rtc_base/system/no_unique_address.h"
|
#include "rtc_base/system/no_unique_address.h"
|
||||||
#include "rtc_base/thread_annotations.h"
|
#include "rtc_base/thread_annotations.h"
|
||||||
#include "video/buffered_frame_decryptor.h"
|
#include "video/buffered_frame_decryptor.h"
|
||||||
|
|
Loading…
Reference in a new issue