subtract_test.cc 9.12 KB
Newer Older
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
4 5 6 7 8 9
 * 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.
Johann's avatar
Johann committed
10
 */
11

12
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
13

14 15
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
16 17 18
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
19
#include "test/util.h"
20
#if CONFIG_AV1
21
#include "av1/common/blockd.h"
22
#endif
23
#include "aom_mem/aom_mem.h"
24
#include "aom_ports/mem.h"
25

clang-format's avatar
clang-format committed
26 27 28 29
typedef void (*SubtractFunc)(int rows, int cols, int16_t *diff_ptr,
                             ptrdiff_t diff_stride, const uint8_t *src_ptr,
                             ptrdiff_t src_stride, const uint8_t *pred_ptr,
                             ptrdiff_t pred_stride);
30

31
namespace {
32

33
class AV1SubtractBlockTest : public ::testing::TestWithParam<SubtractFunc> {
34
 public:
35
  virtual void TearDown() { libaom_test::ClearSystemState(); }
36 37
};

38
using libaom_test::ACMRandom;
39

40
TEST_P(AV1SubtractBlockTest, SimpleSubtract) {
41 42 43
  ACMRandom rnd(ACMRandom::DeterministicSeed());

  // FIXME(rbultje) split in its own file
44 45
  for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES;
       bsize = static_cast<BLOCK_SIZE>(static_cast<int>(bsize) + 1)) {
46 47
    const int block_width = block_size_wide[bsize];
    const int block_height = block_size_high[bsize];
48
    int16_t *diff = reinterpret_cast<int16_t *>(
49
        aom_memalign(16, sizeof(*diff) * block_width * block_height * 2));
50
    uint8_t *pred = reinterpret_cast<uint8_t *>(
51
        aom_memalign(16, block_width * block_height * 2));
clang-format's avatar
clang-format committed
52
    uint8_t *src = reinterpret_cast<uint8_t *>(
53
        aom_memalign(16, block_width * block_height * 2));
54 55 56 57 58 59 60 61 62

    for (int n = 0; n < 100; n++) {
      for (int r = 0; r < block_height; ++r) {
        for (int c = 0; c < block_width * 2; ++c) {
          src[r * block_width * 2 + c] = rnd.Rand8();
          pred[r * block_width * 2 + c] = rnd.Rand8();
        }
      }

clang-format's avatar
clang-format committed
63 64
      GetParam()(block_height, block_width, diff, block_width, src, block_width,
                 pred, block_width);
65 66 67 68

      for (int r = 0; r < block_height; ++r) {
        for (int c = 0; c < block_width; ++c) {
          EXPECT_EQ(diff[r * block_width + c],
clang-format's avatar
clang-format committed
69 70
                    (src[r * block_width + c] - pred[r * block_width + c]))
              << "r = " << r << ", c = " << c << ", bs = " << bsize;
71 72 73
        }
      }

clang-format's avatar
clang-format committed
74 75
      GetParam()(block_height, block_width, diff, block_width * 2, src,
                 block_width * 2, pred, block_width * 2);
76 77 78

      for (int r = 0; r < block_height; ++r) {
        for (int c = 0; c < block_width; ++c) {
clang-format's avatar
clang-format committed
79 80 81 82
          EXPECT_EQ(
              diff[r * block_width * 2 + c],
              (src[r * block_width * 2 + c] - pred[r * block_width * 2 + c]))
              << "r = " << r << ", c = " << c << ", bs = " << bsize;
83 84 85
        }
      }
    }
86 87 88
    aom_free(diff);
    aom_free(pred);
    aom_free(src);
89 90 91
  }
}

92 93
INSTANTIATE_TEST_CASE_P(C, AV1SubtractBlockTest,
                        ::testing::Values(aom_subtract_block_c));
94

Yaowu Xu's avatar
Yaowu Xu committed
95
#if HAVE_SSE2
96 97
INSTANTIATE_TEST_CASE_P(SSE2, AV1SubtractBlockTest,
                        ::testing::Values(aom_subtract_block_sse2));
98
#endif
99
#if HAVE_NEON
100 101
INSTANTIATE_TEST_CASE_P(NEON, AV1SubtractBlockTest,
                        ::testing::Values(aom_subtract_block_neon));
102
#endif
103
#if HAVE_MSA
104 105
INSTANTIATE_TEST_CASE_P(MSA, AV1SubtractBlockTest,
                        ::testing::Values(aom_subtract_block_msa));
106
#endif
107

clang-format's avatar
clang-format committed
108 109 110 111
typedef void (*HBDSubtractFunc)(int rows, int cols, int16_t *diff_ptr,
                                ptrdiff_t diff_stride, const uint8_t *src_ptr,
                                ptrdiff_t src_stride, const uint8_t *pred_ptr,
                                ptrdiff_t pred_stride, int bd);
112 113 114 115 116 117 118 119

using ::std::tr1::get;
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;

// <width, height, bit_dpeth, subtract>
typedef tuple<int, int, int, HBDSubtractFunc> Params;

120
class AV1HBDSubtractBlockTest : public ::testing::TestWithParam<Params> {
121 122 123 124
 public:
  virtual void SetUp() {
    block_width_ = GET_PARAM(0);
    block_height_ = GET_PARAM(1);
125
    bit_depth_ = static_cast<aom_bit_depth_t>(GET_PARAM(2));
126 127 128 129
    func_ = GET_PARAM(3);

    rnd_.Reset(ACMRandom::DeterministicSeed());

130
#if CONFIG_EXT_PARTITION
131
    const size_t max_width = 128;
132 133 134
#else
    const size_t max_width = 64;
#endif
135 136
    const size_t max_block_size = max_width * max_width;
    src_ = CONVERT_TO_BYTEPTR(reinterpret_cast<uint16_t *>(
137
        aom_memalign(16, max_block_size * sizeof(uint16_t))));
138
    pred_ = CONVERT_TO_BYTEPTR(reinterpret_cast<uint16_t *>(
139
        aom_memalign(16, max_block_size * sizeof(uint16_t))));
140
    diff_ = reinterpret_cast<int16_t *>(
141
        aom_memalign(16, max_block_size * sizeof(int16_t)));
142 143 144
  }

