1/* 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <math.h> 12#include <stdlib.h> 13#include <string.h> 14 15#include "third_party/googletest/src/include/gtest/gtest.h" 16#include "test/acm_random.h" 17#include "test/clear_system_state.h" 18#include "test/register_state_check.h" 19#include "test/util.h" 20 21#include "./vp9_rtcd.h" 22#include "vp9/common/vp9_entropy.h" 23#include "vpx/vpx_codec.h" 24#include "vpx/vpx_integer.h" 25 26const int kNumCoeffs = 64; 27const double kPi = 3.141592653589793238462643383279502884; 28void reference_8x8_dct_1d(const double in[8], double out[8], int stride) { 29 const double kInvSqrt2 = 0.707106781186547524400844362104; 30 for (int k = 0; k < 8; k++) { 31 out[k] = 0.0; 32 for (int n = 0; n < 8; n++) 33 out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0); 34 if (k == 0) 35 out[k] = out[k] * kInvSqrt2; 36 } 37} 38 39void reference_8x8_dct_2d(const int16_t input[kNumCoeffs], 40 double output[kNumCoeffs]) { 41 // First transform columns 42 for (int i = 0; i < 8; ++i) { 43 double temp_in[8], temp_out[8]; 44 for (int j = 0; j < 8; ++j) 45 temp_in[j] = input[j*8 + i]; 46 reference_8x8_dct_1d(temp_in, temp_out, 1); 47 for (int j = 0; j < 8; ++j) 48 output[j * 8 + i] = temp_out[j]; 49 } 50 // Then transform rows 51 for (int i = 0; i < 8; ++i) { 52 double temp_in[8], temp_out[8]; 53 for (int j = 0; j < 8; ++j) 54 temp_in[j] = output[j + i*8]; 55 reference_8x8_dct_1d(temp_in, temp_out, 1); 56 // Scale by some magic number 57 for (int j = 0; j < 8; ++j) 58 output[j + i * 8] = temp_out[j] * 2; 59 } 60} 61 62using libvpx_test::ACMRandom; 63 64namespace { 65typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride); 66typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride); 67typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, 68 int tx_type); 69typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, 70 int tx_type); 71 72typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param; 73typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param; 74 75void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { 76 vp9_fdct8x8_c(in, out, stride); 77} 78 79void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { 80 vp9_fht8x8_c(in, out, stride, tx_type); 81} 82 83#if CONFIG_VP9_HIGHBITDEPTH 84void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) { 85 vp9_high_idct8x8_64_add_c(in, out, stride, 10); 86} 87 88void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) { 89 vp9_high_idct8x8_64_add_c(in, out, stride, 12); 90} 91 92void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { 93 vp9_high_iht8x8_64_add_c(in, out, stride, tx_type, 10); 94} 95 96void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { 97 vp9_high_iht8x8_64_add_c(in, out, stride, tx_type, 12); 98} 99#endif 100 101class FwdTrans8x8TestBase { 102 public: 103 virtual ~FwdTrans8x8TestBase() {} 104 105 protected: 106 virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0; 107 virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0; 108 109 void RunSignBiasCheck() { 110 ACMRandom rnd(ACMRandom::DeterministicSeed()); 111 DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64); 112 DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_output_block, 64); 113 int count_sign_block[64][2]; 114 const int count_test_block = 100000; 115 116 memset(count_sign_block, 0, sizeof(count_sign_block)); 117 118 for (int i = 0; i < count_test_block; ++i) { 119 // Initialize a test block with input range [-255, 255]. 120 for (int j = 0; j < 64; ++j) 121 test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) - 122 ((rnd.Rand16() >> (16 - bit_depth_)) & mask_); 123 ASM_REGISTER_STATE_CHECK( 124 RunFwdTxfm(test_input_block, test_output_block, pitch_)); 125 126 for (int j = 0; j < 64; ++j) { 127 if (test_output_block[j] < 0) 128 ++count_sign_block[j][0]; 129 else if (test_output_block[j] > 0) 130 ++count_sign_block[j][1]; 131 } 132 } 133 134 for (int j = 0; j < 64; ++j) { 135 const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]); 136 const int max_diff = 1125; 137 EXPECT_LT(diff, max_diff << (bit_depth_ - 8)) 138 << "Error: 8x8 FDCT/FHT has a sign bias > " 139 << 1. * max_diff / count_test_block * 100 << "%" 140 << " for input range [-255, 255] at index " << j 141 << " count0: " << count_sign_block[j][0] 142 << " count1: " << count_sign_block[j][1] 143 << " diff: " << diff; 144 } 145 146 memset(count_sign_block, 0, sizeof(count_sign_block)); 147 148 for (int i = 0; i < count_test_block; ++i) { 149 // Initialize a test block with input range [-15, 15]. 150 for (int j = 0; j < 64; ++j) 151 test_input_block[j] = (rnd.Rand8() >> 4) - (rnd.Rand8() >> 4); 152 ASM_REGISTER_STATE_CHECK( 153 RunFwdTxfm(test_input_block, test_output_block, pitch_)); 154 155 for (int j = 0; j < 64; ++j) { 156 if (test_output_block[j] < 0) 157 ++count_sign_block[j][0]; 158 else if (test_output_block[j] > 0) 159 ++count_sign_block[j][1]; 160 } 161 } 162 163 for (int j = 0; j < 64; ++j) { 164 const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]); 165 const int max_diff = 10000; 166 EXPECT_LT(diff, max_diff << (bit_depth_ - 8)) 167 << "Error: 4x4 FDCT/FHT has a sign bias > " 168 << 1. * max_diff / count_test_block * 100 << "%" 169 << " for input range [-15, 15] at index " << j 170 << " count0: " << count_sign_block[j][0] 171 << " count1: " << count_sign_block[j][1] 172 << " diff: " << diff; 173 } 174 } 175 176 void RunRoundTripErrorCheck() { 177 ACMRandom rnd(ACMRandom::DeterministicSeed()); 178 int max_error = 0; 179 int total_error = 0; 180 const int count_test_block = 100000; 181 DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64); 182 DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64); 183 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64); 184 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64); 185#if CONFIG_VP9_HIGHBITDEPTH 186 DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64); 187 DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64); 188#endif 189 190 for (int i = 0; i < count_test_block; ++i) { 191 // Initialize a test block with input range [-255, 255]. 192 for (int j = 0; j < 64; ++j) { 193 if (bit_depth_ == VPX_BITS_8) { 194 src[j] = rnd.Rand8(); 195 dst[j] = rnd.Rand8(); 196 test_input_block[j] = src[j] - dst[j]; 197#if CONFIG_VP9_HIGHBITDEPTH 198 } else { 199 src16[j] = rnd.Rand16() & mask_; 200 dst16[j] = rnd.Rand16() & mask_; 201 test_input_block[j] = src16[j] - dst16[j]; 202#endif 203 } 204 } 205 206 ASM_REGISTER_STATE_CHECK( 207 RunFwdTxfm(test_input_block, test_temp_block, pitch_)); 208 for (int j = 0; j < 64; ++j) { 209 if (test_temp_block[j] > 0) { 210 test_temp_block[j] += 2; 211 test_temp_block[j] /= 4; 212 test_temp_block[j] *= 4; 213 } else { 214 test_temp_block[j] -= 2; 215 test_temp_block[j] /= 4; 216 test_temp_block[j] *= 4; 217 } 218 } 219 if (bit_depth_ == VPX_BITS_8) { 220 ASM_REGISTER_STATE_CHECK( 221 RunInvTxfm(test_temp_block, dst, pitch_)); 222#if CONFIG_VP9_HIGHBITDEPTH 223 } else { 224 ASM_REGISTER_STATE_CHECK( 225 RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_)); 226#endif 227 } 228 229 for (int j = 0; j < 64; ++j) { 230#if CONFIG_VP9_HIGHBITDEPTH 231 const int diff = 232 bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; 233#else 234 const int diff = dst[j] - src[j]; 235#endif 236 const int error = diff * diff; 237 if (max_error < error) 238 max_error = error; 239 total_error += error; 240 } 241 } 242 243 EXPECT_GE(1 << 2 * (bit_depth_ - 8), max_error) 244 << "Error: 8x8 FDCT/IDCT or FHT/IHT has an individual" 245 << " roundtrip error > 1"; 246 247 EXPECT_GE((count_test_block << 2 * (bit_depth_ - 8))/5, total_error) 248 << "Error: 8x8 FDCT/IDCT or FHT/IHT has average roundtrip " 249 << "error > 1/5 per block"; 250 } 251 252 void RunExtremalCheck() { 253 ACMRandom rnd(ACMRandom::DeterministicSeed()); 254 int max_error = 0; 255 int total_error = 0; 256 int total_coeff_error = 0; 257 const int count_test_block = 100000; 258 DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64); 259 DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64); 260 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_temp_block, 64); 261 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64); 262 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64); 263#if CONFIG_VP9_HIGHBITDEPTH 264 DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64); 265 DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64); 266#endif 267 268 for (int i = 0; i < count_test_block; ++i) { 269 // Initialize a test block with input range [-mask_, mask_]. 270 for (int j = 0; j < 64; ++j) { 271 if (bit_depth_ == VPX_BITS_8) { 272 if (i == 0) { 273 src[j] = 255; 274 dst[j] = 0; 275 } else if (i == 1) { 276 src[j] = 0; 277 dst[j] = 255; 278 } else { 279 src[j] = rnd.Rand8() % 2 ? 255 : 0; 280 dst[j] = rnd.Rand8() % 2 ? 255 : 0; 281 } 282 test_input_block[j] = src[j] - dst[j]; 283#if CONFIG_VP9_HIGHBITDEPTH 284 } else { 285 if (i == 0) { 286 src16[j] = mask_; 287 dst16[j] = 0; 288 } else if (i == 1) { 289 src16[j] = 0; 290 dst16[j] = mask_; 291 } else { 292 src16[j] = rnd.Rand8() % 2 ? mask_ : 0; 293 dst16[j] = rnd.Rand8() % 2 ? mask_ : 0; 294 } 295 test_input_block[j] = src16[j] - dst16[j]; 296#endif 297 } 298 } 299 300 ASM_REGISTER_STATE_CHECK( 301 RunFwdTxfm(test_input_block, test_temp_block, pitch_)); 302 ASM_REGISTER_STATE_CHECK( 303 fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_)); 304 if (bit_depth_ == VPX_BITS_8) { 305 ASM_REGISTER_STATE_CHECK( 306 RunInvTxfm(test_temp_block, dst, pitch_)); 307#if CONFIG_VP9_HIGHBITDEPTH 308 } else { 309 ASM_REGISTER_STATE_CHECK( 310 RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_)); 311#endif 312 } 313 314 for (int j = 0; j < 64; ++j) { 315#if CONFIG_VP9_HIGHBITDEPTH 316 const int diff = 317 bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; 318#else 319 const int diff = dst[j] - src[j]; 320#endif 321 const int error = diff * diff; 322 if (max_error < error) 323 max_error = error; 324 total_error += error; 325 326 const int coeff_diff = test_temp_block[j] - ref_temp_block[j]; 327 total_coeff_error += abs(coeff_diff); 328 } 329 330 EXPECT_GE(1 << 2 * (bit_depth_ - 8), max_error) 331 << "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has" 332 << "an individual roundtrip error > 1"; 333 334 EXPECT_GE((count_test_block << 2 * (bit_depth_ - 8))/5, total_error) 335 << "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has average" 336 << " roundtrip error > 1/5 per block"; 337 338 EXPECT_EQ(0, total_coeff_error) 339 << "Error: Extremal 8x8 FDCT/FHT has" 340 << "overflow issues in the intermediate steps > 1"; 341 } 342 } 343 344 void RunInvAccuracyCheck() { 345 ACMRandom rnd(ACMRandom::DeterministicSeed()); 346 const int count_test_block = 1000; 347 DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); 348 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs); 349 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); 350 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); 351#if CONFIG_VP9_HIGHBITDEPTH 352 DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs); 353 DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs); 354#endif 355 356 for (int i = 0; i < count_test_block; ++i) { 357 double out_r[kNumCoeffs]; 358 359 // Initialize a test block with input range [-255, 255]. 360 for (int j = 0; j < kNumCoeffs; ++j) { 361 if (bit_depth_ == VPX_BITS_8) { 362 src[j] = rnd.Rand8() % 2 ? 255 : 0; 363 dst[j] = src[j] > 0 ? 0 : 255; 364 in[j] = src[j] - dst[j]; 365#if CONFIG_VP9_HIGHBITDEPTH 366 } else { 367 src16[j] = rnd.Rand8() % 2 ? mask_ : 0; 368 dst16[j] = src16[j] > 0 ? 0 : mask_; 369 in[j] = src16[j] - dst16[j]; 370#endif 371 } 372 } 373 374 reference_8x8_dct_2d(in, out_r); 375 for (int j = 0; j < kNumCoeffs; ++j) 376 coeff[j] = static_cast<tran_low_t>(round(out_r[j])); 377 378 if (bit_depth_ == VPX_BITS_8) { 379 ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_)); 380#if CONFIG_VP9_HIGHBITDEPTH 381 } else { 382 ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 383 pitch_)); 384#endif 385 } 386 387 for (int j = 0; j < kNumCoeffs; ++j) { 388#if CONFIG_VP9_HIGHBITDEPTH 389 const uint32_t diff = 390 bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; 391#else 392 const uint32_t diff = dst[j] - src[j]; 393#endif 394 const uint32_t error = diff * diff; 395 EXPECT_GE(1u << 2 * (bit_depth_ - 8), error) 396 << "Error: 8x8 IDCT has error " << error 397 << " at index " << j; 398 } 399 } 400 } 401 402 void RunFwdAccuracyCheck() { 403 ACMRandom rnd(ACMRandom::DeterministicSeed()); 404 const int count_test_block = 1000; 405 DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); 406 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_r, kNumCoeffs); 407 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs); 408 409 for (int i = 0; i < count_test_block; ++i) { 410 double out_r[kNumCoeffs]; 411 412 // Initialize a test block with input range [-mask_, mask_]. 413 for (int j = 0; j < kNumCoeffs; ++j) 414 in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_; 415 416 RunFwdTxfm(in, coeff, pitch_); 417 reference_8x8_dct_2d(in, out_r); 418 for (int j = 0; j < kNumCoeffs; ++j) 419 coeff_r[j] = static_cast<tran_low_t>(round(out_r[j])); 420 421 for (int j = 0; j < kNumCoeffs; ++j) { 422 const uint32_t diff = coeff[j] - coeff_r[j]; 423 const uint32_t error = diff * diff; 424 EXPECT_GE(9u << 2 * (bit_depth_ - 8), error) 425 << "Error: 8x8 DCT has error " << error 426 << " at index " << j; 427 } 428 } 429 } 430 int pitch_; 431 int tx_type_; 432 FhtFunc fwd_txfm_ref; 433 vpx_bit_depth_t bit_depth_; 434 int mask_; 435}; 436 437class FwdTrans8x8DCT 438 : public FwdTrans8x8TestBase, 439 public ::testing::TestWithParam<Dct8x8Param> { 440 public: 441 virtual ~FwdTrans8x8DCT() {} 442 443 virtual void SetUp() { 444 fwd_txfm_ = GET_PARAM(0); 445 inv_txfm_ = GET_PARAM(1); 446 tx_type_ = GET_PARAM(2); 447 pitch_ = 8; 448 fwd_txfm_ref = fdct8x8_ref; 449 bit_depth_ = GET_PARAM(3); 450 mask_ = (1 << bit_depth_) - 1; 451 } 452 453 virtual void TearDown() { libvpx_test::ClearSystemState(); } 454 455 protected: 456 void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) { 457 fwd_txfm_(in, out, stride); 458 } 459 void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) { 460 inv_txfm_(out, dst, stride); 461 } 462 463 FdctFunc fwd_txfm_; 464 IdctFunc inv_txfm_; 465}; 466 467TEST_P(FwdTrans8x8DCT, SignBiasCheck) { 468 RunSignBiasCheck(); 469} 470 471TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) { 472 RunRoundTripErrorCheck(); 473} 474 475TEST_P(FwdTrans8x8DCT, ExtremalCheck) { 476 RunExtremalCheck(); 477} 478 479TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) { 480 RunFwdAccuracyCheck(); 481} 482 483TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) { 484 RunInvAccuracyCheck(); 485} 486 487class FwdTrans8x8HT 488 : public FwdTrans8x8TestBase, 489 public ::testing::TestWithParam<Ht8x8Param> { 490 public: 491 virtual ~FwdTrans8x8HT() {} 492 493 virtual void SetUp() { 494 fwd_txfm_ = GET_PARAM(0); 495 inv_txfm_ = GET_PARAM(1); 496 tx_type_ = GET_PARAM(2); 497 pitch_ = 8; 498 fwd_txfm_ref = fht8x8_ref; 499 bit_depth_ = GET_PARAM(3); 500 mask_ = (1 << bit_depth_) - 1; 501 } 502 503 virtual void TearDown() { libvpx_test::ClearSystemState(); } 504 505 protected: 506 void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) { 507 fwd_txfm_(in, out, stride, tx_type_); 508 } 509 void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) { 510 inv_txfm_(out, dst, stride, tx_type_); 511 } 512 513 FhtFunc fwd_txfm_; 514 IhtFunc inv_txfm_; 515}; 516 517TEST_P(FwdTrans8x8HT, SignBiasCheck) { 518 RunSignBiasCheck(); 519} 520 521TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) { 522 RunRoundTripErrorCheck(); 523} 524 525TEST_P(FwdTrans8x8HT, ExtremalCheck) { 526 RunExtremalCheck(); 527} 528 529using std::tr1::make_tuple; 530 531#if CONFIG_VP9_HIGHBITDEPTH 532INSTANTIATE_TEST_CASE_P( 533 C, FwdTrans8x8DCT, 534 ::testing::Values( 535 make_tuple(&vp9_high_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10), 536 make_tuple(&vp9_high_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12), 537 make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8))); 538#else 539INSTANTIATE_TEST_CASE_P( 540 C, FwdTrans8x8DCT, 541 ::testing::Values( 542 make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8))); 543#endif 544 545#if CONFIG_VP9_HIGHBITDEPTH 546INSTANTIATE_TEST_CASE_P( 547 C, FwdTrans8x8HT, 548 ::testing::Values( 549 make_tuple(&vp9_high_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10), 550 make_tuple(&vp9_high_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10), 551 make_tuple(&vp9_high_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10), 552 make_tuple(&vp9_high_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10), 553 make_tuple(&vp9_high_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12), 554 make_tuple(&vp9_high_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12), 555 make_tuple(&vp9_high_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12), 556 make_tuple(&vp9_high_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12), 557 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8), 558 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), 559 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), 560 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); 561#else 562INSTANTIATE_TEST_CASE_P( 563 C, FwdTrans8x8HT, 564 ::testing::Values( 565 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8), 566 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), 567 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), 568 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); 569#endif 570 571#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH 572INSTANTIATE_TEST_CASE_P( 573 NEON, FwdTrans8x8DCT, 574 ::testing::Values( 575 make_tuple(&vp9_fdct8x8_neon, &vp9_idct8x8_64_add_neon, 0, 576 VPX_BITS_8))); 577INSTANTIATE_TEST_CASE_P( 578 DISABLED_NEON, FwdTrans8x8HT, 579 ::testing::Values( 580 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8), 581 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8), 582 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8), 583 make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8))); 584#endif 585 586#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH 587INSTANTIATE_TEST_CASE_P( 588 SSE2, FwdTrans8x8DCT, 589 ::testing::Values( 590 make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_sse2, 0, 591 VPX_BITS_8))); 592INSTANTIATE_TEST_CASE_P( 593 SSE2, FwdTrans8x8HT, 594 ::testing::Values( 595 make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 0, VPX_BITS_8), 596 make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8), 597 make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8), 598 make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8))); 599#endif 600 601#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH 602INSTANTIATE_TEST_CASE_P( 603 SSSE3, FwdTrans8x8DCT, 604 ::testing::Values( 605 make_tuple(&vp9_fdct8x8_ssse3, &vp9_idct8x8_64_add_ssse3, 0, 606 VPX_BITS_8))); 607#endif 608} // namespace 609