filterintra_predictors_test.cc 10 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.
10 11
 */

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

Yaowu Xu's avatar
Yaowu Xu committed
14
#include "./av1_rtcd.h"
15 16 17 18
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
19
#include "av1/common/enums.h"
20 21 22 23

namespace {

using std::tr1::tuple;
24
using libaom_test::ACMRandom;
25 26 27 28 29 30 31 32 33 34 35

typedef void (*Predictor)(uint8_t *dst, ptrdiff_t stride, int bs,
                          const uint8_t *above, const uint8_t *left);

// Note:
//  Test parameter list:
//  Reference predictor, optimized predictor, prediction mode, block size
//
typedef tuple<Predictor, Predictor, int> PredFuncMode;
typedef tuple<PredFuncMode, int> PredParams;

36
#if CONFIG_HIGHBITDEPTH
37 38 39 40 41 42 43 44 45 46 47 48 49
typedef void (*HbdPredictor)(uint16_t *dst, ptrdiff_t stride, int bs,
                             const uint16_t *above, const uint16_t *left,
                             int bd);

// Note:
//  Test parameter list:
//  Reference predictor, optimized predictor, prediction mode, block size,
//  bit depth
//
typedef tuple<HbdPredictor, HbdPredictor, int> HbdPredFuncMode;
typedef tuple<HbdPredFuncMode, int, int> HbdPredParams;
#endif

50 51 52 53 54 55 56 57 58 59 60
const int MaxBlkSize = 32;

// By default, disable speed test
#define PREDICTORS_SPEED_TEST (0)

#if PREDICTORS_SPEED_TEST
const int MaxTestNum = 100000;
#else
const int MaxTestNum = 100;
#endif

hui su's avatar
hui su committed
61 62
class AV1FilterIntraPredOptimzTest
    : public ::testing::TestWithParam<PredParams> {
63
 public:
hui su's avatar
hui su committed
64
  virtual ~AV1FilterIntraPredOptimzTest() {}
65 66 67 68 69 70 71
  virtual void SetUp() {
    PredFuncMode funcMode = GET_PARAM(0);
    predFuncRef_ = std::tr1::get<0>(funcMode);
    predFunc_ = std::tr1::get<1>(funcMode);
    mode_ = std::tr1::get<2>(funcMode);
    blockSize_ = GET_PARAM(1);

72 73 74
    alloc_ = new uint8_t[3 * MaxBlkSize + 2];
    predRef_ = new uint8_t[MaxBlkSize * MaxBlkSize];
    pred_ = new uint8_t[MaxBlkSize * MaxBlkSize];
75 76 77 78 79 80
  }

  virtual void TearDown() {
    delete[] alloc_;
    delete[] predRef_;
    delete[] pred_;
81
    libaom_test::ClearSystemState();
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  }

 protected:
  void RunTest() const {
    int tstIndex = 0;
    int stride = blockSize_;
    uint8_t *left = alloc_;
    uint8_t *above = alloc_ + MaxBlkSize + 1;
    while (tstIndex < MaxTestNum) {
      PrepareBuffer();
      predFuncRef_(predRef_, stride, blockSize_, &above[1], left);
      ASM_REGISTER_STATE_CHECK(
          predFunc_(pred_, stride, blockSize_, &above[1], left));
      DiffPred(tstIndex);
      tstIndex += 1;
    }
  }

  void RunSpeedTestC() const {
    int tstIndex = 0;
    int stride = blockSize_;
    uint8_t *left = alloc_;
    uint8_t *above = alloc_ + MaxBlkSize + 1;
    PrepareBuffer();
    while (tstIndex < MaxTestNum) {
      predFuncRef_(predRef_, stride, blockSize_, &above[1], left);
      tstIndex += 1;
    }
  }

  void RunSpeedTestSSE() const {
    int tstIndex = 0;
    int stride = blockSize_;
    uint8_t *left = alloc_;
    uint8_t *above = alloc_ + MaxBlkSize + 1;
    PrepareBuffer();
    while (tstIndex < MaxTestNum) {
      predFunc_(predRef_, stride, blockSize_, &above[1], left);
      tstIndex += 1;
    }
  }

 private:
  void PrepareBuffer() const {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    int i = 0;
    while (i < (3 * MaxBlkSize + 2)) {
      alloc_[i] = rnd.Rand8();
      i += 1;
    }
  }

  void DiffPred(int testNum) const {
    int i = 0;
    while (i < blockSize_ * blockSize_) {
clang-format's avatar
clang-format committed
137 138 139
      EXPECT_EQ(predRef_[i], pred_[i]) << "Error at position: " << i << " "
                                       << "Block size: " << blockSize_ << " "
                                       << "Test number: " << testNum;
140 141 142 143 144 145 146 147 148 149 150 151 152
      i += 1;
    }
  }

  Predictor predFunc_;
  Predictor predFuncRef_;
  int mode_;
  int blockSize_;
  uint8_t *alloc_;
  uint8_t *pred_;
  uint8_t *predRef_;
};

153
#if CONFIG_HIGHBITDEPTH
hui su's avatar
hui su committed
154
class AV1HbdFilterIntraPredOptimzTest
clang-format's avatar
clang-format committed
155
    : public ::testing::TestWithParam<HbdPredParams> {
156
 public:
hui su's avatar
hui su committed
157
  virtual ~AV1HbdFilterIntraPredOptimzTest() {}
158 159 160 161 162 163 164 165
  virtual void SetUp() {
    HbdPredFuncMode funcMode = GET_PARAM(0);
    predFuncRef_ = std::tr1::get<0>(funcMode);
    predFunc_ = std::tr1::get<1>(funcMode);
    mode_ = std::tr1::get<2>(funcMode);
    blockSize_ = GET_PARAM(1);
    bd_ = GET_PARAM(2);

166 167 168
    alloc_ = new uint16_t[3 * MaxBlkSize + 2];
    predRef_ = new uint16_t[MaxBlkSize * MaxBlkSize];
    pred_ = new uint16_t[MaxBlkSize * MaxBlkSize];
169 170 171 172 173 174
  }

  virtual void TearDown() {
    delete[] alloc_;
    delete[] predRef_;
    delete[] pred_;
175
    libaom_test::ClearSystemState();
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
  }

 protected:
  void RunTest() const {
    int tstIndex = 0;
    int stride = blockSize_;
    uint16_t *left = alloc_;
    uint16_t *above = alloc_ + MaxBlkSize + 1;
    while (tstIndex < MaxTestNum) {
      PrepareBuffer();
      predFuncRef_(predRef_, stride, blockSize_, &above[1], left, bd_);
      ASM_REGISTER_STATE_CHECK(
          predFunc_(pred_, stride, blockSize_, &above[1], left, bd_));
      DiffPred(tstIndex);
      tstIndex += 1;
    }
  }

  void RunSpeedTestC() const {
    int tstIndex = 0;
    int stride = blockSize_;
    uint16_t *left = alloc_;
    uint16_t *above = alloc_ + MaxBlkSize + 1;
    PrepareBuffer();
    while (tstIndex < MaxTestNum) {
      predFuncRef_(predRef_, stride, blockSize_, &above[1], left, bd_);
      tstIndex += 1;
    }
  }

  void RunSpeedTestSSE() const {
    int tstIndex = 0;
    int stride = blockSize_;
    uint16_t *left = alloc_;
    uint16_t *above = alloc_ + MaxBlkSize + 1;
    PrepareBuffer();
    while (tstIndex < MaxTestNum) {
      predFunc_(predRef_, stride, blockSize_, &above[1], left, bd_);
      tstIndex += 1;
    }
  }

 private:
  void PrepareBuffer() const {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    int i = 0;
    while (i < (3 * MaxBlkSize + 2)) {
      alloc_[i] = rnd.Rand16() & ((1 << bd_) - 1);
      i += 1;
    }
  }

  void DiffPred(int testNum) const {
    int i = 0;
    while (i < blockSize_ * blockSize_) {
clang-format's avatar
clang-format committed
231 232 233 234
      EXPECT_EQ(predRef_[i], pred_[i]) << "Error at position: " << i << " "
                                       << "Block size: " << blockSize_ << " "
                                       << "Bit depth: " << bd_ << " "
                                       << "Test number: " << testNum;
235 236 237 238 239 240 241 242 243 244 245 246 247
      i += 1;
    }
  }

  HbdPredictor predFunc_;
  HbdPredictor predFuncRef_;
  int mode_;
  int blockSize_;
  int bd_;
  uint16_t *alloc_;
  uint16_t *pred_;
  uint16_t *predRef_;
};
248
#endif  // CONFIG_HIGHBITDEPTH
249

hui su's avatar
hui su committed
250
TEST_P(AV1FilterIntraPredOptimzTest, BitExactCheck) { RunTest(); }
251 252

#if PREDICTORS_SPEED_TEST
hui su's avatar
hui su committed
253
TEST_P(AV1FilterIntraPredOptimzTest, SpeedCheckC) { RunSpeedTestC(); }
254

hui su's avatar
hui su committed
255
TEST_P(AV1FilterIntraPredOptimzTest, SpeedCheckSSE) { RunSpeedTestSSE(); }
256 257
#endif

258
#if CONFIG_HIGHBITDEPTH
hui su's avatar
hui su committed
259
TEST_P(AV1HbdFilterIntraPredOptimzTest, BitExactCheck) { RunTest(); }
260 261

#if PREDICTORS_SPEED_TEST
hui su's avatar
hui su committed
262
TEST_P(AV1HbdFilterIntraPredOptimzTest, SpeedCheckC) { RunSpeedTestC(); }
263

hui su's avatar
hui su committed
264
TEST_P(AV1HbdFilterIntraPredOptimzTest, SpeedCheckSSE) { RunSpeedTestSSE(); }
265
#endif  // PREDICTORS_SPEED_TEST
266
#endif  // CONFIG_HIGHBITDEPTH
267

268 269 270
using std::tr1::make_tuple;

const PredFuncMode kPredFuncMdArray[] = {
Yaowu Xu's avatar
Yaowu Xu committed
271
  make_tuple(av1_dc_filter_predictor_c, av1_dc_filter_predictor_sse4_1,
272
             DC_PRED),
Yaowu Xu's avatar
Yaowu Xu committed
273 274 275
  make_tuple(av1_v_filter_predictor_c, av1_v_filter_predictor_sse4_1, V_PRED),
  make_tuple(av1_h_filter_predictor_c, av1_h_filter_predictor_sse4_1, H_PRED),
  make_tuple(av1_d45_filter_predictor_c, av1_d45_filter_predictor_sse4_1,
276
             D45_PRED),
Yaowu Xu's avatar
Yaowu Xu committed
277
  make_tuple(av1_d135_filter_predictor_c, av1_d135_filter_predictor_sse4_1,
278
             D135_PRED),
Yaowu Xu's avatar
Yaowu Xu committed
279
  make_tuple(av1_d117_filter_predictor_c, av1_d117_filter_predictor_sse4_1,
280
             D117_PRED),
Yaowu Xu's avatar
Yaowu Xu committed
281
  make_tuple(av1_d153_filter_predictor_c, av1_d153_filter_predictor_sse4_1,
282
             D153_PRED),
Yaowu Xu's avatar
Yaowu Xu committed
283
  make_tuple(av1_d207_filter_predictor_c, av1_d207_filter_predictor_sse4_1,
284
             D207_PRED),
Yaowu Xu's avatar
Yaowu Xu committed
285
  make_tuple(av1_d63_filter_predictor_c, av1_d63_filter_predictor_sse4_1,
286
             D63_PRED),
Urvang Joshi's avatar
Urvang Joshi committed
287 288
  make_tuple(av1_paeth_filter_predictor_c, av1_paeth_filter_predictor_sse4_1,
             PAETH_PRED),
289 290
};

clang-format's avatar
clang-format committed
291
const int kBlkSize[] = { 4, 8, 16, 32 };
292 293

INSTANTIATE_TEST_CASE_P(
hui su's avatar
hui su committed
294
    SSE4_1, AV1FilterIntraPredOptimzTest,
clang-format's avatar
clang-format committed
295 296
    ::testing::Combine(::testing::ValuesIn(kPredFuncMdArray),
                       ::testing::ValuesIn(kBlkSize)));
297

298
#if CONFIG_HIGHBITDEPTH
299
const HbdPredFuncMode kHbdPredFuncMdArray[] = {
Yaowu Xu's avatar
Yaowu Xu committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
  make_tuple(av1_highbd_dc_filter_predictor_c,
             av1_highbd_dc_filter_predictor_sse4_1, DC_PRED),
  make_tuple(av1_highbd_v_filter_predictor_c,
             av1_highbd_v_filter_predictor_sse4_1, V_PRED),
  make_tuple(av1_highbd_h_filter_predictor_c,
             av1_highbd_h_filter_predictor_sse4_1, H_PRED),
  make_tuple(av1_highbd_d45_filter_predictor_c,
             av1_highbd_d45_filter_predictor_sse4_1, D45_PRED),
  make_tuple(av1_highbd_d135_filter_predictor_c,
             av1_highbd_d135_filter_predictor_sse4_1, D135_PRED),
  make_tuple(av1_highbd_d117_filter_predictor_c,
             av1_highbd_d117_filter_predictor_sse4_1, D117_PRED),
  make_tuple(av1_highbd_d153_filter_predictor_c,
             av1_highbd_d153_filter_predictor_sse4_1, D153_PRED),
  make_tuple(av1_highbd_d207_filter_predictor_c,
             av1_highbd_d207_filter_predictor_sse4_1, D207_PRED),
  make_tuple(av1_highbd_d63_filter_predictor_c,
             av1_highbd_d63_filter_predictor_sse4_1, D63_PRED),
Urvang Joshi's avatar
Urvang Joshi committed
318 319
  make_tuple(av1_highbd_paeth_filter_predictor_c,
             av1_highbd_paeth_filter_predictor_sse4_1, PAETH_PRED),
320 321
};

clang-format's avatar
clang-format committed
322
const int kBd[] = { 10, 12 };
323 324

INSTANTIATE_TEST_CASE_P(
hui su's avatar
hui su committed
325
    SSE4_1, AV1HbdFilterIntraPredOptimzTest,
clang-format's avatar
clang-format committed
326 327 328
    ::testing::Combine(::testing::ValuesIn(kHbdPredFuncMdArray),
                       ::testing::ValuesIn(kBlkSize),
                       ::testing::ValuesIn(kBd)));
329
#endif  // CONFIG_HIGHBITDEPTH
330

331
}  // namespace