2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
16 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
18 #include "test/acm_random.h"
19 #include "aom/aom_integer.h"
20 #include "aom_dsp/bitreader.h"
21 #include "aom_dsp/bitwriter.h"
23 using libaom_test::ACMRandom
;
26 const int num_tests
= 10;
29 TEST(AV1
, TestBitIO
) {
30 ACMRandom
rnd(ACMRandom::DeterministicSeed());
31 for (int n
= 0; n
< num_tests
; ++n
) {
32 for (int method
= 0; method
<= 7; ++method
) { // we generate various proba
33 const int kBitsToTest
= 1000;
34 uint8_t probas
[kBitsToTest
];
36 for (int i
= 0; i
< kBitsToTest
; ++i
) {
37 const int parity
= i
& 1;
38 /* clang-format off */
40 (method
== 0) ? 0 : (method
== 1) ? 255 :
42 (method
== 3) ? rnd
.Rand8() :
43 (method
== 4) ? (parity
? 0 : 255) :
44 // alternate between low and high proba:
45 (method
== 5) ? (parity
? rnd(128) : 255 - rnd(128)) :
47 (parity
? rnd(64) : 255 - rnd(64)) :
48 (parity
? rnd(32) : 255 - rnd(32));
51 for (int bit_method
= 0; bit_method
<= 3; ++bit_method
) {
52 const int random_seed
= 6432;
53 const int kBufferSize
= 10000;
54 ACMRandom
bit_rnd(random_seed
);
56 uint8_t bw_buffer
[kBufferSize
];
57 aom_start_encode(&bw
, bw_buffer
);
59 int bit
= (bit_method
== 0) ? 0 : (bit_method
== 1) ? 1 : 0;
60 for (int i
= 0; i
< kBitsToTest
; ++i
) {
61 if (bit_method
== 2) {
63 } else if (bit_method
== 3) {
66 aom_write(&bw
, bit
, static_cast<int>(probas
[i
]));
72 aom_reader_init(&br
, bw_buffer
, bw
.pos
);
73 bit_rnd
.Reset(random_seed
);
74 for (int i
= 0; i
< kBitsToTest
; ++i
) {
75 if (bit_method
== 2) {
77 } else if (bit_method
== 3) {
80 GTEST_ASSERT_EQ(aom_read(&br
, probas
[i
], NULL
), bit
)
81 << "pos: " << i
<< " / " << kBitsToTest
82 << " bit_method: " << bit_method
<< " method: " << method
;
89 #define FRAC_DIFF_TOTAL_ERROR 0.18
92 const int kBufferSize
= 10000;
94 uint8_t bw_buffer
[kBufferSize
];
95 const int kSymbols
= 1024;
96 // Coders are noisier at low probabilities, so we start at p = 4.
97 for (int p
= 4; p
< 256; p
++) {
98 double probability
= p
/ 256.;
99 aom_start_encode(&bw
, bw_buffer
);
100 for (int i
= 0; i
< kSymbols
; i
++) {
101 aom_write(&bw
, 0, p
);
103 aom_stop_encode(&bw
);
105 aom_reader_init(&br
, bw_buffer
, bw
.pos
);
106 uint32_t last_tell
= aom_reader_tell(&br
);
107 uint32_t last_tell_frac
= aom_reader_tell_frac(&br
);
108 double frac_diff_total
= 0;
109 GTEST_ASSERT_GE(aom_reader_tell(&br
), 0u);
110 GTEST_ASSERT_LE(aom_reader_tell(&br
), 1u);
111 ASSERT_FALSE(aom_reader_has_overflowed(&br
));
112 for (int i
= 0; i
< kSymbols
; i
++) {
113 aom_read(&br
, p
, NULL
);
114 uint32_t tell
= aom_reader_tell(&br
);
115 uint32_t tell_frac
= aom_reader_tell_frac(&br
);
116 GTEST_ASSERT_GE(tell
, last_tell
)
117 << "tell: " << tell
<< ", last_tell: " << last_tell
;
118 GTEST_ASSERT_GE(tell_frac
, last_tell_frac
)
119 << "tell_frac: " << tell_frac
120 << ", last_tell_frac: " << last_tell_frac
;
121 // Frac tell should round up to tell.
122 GTEST_ASSERT_EQ(tell
, (tell_frac
+ 7) >> 3);
125 fabs(((tell_frac
- last_tell_frac
) / 8.0) + log2(probability
));
126 last_tell_frac
= tell_frac
;
128 const uint32_t expected
= (uint32_t)(-kSymbols
* log2(probability
));
129 // Last tell should be close to the expected value.
130 GTEST_ASSERT_LE(last_tell
, expected
+ 20) << " last_tell: " << last_tell
;
131 // The average frac_diff error should be pretty small.
132 GTEST_ASSERT_LE(frac_diff_total
/ kSymbols
, FRAC_DIFF_TOTAL_ERROR
)
133 << " frac_diff_total: " << frac_diff_total
;
134 ASSERT_FALSE(aom_reader_has_overflowed(&br
));
138 TEST(AV1
, TestHasOverflowed
) {
139 const int kBufferSize
= 10000;
141 uint8_t bw_buffer
[kBufferSize
];
142 const int kSymbols
= 1024;
143 // Coders are noisier at low probabilities, so we start at p = 4.
144 for (int p
= 4; p
< 256; p
++) {
145 aom_start_encode(&bw
, bw_buffer
);
146 for (int i
= 0; i
< kSymbols
; i
++) {
147 aom_write(&bw
, 1, p
);
149 aom_stop_encode(&bw
);
151 aom_reader_init(&br
, bw_buffer
, bw
.pos
);
152 ASSERT_FALSE(aom_reader_has_overflowed(&br
));
153 for (int i
= 0; i
< kSymbols
; i
++) {
154 GTEST_ASSERT_EQ(aom_read(&br
, p
, NULL
), 1);
155 ASSERT_FALSE(aom_reader_has_overflowed(&br
));
157 // In the worst case, the encoder uses just a tiny fraction of the last
158 // byte in the buffer. So to guarantee that aom_reader_has_overflowed()
159 // returns true, we have to consume very nearly 8 additional bits of data.
160 // In the worse case, one of the bits in that byte will be 1, and the rest
161 // will be zero. Once we are past that 1 bit, when the probability of
162 // reading zero symbol from aom_read() is high, each additional symbol read
163 // will consume very little additional data (in the case that p == 255,
164 // approximately -log_2(255/256) ~= 0.0056 bits). In that case it would
165 // take around 178 calls to consume more than 8 bits. That is only an upper
166 // bound. In practice we are not guaranteed to hit the worse case and can
167 // get away with 174 calls.
168 for (int i
= 0; i
< 174; i
++) {
169 aom_read(&br
, p
, NULL
);
171 ASSERT_TRUE(aom_reader_has_overflowed(&br
));