  virtual void TearDown() {
145 146 147
    aom_free(CONVERT_TO_SHORTPTR(src_));
    aom_free(CONVERT_TO_SHORTPTR(pred_));
    aom_free(diff_);
148 149 150 151
  }

 protected:
  void CheckResult();
152
  void RunForSpeed();
153 154 155 156 157

 private:
  ACMRandom rnd_;
  int block_height_;
  int block_width_;
158
  aom_bit_depth_t bit_depth_;
159 160 161 162 163 164
  HBDSubtractFunc func_;
  uint8_t *src_;
  uint8_t *pred_;
  int16_t *diff_;
};

165
void AV1HBDSubtractBlockTest::CheckResult() {
166
  const int test_num = 100;
167 168 169 170 171
#if CONFIG_EXT_PARTITION
  const size_t max_width = 128;
#else
  const size_t max_width = 64;
#endif
172 173 174 175 176 177 178 179 180 181
  const int max_block_size = max_width * max_width;
  const int mask = (1 << bit_depth_) - 1;
  int i, j;

  for (i = 0; i < test_num; ++i) {
    for (j = 0; j < max_block_size; ++j) {
      CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask;
      CONVERT_TO_SHORTPTR(pred_)[j] = rnd_.Rand16() & mask;
    }

clang-format's avatar
clang-format committed
182 183
    func_(block_height_, block_width_, diff_, block_width_, src_, block_width_,
          pred_, block_width_, bit_depth_);
184 185 186 187 188 189 190 191 192 193 194 195

    for (int r = 0; r < block_height_; ++r) {
      for (int c = 0; c < block_width_; ++c) {
        EXPECT_EQ(diff_[r * block_width_ + c],
                  (CONVERT_TO_SHORTPTR(src_)[r * block_width_ + c] -
                   CONVERT_TO_SHORTPTR(pred_)[r * block_width_ + c]))
            << "r = " << r << ", c = " << c << ", test: " << i;
      }
    }
  }
}

196
TEST_P(AV1HBDSubtractBlockTest, CheckResult) { CheckResult(); }
197

198 199
void AV1HBDSubtractBlockTest::RunForSpeed() {
  const int test_num = 200000;
200 201 202 203 204
#if CONFIG_EXT_PARTITION
  const size_t max_width = 128;
#else
  const size_t max_width = 64;
#endif
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
  const int max_block_size = max_width * max_width;
  const int mask = (1 << bit_depth_) - 1;
  int i, j;

  for (j = 0; j < max_block_size; ++j) {
    CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask;
    CONVERT_TO_SHORTPTR(pred_)[j] = rnd_.Rand16() & mask;
  }

  for (i = 0; i < test_num; ++i) {
    func_(block_height_, block_width_, diff_, block_width_, src_, block_width_,
          pred_, block_width_, bit_depth_);
  }
}

TEST_P(AV1HBDSubtractBlockTest, DISABLED_Speed) { RunForSpeed(); }
221 222

#if HAVE_SSE2
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250

const Params kAV1HBDSubtractBlock_sse2[] = {
  make_tuple(4, 4, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(4, 4, 12, &aom_highbd_subtract_block_c),
  make_tuple(4, 8, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(4, 8, 12, &aom_highbd_subtract_block_c),
  make_tuple(8, 4, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(8, 4, 12, &aom_highbd_subtract_block_c),
  make_tuple(8, 8, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(8, 8, 12, &aom_highbd_subtract_block_c),
  make_tuple(8, 16, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(8, 16, 12, &aom_highbd_subtract_block_c),
  make_tuple(16, 8, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(16, 8, 12, &aom_highbd_subtract_block_c),
  make_tuple(16, 16, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(16, 16, 12, &aom_highbd_subtract_block_c),
  make_tuple(16, 32, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(16, 32, 12, &aom_highbd_subtract_block_c),
  make_tuple(32, 16, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(32, 16, 12, &aom_highbd_subtract_block_c),
  make_tuple(32, 32, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(32, 32, 12, &aom_highbd_subtract_block_c),
  make_tuple(32, 64, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(32, 64, 12, &aom_highbd_subtract_block_c),
  make_tuple(64, 32, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(64, 32, 12, &aom_highbd_subtract_block_c),
  make_tuple(64, 64, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(64, 64, 12, &aom_highbd_subtract_block_c),
251
#if CONFIG_EXT_PARTITION
252 253 254 255 256 257
  make_tuple(64, 128, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(64, 128, 12, &aom_highbd_subtract_block_c),
  make_tuple(128, 64, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(128, 64, 12, &aom_highbd_subtract_block_c),
  make_tuple(128, 128, 12, &aom_highbd_subtract_block_sse2),
  make_tuple(128, 128, 12, &aom_highbd_subtract_block_c)
258
#endif  // CONFIG_EXT_PARTITION
259 260 261 262
};

INSTANTIATE_TEST_CASE_P(SSE2, AV1HBDSubtractBlockTest,
                        ::testing::ValuesIn(kAV1HBDSubtractBlock_sse2));
263
#endif  // HAVE_SSE2
264
}  // namespace