test_intra_pred_speed.cc 29.4 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
10
//  Test and time VPX intra-predictor functions
11 12 13 14 15 16

#include <stdio.h>
#include <string.h>

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

17
#include "./vpx_dsp_rtcd.h"
18
#include "test/acm_random.h"
19
#include "test/clear_system_state.h"
20 21 22 23 24 25 26 27 28 29 30 31
#include "test/md5_helper.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/vpx_timer.h"

// -----------------------------------------------------------------------------

namespace {

typedef void (*VpxPredFunc)(uint8_t *dst, ptrdiff_t y_stride,
                            const uint8_t *above, const uint8_t *left);

32 33
const int kBPS = 32;
const int kTotalPixels = 32 * kBPS;
34 35
const int kNumVp9IntraPredFuncs = 13;
const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = {
clang-format's avatar
clang-format committed
36 37 38
  "DC_PRED",   "DC_LEFT_PRED", "DC_TOP_PRED", "DC_128_PRED", "V_PRED",
  "H_PRED",    "D45_PRED",     "D135_PRED",   "D117_PRED",   "D153_PRED",
  "D207_PRED", "D63_PRED",     "TM_PRED"
39 40
};

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
template <typename Pixel>
struct IntraPredTestMem {
  void Init(int block_size, int bd) {
    libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
    Pixel *const above = above_mem + 16;
    const int mask = (1 << bd) - 1;
    for (int i = 0; i < kTotalPixels; ++i) ref_src[i] = rnd.Rand16() & mask;
    for (int i = 0; i < kBPS; ++i) left[i] = rnd.Rand16() & mask;
    for (int i = -1; i < kBPS; ++i) above[i] = rnd.Rand16() & mask;

    // some code assumes the top row has been extended:
    // d45/d63 C-code, for instance, but not the assembly.
    // TODO(jzern): this style of extension isn't strictly necessary.
    ASSERT_LE(block_size, kBPS);
    for (int i = block_size; i < 2 * kBPS; ++i) {
      above[i] = above[block_size - 1];
    }
  }

  DECLARE_ALIGNED(16, Pixel, src[kTotalPixels]);
  DECLARE_ALIGNED(16, Pixel, ref_src[kTotalPixels]);
  DECLARE_ALIGNED(16, Pixel, left[kBPS]);
  DECLARE_ALIGNED(16, Pixel, above_mem[2 * kBPS + 16]);
};

typedef IntraPredTestMem<uint8_t> Vp9IntraPredTestMem;

void CheckMd5Signature(const char name[], const char *const signatures[],
                       const void *data, size_t data_size, int elapsed_time,
                       int idx) {
  libvpx_test::MD5 md5;
  md5.Add(reinterpret_cast<const uint8_t *>(data), data_size);
  printf("Mode %s[%12s]: %5d ms     MD5: %s\n", name, kVp9IntraPredNames[idx],
         elapsed_time, md5.Get());
  EXPECT_STREQ(signatures[idx], md5.Get());
}

78
void TestIntraPred(const char name[], VpxPredFunc const *pred_funcs,
79 80 81 82 83 84 85 86 87
                   const char *const signatures[], int block_size) {
  const int kNumTests = static_cast<int>(
      2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs));
  Vp9IntraPredTestMem intra_pred_test_mem;
  const uint8_t *const above = intra_pred_test_mem.above_mem + 16;

  intra_pred_test_mem.Init(block_size, 8);

  for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) {
88
    if (pred_funcs[k] == NULL) continue;
89 90
    memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src,
           sizeof(intra_pred_test_mem.src));
91 92 93
    vpx_usec_timer timer;
    vpx_usec_timer_start(&timer);
    for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
94 95
      pred_funcs[k](intra_pred_test_mem.src, kBPS, above,
                    intra_pred_test_mem.left);
96
    }
97
    libvpx_test::ClearSystemState();
98 99 100
    vpx_usec_timer_mark(&timer);
    const int elapsed_time =
        static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
101 102
    CheckMd5Signature(name, signatures, intra_pred_test_mem.src,
                      sizeof(intra_pred_test_mem.src), elapsed_time, k);
103 104 105 106
  }
}

