|  | /* | 
|  | * Copyright (c) 2017, Alliance for Open Media. All rights reserved | 
|  | * | 
|  | * This source code is subject to the terms of the BSD 2 Clause License and | 
|  | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License | 
|  | * was not distributed with this source code in the LICENSE file, you can | 
|  | * obtain it at www.aomedia.org/license/software. If the Alliance for Open | 
|  | * Media Patent License 1.0 was not distributed with this source code in the | 
|  | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. | 
|  | */ | 
|  |  | 
|  | #include "third_party/googletest/src/googletest/include/gtest/gtest.h" | 
|  |  | 
|  | #include <cstdlib> | 
|  |  | 
|  | #include "aom_dsp/entenc.h" | 
|  | #include "aom_dsp/entdec.h" | 
|  |  | 
|  | TEST(EC_TEST, random_ec_test) { | 
|  | od_ec_enc enc; | 
|  | od_ec_dec dec; | 
|  | int sz; | 
|  | int i; | 
|  | int ret; | 
|  | unsigned int seed; | 
|  | unsigned char *ptr; | 
|  | uint32_t ptr_sz; | 
|  | char *seed_str; | 
|  | ret = 0; | 
|  | seed_str = getenv("EC_TEST_SEED"); | 
|  | if (seed_str) { | 
|  | seed = atoi(seed_str); | 
|  | } else { | 
|  | seed = 0xdaa1a; | 
|  | } | 
|  | srand(seed); | 
|  | od_ec_enc_init(&enc, 1); | 
|  | /*Test compatibility between multiple different encode/decode routines.*/ | 
|  | for (i = 0; i < 409600; i++) { | 
|  | unsigned *fz; | 
|  | unsigned *fts; | 
|  | unsigned *data; | 
|  | unsigned *tell; | 
|  | unsigned *enc_method; | 
|  | int j; | 
|  | sz = rand() / ((RAND_MAX >> (rand() % 9U)) + 1U); | 
|  | fz = (unsigned *)malloc(sz * sizeof(*fz)); | 
|  | fts = (unsigned *)malloc(sz * sizeof(*fts)); | 
|  | data = (unsigned *)malloc(sz * sizeof(*data)); | 
|  | tell = (unsigned *)malloc((sz + 1) * sizeof(*tell)); | 
|  | enc_method = (unsigned *)malloc(sz * sizeof(*enc_method)); | 
|  | od_ec_enc_reset(&enc); | 
|  | tell[0] = od_ec_enc_tell_frac(&enc); | 
|  | for (j = 0; j < sz; j++) { | 
|  | data[j] = rand() / ((RAND_MAX >> 1) + 1); | 
|  |  | 
|  | fts[j] = CDF_PROB_BITS; | 
|  | fz[j] = (rand() % (CDF_PROB_TOP - 2)) >> (CDF_PROB_BITS - fts[j]); | 
|  | fz[j] = OD_MAXI(fz[j], 1); | 
|  | enc_method[j] = 3 + (rand() & 1); | 
|  | switch (enc_method[j]) { | 
|  | case 3: { | 
|  | od_ec_encode_bool_q15(&enc, data[j], | 
|  | OD_ICDF(fz[j] << (CDF_PROB_BITS - fts[j]))); | 
|  | break; | 
|  | } | 
|  | case 4: { | 
|  | uint16_t cdf[2]; | 
|  | cdf[0] = OD_ICDF(fz[j]); | 
|  | cdf[1] = OD_ICDF(1U << fts[j]); | 
|  | od_ec_encode_cdf_q15(&enc, data[j], cdf, 2); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | tell[j + 1] = od_ec_enc_tell_frac(&enc); | 
|  | } | 
|  | ptr = od_ec_enc_done(&enc, &ptr_sz); | 
|  | EXPECT_GE(((od_ec_enc_tell(&enc) + 7U) >> 3), ptr_sz) | 
|  | << "od_ec_enc_tell() lied: " | 
|  | "there's " | 
|  | << ptr_sz << " bytes instead of " << ((od_ec_enc_tell(&enc) + 7) >> 3) | 
|  | << " (Random seed: " << seed << ")\n"; | 
|  | od_ec_dec_init(&dec, ptr, ptr_sz); | 
|  | EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[0]) | 
|  | << "od_ec_dec_tell() mismatch between encoder and decoder " | 
|  | "at symbol 0: " | 
|  | << (unsigned)od_ec_dec_tell_frac(&dec) << " instead of " << tell[0] | 
|  | << " (Random seed: " << seed << ").\n"; | 
|  | for (j = 0; j < sz; j++) { | 
|  | int dec_method; | 
|  | unsigned int sym = data[j] + 1;  // Initialize sym to an invalid value. | 
|  |  | 
|  | if (CDF_SHIFT == 0) { | 
|  | dec_method = 3 + (rand() & 1); | 
|  | } else { | 
|  | dec_method = enc_method[j]; | 
|  | } | 
|  | switch (dec_method) { | 
|  | case 3: { | 
|  | sym = od_ec_decode_bool_q15( | 
|  | &dec, OD_ICDF(fz[j] << (CDF_PROB_BITS - fts[j]))); | 
|  | break; | 
|  | } | 
|  | case 4: { | 
|  | uint16_t cdf[2]; | 
|  | cdf[0] = OD_ICDF(fz[j]); | 
|  | cdf[1] = OD_ICDF(1U << fts[j]); | 
|  | sym = od_ec_decode_cdf_q15(&dec, cdf, 2); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | EXPECT_EQ(sym, data[j]) | 
|  | << "Decoded " << sym << " instead of " << data[j] | 
|  | << " with fz=" << fz[j] << " and ftb=" << fts[j] << "at position " | 
|  | << j << " of " << sz << " (Random seed: " << seed << ").\n" | 
|  | << "Encoding method: " << enc_method[j] | 
|  | << " decoding method: " << dec_method << "\n"; | 
|  | EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[j + 1]) | 
|  | << "od_ec_dec_tell() mismatch between encoder and " | 
|  | "decoder at symbol " | 
|  | << j + 1 << ": " << (unsigned)od_ec_dec_tell_frac(&dec) | 
|  | << " instead of " << tell[j + 1] << " (Random seed: " << seed | 
|  | << ").\n"; | 
|  | } | 
|  | free(enc_method); | 
|  | free(tell); | 
|  | free(data); | 
|  | free(fts); | 
|  | free(fz); | 
|  | } | 
|  | od_ec_enc_reset(&enc); | 
|  | if (CDF_SHIFT == 0) { | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384)); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384)); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384)); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384)); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576)); | 
|  | od_ec_enc_patch_initial_bits(&enc, 3, 2); | 
|  | EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n"; | 
|  | od_ec_enc_patch_initial_bits(&enc, 0, 5); | 
|  | EXPECT_TRUE(enc.error) | 
|  | << "od_ec_enc_patch_initial_bits() didn't fail when it should have.\n"; | 
|  | od_ec_enc_reset(&enc); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384)); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(16384)); | 
|  | od_ec_encode_bool_q15(&enc, 1, OD_ICDF(32256)); | 
|  | od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576)); | 
|  | od_ec_enc_patch_initial_bits(&enc, 0, 2); | 
|  | EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n"; | 
|  | ptr = od_ec_enc_done(&enc, &ptr_sz); | 
|  | EXPECT_EQ(ptr_sz, 2u); | 
|  | EXPECT_EQ(ptr[0], 63) | 
|  | << "Got " << ptr[0] | 
|  | << " when expecting 63 for od_ec_enc_patch_initial_bits().\n"; | 
|  | } | 
|  | od_ec_enc_clear(&enc); | 
|  | EXPECT_EQ(ret, 0); | 
|  | } |