• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <memory>
16 #include <new>
17 
18 #include "aom_dsp/entenc.h"
19 #include "aom_dsp/entdec.h"
20 
TEST(EC_TEST,random_ec_test)21 TEST(EC_TEST, random_ec_test) {
22   od_ec_enc enc;
23   od_ec_dec dec;
24   int sz;
25   int i;
26   int ret;
27   unsigned int seed;
28   unsigned char *ptr;
29   uint32_t ptr_sz;
30   char *seed_str;
31   ret = 0;
32   seed_str = getenv("EC_TEST_SEED");
33   if (seed_str) {
34     seed = atoi(seed_str);
35   } else {
36     seed = 0xdaa1a;
37   }
38   srand(seed);
39   od_ec_enc_init(&enc, 1);
40   /*Test compatibility between multiple different encode/decode routines.*/
41   for (i = 0; i < 409600; i++) {
42     int j;
43     sz = rand() / ((RAND_MAX >> (rand() % 9U)) + 1U);
44     std::unique_ptr<unsigned[]> fz(new (std::nothrow) unsigned[sz]);
45     ASSERT_NE(fz, nullptr);
46     std::unique_ptr<unsigned[]> fts(new (std::nothrow) unsigned[sz]);
47     ASSERT_NE(fts, nullptr);
48     std::unique_ptr<unsigned[]> data(new (std::nothrow) unsigned[sz]);
49     ASSERT_NE(data, nullptr);
50     std::unique_ptr<unsigned[]> tell(new (std::nothrow) unsigned[sz + 1]);
51     ASSERT_NE(tell, nullptr);
52     std::unique_ptr<unsigned[]> enc_method(new (std::nothrow) unsigned[sz]);
53     ASSERT_NE(enc_method, nullptr);
54     od_ec_enc_reset(&enc);
55     tell[0] = od_ec_enc_tell_frac(&enc);
56     for (j = 0; j < sz; j++) {
57       data[j] = rand() / ((RAND_MAX >> 1) + 1);
58 
59       fts[j] = CDF_PROB_BITS;
60       fz[j] = (rand() % (CDF_PROB_TOP - 2)) >> (CDF_PROB_BITS - fts[j]);
61       fz[j] = OD_MAXI(fz[j], 1);
62       enc_method[j] = 3 + (rand() & 1);
63       switch (enc_method[j]) {
64         case 3: {
65           od_ec_encode_bool_q15(&enc, data[j],
66                                 OD_ICDF(fz[j] << (CDF_PROB_BITS - fts[j])));
67           break;
68         }
69         case 4: {
70           uint16_t cdf[2];
71           cdf[0] = OD_ICDF(fz[j]);
72           cdf[1] = OD_ICDF(1U << fts[j]);
73           od_ec_encode_cdf_q15(&enc, data[j], cdf, 2);
74           break;
75         }
76       }
77 
78       tell[j + 1] = od_ec_enc_tell_frac(&enc);
79     }
80     ptr = od_ec_enc_done(&enc, &ptr_sz);
81     EXPECT_GE(((od_ec_enc_tell(&enc) + 7U) >> 3), ptr_sz)
82         << "od_ec_enc_tell() lied: "
83            "there's "
84         << ptr_sz << " bytes instead of " << ((od_ec_enc_tell(&enc) + 7) >> 3)
85         << " (Random seed: " << seed << ")\n";
86     od_ec_dec_init(&dec, ptr, ptr_sz);
87     EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[0])
88         << "od_ec_dec_tell() mismatch between encoder and decoder "
89            "at symbol 0: "
90         << (unsigned)od_ec_dec_tell_frac(&dec) << " instead of " << tell[0]
91         << " (Random seed: " << seed << ").\n";
92     for (j = 0; j < sz; j++) {
93       int dec_method;
94       unsigned int sym = data[j] + 1;  // Initialize sym to an invalid value.
95 
96       if (CDF_SHIFT == 0) {
97         dec_method = 3 + (rand() & 1);
98       } else {
99         dec_method = enc_method[j];
100       }
101       switch (dec_method) {
102         case 3: {
103           sym = od_ec_decode_bool_q15(
104               &dec, OD_ICDF(fz[j] << (CDF_PROB_BITS - fts[j])));
105           break;
106         }
107         case 4: {
108           uint16_t cdf[2];
109           cdf[0] = OD_ICDF(fz[j]);
110           cdf[1] = OD_ICDF(1U << fts[j]);
111           sym = od_ec_decode_cdf_q15(&dec, cdf, 2);
112           break;
113         }
114       }
115 
116       EXPECT_EQ(sym, data[j])
117           << "Decoded " << sym << " instead of " << data[j]
118           << " with fz=" << fz[j] << " and ftb=" << fts[j] << "at position "
119           << j << " of " << sz << " (Random seed: " << seed << ").\n"
120           << "Encoding method: " << enc_method[j]
121           << " decoding method: " << dec_method << "\n";
122       EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[j + 1])
123           << "od_ec_dec_tell() mismatch between encoder and "
124              "decoder at symbol "
125           << j + 1 << ": " << (unsigned)od_ec_dec_tell_frac(&dec)
126           << " instead of " << tell[j + 1] << " (Random seed: " << seed
127           << ").\n";
128     }
129   }
130   od_ec_enc_reset(&enc);
131   if (CDF_SHIFT == 0) {
132     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
133     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
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(24576));
137     od_ec_enc_patch_initial_bits(&enc, 3, 2);
138     EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n";
139     od_ec_enc_patch_initial_bits(&enc, 0, 5);
140     EXPECT_TRUE(enc.error)
141         << "od_ec_enc_patch_initial_bits() didn't fail when it should have.\n";
142     od_ec_enc_reset(&enc);
143     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
144     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384));
145     od_ec_encode_bool_q15(&enc, 1, OD_ICDF(32256));
146     od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576));
147     od_ec_enc_patch_initial_bits(&enc, 0, 2);
148     EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n";
149     ptr = od_ec_enc_done(&enc, &ptr_sz);
150     EXPECT_EQ(ptr_sz, 2u);
151     EXPECT_EQ(ptr[0], 63)
152         << "Got " << ptr[0]
153         << " when expecting 63 for od_ec_enc_patch_initial_bits().\n";
154   }
155   od_ec_enc_clear(&enc);
156   EXPECT_EQ(ret, 0);
157 }
158