xref: /aosp_15_r20/external/libgav1/src/utils/entropy_decoder_test.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
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