void TestIntraPred4(VpxPredFunc const *pred_funcs) {
107 108 109 110 111 112 113 114
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "e7ed7353c3383fff942e500e9bfe82fe", "2a4a26fcc6ce005eadc08354d196c8a9",
    "269d92eff86f315d9c38fe7640d85b15", "ae2960eea9f71ee3dabe08b282ec1773",
    "6c1abcc44e90148998b51acd11144e9c", "f7bb3186e1ef8a2b326037ff898cad8e",
    "364c1f3fb2f445f935aec2a70a67eaa4", "141624072a4a56773f68fadbdd07c4a7",
    "7be49b08687a5f24df3a2c612fca3876", "459bb5d9fd5b238348179c9a22108cd6",
    "73edb8831bf1bdfce21ae8eaa43b1234", "2e2457f2009c701a355a8b25eb74fcda",
    "52ae4e8bdbe41494c1f43051d4dd7f0b"
115
  };
116
  TestIntraPred("Intra4", pred_funcs, kSignatures, 4);
117 118 119
}

void TestIntraPred8(VpxPredFunc const *pred_funcs) {
120 121 122 123 124 125 126 127
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "d8bbae5d6547cfc17e4f5f44c8730e88", "373bab6d931868d41a601d9d88ce9ac3",
    "6fdd5ff4ff79656c14747598ca9e3706", "d9661c2811d6a73674f40ffb2b841847",
    "7c722d10b19ccff0b8c171868e747385", "f81dd986eb2b50f750d3a7da716b7e27",
    "d500f2c8fc78f46a4c74e4dcf51f14fb", "0e3523f9cab2142dd37fd07ec0760bce",
    "79ac4efe907f0a0f1885d43066cfedee", "19ecf2432ac305057de3b6578474eec6",
    "4f985b61acc6dd5d2d2585fa89ea2e2d", "f1bb25a9060dd262f405f15a38f5f674",
    "209ea00801584829e9a0f7be7d4a74ba"
128
  };
129
  TestIntraPred("Intra8", pred_funcs, kSignatures, 8);
130 131 132
}

void TestIntraPred16(VpxPredFunc const *pred_funcs) {
133 134 135 136 137 138 139 140
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "50971c07ce26977d30298538fffec619", "527a6b9e0dc5b21b98cf276305432bef",
    "7eff2868f80ebc2c43a4f367281d80f7", "67cd60512b54964ef6aff1bd4816d922",
    "48371c87dc95c08a33b2048f89cf6468", "b0acf2872ee411d7530af6d2625a7084",
    "f32aafed4d8d3776ed58bcb6188756d5", "dae208f3dca583529cff49b73f7c4183",
    "7af66a2f4c8e0b4908e40f047e60c47c", "125e3ab6ab9bc961f183ec366a7afa88",
    "6b90f25b23983c35386b9fd704427622", "f8d6b11d710edc136a7c62c917435f93",
    "ed308f18614a362917f411c218aee532"
141
  };
142
  TestIntraPred("Intra16", pred_funcs, kSignatures, 16);
143 144 145
}

void TestIntraPred32(VpxPredFunc const *pred_funcs) {
146 147 148 149 150 151 152 153
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "a0a618c900e65ae521ccc8af789729f2", "985aaa7c72b4a6c2fb431d32100cf13a",
    "10662d09febc3ca13ee4e700120daeb5", "b3b01379ba08916ef6b1b35f7d9ad51c",
    "9f4261755795af97e34679c333ec7004", "bc2c9da91ad97ef0d1610fb0a9041657",
    "75c79b1362ad18abfcdb1aa0aacfc21d", "4039bb7da0f6860090d3c57b5c85468f",
    "b29fff7b61804e68383e3a609b33da58", "e1aa5e49067fd8dba66c2eb8d07b7a89",
    "4e042822909c1c06d3b10a88281df1eb", "72eb9d9e0e67c93f4c66b70348e9fef7",
    "a22d102bcb51ca798aac12ca4ae8f2e8"
154
  };
155
  TestIntraPred("Intra32", pred_funcs, kSignatures, 32);
156 157 158 159 160 161
}

}  // namespace

// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors
// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4.
clang-format's avatar
clang-format committed
162 163 164 165 166 167 168
#define INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, v, h,   \
                        d45, d135, d117, d153, d207, d63, tm)                 \
  TEST(arch, test_func) {                                                     \
    static const VpxPredFunc vpx_intra_pred[] = {                             \
      dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \
    };                                                                        \
    test_func(vpx_intra_pred);                                                \
169 170 171 172
  }

