| 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 |
| 11 #include <math.h> | 11 #include <math.h> |
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include "third_party/googletest/src/include/gtest/gtest.h" | 15 #include "third_party/googletest/src/include/gtest/gtest.h" |
| 16 #include "test/acm_random.h" | 16 #include "test/acm_random.h" |
| 17 #include "test/clear_system_state.h" | 17 #include "test/clear_system_state.h" |
| 18 #include "test/register_state_check.h" | 18 #include "test/register_state_check.h" |
| 19 #include "test/util.h" | 19 #include "test/util.h" |
| 20 | 20 |
| 21 #include "./vp9_rtcd.h" | 21 #include "./vp9_rtcd.h" |
| 22 #include "vp9/common/vp9_entropy.h" | 22 #include "vp9/common/vp9_entropy.h" |
| 23 #include "vpx/vpx_codec.h" |
| 23 #include "vpx/vpx_integer.h" | 24 #include "vpx/vpx_integer.h" |
| 24 | 25 |
| 25 extern "C" { | |
| 26 void vp9_idct16x16_256_add_c(const int16_t *input, uint8_t *output, int pitch); | |
| 27 } | |
| 28 | |
| 29 using libvpx_test::ACMRandom; | 26 using libvpx_test::ACMRandom; |
| 30 | 27 |
| 31 namespace { | 28 namespace { |
| 32 | 29 |
| 33 #ifdef _MSC_VER | 30 #ifdef _MSC_VER |
| 34 static int round(double x) { | 31 static int round(double x) { |
| 35 if (x < 0) | 32 if (x < 0) |
| 36 return static_cast<int>(ceil(x - 0.5)); | 33 return static_cast<int>(ceil(x - 0.5)); |
| 37 else | 34 else |
| 38 return static_cast<int>(floor(x + 0.5)); | 35 return static_cast<int>(floor(x + 0.5)); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 double temp_in[16], temp_out[16]; | 248 double temp_in[16], temp_out[16]; |
| 252 for (int j = 0; j < 16; ++j) | 249 for (int j = 0; j < 16; ++j) |
| 253 temp_in[j] = output[j + i * 16]; | 250 temp_in[j] = output[j + i * 16]; |
| 254 butterfly_16x16_dct_1d(temp_in, temp_out); | 251 butterfly_16x16_dct_1d(temp_in, temp_out); |
| 255 // Scale by some magic number | 252 // Scale by some magic number |
| 256 for (int j = 0; j < 16; ++j) | 253 for (int j = 0; j < 16; ++j) |
| 257 output[j + i * 16] = temp_out[j]/2; | 254 output[j + i * 16] = temp_out[j]/2; |
| 258 } | 255 } |
| 259 } | 256 } |
| 260 | 257 |
| 261 typedef void (*FdctFunc)(const int16_t *in, int16_t *out, int stride); | 258 typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride); |
| 262 typedef void (*IdctFunc)(const int16_t *in, uint8_t *out, int stride); | 259 typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride); |
| 263 typedef void (*FhtFunc)(const int16_t *in, int16_t *out, int stride, | 260 typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, |
| 264 int tx_type); | 261 int tx_type); |
| 265 typedef void (*IhtFunc)(const int16_t *in, uint8_t *out, int stride, | 262 typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, |
| 266 int tx_type); | 263 int tx_type); |
| 267 | 264 |
| 268 typedef std::tr1::tuple<FdctFunc, IdctFunc, int> Dct16x16Param; | 265 typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param; |
| 269 typedef std::tr1::tuple<FhtFunc, IhtFunc, int> Ht16x16Param; | 266 typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param; |
| 270 | 267 |
| 271 void fdct16x16_ref(const int16_t *in, int16_t *out, int stride, | 268 void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride, |
| 272 int /*tx_type*/) { | 269 int /*tx_type*/) { |
| 273 vp9_fdct16x16_c(in, out, stride); | 270 vp9_fdct16x16_c(in, out, stride); |
| 274 } | 271 } |
| 275 | 272 |
| 276 void idct16x16_ref(const int16_t *in, uint8_t *dest, int stride, | 273 void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride, |
| 277 int /*tx_type*/) { | 274 int /*tx_type*/) { |
| 278 vp9_idct16x16_256_add_c(in, dest, stride); | 275 vp9_idct16x16_256_add_c(in, dest, stride); |
| 279 } | 276 } |
| 280 | 277 |
| 281 void fht16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { | 278 void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, |
| 279 int tx_type) { |
| 282 vp9_fht16x16_c(in, out, stride, tx_type); | 280 vp9_fht16x16_c(in, out, stride, tx_type); |
| 283 } | 281 } |
| 284 | 282 |
| 285 void iht16x16_ref(const int16_t *in, uint8_t *dest, int stride, int tx_type) { | 283 void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride, |
| 284 int tx_type) { |
| 286 vp9_iht16x16_256_add_c(in, dest, stride, tx_type); | 285 vp9_iht16x16_256_add_c(in, dest, stride, tx_type); |
| 287 } | 286 } |
| 288 | 287 |
| 288 #if CONFIG_VP9_HIGHBITDEPTH |
| 289 void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) { |
| 290 vp9_high_idct16x16_256_add_c(in, out, stride, 10); |
| 291 } |
| 292 |
| 293 void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) { |
| 294 vp9_high_idct16x16_256_add_c(in, out, stride, 12); |
| 295 } |
| 296 |
| 297 void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride, |
| 298 int tx_type) { |
| 299 idct16x16_10(in, out, stride); |
| 300 } |
| 301 |
| 302 void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride, |
| 303 int tx_type) { |
| 304 idct16x16_12(in, out, stride); |
| 305 } |
| 306 |
| 307 void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { |
| 308 vp9_high_iht16x16_256_add_c(in, out, stride, tx_type, 10); |
| 309 } |
| 310 |
| 311 void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { |
| 312 vp9_high_iht16x16_256_add_c(in, out, stride, tx_type, 12); |
| 313 } |
| 314 #endif |
| 315 |
| 289 class Trans16x16TestBase { | 316 class Trans16x16TestBase { |
| 290 public: | 317 public: |
| 291 virtual ~Trans16x16TestBase() {} | 318 virtual ~Trans16x16TestBase() {} |
| 292 | 319 |
| 293 protected: | 320 protected: |
| 294 virtual void RunFwdTxfm(int16_t *in, int16_t *out, int stride) = 0; | 321 virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0; |
| 295 | 322 |
| 296 virtual void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) = 0; | 323 virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0; |
| 297 | 324 |
| 298 void RunAccuracyCheck() { | 325 void RunAccuracyCheck() { |
| 299 ACMRandom rnd(ACMRandom::DeterministicSeed()); | 326 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 300 uint32_t max_error = 0; | 327 uint32_t max_error = 0; |
| 301 int64_t total_error = 0; | 328 int64_t total_error = 0; |
| 302 const int count_test_block = 10000; | 329 const int count_test_block = 10000; |
| 303 for (int i = 0; i < count_test_block; ++i) { | 330 for (int i = 0; i < count_test_block; ++i) { |
| 304 DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs); | 331 DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs); |
| 305 DECLARE_ALIGNED_ARRAY(16, int16_t, test_temp_block, kNumCoeffs); | 332 DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs); |
| 306 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); | 333 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); |
| 307 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); | 334 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); |
| 335 #if CONFIG_VP9_HIGHBITDEPTH |
| 336 DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs); |
| 337 DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs); |
| 338 #endif |
| 308 | 339 |
| 309 // Initialize a test block with input range [-255, 255]. | 340 // Initialize a test block with input range [-mask_, mask_]. |
| 310 for (int j = 0; j < kNumCoeffs; ++j) { | 341 for (int j = 0; j < kNumCoeffs; ++j) { |
| 311 src[j] = rnd.Rand8(); | 342 if (bit_depth_ == VPX_BITS_8) { |
| 312 dst[j] = rnd.Rand8(); | 343 src[j] = rnd.Rand8(); |
| 313 test_input_block[j] = src[j] - dst[j]; | 344 dst[j] = rnd.Rand8(); |
| 345 test_input_block[j] = src[j] - dst[j]; |
| 346 #if CONFIG_VP9_HIGHBITDEPTH |
| 347 } else { |
| 348 src16[j] = rnd.Rand16() & mask_; |
| 349 dst16[j] = rnd.Rand16() & mask_; |
| 350 test_input_block[j] = src16[j] - dst16[j]; |
| 351 #endif |
| 352 } |
| 314 } | 353 } |
| 315 | 354 |
| 316 ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, | 355 ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, |
| 317 test_temp_block, pitch_)); | 356 test_temp_block, pitch_)); |
| 318 ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_)); | 357 if (bit_depth_ == VPX_BITS_8) { |
| 358 ASM_REGISTER_STATE_CHECK( |
| 359 RunInvTxfm(test_temp_block, dst, pitch_)); |
| 360 #if CONFIG_VP9_HIGHBITDEPTH |
| 361 } else { |
| 362 ASM_REGISTER_STATE_CHECK( |
| 363 RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_)); |
| 364 #endif |
| 365 } |
| 319 | 366 |
| 320 for (int j = 0; j < kNumCoeffs; ++j) { | 367 for (int j = 0; j < kNumCoeffs; ++j) { |
| 368 #if CONFIG_VP9_HIGHBITDEPTH |
| 369 const uint32_t diff = |
| 370 bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; |
| 371 #else |
| 321 const uint32_t diff = dst[j] - src[j]; | 372 const uint32_t diff = dst[j] - src[j]; |
| 373 #endif |
| 322 const uint32_t error = diff * diff; | 374 const uint32_t error = diff * diff; |
| 323 if (max_error < error) | 375 if (max_error < error) |
| 324 max_error = error; | 376 max_error = error; |
| 325 total_error += error; | 377 total_error += error; |
| 326 } | 378 } |
| 327 } | 379 } |
| 328 | 380 |
| 329 EXPECT_GE(1u, max_error) | 381 EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error) |
| 330 << "Error: 16x16 FHT/IHT has an individual round trip error > 1"; | 382 << "Error: 16x16 FHT/IHT has an individual round trip error > 1"; |
| 331 | 383 |
| 332 EXPECT_GE(count_test_block , total_error) | 384 EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error) |
| 333 << "Error: 16x16 FHT/IHT has average round trip error > 1 per block"; | 385 << "Error: 16x16 FHT/IHT has average round trip error > 1 per block"; |
| 334 } | 386 } |
| 335 | 387 |
| 336 void RunCoeffCheck() { | 388 void RunCoeffCheck() { |
| 337 ACMRandom rnd(ACMRandom::DeterministicSeed()); | 389 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 338 const int count_test_block = 1000; | 390 const int count_test_block = 1000; |
| 339 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); | 391 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); |
| 340 DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); | 392 DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs); |
| 341 DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs); | 393 DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs); |
| 342 | 394 |
| 343 for (int i = 0; i < count_test_block; ++i) { | 395 for (int i = 0; i < count_test_block; ++i) { |
| 344 // Initialize a test block with input range [-255, 255]. | 396 // Initialize a test block with input range [-mask_, mask_]. |
| 345 for (int j = 0; j < kNumCoeffs; ++j) | 397 for (int j = 0; j < kNumCoeffs; ++j) |
| 346 input_block[j] = rnd.Rand8() - rnd.Rand8(); | 398 input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); |
| 347 | 399 |
| 348 fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_); | 400 fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_); |
| 349 ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_)); | 401 ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_)); |
| 350 | 402 |
| 351 // The minimum quant value is 4. | 403 // The minimum quant value is 4. |
| 352 for (int j = 0; j < kNumCoeffs; ++j) | 404 for (int j = 0; j < kNumCoeffs; ++j) |
| 353 EXPECT_EQ(output_block[j], output_ref_block[j]); | 405 EXPECT_EQ(output_block[j], output_ref_block[j]); |
| 354 } | 406 } |
| 355 } | 407 } |
| 356 | 408 |
| 357 void RunMemCheck() { | 409 void RunMemCheck() { |
| 358 ACMRandom rnd(ACMRandom::DeterministicSeed()); | 410 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 359 const int count_test_block = 1000; | 411 const int count_test_block = 1000; |
| 360 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); | 412 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); |
| 361 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); | 413 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); |
| 362 DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); | 414 DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs); |
| 363 DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs); | 415 DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs); |
| 364 | 416 |
| 365 for (int i = 0; i < count_test_block; ++i) { | 417 for (int i = 0; i < count_test_block; ++i) { |
| 366 // Initialize a test block with input range [-255, 255]. | 418 // Initialize a test block with input range [-mask_, mask_]. |
| 367 for (int j = 0; j < kNumCoeffs; ++j) { | 419 for (int j = 0; j < kNumCoeffs; ++j) { |
| 368 input_block[j] = rnd.Rand8() - rnd.Rand8(); | 420 input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); |
| 369 input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; | 421 input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; |
| 370 } | 422 } |
| 371 if (i == 0) { | 423 if (i == 0) { |
| 372 for (int j = 0; j < kNumCoeffs; ++j) | 424 for (int j = 0; j < kNumCoeffs; ++j) |
| 373 input_extreme_block[j] = 255; | 425 input_extreme_block[j] = mask_; |
| 374 } else if (i == 1) { | 426 } else if (i == 1) { |
| 375 for (int j = 0; j < kNumCoeffs; ++j) | 427 for (int j = 0; j < kNumCoeffs; ++j) |
| 376 input_extreme_block[j] = -255; | 428 input_extreme_block[j] = -mask_; |
| 377 } | 429 } |
| 378 | 430 |
| 379 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); | 431 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); |
| 380 ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, | 432 ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, |
| 381 output_block, pitch_)); | 433 output_block, pitch_)); |
| 382 | 434 |
| 383 // The minimum quant value is 4. | 435 // The minimum quant value is 4. |
| 384 for (int j = 0; j < kNumCoeffs; ++j) { | 436 for (int j = 0; j < kNumCoeffs; ++j) { |
| 385 EXPECT_EQ(output_block[j], output_ref_block[j]); | 437 EXPECT_EQ(output_block[j], output_ref_block[j]); |
| 386 EXPECT_GE(4 * DCT_MAX_VALUE, abs(output_block[j])) | 438 EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j])) |
| 387 << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE"; | 439 << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE"; |
| 388 } | 440 } |
| 389 } | 441 } |
| 390 } | 442 } |
| 391 | 443 |
| 392 void RunQuantCheck(int dc_thred, int ac_thred) { | 444 void RunQuantCheck(int dc_thred, int ac_thred) { |
| 393 ACMRandom rnd(ACMRandom::DeterministicSeed()); | 445 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 394 const int count_test_block = 1000; | 446 const int count_test_block = 1000; |
| 395 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); | 447 DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); |
| 396 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); | 448 DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); |
| 397 DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); | 449 DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs); |
| 398 | 450 |
| 399 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); | 451 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); |
| 400 DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs); | 452 DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs); |
| 453 #if CONFIG_VP9_HIGHBITDEPTH |
| 454 DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs); |
| 455 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs); |
| 456 #endif |
| 401 | 457 |
| 402 for (int i = 0; i < count_test_block; ++i) { | 458 for (int i = 0; i < count_test_block; ++i) { |
| 403 // Initialize a test block with input range [-255, 255]. | 459 // Initialize a test block with input range [-mask_, mask_]. |
| 404 for (int j = 0; j < kNumCoeffs; ++j) { | 460 for (int j = 0; j < kNumCoeffs; ++j) { |
| 405 input_block[j] = rnd.Rand8() - rnd.Rand8(); | 461 if (bit_depth_ == VPX_BITS_8) |
| 406 input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; | 462 input_block[j] = rnd.Rand8() - rnd.Rand8(); |
| 463 else |
| 464 input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); |
| 465 input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; |
| 407 } | 466 } |
| 408 if (i == 0) | 467 if (i == 0) |
| 409 for (int j = 0; j < kNumCoeffs; ++j) | 468 for (int j = 0; j < kNumCoeffs; ++j) |
| 410 input_extreme_block[j] = 255; | 469 input_extreme_block[j] = mask_; |
| 411 if (i == 1) | 470 if (i == 1) |
| 412 for (int j = 0; j < kNumCoeffs; ++j) | 471 for (int j = 0; j < kNumCoeffs; ++j) |
| 413 input_extreme_block[j] = -255; | 472 input_extreme_block[j] = -mask_; |
| 414 | 473 |
| 415 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); | 474 fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); |
| 416 | 475 |
| 417 // clear reconstructed pixel buffers | 476 // clear reconstructed pixel buffers |
| 418 vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t)); | 477 vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t)); |
| 419 vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t)); | 478 vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t)); |
| 479 #if CONFIG_VP9_HIGHBITDEPTH |
| 480 vpx_memset(dst16, 0, kNumCoeffs * sizeof(uint16_t)); |
| 481 vpx_memset(ref16, 0, kNumCoeffs * sizeof(uint16_t)); |
| 482 #endif |
| 420 | 483 |
| 421 // quantization with maximum allowed step sizes | 484 // quantization with maximum allowed step sizes |
| 422 output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred; | 485 output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred; |
| 423 for (int j = 1; j < kNumCoeffs; ++j) | 486 for (int j = 1; j < kNumCoeffs; ++j) |
| 424 output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred; | 487 output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred; |
| 425 inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_); | 488 if (bit_depth_ == VPX_BITS_8) { |
| 426 ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_)); | 489 inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_); |
| 427 | 490 ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_)); |
| 428 for (int j = 0; j < kNumCoeffs; ++j) | 491 #if CONFIG_VP9_HIGHBITDEPTH |
| 429 EXPECT_EQ(ref[j], dst[j]); | 492 } else { |
| 493 inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_, |
| 494 tx_type_); |
| 495 ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, |
| 496 CONVERT_TO_BYTEPTR(dst16), pitch_)); |
| 497 #endif |
| 498 } |
| 499 if (bit_depth_ == VPX_BITS_8) { |
| 500 for (int j = 0; j < kNumCoeffs; ++j) |
| 501 EXPECT_EQ(ref[j], dst[j]); |
| 502 #if CONFIG_VP9_HIGHBITDEPTH |
| 503 } else { |
| 504 for (int j = 0; j < kNumCoeffs; ++j) |
| 505 EXPECT_EQ(ref16[j], dst16[j]); |
| 506 #endif |
| 507 } |
| 430 } | 508 } |
| 431 } | 509 } |
| 432 | 510 |
| 433 void RunInvAccuracyCheck() { | 511 void RunInvAccuracyCheck() { |
| 434 ACMRandom rnd(ACMRandom::DeterministicSeed()); | 512 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 435 const int count_test_block = 1000; | 513 const int count_test_block = 1000; |
| 436 DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); | 514 DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); |
| 437 DECLARE_ALIGNED_ARRAY(16, int16_t, coeff, kNumCoeffs); | 515 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs); |
| 438 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); | 516 DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); |
| 439 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); | 517 DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); |
| 518 #if CONFIG_VP9_HIGHBITDEPTH |
| 519 DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs); |
| 520 DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs); |
| 521 #endif |
| 440 | 522 |
| 441 for (int i = 0; i < count_test_block; ++i) { | 523 for (int i = 0; i < count_test_block; ++i) { |
| 442 double out_r[kNumCoeffs]; | 524 double out_r[kNumCoeffs]; |
| 443 | 525 |
| 444 // Initialize a test block with input range [-255, 255]. | 526 // Initialize a test block with input range [-255, 255]. |
| 445 for (int j = 0; j < kNumCoeffs; ++j) { | 527 for (int j = 0; j < kNumCoeffs; ++j) { |
| 446 src[j] = rnd.Rand8(); | 528 if (bit_depth_ == VPX_BITS_8) { |
| 447 dst[j] = rnd.Rand8(); | 529 src[j] = rnd.Rand8(); |
| 448 in[j] = src[j] - dst[j]; | 530 dst[j] = rnd.Rand8(); |
| 531 in[j] = src[j] - dst[j]; |
| 532 #if CONFIG_VP9_HIGHBITDEPTH |
| 533 } else { |
| 534 src16[j] = rnd.Rand16() & mask_; |
| 535 dst16[j] = rnd.Rand16() & mask_; |
| 536 in[j] = src16[j] - dst16[j]; |
| 537 #endif |
| 538 } |
| 449 } | 539 } |
| 450 | 540 |
| 451 reference_16x16_dct_2d(in, out_r); | 541 reference_16x16_dct_2d(in, out_r); |
| 452 for (int j = 0; j < kNumCoeffs; ++j) | 542 for (int j = 0; j < kNumCoeffs; ++j) |
| 453 coeff[j] = round(out_r[j]); | 543 coeff[j] = round(out_r[j]); |
| 454 | 544 |
| 455 ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16)); | 545 if (bit_depth_ == VPX_BITS_8) { |
| 546 ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16)); |
| 547 #if CONFIG_VP9_HIGHBITDEPTH |
| 548 } else { |
| 549 ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), |
| 550 16)); |
| 551 #endif |
| 552 } |
| 456 | 553 |
| 457 for (int j = 0; j < kNumCoeffs; ++j) { | 554 for (int j = 0; j < kNumCoeffs; ++j) { |
| 555 #if CONFIG_VP9_HIGHBITDEPTH |
| 556 const uint32_t diff = |
| 557 bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; |
| 558 #else |
| 458 const uint32_t diff = dst[j] - src[j]; | 559 const uint32_t diff = dst[j] - src[j]; |
| 560 #endif |
| 459 const uint32_t error = diff * diff; | 561 const uint32_t error = diff * diff; |
| 460 EXPECT_GE(1u, error) | 562 EXPECT_GE(1u, error) |
| 461 << "Error: 16x16 IDCT has error " << error | 563 << "Error: 16x16 IDCT has error " << error |
| 462 << " at index " << j; | 564 << " at index " << j; |
| 463 } | 565 } |
| 464 } | 566 } |
| 465 } | 567 } |
| 466 int pitch_; | 568 int pitch_; |
| 467 int tx_type_; | 569 int tx_type_; |
| 570 vpx_bit_depth_t bit_depth_; |
| 571 int mask_; |
| 468 FhtFunc fwd_txfm_ref; | 572 FhtFunc fwd_txfm_ref; |
| 469 IhtFunc inv_txfm_ref; | 573 IhtFunc inv_txfm_ref; |
| 470 }; | 574 }; |
| 471 | 575 |
| 472 class Trans16x16DCT | 576 class Trans16x16DCT |
| 473 : public Trans16x16TestBase, | 577 : public Trans16x16TestBase, |
| 474 public ::testing::TestWithParam<Dct16x16Param> { | 578 public ::testing::TestWithParam<Dct16x16Param> { |
| 475 public: | 579 public: |
| 476 virtual ~Trans16x16DCT() {} | 580 virtual ~Trans16x16DCT() {} |
| 477 | 581 |
| 478 virtual void SetUp() { | 582 virtual void SetUp() { |
| 479 fwd_txfm_ = GET_PARAM(0); | 583 fwd_txfm_ = GET_PARAM(0); |
| 480 inv_txfm_ = GET_PARAM(1); | 584 inv_txfm_ = GET_PARAM(1); |
| 481 tx_type_ = GET_PARAM(2); | 585 tx_type_ = GET_PARAM(2); |
| 586 bit_depth_ = GET_PARAM(3); |
| 482 pitch_ = 16; | 587 pitch_ = 16; |
| 483 fwd_txfm_ref = fdct16x16_ref; | 588 fwd_txfm_ref = fdct16x16_ref; |
| 484 inv_txfm_ref = idct16x16_ref; | 589 inv_txfm_ref = idct16x16_ref; |
| 590 mask_ = (1 << bit_depth_) - 1; |
| 591 #if CONFIG_VP9_HIGHBITDEPTH |
| 592 switch (bit_depth_) { |
| 593 case 10: |
| 594 inv_txfm_ref = idct16x16_10_ref; |
| 595 break; |
| 596 case 12: |
| 597 inv_txfm_ref = idct16x16_12_ref; |
| 598 break; |
| 599 default: |
| 600 inv_txfm_ref = idct16x16_ref; |
| 601 break; |
| 602 } |
| 603 #else |
| 604 inv_txfm_ref = idct16x16_ref; |
| 605 #endif |
| 485 } | 606 } |
| 486 virtual void TearDown() { libvpx_test::ClearSystemState(); } | 607 virtual void TearDown() { libvpx_test::ClearSystemState(); } |
| 487 | 608 |
| 488 protected: | 609 protected: |
| 489 void RunFwdTxfm(int16_t *in, int16_t *out, int stride) { | 610 void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) { |
| 490 fwd_txfm_(in, out, stride); | 611 fwd_txfm_(in, out, stride); |
| 491 } | 612 } |
| 492 void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) { | 613 void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) { |
| 493 inv_txfm_(out, dst, stride); | 614 inv_txfm_(out, dst, stride); |
| 494 } | 615 } |
| 495 | 616 |
| 496 FdctFunc fwd_txfm_; | 617 FdctFunc fwd_txfm_; |
| 497 IdctFunc inv_txfm_; | 618 IdctFunc inv_txfm_; |
| 498 }; | 619 }; |
| 499 | 620 |
| 500 TEST_P(Trans16x16DCT, AccuracyCheck) { | 621 TEST_P(Trans16x16DCT, AccuracyCheck) { |
| 501 RunAccuracyCheck(); | 622 RunAccuracyCheck(); |
| 502 } | 623 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 522 class Trans16x16HT | 643 class Trans16x16HT |
| 523 : public Trans16x16TestBase, | 644 : public Trans16x16TestBase, |
| 524 public ::testing::TestWithParam<Ht16x16Param> { | 645 public ::testing::TestWithParam<Ht16x16Param> { |
| 525 public: | 646 public: |
| 526 virtual ~Trans16x16HT() {} | 647 virtual ~Trans16x16HT() {} |
| 527 | 648 |
| 528 virtual void SetUp() { | 649 virtual void SetUp() { |
| 529 fwd_txfm_ = GET_PARAM(0); | 650 fwd_txfm_ = GET_PARAM(0); |
| 530 inv_txfm_ = GET_PARAM(1); | 651 inv_txfm_ = GET_PARAM(1); |
| 531 tx_type_ = GET_PARAM(2); | 652 tx_type_ = GET_PARAM(2); |
| 653 bit_depth_ = GET_PARAM(3); |
| 532 pitch_ = 16; | 654 pitch_ = 16; |
| 533 fwd_txfm_ref = fht16x16_ref; | 655 fwd_txfm_ref = fht16x16_ref; |
| 534 inv_txfm_ref = iht16x16_ref; | 656 inv_txfm_ref = iht16x16_ref; |
| 657 mask_ = (1 << bit_depth_) - 1; |
| 658 #if CONFIG_VP9_HIGHBITDEPTH |
| 659 switch (bit_depth_) { |
| 660 case VPX_BITS_10: |
| 661 inv_txfm_ref = iht16x16_10; |
| 662 break; |
| 663 case VPX_BITS_12: |
| 664 inv_txfm_ref = iht16x16_12; |
| 665 break; |
| 666 default: |
| 667 inv_txfm_ref = iht16x16_ref; |
| 668 break; |
| 669 } |
| 670 #else |
| 671 inv_txfm_ref = iht16x16_ref; |
| 672 #endif |
| 535 } | 673 } |
| 536 virtual void TearDown() { libvpx_test::ClearSystemState(); } | 674 virtual void TearDown() { libvpx_test::ClearSystemState(); } |
| 537 | 675 |
| 538 protected: | 676 protected: |
| 539 void RunFwdTxfm(int16_t *in, int16_t *out, int stride) { | 677 void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) { |
| 540 fwd_txfm_(in, out, stride, tx_type_); | 678 fwd_txfm_(in, out, stride, tx_type_); |
| 541 } | 679 } |
| 542 void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) { | 680 void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) { |
| 543 inv_txfm_(out, dst, stride, tx_type_); | 681 inv_txfm_(out, dst, stride, tx_type_); |
| 544 } | 682 } |
| 545 | 683 |
| 546 FhtFunc fwd_txfm_; | 684 FhtFunc fwd_txfm_; |
| 547 IhtFunc inv_txfm_; | 685 IhtFunc inv_txfm_; |
| 548 }; | 686 }; |
| 549 | 687 |
| 550 TEST_P(Trans16x16HT, AccuracyCheck) { | 688 TEST_P(Trans16x16HT, AccuracyCheck) { |
| 551 RunAccuracyCheck(); | 689 RunAccuracyCheck(); |
| 552 } | 690 } |
| 553 | 691 |
| 554 TEST_P(Trans16x16HT, CoeffCheck) { | 692 TEST_P(Trans16x16HT, CoeffCheck) { |
| 555 RunCoeffCheck(); | 693 RunCoeffCheck(); |
| 556 } | 694 } |
| 557 | 695 |
| 558 TEST_P(Trans16x16HT, MemCheck) { | 696 TEST_P(Trans16x16HT, MemCheck) { |
| 559 RunMemCheck(); | 697 RunMemCheck(); |
| 560 } | 698 } |
| 561 | 699 |
| 562 TEST_P(Trans16x16HT, QuantCheck) { | 700 TEST_P(Trans16x16HT, QuantCheck) { |
| 563 // The encoder skips any non-DC intra prediction modes, | 701 // The encoder skips any non-DC intra prediction modes, |
| 564 // when the quantization step size goes beyond 988. | 702 // when the quantization step size goes beyond 988. |
| 565 RunQuantCheck(549, 988); | 703 RunQuantCheck(549, 988); |
| 566 } | 704 } |
| 567 | 705 |
| 568 using std::tr1::make_tuple; | 706 using std::tr1::make_tuple; |
| 569 | 707 |
| 708 #if CONFIG_VP9_HIGHBITDEPTH |
| 570 INSTANTIATE_TEST_CASE_P( | 709 INSTANTIATE_TEST_CASE_P( |
| 571 C, Trans16x16DCT, | 710 C, Trans16x16DCT, |
| 572 ::testing::Values( | 711 ::testing::Values( |
| 573 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0))); | 712 make_tuple(&vp9_high_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10), |
| 713 make_tuple(&vp9_high_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12), |
| 714 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8))); |
| 715 #else |
| 716 INSTANTIATE_TEST_CASE_P( |
| 717 C, Trans16x16DCT, |
| 718 ::testing::Values( |
| 719 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8))); |
| 720 #endif |
| 721 |
| 722 #if CONFIG_VP9_HIGHBITDEPTH |
| 574 INSTANTIATE_TEST_CASE_P( | 723 INSTANTIATE_TEST_CASE_P( |
| 575 C, Trans16x16HT, | 724 C, Trans16x16HT, |
| 576 ::testing::Values( | 725 ::testing::Values( |
| 577 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0), | 726 make_tuple(&vp9_high_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10), |
| 578 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1), | 727 make_tuple(&vp9_high_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10), |
| 579 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2), | 728 make_tuple(&vp9_high_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10), |
| 580 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3))); | 729 make_tuple(&vp9_high_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10), |
| 730 make_tuple(&vp9_high_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12), |
| 731 make_tuple(&vp9_high_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12), |
| 732 make_tuple(&vp9_high_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12), |
| 733 make_tuple(&vp9_high_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12), |
| 734 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8), |
| 735 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), |
| 736 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), |
| 737 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8))); |
| 738 #else |
| 739 INSTANTIATE_TEST_CASE_P( |
| 740 C, Trans16x16HT, |
| 741 ::testing::Values( |
| 742 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8), |
| 743 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), |
| 744 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), |
| 745 make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8))); |
| 746 #endif |
| 581 | 747 |
| 582 #if HAVE_NEON_ASM | 748 #if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH |
| 583 INSTANTIATE_TEST_CASE_P( | 749 INSTANTIATE_TEST_CASE_P( |
| 584 NEON, Trans16x16DCT, | 750 NEON, Trans16x16DCT, |
| 585 ::testing::Values( | 751 ::testing::Values( |
| 586 make_tuple(&vp9_fdct16x16_c, | 752 make_tuple(&vp9_fdct16x16_c, |
| 587 &vp9_idct16x16_256_add_neon, 0))); | 753 &vp9_idct16x16_256_add_neon, 0, VPX_BITS_8))); |
| 588 #endif | 754 #endif |
| 589 | 755 |
| 590 #if HAVE_SSE2 | 756 #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH |
| 591 INSTANTIATE_TEST_CASE_P( | 757 INSTANTIATE_TEST_CASE_P( |
| 592 SSE2, Trans16x16DCT, | 758 SSE2, Trans16x16DCT, |
| 593 ::testing::Values( | 759 ::testing::Values( |
| 594 make_tuple(&vp9_fdct16x16_sse2, | 760 make_tuple(&vp9_fdct16x16_sse2, |
| 595 &vp9_idct16x16_256_add_sse2, 0))); | 761 &vp9_idct16x16_256_add_sse2, 0, VPX_BITS_8))); |
| 596 INSTANTIATE_TEST_CASE_P( | 762 INSTANTIATE_TEST_CASE_P( |
| 597 SSE2, Trans16x16HT, | 763 SSE2, Trans16x16HT, |
| 598 ::testing::Values( | 764 ::testing::Values( |
| 599 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0), | 765 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0, |
| 600 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1), | 766 VPX_BITS_8), |
| 601 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2), | 767 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1, |
| 602 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3))); | 768 VPX_BITS_8), |
| 769 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2, |
| 770 VPX_BITS_8), |
| 771 make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3, |
| 772 VPX_BITS_8))); |
| 603 #endif | 773 #endif |
| 604 | 774 |
| 605 #if HAVE_SSSE3 | 775 #if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH |
| 606 INSTANTIATE_TEST_CASE_P( | 776 INSTANTIATE_TEST_CASE_P( |
| 607 SSSE3, Trans16x16DCT, | 777 SSSE3, Trans16x16DCT, |
| 608 ::testing::Values( | 778 ::testing::Values( |
| 609 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0))); | 779 make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0, |
| 780 VPX_BITS_8))); |
| 610 #endif | 781 #endif |
| 611 } // namespace | 782 } // namespace |
| OLD | NEW |