Skip to content

Commit c2a8241

Browse files
Fanny LinderborgWebRTC LUCI CQ
authored andcommitted
Add support for the Halton sequence
Bug: b/358039777 Change-Id: Id191d584e22cf82384a5d16ed355f41c0bb32b7b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/358981 Reviewed-by: Erik Språng <[email protected]> Commit-Queue: Fanny Linderborg <[email protected]> Cr-Commit-Position: refs/heads/main@{#42764}
1 parent 0616340 commit c2a8241

File tree

5 files changed

+222
-0
lines changed

5 files changed

+222
-0
lines changed

video/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,7 @@ if (rtc_include_tests) {
959959
"config:encoder_config",
960960
"config:streams_config",
961961
"config:video_config_tests",
962+
"corruption_detection:corruption_detection_tests",
962963
"//third_party/abseil-cpp/absl/algorithm:container",
963964
"//third_party/abseil-cpp/absl/functional:any_invocable",
964965
"//third_party/abseil-cpp/absl/memory",

video/corruption_detection/BUILD.gn

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright 2024 The WebRTC project authors. All rights reserved.
2+
#
3+
# Use of this source code is governed by a BSD-style license
4+
# that can be found in the LICENSE file in the root of the source
5+
# tree. An additional intellectual property rights grant can be found
6+
# in the file PATENTS. All contributing project authors may
7+
# be found in the AUTHORS file in the root of the source tree.
8+
9+
import("../../webrtc.gni")
10+
11+
rtc_library("halton_sequence") {
12+
sources = [
13+
"halton_sequence.cc",
14+
"halton_sequence.h",
15+
]
16+
deps = [ "../../rtc_base:checks" ]
17+
}
18+
19+
if (rtc_include_tests) {
20+
rtc_library("halton_sequence_unittest") {
21+
testonly = true
22+
sources = [ "halton_sequence_unittest.cc" ]
23+
deps = [
24+
":halton_sequence",
25+
"../../test/:test_support",
26+
]
27+
}
28+
29+
rtc_library("corruption_detection_tests") {
30+
testonly = true
31+
sources = []
32+
deps = [ ":halton_sequence_unittest" ]
33+
}
34+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2024 The WebRTC project authors. All rights reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
11+
#include "video/corruption_detection/halton_sequence.h"
12+
13+
#include <algorithm>
14+
#include <vector>
15+
16+
#include "rtc_base/checks.h"
17+
18+
namespace webrtc {
19+
namespace {
20+
21+
static constexpr int kMaxDimensions = 5;
22+
const int kBases[kMaxDimensions] = {2, 3, 5, 7, 11};
23+
24+
double GetVanDerCorputSequenceElement(int sequence_idx, int base) {
25+
if (sequence_idx < 0 || base < 2) {
26+
sequence_idx = 0;
27+
base = 2;
28+
}
29+
double element = 0.0;
30+
double positional_value = 1.0;
31+
int left = sequence_idx;
32+
while (left > 0) {
33+
positional_value /= base;
34+
element += positional_value * (left % base);
35+
left /= base;
36+
}
37+
return element;
38+
}
39+
40+
} // namespace
41+
42+
HaltonSequence::HaltonSequence(int num_dimensions)
43+
: num_dimensions_(num_dimensions), current_idx_(0) {
44+
RTC_CHECK_GE(num_dimensions_, 1)
45+
<< "num_dimensions must be >= 1. Will be set to 1.";
46+
RTC_CHECK_LE(num_dimensions_, kMaxDimensions)
47+
<< "num_dimensions must be <= " << kMaxDimensions << ". Will be set to "
48+
<< kMaxDimensions << ".";
49+
num_dimensions_ = std::clamp(num_dimensions_, 1, kMaxDimensions);
50+
}
51+
52+
std::vector<double> HaltonSequence::GetNext() {
53+
std::vector<double> point = {};
54+
point.reserve(num_dimensions_);
55+
for (int i = 0; i < num_dimensions_; ++i) {
56+
point.push_back(GetVanDerCorputSequenceElement(current_idx_, kBases[i]));
57+
}
58+
++current_idx_;
59+
return point;
60+
}
61+
62+
void HaltonSequence::Reset() {
63+
HaltonSequence::current_idx_ = 0;
64+
}
65+
66+
} // namespace webrtc
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2024 The WebRTC project authors. All rights reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
11+
#ifndef VIDEO_CORRUPTION_DETECTION_HALTON_SEQUENCE_H_
12+
#define VIDEO_CORRUPTION_DETECTION_HALTON_SEQUENCE_H_
13+
14+
#include <vector>
15+
16+
namespace webrtc {
17+
18+
// Generates the Halton sequence: a low discrepancy sequence of doubles in the
19+
// half-open interval [0,1). See https://en.wikipedia.org/wiki/Halton_sequence
20+
// for information on how the sequence is constructed.
21+
class HaltonSequence {
22+
public:
23+
// Creates a sequence in `num_dimensions` number of dimensions. Possible
24+
// values are [1, 5].
25+
explicit HaltonSequence(int num_dimensions);
26+
// Creates a default sequence in a single dimension.
27+
HaltonSequence() = default;
28+
HaltonSequence(const HaltonSequence&) = default;
29+
HaltonSequence(HaltonSequence&&) = default;
30+
HaltonSequence& operator=(const HaltonSequence&) = default;
31+
HaltonSequence& operator=(HaltonSequence&&) = default;
32+
~HaltonSequence() = default;
33+
34+
// Gets the next point in the sequence where each value is in the half-open
35+
// interval [0,1).
36+
std::vector<double> GetNext();
37+
int GetCurrentIndex() const { return current_idx_; }
38+
void SetCurrentIndex(int idx) { current_idx_ = idx; }
39+
void Reset();
40+
41+
private:
42+
int num_dimensions_ = 1;
43+
int current_idx_ = 0;
44+
};
45+
46+
} // namespace webrtc
47+
48+
#endif // VIDEO_CORRUPTION_DETECTION_HALTON_SEQUENCE_H_
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2024 The WebRTC project authors. All rights reserved.
3+
*
4+
* Use of this source code is governed by a BSD-style license
5+
* that can be found in the LICENSE file in the root of the source
6+
* tree. An additional intellectual property rights grant can be found
7+
* in the file PATENTS. All contributing project authors may
8+
* be found in the AUTHORS file in the root of the source tree.
9+
*/
10+
11+
#include "video/corruption_detection/halton_sequence.h"
12+
13+
#include "test/gmock.h"
14+
#include "test/gtest.h"
15+
16+
namespace webrtc {
17+
namespace {
18+
19+
using ::testing::DoubleEq;
20+
using ::testing::ElementsAre;
21+
22+
TEST(HaltonSequenceTest, ShouldGenerateBase2SequenceByDefault) {
23+
HaltonSequence halton_sequence;
24+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(0.0)));
25+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(1.0 / 2)));
26+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(1.0 / 4)));
27+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(3.0 / 4)));
28+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(1.0 / 8)));
29+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(5.0 / 8)));
30+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(3.0 / 8)));
31+
}
32+
33+
TEST(HaltonSequenceTest,
34+
ShouldGenerateBase2Base3SequencesWhenCreatedAs2Dimensional) {
35+
HaltonSequence halton_sequence(2);
36+
EXPECT_THAT(halton_sequence.GetNext(),
37+
ElementsAre(DoubleEq(0.0), DoubleEq(0.0)));
38+
EXPECT_THAT(halton_sequence.GetNext(),
39+
ElementsAre(DoubleEq(1.0 / 2), DoubleEq(1.0 / 3)));
40+
EXPECT_THAT(halton_sequence.GetNext(),
41+
ElementsAre(DoubleEq(1.0 / 4), DoubleEq(2.0 / 3)));
42+
EXPECT_THAT(halton_sequence.GetNext(),
43+
ElementsAre(DoubleEq(3.0 / 4), DoubleEq(1.0 / 9)));
44+
EXPECT_THAT(halton_sequence.GetNext(),
45+
ElementsAre(DoubleEq(1.0 / 8), DoubleEq(4.0 / 9)));
46+
EXPECT_THAT(halton_sequence.GetNext(),
47+
ElementsAre(DoubleEq(5.0 / 8), DoubleEq(7.0 / 9)));
48+
EXPECT_THAT(halton_sequence.GetNext(),
49+
ElementsAre(DoubleEq(3.0 / 8), DoubleEq(2.0 / 9)));
50+
}
51+
52+
TEST(HaltonSequenceTest, ShouldRestartSequenceWhenResetIsCalled) {
53+
HaltonSequence halton_sequence;
54+
EXPECT_THAT(halton_sequence.GetCurrentIndex(), 0);
55+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(0.0)));
56+
EXPECT_THAT(halton_sequence.GetCurrentIndex(), 1);
57+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(1.0 / 2)));
58+
EXPECT_THAT(halton_sequence.GetCurrentIndex(), 2);
59+
halton_sequence.Reset();
60+
EXPECT_THAT(halton_sequence.GetCurrentIndex(), 0);
61+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(0.0)));
62+
}
63+
64+
TEST(HaltonSequenceTest, ShouldSetCurrentIndexWhenSetCurrentIndexIsCalled) {
65+
HaltonSequence halton_sequence;
66+
EXPECT_THAT(halton_sequence.GetCurrentIndex(), 0);
67+
halton_sequence.SetCurrentIndex(3);
68+
EXPECT_THAT(halton_sequence.GetCurrentIndex(), 3);
69+
EXPECT_THAT(halton_sequence.GetNext(), ElementsAre(DoubleEq(3.0 / 4)));
70+
}
71+
72+
} // namespace
73+
} // namespace webrtc

0 commit comments

Comments
 (0)