// -----------------------------------------------------------------------------

173 174 175 176 177 178 179
INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c,
                vpx_dc_left_predictor_4x4_c, vpx_dc_top_predictor_4x4_c,
                vpx_dc_128_predictor_4x4_c, vpx_v_predictor_4x4_c,
                vpx_h_predictor_4x4_c, vpx_d45_predictor_4x4_c,
                vpx_d135_predictor_4x4_c, vpx_d117_predictor_4x4_c,
                vpx_d153_predictor_4x4_c, vpx_d207_predictor_4x4_c,
                vpx_d63_predictor_4x4_c, vpx_tm_predictor_4x4_c)
180

181 182 183 184 185 186 187
INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c,
                vpx_dc_left_predictor_8x8_c, vpx_dc_top_predictor_8x8_c,
                vpx_dc_128_predictor_8x8_c, vpx_v_predictor_8x8_c,
                vpx_h_predictor_8x8_c, vpx_d45_predictor_8x8_c,
                vpx_d135_predictor_8x8_c, vpx_d117_predictor_8x8_c,
                vpx_d153_predictor_8x8_c, vpx_d207_predictor_8x8_c,
                vpx_d63_predictor_8x8_c, vpx_tm_predictor_8x8_c)
188

189 190 191 192 193 194 195
INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c,
                vpx_dc_left_predictor_16x16_c, vpx_dc_top_predictor_16x16_c,
                vpx_dc_128_predictor_16x16_c, vpx_v_predictor_16x16_c,
                vpx_h_predictor_16x16_c, vpx_d45_predictor_16x16_c,
                vpx_d135_predictor_16x16_c, vpx_d117_predictor_16x16_c,
                vpx_d153_predictor_16x16_c, vpx_d207_predictor_16x16_c,
                vpx_d63_predictor_16x16_c, vpx_tm_predictor_16x16_c)
196

197 198 199 200 201 202 203 204
INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c,
                vpx_dc_left_predictor_32x32_c, vpx_dc_top_predictor_32x32_c,
                vpx_dc_128_predictor_32x32_c, vpx_v_predictor_32x32_c,
                vpx_h_predictor_32x32_c, vpx_d45_predictor_32x32_c,
                vpx_d135_predictor_32x32_c, vpx_d117_predictor_32x32_c,
                vpx_d153_predictor_32x32_c, vpx_d207_predictor_32x32_c,
                vpx_d63_predictor_32x32_c, vpx_tm_predictor_32x32_c)

205
#if HAVE_SSE2
206 207 208 209 210 211 212 213 214 215 216 217 218
INTRA_PRED_TEST(SSE2, TestIntraPred4, vpx_dc_predictor_4x4_sse2,
                vpx_dc_left_predictor_4x4_sse2, vpx_dc_top_predictor_4x4_sse2,
                vpx_dc_128_predictor_4x4_sse2, vpx_v_predictor_4x4_sse2,
                vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, NULL,
                NULL, NULL, vpx_d207_predictor_4x4_sse2, NULL,
                vpx_tm_predictor_4x4_sse2)

INTRA_PRED_TEST(SSE2, TestIntraPred8, vpx_dc_predictor_8x8_sse2,
                vpx_dc_left_predictor_8x8_sse2, vpx_dc_top_predictor_8x8_sse2,
                vpx_dc_128_predictor_8x8_sse2, vpx_v_predictor_8x8_sse2,
                vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, NULL,
                NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_sse2)

219 220 221 222
INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2,
                vpx_dc_left_predictor_16x16_sse2,
                vpx_dc_top_predictor_16x16_sse2,
                vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2,
Jian Zhou's avatar
Jian Zhou committed
223
                vpx_h_predictor_16x16_sse2, NULL, NULL, NULL, NULL, NULL, NULL,
224
                vpx_tm_predictor_16x16_sse2)
225 226 227 228 229 230 231

INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
                vpx_dc_left_predictor_32x32_sse2,
                vpx_dc_top_predictor_32x32_sse2,
                vpx_dc_128_predictor_32x32_sse2, vpx_v_predictor_32x32_sse2,
                vpx_h_predictor_32x32_sse2, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_32x32_sse2)
232
#endif  // HAVE_SSE2
233

