1 // Copyright 2021 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/utils/entropy_decoder.h"
16
17 #include <cstdint>
18 #include <cstdio>
19
20 #include "absl/time/clock.h"
21 #include "absl/time/time.h"
22 #include "gtest/gtest.h"
23
24 namespace libgav1 {
25 namespace {
26
27 #include "src/utils/entropy_decoder_test_data.inc"
28
29 class EntropyDecoderTest : public testing::Test {
30 protected:
31 // If compile_time is true, tests
32 // bool EntropyDecoder::ReadSymbol(uint16_t* cdf).
33 // Otherwise, tests
34 // int EntropyDecoder::ReadSymbol(uint16_t* cdf, int symbol_count)
35 // with symbol_count=2.
36 template <bool compile_time>
37 void TestReadSymbolBoolean(int num_runs);
38
39 // For N = 3..16 (except 15):
40 // template <bool compile_time>
41 // void TestReadSymbolN(int num_runs);
42 //
43 // If compile_time is true, tests
44 // int EntropyDecoder::ReadSymbol<N>(uint16_t* const cdf).
45 // Otherwise, tests
46 // int EntropyDecoder::ReadSymbol(uint16_t* cdf, int symbol_count)
47 // with symbol_count=N.
48 //
49 // NOTE: symbol_count=15 is not tested because AV1 does not use it.
50 template <bool compile_time>
51 void TestReadSymbol3(int num_runs);
52
53 template <bool compile_time>
54 void TestReadSymbol4(int num_runs);
55
56 template <bool compile_time>
57 void TestReadSymbol5(int num_runs);
58
59 template <bool compile_time>
60 void TestReadSymbol6(int num_runs);
61
62 template <bool compile_time>
63 void TestReadSymbol7(int num_runs);
64
65 template <bool compile_time>
66 void TestReadSymbol8(int num_runs);
67
68 template <bool compile_time>
69 void TestReadSymbol9(int num_runs);
70
71 template <bool compile_time>
72 void TestReadSymbol10(int num_runs);
73
74 template <bool compile_time>
75 void TestReadSymbol11(int num_runs);
76
77 template <bool compile_time>
78 void TestReadSymbol12(int num_runs);
79
80 template <bool compile_time>
81 void TestReadSymbol13(int num_runs);
82
83 template <bool compile_time>
84 void TestReadSymbol14(int num_runs);
85
86 template <bool compile_time>
87 void TestReadSymbol16(int num_runs);
88 };
89
90 template <bool compile_time>
TestReadSymbolBoolean(int num_runs)91 void EntropyDecoderTest::TestReadSymbolBoolean(int num_runs) {
92 static constexpr int kSymbols[4][4] = {{0, 0, 1, 1}, //
93 {0, 1, 1, 0}, //
94 {1, 0, 1, 0}, //
95 {1, 0, 0, 1}};
96 absl::Duration elapsed_time;
97 bool symbols[1024 * 4 * 4];
98 for (int run = 0; run < num_runs; ++run) {
99 EntropyDecoder reader(kBytesTestReadSymbolBoolean,
100 kNumBytesTestReadSymbolBoolean,
101 /*allow_update_cdf=*/true);
102 uint16_t cdf[4][3] = {
103 {16384, 0, 0},
104 {32768 - 8386, 0, 0},
105 {32768 - 24312, 0, 0},
106 {16384, 0, 0},
107 };
108 const absl::Time start = absl::Now();
109 int index = 0;
110 for (int i = 0; i < 1024; ++i) {
111 for (int j = 0; j < 4; ++j) {
112 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
113 if (compile_time) {
114 symbols[index++] = reader.ReadSymbol(cdf[k]);
115 } else {
116 symbols[index++] = reader.ReadSymbol(cdf[k], 2) != 0;
117 }
118 }
119 }
120 }
121 elapsed_time += absl::Now() - start;
122 }
123 if (compile_time) {
124 printf("TestReadSymbolBooleanCompileTime(%d): %5d us\n", num_runs,
125 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
126 } else {
127 printf("TestReadSymbolBoolean(%d): %5d us\n", num_runs,
128 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
129 }
130
131 int index = 0;
132 for (int i = 0; i < 1024; ++i) {
133 for (int j = 0; j < 4; ++j) { // NOLINT(modernize-loop-convert)
134 for (int k = 0; k < 4; ++k) {
135 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
136 }
137 }
138 }
139 }
140
141 template <bool compile_time>
TestReadSymbol3(int num_runs)142 void EntropyDecoderTest::TestReadSymbol3(int num_runs) {
143 static constexpr int kSymbols[6][4] = {{0, 2, 1, 2}, //
144 {1, 1, 2, 1}, //
145 {2, 0, 0, 0}, //
146 {0, 2, 0, 2}, //
147 {1, 2, 1, 0}, //
148 {2, 1, 1, 0}};
149 absl::Duration elapsed_time;
150 int symbols[1024 * 6 * 4];
151 for (int run = 0; run < num_runs; ++run) {
152 EntropyDecoder reader(kBytesTestReadSymbol3, kNumBytesTestReadSymbol3,
153 /*allow_update_cdf=*/true);
154 uint16_t cdf[4][4] = {
155 // pdf: 1/3, 1/3, 1/3
156 {32768 - 10923, 32768 - 21845, 0, 0},
157 // pdf: 1/6, 2/6, 3/6
158 {32768 - 5461, 32768 - 16384, 0, 0},
159 // pdf: 2/6, 3/6, 1/6
160 {32768 - 10923, 32768 - 27307, 0, 0},
161 // pdf: 3/6, 1/6, 2/6
162 {32768 - 16384, 32768 - 21845, 0, 0},
163 };
164 const absl::Time start = absl::Now();
165 int index = 0;
166 for (int i = 0; i < 1024; ++i) {
167 for (int j = 0; j < 6; ++j) {
168 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
169 if (compile_time) {
170 symbols[index++] = reader.ReadSymbol<3>(cdf[k]);
171 } else {
172 symbols[index++] = reader.ReadSymbol(cdf[k], 3);
173 }
174 }
175 }
176 }
177 elapsed_time += absl::Now() - start;
178 }
179 if (compile_time) {
180 printf("TestReadSymbol3CompileTime(%d): %5d us\n", num_runs,
181 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
182 } else {
183 printf("TestReadSymbol3(%d): %5d us\n", num_runs,
184 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
185 }
186
187 int index = 0;
188 for (int i = 0; i < 1024; ++i) {
189 for (int j = 0; j < 6; ++j) { // NOLINT(modernize-loop-convert)
190 for (int k = 0; k < 4; ++k) {
191 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
192 }
193 }
194 }
195 }
196
197 template <bool compile_time>
TestReadSymbol4(int num_runs)198 void EntropyDecoderTest::TestReadSymbol4(int num_runs) {
199 static constexpr int kSymbols[8][4] = {{0, 0, 3, 3}, //
200 {0, 0, 2, 2}, //
201 {1, 1, 0, 0}, //
202 {1, 2, 1, 1}, //
203 {2, 2, 3, 2}, //
204 {2, 3, 2, 1}, //
205 {3, 3, 0, 0}, //
206 {3, 3, 1, 1}};
207 absl::Duration elapsed_time;
208 int symbols[1024 * 8 * 4];
209 for (int run = 0; run < num_runs; ++run) {
210 EntropyDecoder reader(kBytesTestReadSymbol4, kNumBytesTestReadSymbol4,
211 /*allow_update_cdf=*/true);
212 uint16_t cdf[4][5] = {
213 // pdf: 1/4, 1/4, 1/4, 1/4
214 {32768 - 8192, 32768 - 16384, 32768 - 24576, 0, 0},
215 // pdf: 2/8, 1/8, 2/8, 3/8
216 {32768 - 8192, 32768 - 12288, 32768 - 20480, 0, 0},
217 // pdf: 1/4, 1/4, 1/4, 1/4
218 {32768 - 8192, 32768 - 16384, 32768 - 24576, 0, 0},
219 // pdf: 2/8, 3/8, 2/8, 1/8
220 {32768 - 8192, 32768 - 20480, 32768 - 28672, 0, 0},
221 };
222 const absl::Time start = absl::Now();
223 int index = 0;
224 for (int i = 0; i < 1024; ++i) {
225 for (int j = 0; j < 8; ++j) {
226 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
227 if (compile_time) {
228 symbols[index++] = reader.ReadSymbol<4>(cdf[k]);
229 } else {
230 symbols[index++] = reader.ReadSymbol(cdf[k], 4);
231 }
232 }
233 }
234 }
235 elapsed_time += absl::Now() - start;
236 }
237 if (compile_time) {
238 printf("TestReadSymbol4CompileTime(%d): %5d us\n", num_runs,
239 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
240 } else {
241 printf("TestReadSymbol4(%d): %5d us\n", num_runs,
242 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
243 }
244
245 int index = 0;
246 for (int i = 0; i < 1024; ++i) {
247 for (int j = 0; j < 8; ++j) { // NOLINT(modernize-loop-convert)
248 for (int k = 0; k < 4; ++k) {
249 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
250 }
251 }
252 }
253 }
254
255 template <bool compile_time>
TestReadSymbol5(int num_runs)256 void EntropyDecoderTest::TestReadSymbol5(int num_runs) {
257 static constexpr int kSymbols[10][4] = {{0, 0, 4, 4}, //
258 {0, 1, 3, 3}, //
259 {1, 2, 2, 2}, //
260 {1, 3, 1, 1}, //
261 {2, 4, 0, 0}, //
262 {2, 0, 4, 3}, //
263 {3, 1, 3, 2}, //
264 {3, 2, 2, 1}, //
265 {4, 3, 1, 2}, //
266 {4, 0, 4, 2}};
267 absl::Duration elapsed_time;
268 int symbols[320 * 10 * 4];
269 for (int run = 0; run < num_runs; ++run) {
270 EntropyDecoder reader(kBytesTestReadSymbol5, kNumBytesTestReadSymbol5,
271 /*allow_update_cdf=*/true);
272 uint16_t cdf[4][6] = {
273 // pdf: 1/5, 1/5, 1/5, 1/5, 1/5
274 {32768 - 6554, 32768 - 13107, 32768 - 19661, 32768 - 26214, 0, 0},
275 // pdf: 3/10, 2/10, 2/10, 2/10, 1/10
276 {32768 - 9830, 32768 - 16384, 32768 - 22938, 32768 - 29491, 0, 0},
277 // pdf: 1/10, 2/10, 2/10, 2/10, 3/10
278 {32768 - 3277, 32768 - 9830, 32768 - 16384, 32768 - 22938, 0, 0},
279 // pdf: 1/10, 2/10, 4/10, 2/10, 1/10
280 {32768 - 3277, 32768 - 9830, 32768 - 22938, 32768 - 29491, 0, 0},
281 };
282 const absl::Time start = absl::Now();
283 int index = 0;
284 for (int i = 0; i < 320; ++i) {
285 for (int j = 0; j < 10; ++j) {
286 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
287 if (compile_time) {
288 symbols[index++] = reader.ReadSymbol<5>(cdf[k]);
289 } else {
290 symbols[index++] = reader.ReadSymbol(cdf[k], 5);
291 }
292 }
293 }
294 }
295 elapsed_time += absl::Now() - start;
296 }
297 if (compile_time) {
298 printf("TestReadSymbol5CompileTime(%d): %5d us\n", num_runs,
299 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
300 } else {
301 printf("TestReadSymbol5(%d): %5d us\n", num_runs,
302 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
303 }
304
305 int index = 0;
306 for (int i = 0; i < 320; ++i) {
307 for (int j = 0; j < 10; ++j) { // NOLINT(modernize-loop-convert)
308 for (int k = 0; k < 4; ++k) {
309 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
310 }
311 }
312 }
313 }
314
315 template <bool compile_time>
TestReadSymbol6(int num_runs)316 void EntropyDecoderTest::TestReadSymbol6(int num_runs) {
317 static constexpr int kSymbols[12][4] = {{0, 0, 5, 5}, //
318 {0, 1, 4, 4}, //
319 {1, 2, 3, 3}, //
320 {1, 3, 2, 2}, //
321 {2, 4, 1, 1}, //
322 {2, 5, 0, 0}, //
323 {3, 0, 5, 4}, //
324 {3, 1, 4, 3}, //
325 {4, 2, 3, 2}, //
326 {4, 3, 2, 1}, //
327 {5, 4, 1, 3}, //
328 {5, 0, 5, 2}};
329 absl::Duration elapsed_time;
330 int symbols[256 * 12 * 4];
331 for (int run = 0; run < num_runs; ++run) {
332 EntropyDecoder reader(kBytesTestReadSymbol6, kNumBytesTestReadSymbol6,
333 /*allow_update_cdf=*/true);
334 uint16_t cdf[4][7] = {
335 // pmf: 1/6, 1/6, 1/6, 1/6, 1/6, 1/6
336 {32768 - 5461, 32768 - 10923, 32768 - 16384, 32768 - 21845,
337 32768 - 27307, 0, 0},
338 // pmf: 3/12, 2/12, 2/12, 2/12, 2/12, 1/12
339 {32768 - 8192, 32768 - 13653, 32768 - 19115, 32768 - 24576,
340 32768 - 30037, 0, 0},
341 // pmf: 1/12, 2/12, 2/12, 2/12, 2/12, 3/12
342 {32768 - 2731, 32768 - 8192, 32768 - 13653, 32768 - 19115,
343 32768 - 24576, 0, 0},
344 // pmf: 1/12, 2/12, 3/12, 3/12, 2/12, 1/12
345 {32768 - 2731, 32768 - 8192, 32768 - 16384, 32768 - 24576,
346 32768 - 30037, 0, 0},
347 };
348 const absl::Time start = absl::Now();
349 int index = 0;
350 for (int i = 0; i < 256; ++i) {
351 for (int j = 0; j < 12; ++j) {
352 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
353 if (compile_time) {
354 symbols[index++] = reader.ReadSymbol<6>(cdf[k]);
355 } else {
356 symbols[index++] = reader.ReadSymbol(cdf[k], 6);
357 }
358 }
359 }
360 }
361 elapsed_time += absl::Now() - start;
362 }
363 if (compile_time) {
364 printf("TestReadSymbol6CompileTime(%d): %5d us\n", num_runs,
365 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
366 } else {
367 printf("TestReadSymbol6(%d): %5d us\n", num_runs,
368 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
369 }
370
371 int index = 0;
372 for (int i = 0; i < 256; ++i) {
373 for (int j = 0; j < 12; ++j) { // NOLINT(modernize-loop-convert)
374 for (int k = 0; k < 4; ++k) {
375 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
376 }
377 }
378 }
379 }
380
381 template <bool compile_time>
TestReadSymbol7(int num_runs)382 void EntropyDecoderTest::TestReadSymbol7(int num_runs) {
383 static constexpr int kSymbols[14][4] = {{0, 4, 6, 3}, //
384 {1, 5, 5, 2}, //
385 {2, 6, 4, 1}, //
386 {3, 0, 3, 0}, //
387 {4, 1, 2, 6}, //
388 {5, 2, 1, 5}, //
389 {6, 3, 0, 4}, //
390 {0, 0, 6, 5}, //
391 {2, 1, 4, 3}, //
392 {4, 3, 6, 1}, //
393 {6, 5, 2, 4}, //
394 {1, 0, 5, 2}, //
395 {3, 2, 3, 2}, //
396 {5, 4, 5, 3}};
397 absl::Duration elapsed_time;
398 int symbols[1024 * 14 * 4];
399 for (int run = 0; run < num_runs; ++run) {
400 EntropyDecoder reader(kBytesTestReadSymbol7, kNumBytesTestReadSymbol7,
401 /*allow_update_cdf=*/true);
402 uint16_t cdf[4][8] = {
403 // pdf: 1/7, 1/7, 1/7, 1/7, 1/7, 1/7, 1/7
404 {32768 - 4681, 32768 - 9362, 32768 - 14043, 32768 - 18725,
405 32768 - 23406, 32768 - 28087, 0, 0},
406 // pdf: 3/14, 2/14, 2/14, 2/14, 2/14, 2/14, 1/14
407 {32768 - 7022, 32768 - 11703, 32768 - 16384, 32768 - 21065,
408 32768 - 25746, 32768 - 30427, 0, 0},
409 // pdf: 1/14, 1/14, 2/14, 2/14, 2/14, 3/14, 3/14
410 {32768 - 2341, 32768 - 4681, 32768 - 9362, 32768 - 14043, 32768 - 18725,
411 32768 - 25746, 0, 0},
412 // pdf: 1/14, 2/14, 3/14, 3/14, 2/14, 2/14, 1/14
413 {32768 - 2341, 32768 - 7022, 32768 - 14043, 32768 - 21065,
414 32768 - 25746, 32768 - 30427, 0, 0},
415 };
416 const absl::Time start = absl::Now();
417 int index = 0;
418 for (int i = 0; i < 1024; ++i) {
419 for (int j = 0; j < 14; ++j) {
420 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
421 if (compile_time) {
422 symbols[index++] = reader.ReadSymbol<7>(cdf[k]);
423 } else {
424 symbols[index++] = reader.ReadSymbol(cdf[k], 7);
425 }
426 }
427 }
428 }
429 elapsed_time += absl::Now() - start;
430 }
431 if (compile_time) {
432 printf("TestReadSymbol7CompileTime(%d): %5d us\n", num_runs,
433 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
434 } else {
435 printf("TestReadSymbol7(%d): %5d us\n", num_runs,
436 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
437 }
438
439 int index = 0;
440 for (int i = 0; i < 1024; ++i) {
441 for (int j = 0; j < 14; ++j) { // NOLINT(modernize-loop-convert)
442 for (int k = 0; k < 4; ++k) {
443 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
444 }
445 }
446 }
447 }
448
449 template <bool compile_time>
TestReadSymbol8(int num_runs)450 void EntropyDecoderTest::TestReadSymbol8(int num_runs) {
451 static constexpr int kSymbols[16][4] = {{0, 4, 7, 3}, //
452 {1, 5, 6, 2}, //
453 {2, 6, 5, 1}, //
454 {3, 7, 4, 0}, //
455 {4, 0, 3, 7}, //
456 {5, 1, 2, 6}, //
457 {6, 2, 1, 5}, //
458 {7, 3, 0, 4}, //
459 {0, 0, 6, 5}, //
460 {2, 1, 4, 3}, //
461 {4, 3, 6, 4}, //
462 {6, 5, 2, 2}, //
463 {1, 0, 7, 3}, //
464 {3, 2, 5, 5}, //
465 {5, 4, 7, 2}, //
466 {7, 6, 3, 4}};
467 absl::Duration elapsed_time;
468 int symbols[1024 * 16 * 4];
469 for (int run = 0; run < num_runs; ++run) {
470 EntropyDecoder reader(kBytesTestReadSymbol8, kNumBytesTestReadSymbol8,
471 /*allow_update_cdf=*/true);
472 uint16_t cdf[4][9] = {
473 // pdf: 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8
474 {32768 - 4096, 32768 - 8192, 32768 - 12288, 32768 - 16384,
475 32768 - 20480, 32768 - 24576, 32768 - 28672, 0, 0},
476 // pdf: 3/16, 2/16, 2/16, 2/16, 2/16, 2/16, 2/16, 1/16
477 {32768 - 6144, 32768 - 10240, 32768 - 14336, 32768 - 18432,
478 32768 - 22528, 32768 - 26624, 32768 - 30720, 0, 0},
479 // pdf: 1/16, 1/16, 2/16, 2/16, 2/16, 2/16, 3/16, 3/16
480 {32768 - 2048, 32768 - 4096, 32768 - 8192, 32768 - 12288, 32768 - 16384,
481 32768 - 20480, 32768 - 26624, 0, 0},
482 // pdf: 1/16, 1/16, 3/16, 3/16, 3/16, 3/16, 1/16, 1/16
483 {32768 - 2048, 32768 - 4096, 32768 - 10240, 32768 - 16384,
484 32768 - 22528, 32768 - 28672, 32768 - 30720, 0, 0},
485 };
486 const absl::Time start = absl::Now();
487 int index = 0;
488 for (int i = 0; i < 1024; ++i) {
489 for (int j = 0; j < 16; ++j) {
490 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
491 if (compile_time) {
492 symbols[index++] = reader.ReadSymbol<8>(cdf[k]);
493 } else {
494 symbols[index++] = reader.ReadSymbol(cdf[k], 8);
495 }
496 }
497 }
498 }
499 elapsed_time += absl::Now() - start;
500 }
501 if (compile_time) {
502 printf("TestReadSymbol8CompileTime(%d): %5d us\n", num_runs,
503 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
504 } else {
505 printf("TestReadSymbol8(%d): %5d us\n", num_runs,
506 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
507 }
508
509 int index = 0;
510 for (int i = 0; i < 1024; ++i) {
511 for (int j = 0; j < 16; ++j) { // NOLINT(modernize-loop-convert)
512 for (int k = 0; k < 4; ++k) {
513 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
514 }
515 }
516 }
517 }
518
519 template <bool compile_time>
TestReadSymbol9(int num_runs)520 void EntropyDecoderTest::TestReadSymbol9(int num_runs) {
521 static constexpr int kSymbols[18][4] = {{0, 4, 8, 3}, //
522 {1, 5, 7, 2}, //
523 {2, 6, 6, 1}, //
524 {3, 7, 5, 0}, //
525 {4, 8, 4, 8}, //
526 {5, 0, 3, 7}, //
527 {6, 1, 2, 6}, //
528 {7, 2, 1, 5}, //
529 {8, 3, 0, 4}, //
530 {0, 0, 8, 7}, //
531 {2, 1, 6, 5}, //
532 {4, 3, 4, 3}, //
533 {6, 5, 2, 1}, //
534 {8, 7, 7, 6}, //
535 {1, 0, 5, 4}, //
536 {3, 2, 3, 2}, //
537 {5, 4, 1, 4}, //
538 {7, 6, 8, 4}};
539 absl::Duration elapsed_time;
540 int symbols[128 * 18 * 4];
541 for (int run = 0; run < num_runs; ++run) {
542 EntropyDecoder reader(kBytesTestReadSymbol9, kNumBytesTestReadSymbol9,
543 /*allow_update_cdf=*/true);
544 uint16_t cdf[4][10] = {
545 // pmf: 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9
546 {32768 - 3641, 32768 - 7282, 32768 - 10923, 32768 - 14564,
547 32768 - 18204, 32768 - 21845, 32768 - 25486, 32768 - 29127, 0, 0},
548 // pmf: 3/18, 2/18, 2/18, 2/18, 2/18, 2/18, 2/18, 2/18, 1/18
549 {32768 - 5461, 32768 - 9102, 32768 - 12743, 32768 - 16384,
550 32768 - 20025, 32768 - 23666, 32768 - 27307, 32768 - 30948, 0, 0},
551 // pmf: 1/18, 2/18, 2/18, 2/18, 2/18, 2/18, 2/18, 2/18, 3/18
552 {32768 - 1820, 32768 - 5461, 32768 - 9102, 32768 - 12743, 32768 - 16384,
553 32768 - 20025, 32768 - 23666, 32768 - 27307, 0, 0},
554 // pmf: 1/18, 2/18, 2/18, 2/18, 4/18, 2/18, 2/18, 2/18, 1/18
555 {32768 - 1820, 32768 - 5461, 32768 - 9102, 32768 - 12743, 32768 - 20025,
556 32768 - 23666, 32768 - 27307, 32768 - 30948, 0, 0},
557 };
558 const absl::Time start = absl::Now();
559 int index = 0;
560 for (int i = 0; i < 128; ++i) {
561 for (int j = 0; j < 18; ++j) {
562 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
563 if (compile_time) {
564 symbols[index++] = reader.ReadSymbol<9>(cdf[k]);
565 } else {
566 symbols[index++] = reader.ReadSymbol(cdf[k], 9);
567 }
568 }
569 }
570 }
571 elapsed_time += absl::Now() - start;
572 }
573 if (compile_time) {
574 printf("TestReadSymbol9CompileTime(%d): %5d us\n", num_runs,
575 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
576 } else {
577 printf("TestReadSymbol9(%d): %5d us\n", num_runs,
578 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
579 }
580
581 int index = 0;
582 for (int i = 0; i < 128; ++i) {
583 for (int j = 0; j < 18; ++j) { // NOLINT(modernize-loop-convert)
584 for (int k = 0; k < 4; ++k) {
585 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
586 }
587 }
588 }
589 }
590
591 template <bool compile_time>
TestReadSymbol10(int num_runs)592 void EntropyDecoderTest::TestReadSymbol10(int num_runs) {
593 static constexpr int kSymbols[20][4] = {{0, 5, 9, 4}, //
594 {1, 6, 8, 3}, //
595 {2, 7, 7, 2}, //
596 {3, 8, 6, 1}, //
597 {4, 9, 5, 0}, //
598 {5, 0, 4, 9}, //
599 {6, 1, 3, 8}, //
600 {7, 2, 2, 7}, //
601 {8, 3, 1, 6}, //
602 {9, 4, 0, 5}, //
603 {0, 0, 9, 7}, //
604 {2, 1, 8, 5}, //
605 {4, 3, 6, 3}, //
606 {6, 5, 4, 1}, //
607 {8, 7, 2, 8}, //
608 {1, 0, 9, 6}, //
609 {3, 2, 7, 4}, //
610 {5, 4, 5, 2}, //
611 {7, 6, 3, 5}, //
612 {9, 8, 1, 4}};
613 absl::Duration elapsed_time;
614 int symbols[96 * 20 * 4];
615 for (int run = 0; run < num_runs; ++run) {
616 EntropyDecoder reader(kBytesTestReadSymbol10, kNumBytesTestReadSymbol10,
617 /*allow_update_cdf=*/true);
618 uint16_t cdf[4][11] = {
619 // pmf: 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10, 1/10
620 {32768 - 3277, 32768 - 6554, 32768 - 9830, 32768 - 13107, 32768 - 16384,
621 32768 - 19661, 32768 - 22938, 32768 - 26214, 32768 - 29491, 0, 0},
622 // pmf: 3/20, 2/20, 2/20, 2/20, 2/20, 2/20, 2/20, 2/20, 2/20, 1/20
623 {32768 - 4915, 32768 - 8192, 32768 - 11469, 32768 - 14746,
624 32768 - 18022, 32768 - 21299, 32768 - 24576, 32768 - 27853,
625 32768 - 31130, 0, 0},
626 // pmf: 1/20, 2/20, 2/20, 2/20, 2/20, 2/20, 2/20, 2/20, 2/20, 3/20
627 {32768 - 1638, 32768 - 4915, 32768 - 8192, 32768 - 11469, 32768 - 14746,
628 32768 - 18022, 32768 - 21299, 32768 - 24576, 32768 - 27853, 0, 0},
629 // pmf: 1/20, 2/20, 2/20, 2/20, 3/20, 3/20, 2/20, 2/20, 2/20, 1/20
630 {32768 - 1638, 32768 - 4915, 32768 - 8192, 32768 - 11469, 32768 - 16384,
631 32768 - 21299, 32768 - 24576, 32768 - 27853, 32768 - 31130, 0, 0},
632 };
633 const absl::Time start = absl::Now();
634 int index = 0;
635 for (int i = 0; i < 96; ++i) {
636 for (int j = 0; j < 20; ++j) {
637 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
638 if (compile_time) {
639 symbols[index++] = reader.ReadSymbol<10>(cdf[k]);
640 } else {
641 symbols[index++] = reader.ReadSymbol(cdf[k], 10);
642 }
643 }
644 }
645 }
646 elapsed_time += absl::Now() - start;
647 }
648 if (compile_time) {
649 printf("TestReadSymbol10CompileTime(%d): %5d us\n", num_runs,
650 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
651 } else {
652 printf("TestReadSymbol10(%d): %5d us\n", num_runs,
653 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
654 }
655
656 int index = 0;
657 for (int i = 0; i < 96; ++i) {
658 for (int j = 0; j < 20; ++j) { // NOLINT(modernize-loop-convert)
659 for (int k = 0; k < 4; ++k) {
660 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
661 }
662 }
663 }
664 }
665
666 template <bool compile_time>
TestReadSymbol11(int num_runs)667 void EntropyDecoderTest::TestReadSymbol11(int num_runs) {
668 static constexpr int kSymbols[22][4] = {{0, 6, 10, 5}, //
669 {1, 7, 9, 4}, //
670 {2, 8, 8, 3}, //
671 {3, 9, 7, 2}, //
672 {4, 10, 6, 1}, //
673 {5, 0, 5, 0}, //
674 {6, 1, 4, 10}, //
675 {7, 2, 3, 9}, //
676 {8, 3, 2, 8}, //
677 {9, 4, 1, 7}, //
678 {10, 5, 0, 6}, //
679 {0, 0, 10, 9}, //
680 {2, 1, 8, 7}, //
681 {4, 3, 6, 5}, //
682 {6, 5, 4, 3}, //
683 {8, 7, 2, 1}, //
684 {10, 9, 10, 8}, //
685 {1, 0, 9, 6}, //
686 {3, 2, 7, 4}, //
687 {5, 4, 5, 2}, //
688 {7, 6, 3, 5}, //
689 {9, 8, 1, 5}};
690 absl::Duration elapsed_time;
691 int symbols[96 * 22 * 4];
692 for (int run = 0; run < num_runs; ++run) {
693 EntropyDecoder reader(kBytesTestReadSymbol11, kNumBytesTestReadSymbol11,
694 /*allow_update_cdf=*/true);
695 uint16_t cdf[4][12] = {
696 // pmf: 1/11, 1/11, 1/11, 1/11, 1/11, 1/11, 1/11, 1/11, 1/11, 1/11, 1/11
697 {32768 - 2979, 32768 - 5958, 32768 - 8937, 32768 - 11916, 32768 - 14895,
698 32768 - 17873, 32768 - 20852, 32768 - 23831, 32768 - 26810,
699 32768 - 29789, 0, 0},
700 // pmf: 3/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 1/22
701 {32768 - 4468, 32768 - 7447, 32768 - 10426, 32768 - 13405,
702 32768 - 16384, 32768 - 19363, 32768 - 22342, 32768 - 25321,
703 32768 - 28300, 32768 - 31279, 0, 0},
704 // pmf: 1/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 2/22, 3/22
705 {32768 - 1489, 32768 - 4468, 32768 - 7447, 32768 - 10426, 32768 - 13405,
706 32768 - 16384, 32768 - 19363, 32768 - 22342, 32768 - 25321,
707 32768 - 28300, 0, 0},
708 // pmf: 1/22, 2/22, 2/22, 2/22, 2/22, 4/22, 2/22, 2/22, 2/22, 2/22, 1/22
709 {32768 - 1489, 32768 - 4468, 32768 - 7447, 32768 - 10426, 32768 - 13405,
710 32768 - 19363, 32768 - 22342, 32768 - 25321, 32768 - 28300,
711 32768 - 31279, 0, 0},
712 };
713 const absl::Time start = absl::Now();
714 int index = 0;
715 for (int i = 0; i < 96; ++i) {
716 for (int j = 0; j < 22; ++j) {
717 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
718 if (compile_time) {
719 symbols[index++] = reader.ReadSymbol<11>(cdf[k]);
720 } else {
721 symbols[index++] = reader.ReadSymbol(cdf[k], 11);
722 }
723 }
724 }
725 }
726 elapsed_time += absl::Now() - start;
727 }
728 if (compile_time) {
729 printf("TestReadSymbol11CompileTime(%d): %5d us\n", num_runs,
730 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
731 } else {
732 printf("TestReadSymbol11(%d): %5d us\n", num_runs,
733 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
734 }
735
736 int index = 0;
737 for (int i = 0; i < 96; ++i) {
738 for (int j = 0; j < 22; ++j) { // NOLINT(modernize-loop-convert)
739 for (int k = 0; k < 4; ++k) {
740 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
741 }
742 }
743 }
744 }
745
746 template <bool compile_time>
TestReadSymbol12(int num_runs)747 void EntropyDecoderTest::TestReadSymbol12(int num_runs) {
748 static constexpr int kSymbols[24][4] = {{0, 6, 11, 5}, //
749 {1, 7, 10, 4}, //
750 {2, 8, 9, 3}, //
751 {3, 9, 8, 2}, //
752 {4, 10, 7, 1}, //
753 {5, 11, 6, 0}, //
754 {6, 0, 5, 11}, //
755 {7, 1, 4, 10}, //
756 {8, 2, 3, 9}, //
757 {9, 3, 2, 8}, //
758 {10, 4, 1, 7}, //
759 {11, 5, 0, 6}, //
760 {0, 0, 11, 9}, //
761 {2, 1, 10, 7}, //
762 {4, 3, 8, 5}, //
763 {6, 5, 6, 3}, //
764 {8, 7, 4, 1}, //
765 {10, 9, 2, 10}, //
766 {1, 0, 11, 8}, //
767 {3, 2, 9, 6}, //
768 {5, 4, 7, 4}, //
769 {7, 6, 5, 2}, //
770 {9, 8, 3, 6}, //
771 {11, 10, 1, 5}};
772 absl::Duration elapsed_time;
773 int symbols[80 * 24 * 4];
774 for (int run = 0; run < num_runs; ++run) {
775 EntropyDecoder reader(kBytesTestReadSymbol12, kNumBytesTestReadSymbol12,
776 /*allow_update_cdf=*/true);
777 uint16_t cdf[4][13] = {
778 // pmf: 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12,
779 // 1/12,
780 // 1/12
781 {32768 - 2731, 32768 - 5461, 32768 - 8192, 32768 - 10923, 32768 - 13653,
782 32768 - 16384, 32768 - 19115, 32768 - 21845, 32768 - 24576,
783 32768 - 27307, 32768 - 30037, 0, 0},
784 // pmf: 3/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24,
785 // 2/24,
786 // 1/24
787 {32768 - 4096, 32768 - 6827, 32768 - 9557, 32768 - 12288, 32768 - 15019,
788 32768 - 17749, 32768 - 20480, 32768 - 23211, 32768 - 25941,
789 32768 - 28672, 32768 - 31403, 0, 0},
790 // pmf: 1/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24, 2/24,
791 // 2/24,
792 // 3/24
793 {32768 - 1365, 32768 - 4096, 32768 - 6827, 32768 - 9557, 32768 - 12288,
794 32768 - 15019, 32768 - 17749, 32768 - 20480, 32768 - 23211,
795 32768 - 25941, 32768 - 28672, 0, 0},
796 // pmf: 1/24, 2/24, 2/24, 2/24, 2/24, 3/24, 3/24, 2/24, 2/24, 2/24,
797 // 2/24,
798 // 1/24
799 {32768 - 1365, 32768 - 4096, 32768 - 6827, 32768 - 9557, 32768 - 12288,
800 32768 - 16384, 32768 - 20480, 32768 - 23211, 32768 - 25941,
801 32768 - 28672, 32768 - 31403, 0, 0},
802 };
803 const absl::Time start = absl::Now();
804 int index = 0;
805 for (int i = 0; i < 80; ++i) {
806 for (int j = 0; j < 24; ++j) {
807 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
808 if (compile_time) {
809 symbols[index++] = reader.ReadSymbol<12>(cdf[k]);
810 } else {
811 symbols[index++] = reader.ReadSymbol(cdf[k], 12);
812 }
813 }
814 }
815 }
816 elapsed_time += absl::Now() - start;
817 }
818 if (compile_time) {
819 printf("TestReadSymbol12CompileTime(%d): %5d us\n", num_runs,
820 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
821 } else {
822 printf("TestReadSymbol12(%d): %5d us\n", num_runs,
823 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
824 }
825
826 int index = 0;
827 for (int i = 0; i < 80; ++i) {
828 for (int j = 0; j < 24; ++j) { // NOLINT(modernize-loop-convert)
829 for (int k = 0; k < 4; ++k) {
830 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
831 }
832 }
833 }
834 }
835
836 template <bool compile_time>
TestReadSymbol13(int num_runs)837 void EntropyDecoderTest::TestReadSymbol13(int num_runs) {
838 static constexpr int kSymbols[26][4] = {{0, 6, 12, 5}, //
839 {1, 7, 11, 4}, //
840 {2, 8, 10, 3}, //
841 {3, 9, 9, 2}, //
842 {4, 10, 8, 1}, //
843 {5, 11, 7, 0}, //
844 {6, 12, 6, 12}, //
845 {7, 0, 5, 11}, //
846 {8, 1, 4, 10}, //
847 {9, 2, 3, 9}, //
848 {10, 3, 2, 8}, //
849 {11, 4, 1, 7}, //
850 {12, 5, 0, 6}, //
851 {0, 0, 12, 11}, //
852 {2, 1, 10, 9}, //
853 {4, 3, 8, 7}, //
854 {6, 5, 6, 5}, //
855 {8, 7, 4, 3}, //
856 {10, 9, 2, 1}, //
857 {12, 11, 12, 10}, //
858 {1, 0, 11, 8}, //
859 {3, 2, 9, 6}, //
860 {5, 4, 7, 4}, //
861 {7, 6, 5, 2}, //
862 {9, 8, 3, 6}, //
863 {11, 10, 1, 6}};
864 absl::Duration elapsed_time;
865 int symbols[64 * 26 * 4];
866 for (int run = 0; run < num_runs; ++run) {
867 EntropyDecoder reader(kBytesTestReadSymbol13, kNumBytesTestReadSymbol13,
868 /*allow_update_cdf=*/true);
869 uint16_t cdf[4][14] = {
870 // pmf: 1/13, 1/13, 1/13, 1/13, 1/13, 1/13, 1/13, 1/13, 1/13, 1/13,
871 // 1/13, 1/13, 1/13
872 {32768 - 2521, 32768 - 5041, 32768 - 7562, 32768 - 10082, 32768 - 12603,
873 32768 - 15124, 32768 - 17644, 32768 - 20165, 32768 - 22686,
874 32768 - 25206, 32768 - 27727, 32768 - 30247, 0, 0},
875 // pmf: 3/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26,
876 // 2/26, 2/26, 1/26
877 {32768 - 3781, 32768 - 6302, 32768 - 8822, 32768 - 11343, 32768 - 13863,
878 32768 - 16384, 32768 - 18905, 32768 - 21425, 32768 - 23946,
879 32768 - 26466, 32768 - 28987, 32768 - 31508, 0, 0},
880 // pmf: 1/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26, 2/26,
881 // 2/26, 2/26, 3/26
882 {32768 - 1260, 32768 - 3781, 32768 - 6302, 32768 - 8822, 32768 - 11343,
883 32768 - 13863, 32768 - 16384, 32768 - 18905, 32768 - 21425,
884 32768 - 23946, 32768 - 26466, 32768 - 28987, 0, 0},
885 // pmf: 1/26, 2/26, 2/26, 2/26, 2/26, 2/26, 4/26, 2/26, 2/26, 2/26,
886 // 2/26, 2/26, 1/26
887 {32768 - 1260, 32768 - 3781, 32768 - 6302, 32768 - 8822, 32768 - 11343,
888 32768 - 13863, 32768 - 18905, 32768 - 21425, 32768 - 23946,
889 32768 - 26466, 32768 - 28987, 32768 - 31508, 0, 0},
890 };
891 const absl::Time start = absl::Now();
892 int index = 0;
893 for (int i = 0; i < 64; ++i) {
894 for (int j = 0; j < 26; ++j) {
895 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
896 if (compile_time) {
897 symbols[index++] = reader.ReadSymbol<13>(cdf[k]);
898 } else {
899 symbols[index++] = reader.ReadSymbol(cdf[k], 13);
900 }
901 }
902 }
903 }
904 elapsed_time += absl::Now() - start;
905 }
906 if (compile_time) {
907 printf("TestReadSymbol13CompileTime(%d): %5d us\n", num_runs,
908 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
909 } else {
910 printf("TestReadSymbol13(%d): %5d us\n", num_runs,
911 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
912 }
913
914 int index = 0;
915 for (int i = 0; i < 64; ++i) {
916 for (int j = 0; j < 26; ++j) { // NOLINT(modernize-loop-convert)
917 for (int k = 0; k < 4; ++k) {
918 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
919 }
920 }
921 }
922 }
923
924 template <bool compile_time>
TestReadSymbol14(int num_runs)925 void EntropyDecoderTest::TestReadSymbol14(int num_runs) {
926 static constexpr int kSymbols[28][4] = {{0, 7, 13, 6}, //
927 {1, 8, 12, 5}, //
928 {2, 9, 11, 4}, //
929 {3, 10, 10, 3}, //
930 {4, 11, 9, 2}, //
931 {5, 12, 8, 1}, //
932 {6, 13, 7, 0}, //
933 {7, 0, 6, 13}, //
934 {8, 1, 5, 12}, //
935 {9, 2, 4, 11}, //
936 {10, 3, 3, 10}, //
937 {11, 4, 2, 9}, //
938 {12, 5, 1, 8}, //
939 {13, 6, 0, 7}, //
940 {0, 0, 13, 11}, //
941 {2, 1, 12, 9}, //
942 {4, 3, 10, 7}, //
943 {6, 5, 8, 5}, //
944 {8, 7, 6, 3}, //
945 {10, 9, 4, 1}, //
946 {12, 11, 2, 12}, //
947 {1, 0, 13, 10}, //
948 {3, 2, 11, 8}, //
949 {5, 4, 9, 6}, //
950 {7, 6, 7, 4}, //
951 {9, 8, 5, 2}, //
952 {11, 10, 3, 7}, //
953 {13, 12, 1, 6}};
954 absl::Duration elapsed_time;
955 int symbols[64 * 28 * 4];
956 for (int run = 0; run < num_runs; ++run) {
957 EntropyDecoder reader(kBytesTestReadSymbol14, kNumBytesTestReadSymbol14,
958 /*allow_update_cdf=*/true);
959 uint16_t cdf[4][15] = {
960 // pmf: 1/14, 1/14, 1/14, 1/14, 1/14, 1/14, 1/14, 1/14, 1/14, 1/14,
961 // 1/14, 1/14, 1/14, 1/14
962 {32768 - 2341, 32768 - 4681, 32768 - 7022, 32768 - 9362, 32768 - 11703,
963 32768 - 14043, 32768 - 16384, 32768 - 18725, 32768 - 21065,
964 32768 - 23406, 32768 - 25746, 32768 - 28087, 32768 - 30427, 0, 0},
965 // pmf: 3/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28,
966 // 2/28, 2/28, 2/28, 1/28
967 {32768 - 3511, 32768 - 5851, 32768 - 8192, 32768 - 10533, 32768 - 12873,
968 32768 - 15214, 32768 - 17554, 32768 - 19895, 32768 - 22235,
969 32768 - 24576, 32768 - 26917, 32768 - 29257, 32768 - 31598, 0, 0},
970 // pmf: 1/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28, 2/28,
971 // 2/28, 2/28, 2/28, 3/28
972 {32768 - 1170, 32768 - 3511, 32768 - 5851, 32768 - 8192, 32768 - 10533,
973 32768 - 12873, 32768 - 15214, 32768 - 17554, 32768 - 19895,
974 32768 - 22235, 32768 - 24576, 32768 - 26917, 32768 - 29257, 0, 0},
975 // pmf: 1/28, 2/28, 2/28, 2/28, 2/28, 2/28, 3/28, 3/28, 2/28, 2/28,
976 // 2/28, 2/28, 2/28, 1/28
977 {32768 - 1170, 32768 - 3511, 32768 - 5851, 32768 - 8192, 32768 - 10533,
978 32768 - 12873, 32768 - 16384, 32768 - 19895, 32768 - 22235,
979 32768 - 24576, 32768 - 26917, 32768 - 29257, 32768 - 31598, 0, 0},
980 };
981 const absl::Time start = absl::Now();
982 int index = 0;
983 for (int i = 0; i < 64; ++i) {
984 for (int j = 0; j < 28; ++j) {
985 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
986 if (compile_time) {
987 symbols[index++] = reader.ReadSymbol<14>(cdf[k]);
988 } else {
989 symbols[index++] = reader.ReadSymbol(cdf[k], 14);
990 }
991 }
992 }
993 }
994 elapsed_time += absl::Now() - start;
995 }
996 if (compile_time) {
997 printf("TestReadSymbol14CompileTime(%d): %5d us\n", num_runs,
998 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
999 } else {
1000 printf("TestReadSymbol14(%d): %5d us\n", num_runs,
1001 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1002 }
1003
1004 int index = 0;
1005 for (int i = 0; i < 64; ++i) {
1006 for (int j = 0; j < 28; ++j) { // NOLINT(modernize-loop-convert)
1007 for (int k = 0; k < 4; ++k) {
1008 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
1009 }
1010 }
1011 }
1012 }
1013
1014 template <bool compile_time>
TestReadSymbol16(int num_runs)1015 void EntropyDecoderTest::TestReadSymbol16(int num_runs) {
1016 static constexpr int kSymbols[32][4] = {{0, 8, 15, 7}, //
1017 {1, 9, 14, 6}, //
1018 {2, 10, 13, 5}, //
1019 {3, 11, 12, 4}, //
1020 {4, 12, 11, 3}, //
1021 {5, 13, 10, 2}, //
1022 {6, 14, 9, 1}, //
1023 {7, 15, 8, 0}, //
1024 {8, 0, 7, 15}, //
1025 {9, 1, 6, 14}, //
1026 {10, 2, 5, 13}, //
1027 {11, 3, 4, 12}, //
1028 {12, 4, 3, 11}, //
1029 {13, 5, 2, 10}, //
1030 {14, 6, 1, 9}, //
1031 {15, 7, 0, 8}, //
1032 {0, 0, 15, 13}, //
1033 {2, 1, 14, 11}, //
1034 {4, 3, 12, 9}, //
1035 {6, 5, 10, 7}, //
1036 {8, 7, 8, 5}, //
1037 {10, 9, 6, 3}, //
1038 {12, 11, 4, 1}, //
1039 {14, 13, 2, 14}, //
1040 {1, 0, 15, 12}, //
1041 {3, 2, 13, 10}, //
1042 {5, 4, 11, 8}, //
1043 {7, 6, 9, 6}, //
1044 {9, 8, 7, 4}, //
1045 {11, 10, 5, 2}, //
1046 {13, 12, 3, 8}, //
1047 {15, 14, 1, 7}};
1048 absl::Duration elapsed_time;
1049 int symbols[48 * 32 * 4];
1050 for (int run = 0; run < num_runs; ++run) {
1051 EntropyDecoder reader(kBytesTestReadSymbol16, kNumBytesTestReadSymbol16,
1052 /*allow_update_cdf=*/true);
1053 uint16_t cdf[4][17] = {
1054 // pmf: 1/16, 1/16, 1/16, 1/16, 1/16, 1/16, 1/16, 1/16, 1/16, 1/16,
1055 // 1/16, 1/16, 1/16, 1/16, 1/16, 1/16
1056 {32768 - 2048, 32768 - 4096, 32768 - 6144, 32768 - 8192, 32768 - 10240,
1057 32768 - 12288, 32768 - 14336, 32768 - 16384, 32768 - 18432,
1058 32768 - 20480, 32768 - 22528, 32768 - 24576, 32768 - 26624,
1059 32768 - 28672, 32768 - 30720, 0, 0},
1060 // pmf: 3/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32,
1061 // 2/32, 2/32, 2/32, 2/32, 2/32, 1/32
1062 {32768 - 3072, 32768 - 5120, 32768 - 7168, 32768 - 9216, 32768 - 11264,
1063 32768 - 13312, 32768 - 15360, 32768 - 17408, 32768 - 19456,
1064 32768 - 21504, 32768 - 23552, 32768 - 25600, 32768 - 27648,
1065 32768 - 29696, 32768 - 31744, 0, 0},
1066 // pmf: 1/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32,
1067 // 2/32, 2/32, 2/32, 2/32, 2/32, 3/32
1068 {32768 - 1024, 32768 - 3072, 32768 - 5120, 32768 - 7168, 32768 - 9216,
1069 32768 - 11264, 32768 - 13312, 32768 - 15360, 32768 - 17408,
1070 32768 - 19456, 32768 - 21504, 32768 - 23552, 32768 - 25600,
1071 32768 - 27648, 32768 - 29696, 0, 0},
1072 // pmf: 1/32, 2/32, 2/32, 2/32, 2/32, 2/32, 2/32, 3/32, 3/32, 2/32,
1073 // 2/32, 2/32, 2/32, 2/32, 2/32, 1/32
1074 {32768 - 1024, 32768 - 3072, 32768 - 5120, 32768 - 7168, 32768 - 9216,
1075 32768 - 11264, 32768 - 13312, 32768 - 16384, 32768 - 19456,
1076 32768 - 21504, 32768 - 23552, 32768 - 25600, 32768 - 27648,
1077 32768 - 29696, 32768 - 31744, 0, 0},
1078 };
1079 const absl::Time start = absl::Now();
1080 int index = 0;
1081 for (int i = 0; i < 48; ++i) {
1082 for (int j = 0; j < 32; ++j) {
1083 for (int k = 0; k < 4; ++k) { // NOLINT(modernize-loop-convert)
1084 if (compile_time) {
1085 symbols[index++] = reader.ReadSymbol<16>(cdf[k]);
1086 } else {
1087 symbols[index++] = reader.ReadSymbol(cdf[k], 16);
1088 }
1089 }
1090 }
1091 }
1092 elapsed_time += absl::Now() - start;
1093 }
1094 if (compile_time) {
1095 printf("TestReadSymbol16CompileTime(%d): %5d us\n", num_runs,
1096 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1097 } else {
1098 printf("TestReadSymbol16(%d): %5d us\n", num_runs,
1099 static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1100 }
1101
1102 int index = 0;
1103 for (int i = 0; i < 48; ++i) {
1104 for (int j = 0; j < 32; ++j) { // NOLINT(modernize-loop-convert)
1105 for (int k = 0; k < 4; ++k) {
1106 ASSERT_EQ(symbols[index++], kSymbols[j][k]);
1107 }
1108 }
1109 }
1110 }
1111
TEST_F(EntropyDecoderTest,ReadSymbolBoolean)1112 TEST_F(EntropyDecoderTest, ReadSymbolBoolean) {
1113 TestReadSymbolBoolean</*compile_time=*/false>(1);
1114 }
1115
TEST_F(EntropyDecoderTest,ReadSymbolBooleanCompileTime)1116 TEST_F(EntropyDecoderTest, ReadSymbolBooleanCompileTime) {
1117 TestReadSymbolBoolean</*compile_time=*/true>(1);
1118 }
1119
TEST_F(EntropyDecoderTest,ReadSymbol3)1120 TEST_F(EntropyDecoderTest, ReadSymbol3) {
1121 TestReadSymbol3</*compile_time=*/false>(1);
1122 }
1123
TEST_F(EntropyDecoderTest,ReadSymbol3CompileTime)1124 TEST_F(EntropyDecoderTest, ReadSymbol3CompileTime) {
1125 TestReadSymbol3</*compile_time=*/true>(1);
1126 }
1127
TEST_F(EntropyDecoderTest,ReadSymbol4)1128 TEST_F(EntropyDecoderTest, ReadSymbol4) {
1129 TestReadSymbol4</*compile_time=*/false>(1);
1130 }
1131
TEST_F(EntropyDecoderTest,ReadSymbol4CompileTime)1132 TEST_F(EntropyDecoderTest, ReadSymbol4CompileTime) {
1133 TestReadSymbol4</*compile_time=*/true>(1);
1134 }
1135
TEST_F(EntropyDecoderTest,ReadSymbol5)1136 TEST_F(EntropyDecoderTest, ReadSymbol5) {
1137 TestReadSymbol5</*compile_time=*/false>(1);
1138 }
1139
TEST_F(EntropyDecoderTest,ReadSymbol5CompileTime)1140 TEST_F(EntropyDecoderTest, ReadSymbol5CompileTime) {
1141 TestReadSymbol5</*compile_time=*/true>(1);
1142 }
1143
TEST_F(EntropyDecoderTest,ReadSymbol6)1144 TEST_F(EntropyDecoderTest, ReadSymbol6) {
1145 TestReadSymbol6</*compile_time=*/false>(1);
1146 }
1147
TEST_F(EntropyDecoderTest,ReadSymbol6CompileTime)1148 TEST_F(EntropyDecoderTest, ReadSymbol6CompileTime) {
1149 TestReadSymbol6</*compile_time=*/true>(1);
1150 }
1151
TEST_F(EntropyDecoderTest,ReadSymbol7)1152 TEST_F(EntropyDecoderTest, ReadSymbol7) {
1153 TestReadSymbol7</*compile_time=*/false>(1);
1154 }
1155
TEST_F(EntropyDecoderTest,ReadSymbol7CompileTime)1156 TEST_F(EntropyDecoderTest, ReadSymbol7CompileTime) {
1157 TestReadSymbol7</*compile_time=*/true>(1);
1158 }
1159
TEST_F(EntropyDecoderTest,ReadSymbol8)1160 TEST_F(EntropyDecoderTest, ReadSymbol8) {
1161 TestReadSymbol8</*compile_time=*/false>(1);
1162 }
1163
TEST_F(EntropyDecoderTest,ReadSymbol8CompileTime)1164 TEST_F(EntropyDecoderTest, ReadSymbol8CompileTime) {
1165 TestReadSymbol8</*compile_time=*/true>(1);
1166 }
1167
TEST_F(EntropyDecoderTest,ReadSymbol9)1168 TEST_F(EntropyDecoderTest, ReadSymbol9) {
1169 TestReadSymbol9</*compile_time=*/false>(1);
1170 }
1171
TEST_F(EntropyDecoderTest,ReadSymbol9CompileTime)1172 TEST_F(EntropyDecoderTest, ReadSymbol9CompileTime) {
1173 TestReadSymbol9</*compile_time=*/true>(1);
1174 }
1175
TEST_F(EntropyDecoderTest,ReadSymbol10)1176 TEST_F(EntropyDecoderTest, ReadSymbol10) {
1177 TestReadSymbol10</*compile_time=*/false>(1);
1178 }
1179
TEST_F(EntropyDecoderTest,ReadSymbol10CompileTime)1180 TEST_F(EntropyDecoderTest, ReadSymbol10CompileTime) {
1181 TestReadSymbol10</*compile_time=*/true>(1);
1182 }
1183
TEST_F(EntropyDecoderTest,ReadSymbol11)1184 TEST_F(EntropyDecoderTest, ReadSymbol11) {
1185 TestReadSymbol11</*compile_time=*/false>(1);
1186 }
1187
TEST_F(EntropyDecoderTest,ReadSymbol11CompileTime)1188 TEST_F(EntropyDecoderTest, ReadSymbol11CompileTime) {
1189 TestReadSymbol11</*compile_time=*/true>(1);
1190 }
1191
TEST_F(EntropyDecoderTest,ReadSymbol12)1192 TEST_F(EntropyDecoderTest, ReadSymbol12) {
1193 TestReadSymbol12</*compile_time=*/false>(1);
1194 }
1195
TEST_F(EntropyDecoderTest,ReadSymbol12CompileTime)1196 TEST_F(EntropyDecoderTest, ReadSymbol12CompileTime) {
1197 TestReadSymbol12</*compile_time=*/true>(1);
1198 }
1199
TEST_F(EntropyDecoderTest,ReadSymbol13)1200 TEST_F(EntropyDecoderTest, ReadSymbol13) {
1201 TestReadSymbol13</*compile_time=*/false>(1);
1202 }
1203
TEST_F(EntropyDecoderTest,ReadSymbol13CompileTime)1204 TEST_F(EntropyDecoderTest, ReadSymbol13CompileTime) {
1205 TestReadSymbol13</*compile_time=*/true>(1);
1206 }
1207
TEST_F(EntropyDecoderTest,ReadSymbol14)1208 TEST_F(EntropyDecoderTest, ReadSymbol14) {
1209 TestReadSymbol14</*compile_time=*/false>(1);
1210 }
1211
TEST_F(EntropyDecoderTest,ReadSymbol14CompileTime)1212 TEST_F(EntropyDecoderTest, ReadSymbol14CompileTime) {
1213 TestReadSymbol14</*compile_time=*/true>(1);
1214 }
1215
TEST_F(EntropyDecoderTest,ReadSymbol16)1216 TEST_F(EntropyDecoderTest, ReadSymbol16) {
1217 TestReadSymbol16</*compile_time=*/false>(1);
1218 }
1219
TEST_F(EntropyDecoderTest,ReadSymbol16CompileTime)1220 TEST_F(EntropyDecoderTest, ReadSymbol16CompileTime) {
1221 TestReadSymbol16</*compile_time=*/true>(1);
1222 }
1223
TEST_F(EntropyDecoderTest,DISABLED_Speed)1224 TEST_F(EntropyDecoderTest, DISABLED_Speed) {
1225 // compile_time=true is only tested for those symbol_count values that have
1226 // an instantiation of the EntropyDecoder::ReadSymbol<symbol_count> template
1227 // method.
1228 TestReadSymbolBoolean</*compile_time=*/false>(10000);
1229 TestReadSymbolBoolean</*compile_time=*/true>(10000);
1230 TestReadSymbol3</*compile_time=*/false>(5000);
1231 TestReadSymbol3</*compile_time=*/true>(5000);
1232 TestReadSymbol4</*compile_time=*/false>(2000);
1233 TestReadSymbol4</*compile_time=*/true>(2000);
1234 TestReadSymbol5</*compile_time=*/false>(5000);
1235 TestReadSymbol5</*compile_time=*/true>(5000);
1236 TestReadSymbol6</*compile_time=*/false>(5000);
1237 TestReadSymbol6</*compile_time=*/true>(5000);
1238 TestReadSymbol7</*compile_time=*/false>(1000);
1239 TestReadSymbol7</*compile_time=*/true>(1000);
1240 TestReadSymbol8</*compile_time=*/false>(1000);
1241 TestReadSymbol8</*compile_time=*/true>(1000);
1242 TestReadSymbol9</*compile_time=*/false>(5000);
1243 TestReadSymbol9</*compile_time=*/true>(5000);
1244 TestReadSymbol10</*compile_time=*/false>(5000);
1245 TestReadSymbol10</*compile_time=*/true>(5000);
1246 TestReadSymbol11</*compile_time=*/false>(5000);
1247 TestReadSymbol11</*compile_time=*/true>(5000);
1248 TestReadSymbol12</*compile_time=*/false>(5000);
1249 TestReadSymbol12</*compile_time=*/true>(5000);
1250 TestReadSymbol13</*compile_time=*/false>(5000);
1251 TestReadSymbol13</*compile_time=*/true>(5000);
1252 TestReadSymbol14</*compile_time=*/false>(5000);
1253 TestReadSymbol14</*compile_time=*/true>(5000);
1254 TestReadSymbol16</*compile_time=*/false>(5000);
1255 TestReadSymbol16</*compile_time=*/true>(5000);
1256 }
1257
1258 } // namespace
1259 } // namespace libgav1
1260