1 /* 2 * Copyright (c) 2017 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 #include <limits> 15 #include <tuple> 16 17 #include "third_party/googletest/src/include/gtest/gtest.h" 18 19 #include "./vpx_dsp_rtcd.h" 20 #include "test/acm_random.h" 21 #include "test/buffer.h" 22 #include "test/clear_system_state.h" 23 #include "test/register_state_check.h" 24 #include "test/util.h" 25 #include "vpx/vpx_codec.h" 26 #include "vpx/vpx_integer.h" 27 #include "vpx_dsp/vpx_dsp_common.h" 28 29 using libvpx_test::ACMRandom; 30 using libvpx_test::Buffer; 31 using std::make_tuple; 32 using std::tuple; 33 34 namespace { 35 typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride); 36 37 typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t> 38 PartialFdctParam; 39 40 tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) { 41 int64_t sum = 0; 42 if (in.TopLeftPixel() != NULL) { 43 for (int y = 0; y < size; ++y) { 44 for (int x = 0; x < size; ++x) { 45 sum += in.TopLeftPixel()[y * in.stride() + x]; 46 } 47 } 48 } else { 49 assert(0); 50 } 51 52 switch (size) { 53 case 4: sum *= 2; break; 54 case 8: /*sum = sum;*/ break; 55 case 16: sum >>= 1; break; 56 case 32: sum >>= 3; break; 57 } 58 59 return static_cast<tran_low_t>(sum); 60 } 61 62 class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> { 63 public: 64 PartialFdctTest() { 65 fwd_txfm_ = GET_PARAM(0); 66 size_ = GET_PARAM(1); 67 bit_depth_ = GET_PARAM(2); 68 } 69 70 virtual void TearDown() { libvpx_test::ClearSystemState(); } 71 72 protected: 73 void RunTest() { 74 ACMRandom rnd(ACMRandom::DeterministicSeed()); 75 const int16_t maxvalue = 76 clip_pixel_highbd(std::numeric_limits<int16_t>::max(), bit_depth_); 77 const int16_t minvalue = -maxvalue; 78 Buffer<int16_t> input_block = 79 Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16); 80 ASSERT_TRUE(input_block.Init()); 81 Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16); 82 ASSERT_TRUE(output_block.Init()); 83 84 if (output_block.TopLeftPixel() != NULL) { 85 for (int i = 0; i < 100; ++i) { 86 if (i == 0) { 87 input_block.Set(maxvalue); 88 } else if (i == 1) { 89 input_block.Set(minvalue); 90 } else { 91 input_block.Set(&rnd, minvalue, maxvalue); 92 } 93 94 ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(), 95 output_block.TopLeftPixel(), 96 input_block.stride())); 97 98 EXPECT_EQ(partial_fdct_ref(input_block, size_), 99 output_block.TopLeftPixel()[0]); 100 } 101 } else { 102 assert(0); 103 } 104 } 105 106 PartialFdctFunc fwd_txfm_; 107 vpx_bit_depth_t bit_depth_; 108 int size_; 109 }; 110 111 TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); } 112 113 #if CONFIG_VP9_HIGHBITDEPTH 114 INSTANTIATE_TEST_CASE_P( 115 C, PartialFdctTest, 116 ::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12), 117 make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10), 118 make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8), 119 make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12), 120 make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10), 121 make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8), 122 make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12), 123 make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10), 124 make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8), 125 make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8))); 126 #else 127 INSTANTIATE_TEST_CASE_P( 128 C, PartialFdctTest, 129 ::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8), 130 make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8), 131 make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8), 132 make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8))); 133 #endif // CONFIG_VP9_HIGHBITDEPTH 134 135 #if HAVE_SSE2 136 INSTANTIATE_TEST_CASE_P( 137 SSE2, PartialFdctTest, 138 ::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8), 139 make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8), 140 make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8), 141 make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8))); 142 #endif // HAVE_SSE2 143 144 #if HAVE_NEON 145 #if CONFIG_VP9_HIGHBITDEPTH 146 INSTANTIATE_TEST_CASE_P( 147 NEON, PartialFdctTest, 148 ::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8), 149 make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8), 150 make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12), 151 make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10), 152 make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8), 153 make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8))); 154 #else 155 INSTANTIATE_TEST_CASE_P( 156 NEON, PartialFdctTest, 157 ::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8), 158 make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8), 159 make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8), 160 make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8))); 161 #endif // CONFIG_VP9_HIGHBITDEPTH 162 #endif // HAVE_NEON 163 164 #if HAVE_MSA 165 #if CONFIG_VP9_HIGHBITDEPTH 166 INSTANTIATE_TEST_CASE_P(MSA, PartialFdctTest, 167 ::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8, 168 VPX_BITS_8))); 169 #else // !CONFIG_VP9_HIGHBITDEPTH 170 INSTANTIATE_TEST_CASE_P( 171 MSA, PartialFdctTest, 172 ::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8), 173 make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8), 174 make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8))); 175 #endif // CONFIG_VP9_HIGHBITDEPTH 176 #endif // HAVE_MSA 177 } // namespace 178