234
#if HAVE_SSSE3
235 236 237 238 239 240
INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, vpx_d153_predictor_4x4_ssse3, NULL,
                vpx_d63_predictor_4x4_ssse3, NULL)
INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, vpx_d153_predictor_8x8_ssse3,
                vpx_d207_predictor_8x8_ssse3, vpx_d63_predictor_8x8_ssse3, NULL)
clang-format's avatar
clang-format committed
241 242 243 244
INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_d45_predictor_16x16_ssse3, NULL, NULL,
                vpx_d153_predictor_16x16_ssse3, vpx_d207_predictor_16x16_ssse3,
                vpx_d63_predictor_16x16_ssse3, NULL)
245 246 247 248
INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_d45_predictor_32x32_ssse3, NULL, NULL,
                vpx_d153_predictor_32x32_ssse3, vpx_d207_predictor_32x32_ssse3,
                vpx_d63_predictor_32x32_ssse3, NULL)
249
#endif  // HAVE_SSSE3
250 251

#if HAVE_DSPR2
252 253 254 255 256 257
INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, NULL, NULL,
                NULL, NULL, vpx_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL,
                NULL, NULL, vpx_tm_predictor_4x4_dspr2)
INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, NULL, NULL,
                NULL, NULL, vpx_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL,
                NULL, NULL, vpx_tm_predictor_8x8_c)
258 259
INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, NULL,
                NULL, NULL, NULL, vpx_h_predictor_16x16_dspr2, NULL, NULL, NULL,
260 261 262 263
                NULL, NULL, NULL, NULL)
#endif  // HAVE_DSPR2

#if HAVE_NEON
264 265 266 267 268 269 270 271 272
INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
                vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon,
                vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon,
                vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon,
                vpx_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_4x4_neon)
INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon,
                vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon,
                vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon,
273 274 275
                vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon,
                vpx_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_8x8_neon)
276 277 278 279
INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon,
                vpx_dc_left_predictor_16x16_neon,
                vpx_dc_top_predictor_16x16_neon,
                vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon,
280 281 282
                vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon,
                vpx_d135_predictor_16x16_neon, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_16x16_neon)
283 284 285 286
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
                vpx_dc_left_predictor_32x32_neon,
                vpx_dc_top_predictor_32x32_neon,
                vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
287 288
                vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon,
                vpx_d135_predictor_32x32_neon, NULL, NULL, NULL, NULL,
289
                vpx_tm_predictor_32x32_neon)
290 291
#endif  // HAVE_NEON

292
#if HAVE_MSA
293 294 295 296 297 298 299 300 301 302
INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa,
                vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa,
                vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa,
                vpx_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_4x4_msa)
INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa,
                vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa,
                vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa,
                vpx_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_8x8_msa)
303 304 305
INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa,
                vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa,
                vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa,
clang-format's avatar
clang-format committed
306 307
                vpx_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_16x16_msa)
308 309 310 311 312
INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
                vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa,
                vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa,
                vpx_h_predictor_32x32_msa, NULL, NULL, NULL, NULL, NULL, NULL,
                vpx_tm_predictor_32x32_msa)
313 314
#endif  // HAVE_MSA

315
#if HAVE_VSX
Luca Barbato's avatar
Luca Barbato committed
316 317
INTRA_PRED_TEST(VSX, TestIntraPred4, NULL, NULL, NULL, NULL, NULL,
                vpx_h_predictor_4x4_vsx, NULL, NULL, NULL, NULL, NULL, NULL,
Luca Barbato's avatar
Luca Barbato committed
318
                vpx_tm_predictor_4x4_vsx)
Luca Barbato's avatar
Luca Barbato committed
319

Luca Barbato's avatar
Luca Barbato committed
320
INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, NULL, NULL, NULL,
Luca Barbato's avatar
Luca Barbato committed
321 322 323
                NULL, vpx_h_predictor_8x8_vsx, vpx_d45_predictor_8x8_vsx, NULL,
                NULL, NULL, NULL, vpx_d63_predictor_8x8_vsx,
                vpx_tm_predictor_8x8_vsx)
Luca Barbato's avatar
Luca Barbato committed
324

