| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 typedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride, | 265 typedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride, |
| 266 int tx_type); | 266 int tx_type); |
| 267 | 267 |
| 268 typedef std::tr1::tuple<fdct_t, idct_t, int> dct_16x16_param_t; | 268 typedef std::tr1::tuple<fdct_t, idct_t, int> dct_16x16_param_t; |
| 269 typedef std::tr1::tuple<fht_t, iht_t, int> ht_16x16_param_t; | 269 typedef std::tr1::tuple<fht_t, iht_t, int> ht_16x16_param_t; |
| 270 | 270 |
| 271 void fdct16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { | 271 void fdct16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { |
| 272 vp9_fdct16x16_c(in, out, stride); | 272 vp9_fdct16x16_c(in, out, stride); |
| 273 } | 273 } |
| 274 | 274 |
| 275 void idct16x16_ref(const int16_t *in, uint8_t *dest, int stride, int tx_type) { |
| 276 vp9_idct16x16_256_add_c(in, dest, stride); |
| 277 } |
| 278 |
| 275 void fht16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { | 279 void fht16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { |
| 276 vp9_fht16x16_c(in, out, stride, tx_type); | 280 vp9_fht16x16_c(in, out, stride, tx_type); |
| 277 } | 281 } |
| 278 | 282 |
| 283 void iht16x16_ref(const int16_t *in, uint8_t *dest, int stride, int tx_type) { |
| 284 vp9_iht16x16_256_add_c(in, dest, stride, tx_type); |
| 285 } |
| 286 |
| 279 class Trans16x16TestBase { | 287 class Trans16x16TestBase { |
| 280 public: | 288 public: |
| 281 virtual ~Trans16x16TestBase() {} | 289 virtual ~Trans16x16TestBase() {} |
| 282 | 290 |
| 283 protected: | 291 protected: |
| 284 virtual void RunFwdTxfm(int16_t *in, int16_t *out, int stride) = 0; | 292 virtual void RunFwdTxfm(int16_t *in, int16_t *out, int stride) = 0; |
| 285 | 293 |
| 286 virtual void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) = 0; | 294 virtual void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) = 0; |
| 287 | 295 |
| 288 void RunAccuracyCheck() { | 296 void RunAccuracyCheck() { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); | 359 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); |
| 352 DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); | 360 DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); |
| 353 DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs); | 361 DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs); |
| 354 | 362 |
| 355 for (int i = 0; i < count_test_block; ++i) { | 363 for (int i = 0; i < count_test_block; ++i) { |
| 356 // Initialize a test block with input range [-255, 255]. | 364 // Initialize a test block with input range [-255, 255]. |
| 357 for (int j = 0; j < kNumCoeffs; ++j) { | 365 for (int j = 0; j < kNumCoeffs; ++j) { |
| 358 input_block[j] = rnd.Rand8() - rnd.Rand8(); | 366 input_block[j] = rnd.Rand8() - rnd.Rand8(); |
| 359 input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; | 367 input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; |
| 360 } | 368 } |
| 361 if (i == 0) | 369 if (i == 0) { |
| 362 for (int j = 0; j < kNumCoeffs; ++j) | 370 for (int j = 0; j < kNumCoeffs; ++j) |
| 363 input_extreme_block[j] = 255; | 371 input_extreme_block[j] = 255; |
| 364 if (i == 1) | 372 } else if (i == 1) { |
| 365 for (int j = 0; j < kNumCoeffs; ++j) | 373 for (int j = 0; j < kNumCoeffs; ++j) |
| 366 input_extreme_block[j] = -255; | 374 input_extreme_block[j] = -255; |
| 375 } |
| 367 | 376 |
| 368 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); | 377 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); |
| 369 REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, | 378 REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, |
| 370 output_block, pitch_)); | 379 output_block, pitch_)); |
| 371 | 380 |
| 372 // The minimum quant value is 4. | 381 // The minimum quant value is 4. |
| 373 for (int j = 0; j < kNumCoeffs; ++j) { | 382 for (int j = 0; j < kNumCoeffs; ++j) { |
| 374 EXPECT_EQ(output_block[j], output_ref_block[j]); | 383 EXPECT_EQ(output_block[j], output_ref_block[j]); |
| 375 EXPECT_GE(4 * DCT_MAX_VALUE, abs(output_block[j])) | 384 EXPECT_GE(4 * DCT_MAX_VALUE, abs(output_block[j])) |
| 376 << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE"; | 385 << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE"; |
| 377 } | 386 } |
| 378 } | 387 } |
| 379 } | 388 } |
| 380 | 389 |
| 390 void RunQuantCheck(int dc_thred, int ac_thred) { |
| 391 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 392 const int count_test_block = 1000; |
| 393 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); |
| 394 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); |
| 395 DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); |
| 396 |
| 397 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); |
| 398 DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs); |
| 399 |
| 400 for (int i = 0; i < count_test_block; ++i) { |
| 401 // Initialize a test block with input range [-255, 255]. |
| 402 for (int j = 0; j < kNumCoeffs; ++j) { |
| 403 input_block[j] = rnd.Rand8() - rnd.Rand8(); |
| 404 input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; |
| 405 } |
| 406 if (i == 0) |
| 407 for (int j = 0; j < kNumCoeffs; ++j) |
| 408 input_extreme_block[j] = 255; |
| 409 if (i == 1) |
| 410 for (int j = 0; j < kNumCoeffs; ++j) |
| 411 input_extreme_block[j] = -255; |
| 412 |
| 413 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); |
| 414 |
| 415 // clear reconstructed pixel buffers |
| 416 vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t)); |
| 417 vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t)); |
| 418 |
| 419 // quantization with maximum allowed step sizes |
| 420 output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred; |
| 421 for (int j = 1; j < kNumCoeffs; ++j) |
| 422 output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred; |
| 423 inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_); |
| 424 REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_)); |
| 425 |
| 426 for (int j = 0; j < kNumCoeffs; ++j) |
| 427 EXPECT_EQ(ref[j], dst[j]); |
| 428 } |
| 429 } |
| 430 |
| 381 void RunInvAccuracyCheck() { | 431 void RunInvAccuracyCheck() { |
| 382 ACMRandom rnd(ACMRandom::DeterministicSeed()); | 432 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 383 const int count_test_block = 1000; | 433 const int count_test_block = 1000; |
| 384 DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); | 434 DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); |
| 385 DECLARE_ALIGNED_ARRAY(16, int16_t, coeff, kNumCoeffs); | 435 DECLARE_ALIGNED_ARRAY(16, int16_t, coeff, kNumCoeffs); |
| 386 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); | 436 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); |
| 387 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); | 437 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); |
| 388 | 438 |
| 389 for (int i = 0; i < count_test_block; ++i) { | 439 for (int i = 0; i < count_test_block; ++i) { |
| 390 double out_r[kNumCoeffs]; | 440 double out_r[kNumCoeffs]; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 407 const uint32_t error = diff * diff; | 457 const uint32_t error = diff * diff; |
| 408 EXPECT_GE(1u, error) | 458 EXPECT_GE(1u, error) |
| 409 << "Error: 16x16 IDCT has error " << error | 459 << "Error: 16x16 IDCT has error " << error |
| 410 << " at index " << j; | 460 << " at index " << j; |
| 411 } | 461 } |
| 412 } | 462 } |
| 413 } | 463 } |
| 414 int pitch_; | 464 int pitch_; |
| 415 int tx_type_; | 465 int tx_type_; |
| 416 fht_t fwd_txfm_ref; | 466 fht_t fwd_txfm_ref; |
| 467 iht_t inv_txfm_ref; |
| 417 }; | 468 }; |
| 418 | 469 |
| 419 class Trans16x16DCT | 470 class Trans16x16DCT |
| 420 : public Trans16x16TestBase, | 471 : public Trans16x16TestBase, |
| 421 public ::testing::TestWithParam<dct_16x16_param_t> { | 472 public ::testing::TestWithParam<dct_16x16_param_t> { |
| 422 public: | 473 public: |
| 423 virtual ~Trans16x16DCT() {} | 474 virtual ~Trans16x16DCT() {} |
| 424 | 475 |
| 425 virtual void SetUp() { | 476 virtual void SetUp() { |
| 426 fwd_txfm_ = GET_PARAM(0); | 477 fwd_txfm_ = GET_PARAM(0); |
| 427 inv_txfm_ = GET_PARAM(1); | 478 inv_txfm_ = GET_PARAM(1); |
| 428 tx_type_ = GET_PARAM(2); | 479 tx_type_ = GET_PARAM(2); |
| 429 pitch_ = 16; | 480 pitch_ = 16; |
| 430 fwd_txfm_ref = fdct16x16_ref; | 481 fwd_txfm_ref = fdct16x16_ref; |
| 482 inv_txfm_ref = idct16x16_ref; |
| 431 } | 483 } |
| 432 virtual void TearDown() { libvpx_test::ClearSystemState(); } | 484 virtual void TearDown() { libvpx_test::ClearSystemState(); } |
| 433 | 485 |
| 434 protected: | 486 protected: |
| 435 void RunFwdTxfm(int16_t *in, int16_t *out, int stride) { | 487 void RunFwdTxfm(int16_t *in, int16_t *out, int stride) { |
| 436 fwd_txfm_(in, out, stride); | 488 fwd_txfm_(in, out, stride); |
| 437 } | 489 } |
| 438 void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) { | 490 void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) { |
| 439 inv_txfm_(out, dst, stride); | 491 inv_txfm_(out, dst, stride); |
| 440 } | 492 } |
| 441 | 493 |
| 442 fdct_t fwd_txfm_; | 494 fdct_t fwd_txfm_; |
| 443 idct_t inv_txfm_; | 495 idct_t inv_txfm_; |
| 444 }; | 496 }; |
| 445 | 497 |
| 446 TEST_P(Trans16x16DCT, AccuracyCheck) { | 498 TEST_P(Trans16x16DCT, AccuracyCheck) { |
| 447 RunAccuracyCheck(); | 499 RunAccuracyCheck(); |
| 448 } | 500 } |
| 449 | 501 |
| 450 TEST_P(Trans16x16DCT, CoeffCheck) { | 502 TEST_P(Trans16x16DCT, CoeffCheck) { |
| 451 RunCoeffCheck(); | 503 RunCoeffCheck(); |
| 452 } | 504 } |
| 453 | 505 |
| 454 TEST_P(Trans16x16DCT, MemCheck) { | 506 TEST_P(Trans16x16DCT, MemCheck) { |
| 455 RunMemCheck(); | 507 RunMemCheck(); |
| 456 } | 508 } |
| 457 | 509 |
| 510 TEST_P(Trans16x16DCT, QuantCheck) { |
| 511 // Use maximally allowed quantization step sizes for DC and AC |
| 512 // coefficients respectively. |
| 513 RunQuantCheck(1336, 1828); |
| 514 } |
| 515 |
| 458 TEST_P(Trans16x16DCT, InvAccuracyCheck) { | 516 TEST_P(Trans16x16DCT, InvAccuracyCheck) { |
| 459 RunInvAccuracyCheck(); | 517 RunInvAccuracyCheck(); |
| 460 } | 518 } |
| 461 | 519 |
| 462 class Trans16x16HT | 520 class Trans16x16HT |
| 463 : public Trans16x16TestBase, | 521 : public Trans16x16TestBase, |
| 464 public ::testing::TestWithParam<ht_16x16_param_t> { | 522 public ::testing::TestWithParam<ht_16x16_param_t> { |
| 465 public: | 523 public: |
| 466 virtual ~Trans16x16HT() {} | 524 virtual ~Trans16x16HT() {} |
| 467 | 525 |
| 468 virtual void SetUp() { | 526 virtual void SetUp() { |
| 469 fwd_txfm_ = GET_PARAM(0); | 527 fwd_txfm_ = GET_PARAM(0); |
| 470 inv_txfm_ = GET_PARAM(1); | 528 inv_txfm_ = GET_PARAM(1); |
| 471 tx_type_ = GET_PARAM(2); | 529 tx_type_ = GET_PARAM(2); |
| 472 pitch_ = 16; | 530 pitch_ = 16; |
| 473 fwd_txfm_ref = fht16x16_ref; | 531 fwd_txfm_ref = fht16x16_ref; |
| 532 inv_txfm_ref = iht16x16_ref; |
| 474 } | 533 } |
| 475 virtual void TearDown() { libvpx_test::ClearSystemState(); } | 534 virtual void TearDown() { libvpx_test::ClearSystemState(); } |
| 476 | 535 |
| 477 protected: | 536 protected: |
| 478 void RunFwdTxfm(int16_t *in, int16_t *out, int stride) { | 537 void RunFwdTxfm(int16_t *in, int16_t *out, int stride) { |
| 479 fwd_txfm_(in, out, stride, tx_type_); | 538 fwd_txfm_(in, out, stride, tx_type_); |
| 480 } | 539 } |
| 481 void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) { | 540 void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) { |
| 482 inv_txfm_(out, dst, stride, tx_type_); | 541 inv_txfm_(out, dst, stride, tx_type_); |
| 483 } | 542 } |
| 484 | 543 |
| 485 fht_t fwd_txfm_; | 544 fht_t fwd_txfm_; |
| 486 iht_t inv_txfm_; | 545 iht_t inv_txfm_; |
| 487 }; | 546 }; |
| 488 | 547 |
| 489 TEST_P(Trans16x16HT, AccuracyCheck) { | 548 TEST_P(Trans16x16HT, AccuracyCheck) { |
| 490 RunAccuracyCheck(); | 549 RunAccuracyCheck(); |
| 491 } | 550 } |
| 492 | 551 |
| 493 TEST_P(Trans16x16HT, CoeffCheck) { | 552 TEST_P(Trans16x16HT, CoeffCheck) { |
| 494 RunCoeffCheck(); | 553 RunCoeffCheck(); |
| 495 } | 554 } |
| 496 | 555 |
| 497 TEST_P(Trans16x16HT, MemCheck) { | 556 TEST_P(Trans16x16HT, MemCheck) { |
| 498 RunMemCheck(); | 557 RunMemCheck(); |
| 499 } | 558 } |
| 500 | 559 |
| 560 TEST_P(Trans16x16HT, QuantCheck) { |
| 561 // The encoder skips any non-DC intra prediction modes, |
| 562 // when the quantization step size goes beyond 988. |
| 563 RunQuantCheck(549, 988); |
| 564 } |
| 565 |
| 501 using std::tr1::make_tuple; | 566 using std::tr1::make_tuple; |
| 502 | 567 |
| 503 INSTANTIATE_TEST_CASE_P( | 568 INSTANTIATE_TEST_CASE_P( |
| 504 C, Trans16x16DCT, | 569 C, Trans16x16DCT, |
| 505 ::testing::Values( | 570 ::testing::Values( |
| 506 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0))); | 571 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0))); |
| 507 INSTANTIATE_TEST_CASE_P( | 572 INSTANTIATE_TEST_CASE_P( |
| 508 C, Trans16x16HT, | 573 C, Trans16x16HT, |
| 509 ::testing::Values( | 574 ::testing::Values( |
| 510 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0), | 575 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 527 make_tuple(&vp9_fdct16x16_sse2, | 592 make_tuple(&vp9_fdct16x16_sse2, |
| 528 &vp9_idct16x16_256_add_sse2, 0))); | 593 &vp9_idct16x16_256_add_sse2, 0))); |
| 529 INSTANTIATE_TEST_CASE_P( | 594 INSTANTIATE_TEST_CASE_P( |
| 530 SSE2, Trans16x16HT, | 595 SSE2, Trans16x16HT, |
| 531 ::testing::Values( | 596 ::testing::Values( |
| 532 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0), | 597 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0), |
| 533 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1), | 598 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1), |
| 534 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2), | 599 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2), |
| 535 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3))); | 600 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3))); |
| 536 #endif | 601 #endif |
| 602 |
| 603 #if HAVE_SSSE3 |
| 604 INSTANTIATE_TEST_CASE_P( |
| 605 SSSE3, Trans16x16DCT, |
| 606 ::testing::Values( |
| 607 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0))); |
| 608 #endif |
| 609 |
| 610 #if HAVE_AVX2 |
| 611 // TODO(jzern): these prototypes can be removed after the avx2 versions are |
| 612 // reenabled in vp9_rtcd_defs.pl. |
| 613 extern "C" { |
| 614 void vp9_fdct16x16_avx2(const int16_t *input, int16_t *output, int stride); |
| 615 void vp9_fht16x16_avx2(const int16_t *input, int16_t *output, int stride, |
| 616 int tx_type); |
| 617 } |
| 618 INSTANTIATE_TEST_CASE_P( |
| 619 DISABLED_AVX2, Trans16x16DCT, |
| 620 ::testing::Values( |
| 621 make_tuple(&vp9_fdct16x16_avx2, |
| 622 &vp9_idct16x16_256_add_c, 0))); |
| 623 INSTANTIATE_TEST_CASE_P( |
| 624 AVX2, Trans16x16HT, |
| 625 ::testing::Values( |
| 626 make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 3))); |
| 627 INSTANTIATE_TEST_CASE_P( |
| 628 DISABLED_AVX2, Trans16x16HT, |
| 629 ::testing::Values( |
| 630 make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 0), |
| 631 make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 1), |
| 632 make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 2))); |
| 633 #endif |
| 537 } // namespace | 634 } // namespace |
| OLD | NEW |