1 /*
2  * Copyright (c) 2017, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
13 
14 #include <cstdlib>
15 
16 #include "aom_dsp/entenc.h"
17 #include "aom_dsp/entdec.h"
18 
TEST(EC_TEST,random_ec_test)19 TEST(EC_TEST, random_ec_test) {
20   od_ec_enc enc;
21   od_ec_dec dec;
22   int sz;
23   int i;
24   int ret;
25   unsigned int sym;
26   unsigned int seed;
27   unsigned char *ptr;
28   uint32_t ptr_sz;
29   char *seed_str;
30   ret = 0;
31   seed_str = getenv("EC_TEST_SEED");
32   if (seed_str) {
33     seed = atoi(seed_str);
34   } else {
35     seed = 0xdaa1a;
36   }
37   srand(seed);
38   od_ec_enc_init(&enc, 1);
39   /*Test compatibility between multiple different encode/decode routines.*/
40   for (i = 0; i < 409600; i++) {
41     unsigned *fz;
42     unsigned *fts;
43     unsigned *data;
44     unsigned *tell;
45     unsigned *enc_method;
46     int j;
47     sz = rand() / ((RAND_MAX >> (rand() % 9U)) + 1U);
48     fz = (unsigned *)malloc(sz * sizeof(*fz));
49     fts = (unsigned *)malloc(sz * sizeof(*fts));
50     data = (unsigned *)malloc(sz * sizeof(*data));
51     tell = (unsigned *)malloc((sz + 1) * sizeof(*tell));
52     enc_method = (unsigned *)malloc(sz * sizeof(*enc_method));
53     od_ec_enc_reset(&enc);
54     tell[0] = od_ec_enc_tell_frac(&enc);
55     for (j = 0; j < sz; j++) {
56       data[j] = rand() / ((RAND_MAX >> 1) + 1);
57 
58       fts[j] = CDF_PROB_BITS;
59       fz[j] = (rand() % (CDF_PROB_TOP - 2)) >> (CDF_PROB_BITS - fts[j]);
60       fz[j] = OD_MAXI(fz[j], 1);
61       enc_method[j] = 3 + (rand() & 1);
62       switch (enc_method[j]) {
63         case 3: {
64           od_ec_encode_bool_q15(&enc, data[j],
65                                 OD_ICDF(fz[j] << (CDF_PROB_BITS - fts[j])));
66           break;
67         }
68         case 4: {
69           uint16_t cdf[2];
70           cdf[0] = OD_ICDF(fz[j]);
71           cdf[1] = OD_ICDF(1U << fts[j]);
72           od_ec_encode_cdf_q15(&enc, data[j], cdf, 2);
73           break;
74         }
75       }
76 
77       tell[j + 1] = od_ec_enc_tell_frac(&enc);
78     }
79     ptr = od_ec_enc_done(&enc, &ptr_sz);
80     EXPECT_GE(((od_ec_enc_tell(&enc) + 7U) >> 3), ptr_sz)
81         << "od_ec_enc_tell() lied: "
82            "there's "
83         << ptr_sz << " bytes instead of " << ((od_ec_enc_tell(&enc) + 7) >> 3)
84         << " (Random seed: " << seed << ")\n";
85     od_ec_dec_init(&dec, ptr, ptr_sz);
86     EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[0])
87         << "od_ec_dec_tell() mismatch between encoder and decoder "
88            "at symbol 0: "
89         << (unsigned)od_ec_dec_tell_frac(&dec) << " instead of " << tell[0]
90         << " (Random seed: " << seed << ").\n";
91     for (j = 0; j < sz; j++) {
92       int dec_method;
93       if (CDF_SHIFT == 0) {
94         dec_method = 3 + (rand() & 1);
95       } else {
96         dec_method = enc_method[j];
97       }
98       switch (dec_method) {
99         case 3: {
100           sym = od_ec_decode_bool_q15(
101               &dec, OD_ICDF(fz[j] << (CDF_PROB_BITS - fts[j])));
102           break;
103         }
104         case 4: {
105           uint16_t cdf[2];
106           cdf[0] = OD_ICDF(fz[j]);
107           cdf[1] = OD_ICDF(1U << fts[j]);
108           sym = od_ec_decode_cdf_q15(&dec, cdf, 2);
109           break;
110         }
111       }
112 
113       EXPECT_EQ(sym, data[j])
114           << "Decoded " << sym << " instead of " << data[j]
115           << " with fz=" << fz[j] << " and ftb=" << fts[j] << "at position "
116           << j << " of " << sz << " (Random seed: " << seed << ").\n"
117           << "Encoding method: " << enc_method[j]
118           << " decoding method: " << dec_method << "\n";
119       EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[j + 1])
120           << "od_ec_dec_tell() mismatch between encoder and "
121              "decoder at symbol "
122           << j + 1 << ": " << (unsigned)od_ec_dec_tell_frac(&dec)
123           << " instead of " << tell[j + 1] << " (Random seed: " << seed
124           << ").\n";
125     }
126     free(enc_method);
127     free(tell);
128     free(data);
129     free(fts);
130     free(fz);
131   }
132   od_ec_enc_reset(&enc);
133   if (CDF_SHIFT == 0) {
134     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
135     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
136     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
137     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
138     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576));
139     od_ec_enc_patch_initial_bits(&enc, 3, 2);
140     EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n";
141     od_ec_enc_patch_initial_bits(&enc, 0, 5);
142     EXPECT_TRUE(enc.error)
143         << "od_ec_enc_patch_initial_bits() didn't fail when it should have.\n";
144     od_ec_enc_reset(&enc);
145     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
146     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
147     od_ec_encode_bool_q15(&enc, 1, OD_ICDF(32256));
148     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576));
149     od_ec_enc_patch_initial_bits(&enc, 0, 2);
150     EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n";
151     ptr = od_ec_enc_done(&enc, &ptr_sz);
152     EXPECT_EQ(ptr_sz, 2u);
153     EXPECT_EQ(ptr[0], 63)
154         << "Got " << ptr[0]
155         << " when expecting 63 for od_ec_enc_patch_initial_bits().\n";
156   }
157   od_ec_enc_clear(&enc);
158   EXPECT_EQ(ret, 0);
159 }
160