Luca Barbato's avatar
Luca Barbato committed
325 326 327
INTRA_PRED_TEST(VSX, TestIntraPred16, vpx_dc_predictor_16x16_vsx,
                vpx_dc_left_predictor_16x16_vsx, vpx_dc_top_predictor_16x16_vsx,
                vpx_dc_128_predictor_16x16_vsx, vpx_v_predictor_16x16_vsx,
Luca Barbato's avatar
Luca Barbato committed
328
                vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, NULL,
Luca Barbato's avatar
Luca Barbato committed
329 330
                NULL, NULL, NULL, vpx_d63_predictor_16x16_vsx,
                vpx_tm_predictor_16x16_vsx)
Luca Barbato's avatar
Luca Barbato committed
331 332 333 334

INTRA_PRED_TEST(VSX, TestIntraPred32, vpx_dc_predictor_32x32_vsx,
                vpx_dc_left_predictor_32x32_vsx, vpx_dc_top_predictor_32x32_vsx,
                vpx_dc_128_predictor_32x32_vsx, vpx_v_predictor_32x32_vsx,
Luca Barbato's avatar
Luca Barbato committed
335
                vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, NULL,
Luca Barbato's avatar
Luca Barbato committed
336 337
                NULL, NULL, NULL, vpx_d63_predictor_32x32_vsx,
                vpx_tm_predictor_32x32_vsx)
338 339
#endif  // HAVE_VSX

340 341
// -----------------------------------------------------------------------------

342 343
#if CONFIG_VP9_HIGHBITDEPTH
namespace {
344

345 346 347
typedef void (*VpxHighbdPredFunc)(uint16_t *dst, ptrdiff_t y_stride,
                                  const uint16_t *above, const uint16_t *left,
                                  int bd);
348

349
typedef IntraPredTestMem<uint16_t> Vp9HighbdIntraPredTestMem;
350

351 352 353 354 355 356
void TestHighbdIntraPred(const char name[], VpxHighbdPredFunc const *pred_funcs,
                         const char *const signatures[], int block_size) {
  const int kNumTests = static_cast<int>(
      2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs));
  Vp9HighbdIntraPredTestMem intra_pred_test_mem;
  const uint16_t *const above = intra_pred_test_mem.above_mem + 16;
357

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
  intra_pred_test_mem.Init(block_size, 12);

  for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) {
    if (pred_funcs[k] == NULL) continue;
    memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src,
           sizeof(intra_pred_test_mem.src));
    vpx_usec_timer timer;
    vpx_usec_timer_start(&timer);
    for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
      pred_funcs[k](intra_pred_test_mem.src, kBPS, above,
                    intra_pred_test_mem.left, 12);
    }
    libvpx_test::ClearSystemState();
    vpx_usec_timer_mark(&timer);
    const int elapsed_time =
        static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
    CheckMd5Signature(name, signatures, intra_pred_test_mem.src,
                      sizeof(intra_pred_test_mem.src), elapsed_time, k);
  }
}

void TestHighbdIntraPred4(VpxHighbdPredFunc const *pred_funcs) {
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "11f74af6c5737df472f3275cbde062fa", "51bea056b6447c93f6eb8f6b7e8f6f71",
    "27e97f946766331795886f4de04c5594", "53ab15974b049111fb596c5168ec7e3f",
    "f0b640bb176fbe4584cf3d32a9b0320a", "729783ca909e03afd4b47111c80d967b",
    "fbf1c30793d9f32812e4d9f905d53530", "293fc903254a33754133314c6cdba81f",
    "f8074d704233e73dfd35b458c6092374", "aa6363d08544a1ec4da33d7a0be5640d",
    "462abcfdfa3d087bb33c9a88f2aec491", "863eab65d22550dd44a2397277c1ec71",
    "23d61df1574d0fa308f9731811047c4b"
  };
  TestHighbdIntraPred("Intra4", pred_funcs, kSignatures, 4);
}

void TestHighbdIntraPred8(VpxHighbdPredFunc const *pred_funcs) {
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "03da8829fe94663047fd108c5fcaa71d", "ecdb37b8120a2d3a4c706b016bd1bfd7",
    "1d4543ed8d2b9368cb96898095fe8a75", "f791c9a67b913cbd82d9da8ecede30e2",
    "065c70646f4dbaff913282f55a45a441", "51f87123616662ef7c35691497dfd0ba",
    "2a5b0131ef4716f098ee65e6df01e3dd", "9ffe186a6bc7db95275f1bbddd6f7aba",
    "a3258a2eae2e2bd55cb8f71351b22998", "8d909f0a2066e39b3216092c6289ece4",
    "d183abb30b9f24c886a0517e991b22c7", "702a42fe4c7d665dc561b2aeeb60f311",
    "7b5dbbbe7ae3a4ac2948731600bde5d6"
  };
  TestHighbdIntraPred("Intra8", pred_funcs, kSignatures, 8);
}

void TestHighbdIntraPred16(VpxHighbdPredFunc const *pred_funcs) {
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "e33cb3f56a878e2fddb1b2fc51cdd275", "c7bff6f04b6052c8ab335d726dbbd52d",
    "d0b0b47b654a9bcc5c6008110a44589b", "78f5da7b10b2b9ab39f114a33b6254e9",
    "c78e31d23831abb40d6271a318fdd6f3", "90d1347f4ec9198a0320daecb6ff90b8",
    "d2c623746cbb64a0c9e29c10f2c57041", "cf28bd387b81ad3e5f1a1c779a4b70a0",
    "24c304330431ddeaf630f6ce94af2eac", "91a329798036bf64e8e00a87b131b8b1",
    "d39111f22885307f920796a42084c872", "e2e702f7250ece98dd8f3f2854c31eeb",
    "e2fb05b01eb8b88549e85641d8ce5b59"
  };
  TestHighbdIntraPred("Intra16", pred_funcs, kSignatures, 16);
}

void TestHighbdIntraPred32(VpxHighbdPredFunc const *pred_funcs) {
  static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
    "a3e8056ba7e36628cce4917cd956fedd", "cc7d3024fe8748b512407edee045377e",
    "2aab0a0f330a1d3e19b8ecb8f06387a3", "a547bc3fb7b06910bf3973122a426661",
    "26f712514da95042f93d6e8dc8e431dc", "bb08c6e16177081daa3d936538dbc2e3",
    "8f031af3e2650e89620d8d2c3a843d8b", "42867c8553285e94ee8e4df7abafbda8",
    "6496bdee96100667833f546e1be3d640", "2ebfa25bf981377e682e580208504300",
    "3e8ae52fd1f607f348aa4cb436c71ab7", "3d4efe797ca82193613696753ea624c4",
    "cb8aab6d372278f3131e8d99efde02d9"
  };
  TestHighbdIntraPred("Intra32", pred_funcs, kSignatures, 32);
}

}  // namespace

// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors
// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4.
#define HIGHBD_INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128,  \
                               v, h, d45, d135, d117, d153, d207, d63, tm)    \
  TEST(arch, test_func) {                                                     \
    static const VpxHighbdPredFunc vpx_intra_pred[] = {                       \
      dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \
    };                                                                        \
    test_func(vpx_intra_pred);                                                \
  }

// -----------------------------------------------------------------------------

HIGHBD_INTRA_PRED_TEST(
    C, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_c,
    vpx_highbd_dc_left_predictor_4x4_c, vpx_highbd_dc_top_predictor_4x4_c,
    vpx_highbd_dc_128_predictor_4x4_c, vpx_highbd_v_predictor_4x4_c,
    vpx_highbd_h_predictor_4x4_c, vpx_highbd_d45_predictor_4x4_c,
    vpx_highbd_d135_predictor_4x4_c, vpx_highbd_d117_predictor_4x4_c,
    vpx_highbd_d153_predictor_4x4_c, vpx_highbd_d207_predictor_4x4_c,
    vpx_highbd_d63_predictor_4x4_c, vpx_highbd_tm_predictor_4x4_c)

HIGHBD_INTRA_PRED_TEST(
    C, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_c,
    vpx_highbd_dc_left_predictor_8x8_c, vpx_highbd_dc_top_predictor_8x8_c,
    vpx_highbd_dc_128_predictor_8x8_c, vpx_highbd_v_predictor_8x8_c,
    vpx_highbd_h_predictor_8x8_c, vpx_highbd_d45_predictor_8x8_c,
    vpx_highbd_d135_predictor_8x8_c, vpx_highbd_d117_predictor_8x8_c,
    vpx_highbd_d153_predictor_8x8_c, vpx_highbd_d207_predictor_8x8_c,
    vpx_highbd_d63_predictor_8x8_c, vpx_highbd_tm_predictor_8x8_c)

HIGHBD_INTRA_PRED_TEST(
    C, TestHighbdIntraPred16, vpx_highbd_dc_predictor_16x16_c,
    vpx_highbd_dc_left_predictor_16x16_c, vpx_highbd_dc_top_predictor_16x16_c,
    vpx_highbd_dc_128_predictor_16x16_c, vpx_highbd_v_predictor_16x16_c,
    vpx_highbd_h_predictor_16x16_c, vpx_highbd_d45_predictor_16x16_c,
    vpx_highbd_d135_predictor_16x16_c, vpx_highbd_d117_predictor_16x16_c,
    vpx_highbd_d153_predictor_16x16_c, vpx_highbd_d207_predictor_16x16_c,
    vpx_highbd_d63_predictor_16x16_c, vpx_highbd_tm_predictor_16x16_c)

HIGHBD_INTRA_PRED_TEST(
    C, TestHighbdIntraPred32, vpx_highbd_dc_predictor_32x32_c,
    vpx_highbd_dc_left_predictor_32x32_c, vpx_highbd_dc_top_predictor_32x32_c,
    vpx_highbd_dc_128_predictor_32x32_c, vpx_highbd_v_predictor_32x32_c,
    vpx_highbd_h_predictor_32x32_c, vpx_highbd_d45_predictor_32x32_c,
    vpx_highbd_d135_predictor_32x32_c, vpx_highbd_d117_predictor_32x32_c,
    vpx_highbd_d153_predictor_32x32_c, vpx_highbd_d207_predictor_32x32_c,
    vpx_highbd_d63_predictor_32x32_c, vpx_highbd_tm_predictor_32x32_c)

#if HAVE_SSE2
483 484 485 486
HIGHBD_INTRA_PRED_TEST(
    SSE2, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_sse2,
    vpx_highbd_dc_left_predictor_4x4_sse2, vpx_highbd_dc_top_predictor_4x4_sse2,
    vpx_highbd_dc_128_predictor_4x4_sse2, vpx_highbd_v_predictor_4x4_sse2,
487
    vpx_highbd_h_predictor_4x4_sse2, NULL, vpx_highbd_d135_predictor_4x4_sse2,
488 489 490
    vpx_highbd_d117_predictor_4x4_sse2, vpx_highbd_d153_predictor_4x4_sse2,
    vpx_highbd_d207_predictor_4x4_sse2, vpx_highbd_d63_predictor_4x4_sse2,
    vpx_highbd_tm_predictor_4x4_c)
491 492

HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred8,
493 494
                       vpx_highbd_dc_predictor_8x8_sse2,
                       vpx_highbd_dc_left_predictor_8x8_sse2,
495 496
                       vpx_highbd_dc_top_predictor_8x8_sse2,
                       vpx_highbd_dc_128_predictor_8x8_sse2,
497 498 499
                       vpx_highbd_v_predictor_8x8_sse2,
                       vpx_highbd_h_predictor_8x8_sse2, NULL, NULL, NULL, NULL,
                       NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2)
500 501

HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred16,
502 503
                       vpx_highbd_dc_predictor_16x16_sse2,
                       vpx_highbd_dc_left_predictor_16x16_sse2,
504 505
                       vpx_highbd_dc_top_predictor_16x16_sse2,
                       vpx_highbd_dc_128_predictor_16x16_sse2,
506 507 508
                       vpx_highbd_v_predictor_16x16_sse2,
                       vpx_highbd_h_predictor_16x16_sse2, NULL, NULL, NULL,
                       NULL, NULL, NULL, vpx_highbd_tm_predictor_16x16_sse2)
509 510

HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred32,
511 512
                       vpx_highbd_dc_predictor_32x32_sse2,
                       vpx_highbd_dc_left_predictor_32x32_sse2,
513 514
                       vpx_highbd_dc_top_predictor_32x32_sse2,
                       vpx_highbd_dc_128_predictor_32x32_sse2,
515 516 517
                       vpx_highbd_v_predictor_32x32_sse2,
                       vpx_highbd_h_predictor_32x32_sse2, NULL, NULL, NULL,
                       NULL, NULL, NULL, vpx_highbd_tm_predictor_32x32_sse2)
518 519
#endif  // HAVE_SSE2

520 521
#if HAVE_SSSE3
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, NULL, NULL, NULL, NULL,
522 523
                       NULL, NULL, vpx_highbd_d45_predictor_4x4_ssse3, NULL,
                       NULL, NULL, NULL, NULL, NULL)
524
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, NULL, NULL, NULL, NULL,
525 526
                       NULL, NULL, vpx_highbd_d45_predictor_8x8_ssse3,
                       vpx_highbd_d135_predictor_8x8_ssse3,
527 528
                       vpx_highbd_d117_predictor_8x8_ssse3,
                       vpx_highbd_d153_predictor_8x8_ssse3,
529
                       vpx_highbd_d207_predictor_8x8_ssse3,
530
                       vpx_highbd_d63_predictor_8x8_ssse3, NULL)
531
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, NULL, NULL, NULL, NULL,
532 533
                       NULL, NULL, vpx_highbd_d45_predictor_16x16_ssse3,
                       vpx_highbd_d135_predictor_16x16_ssse3,
534 535
                       vpx_highbd_d117_predictor_16x16_ssse3,
                       vpx_highbd_d153_predictor_16x16_ssse3,
536
                       vpx_highbd_d207_predictor_16x16_ssse3,
537
                       vpx_highbd_d63_predictor_16x16_ssse3, NULL)
538
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, NULL, NULL, NULL, NULL,
539 540
                       NULL, NULL, vpx_highbd_d45_predictor_32x32_ssse3,
                       vpx_highbd_d135_predictor_32x32_ssse3,
541 542
                       vpx_highbd_d117_predictor_32x32_ssse3,
                       vpx_highbd_d153_predictor_32x32_ssse3,
543
                       vpx_highbd_d207_predictor_32x32_ssse3,
544
                       vpx_highbd_d63_predictor_32x32_ssse3, NULL)
545 546
#endif  // HAVE_SSSE3

547
#if HAVE_NEON
548 549 550 551 552
HIGHBD_INTRA_PRED_TEST(
    NEON, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_neon,
    vpx_highbd_dc_left_predictor_4x4_neon, vpx_highbd_dc_top_predictor_4x4_neon,
    vpx_highbd_dc_128_predictor_4x4_neon, vpx_highbd_v_predictor_4x4_neon,
    vpx_highbd_h_predictor_4x4_neon, vpx_highbd_d45_predictor_4x4_neon,
553 554
    vpx_highbd_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
    vpx_highbd_tm_predictor_4x4_neon)
555 556 557 558 559
HIGHBD_INTRA_PRED_TEST(
    NEON, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_neon,
    vpx_highbd_dc_left_predictor_8x8_neon, vpx_highbd_dc_top_predictor_8x8_neon,
    vpx_highbd_dc_128_predictor_8x8_neon, vpx_highbd_v_predictor_8x8_neon,
    vpx_highbd_h_predictor_8x8_neon, vpx_highbd_d45_predictor_8x8_neon,
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    vpx_highbd_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
    vpx_highbd_tm_predictor_8x8_neon)
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred16,
                       vpx_highbd_dc_predictor_16x16_neon,
                       vpx_highbd_dc_left_predictor_16x16_neon,
                       vpx_highbd_dc_top_predictor_16x16_neon,
                       vpx_highbd_dc_128_predictor_16x16_neon,
                       vpx_highbd_v_predictor_16x16_neon,
                       vpx_highbd_h_predictor_16x16_neon,
                       vpx_highbd_d45_predictor_16x16_neon,
                       vpx_highbd_d135_predictor_16x16_neon, NULL, NULL, NULL,
                       NULL, vpx_highbd_tm_predictor_16x16_neon)
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred32,
                       vpx_highbd_dc_predictor_32x32_neon,
                       vpx_highbd_dc_left_predictor_32x32_neon,
                       vpx_highbd_dc_top_predictor_32x32_neon,
                       vpx_highbd_dc_128_predictor_32x32_neon,
                       vpx_highbd_v_predictor_32x32_neon,
                       vpx_highbd_h_predictor_32x32_neon,
                       vpx_highbd_d45_predictor_32x32_neon,
                       vpx_highbd_d135_predictor_32x32_neon, NULL, NULL, NULL,
                       NULL, vpx_highbd_tm_predictor_32x32_neon)
582 583
#endif  // HAVE_NEON

584
#endif  // CONFIG_VP9_HIGHBITDEPTH
585

586
#include "test/test_libvpx.cc"