tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pickrst_test.cc (27623B)


      1 /*
      2 * Copyright (c) 2018, Alliance for Open Media. All rights reserved.
      3 *
      4 * This source code is subject to the terms of the BSD 2 Clause License and
      5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6 * was not distributed with this source code in the LICENSE file, you can
      7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8 * Media Patent License 1.0 was not distributed with this source code in the
      9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10 */
     11 
     12 #include <tuple>
     13 
     14 #include "gtest/gtest.h"
     15 
     16 #include "test/register_state_check.h"
     17 #include "test/acm_random.h"
     18 #include "test/util.h"
     19 
     20 #include "config/aom_config.h"
     21 #include "config/aom_dsp_rtcd.h"
     22 
     23 #include "aom/aom_integer.h"
     24 #include "aom_ports/aom_timer.h"
     25 #include "av1/encoder/pickrst.h"
     26 
     27 #define MAX_DATA_BLOCK 384
     28 
     29 namespace pickrst_test_lowbd {
     30 static const int kIterations = 100;
     31 
     32 using lowbd_pixel_proj_error_func = int64_t (*)(
     33    const uint8_t *src8, int width, int height, int src_stride,
     34    const uint8_t *dat8, int dat_stride, int32_t *flt0, int flt0_stride,
     35    int32_t *flt1, int flt1_stride, int xq[2], const sgr_params_type *params);
     36 
     37 ////////////////////////////////////////////////////////////////////////////////
     38 // 8 bit
     39 ////////////////////////////////////////////////////////////////////////////////
     40 
     41 using PixelProjErrorTestParam = std::tuple<const lowbd_pixel_proj_error_func>;
     42 
     43 class PixelProjErrorTest
     44    : public ::testing::TestWithParam<PixelProjErrorTestParam> {
     45 public:
     46  void SetUp() override {
     47    target_func_ = GET_PARAM(0);
     48    src_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
     49                                  sizeof(*src_)));
     50    ASSERT_NE(src_, nullptr);
     51    dgd_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
     52                                  sizeof(*dgd_)));
     53    ASSERT_NE(dgd_, nullptr);
     54    flt0_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
     55                                   sizeof(*flt0_)));
     56    ASSERT_NE(flt0_, nullptr);
     57    flt1_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
     58                                   sizeof(*flt1_)));
     59    ASSERT_NE(flt1_, nullptr);
     60  }
     61  void TearDown() override {
     62    aom_free(src_);
     63    aom_free(dgd_);
     64    aom_free(flt0_);
     65    aom_free(flt1_);
     66  }
     67  void RunPixelProjErrorTest(int32_t run_times);
     68  void RunPixelProjErrorTest_ExtremeValues();
     69 
     70 private:
     71  lowbd_pixel_proj_error_func target_func_;
     72  libaom_test::ACMRandom rng_;
     73  uint8_t *src_;
     74  uint8_t *dgd_;
     75  int32_t *flt0_;
     76  int32_t *flt1_;
     77 };
     78 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelProjErrorTest);
     79 
     80 void PixelProjErrorTest::RunPixelProjErrorTest(int32_t run_times) {
     81  int h_end = run_times != 1 ? 128 : (rng_.Rand16() % MAX_DATA_BLOCK) + 1;
     82  int v_end = run_times != 1 ? 128 : (rng_.Rand16() % MAX_DATA_BLOCK) + 1;
     83  const int dgd_stride = MAX_DATA_BLOCK;
     84  const int src_stride = MAX_DATA_BLOCK;
     85  const int flt0_stride = MAX_DATA_BLOCK;
     86  const int flt1_stride = MAX_DATA_BLOCK;
     87  sgr_params_type params;
     88  int xq[2];
     89  const int iters = run_times == 1 ? kIterations : 4;
     90  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
     91    int64_t err_ref = 0, err_test = 1;
     92    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
     93      dgd_[i] = rng_.Rand8();
     94      src_[i] = rng_.Rand8();
     95      flt0_[i] = rng_.Rand15Signed();
     96      flt1_[i] = rng_.Rand15Signed();
     97    }
     98    xq[0] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
     99    xq[1] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    100    params.r[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter % 2);
    101    params.r[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter / 2);
    102    params.s[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter % 2);
    103    params.s[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter / 2);
    104    uint8_t *dgd = dgd_;
    105    uint8_t *src = src_;
    106 
    107    aom_usec_timer timer;
    108    aom_usec_timer_start(&timer);
    109    for (int i = 0; i < run_times; ++i) {
    110      err_ref = av1_lowbd_pixel_proj_error_c(src, h_end, v_end, src_stride, dgd,
    111                                             dgd_stride, flt0_, flt0_stride,
    112                                             flt1_, flt1_stride, xq, &params);
    113    }
    114    aom_usec_timer_mark(&timer);
    115    const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    116    aom_usec_timer_start(&timer);
    117    for (int i = 0; i < run_times; ++i) {
    118      err_test =
    119          target_func_(src, h_end, v_end, src_stride, dgd, dgd_stride, flt0_,
    120                       flt0_stride, flt1_, flt1_stride, xq, &params);
    121    }
    122    aom_usec_timer_mark(&timer);
    123    const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    124    if (run_times > 10) {
    125      printf("r0 %d r1 %d %3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", params.r[0],
    126             params.r[1], h_end, v_end, time1, time2, time1 / time2);
    127    }
    128    ASSERT_EQ(err_ref, err_test);
    129  }
    130 }
    131 
    132 void PixelProjErrorTest::RunPixelProjErrorTest_ExtremeValues() {
    133  const int h_start = 0;
    134  int h_end = 192;
    135  const int v_start = 0;
    136  int v_end = 192;
    137  const int dgd_stride = MAX_DATA_BLOCK;
    138  const int src_stride = MAX_DATA_BLOCK;
    139  const int flt0_stride = MAX_DATA_BLOCK;
    140  const int flt1_stride = MAX_DATA_BLOCK;
    141  sgr_params_type params;
    142  int xq[2];
    143  const int iters = kIterations;
    144  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    145    int64_t err_ref = 0, err_test = 1;
    146    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    147      dgd_[i] = 0;
    148      src_[i] = 255;
    149      flt0_[i] = rng_.Rand15Signed();
    150      flt1_[i] = rng_.Rand15Signed();
    151    }
    152    xq[0] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    153    xq[1] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    154    params.r[0] = rng_.Rand8() % MAX_RADIUS;
    155    params.r[1] = rng_.Rand8() % MAX_RADIUS;
    156    params.s[0] = rng_.Rand8() % MAX_RADIUS;
    157    params.s[1] = rng_.Rand8() % MAX_RADIUS;
    158    uint8_t *dgd = dgd_;
    159    uint8_t *src = src_;
    160 
    161    err_ref = av1_lowbd_pixel_proj_error_c(
    162        src, h_end - h_start, v_end - v_start, src_stride, dgd, dgd_stride,
    163        flt0_, flt0_stride, flt1_, flt1_stride, xq, &params);
    164 
    165    err_test = target_func_(src, h_end - h_start, v_end - v_start, src_stride,
    166                            dgd, dgd_stride, flt0_, flt0_stride, flt1_,
    167                            flt1_stride, xq, &params);
    168 
    169    ASSERT_EQ(err_ref, err_test);
    170  }
    171 }
    172 
    173 TEST_P(PixelProjErrorTest, RandomValues) { RunPixelProjErrorTest(1); }
    174 
    175 TEST_P(PixelProjErrorTest, ExtremeValues) {
    176  RunPixelProjErrorTest_ExtremeValues();
    177 }
    178 
    179 TEST_P(PixelProjErrorTest, DISABLED_Speed) { RunPixelProjErrorTest(200000); }
    180 
    181 #if HAVE_SSE4_1
    182 INSTANTIATE_TEST_SUITE_P(SSE4_1, PixelProjErrorTest,
    183                         ::testing::Values(av1_lowbd_pixel_proj_error_sse4_1));
    184 #endif  // HAVE_SSE4_1
    185 
    186 #if HAVE_AVX2
    187 
    188 INSTANTIATE_TEST_SUITE_P(AVX2, PixelProjErrorTest,
    189                         ::testing::Values(av1_lowbd_pixel_proj_error_avx2));
    190 #endif  // HAVE_AVX2
    191 
    192 #if HAVE_NEON
    193 
    194 INSTANTIATE_TEST_SUITE_P(NEON, PixelProjErrorTest,
    195                         ::testing::Values(av1_lowbd_pixel_proj_error_neon));
    196 #endif  // HAVE_NEON
    197 
    198 }  // namespace pickrst_test_lowbd
    199 
    200 #if CONFIG_AV1_HIGHBITDEPTH
    201 namespace pickrst_test_highbd {
    202 static const int kIterations = 100;
    203 
    204 using highbd_pixel_proj_error_func = int64_t (*)(
    205    const uint8_t *src8, int width, int height, int src_stride,
    206    const uint8_t *dat8, int dat_stride, int32_t *flt0, int flt0_stride,
    207    int32_t *flt1, int flt1_stride, int xq[2], const sgr_params_type *params);
    208 
    209 ////////////////////////////////////////////////////////////////////////////////
    210 // High bit-depth
    211 ////////////////////////////////////////////////////////////////////////////////
    212 
    213 using PixelProjErrorTestParam = std::tuple<const highbd_pixel_proj_error_func>;
    214 
    215 class PixelProjHighbdErrorTest
    216    : public ::testing::TestWithParam<PixelProjErrorTestParam> {
    217 public:
    218  void SetUp() override {
    219    target_func_ = GET_PARAM(0);
    220    src_ =
    221        (uint16_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*src_));
    222    ASSERT_NE(src_, nullptr);
    223    dgd_ =
    224        (uint16_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*dgd_));
    225    ASSERT_NE(dgd_, nullptr);
    226    flt0_ =
    227        (int32_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*flt0_));
    228    ASSERT_NE(flt0_, nullptr);
    229    flt1_ =
    230        (int32_t *)aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*flt1_));
    231    ASSERT_NE(flt1_, nullptr);
    232  }
    233  void TearDown() override {
    234    aom_free(src_);
    235    aom_free(dgd_);
    236    aom_free(flt0_);
    237    aom_free(flt1_);
    238  }
    239  void RunPixelProjErrorTest(int32_t run_times);
    240  void RunPixelProjErrorTest_ExtremeValues();
    241 
    242 private:
    243  highbd_pixel_proj_error_func target_func_;
    244  libaom_test::ACMRandom rng_;
    245  uint16_t *src_;
    246  uint16_t *dgd_;
    247  int32_t *flt0_;
    248  int32_t *flt1_;
    249 };
    250 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelProjHighbdErrorTest);
    251 
    252 void PixelProjHighbdErrorTest::RunPixelProjErrorTest(int32_t run_times) {
    253  int h_end = run_times != 1 ? 128 : (rng_.Rand16() % MAX_DATA_BLOCK) + 1;
    254  int v_end = run_times != 1 ? 128 : (rng_.Rand16() % MAX_DATA_BLOCK) + 1;
    255  const int dgd_stride = MAX_DATA_BLOCK;
    256  const int src_stride = MAX_DATA_BLOCK;
    257  const int flt0_stride = MAX_DATA_BLOCK;
    258  const int flt1_stride = MAX_DATA_BLOCK;
    259  sgr_params_type params;
    260  int xq[2];
    261  const int iters = run_times == 1 ? kIterations : 4;
    262  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    263    int64_t err_ref = 0, err_test = 1;
    264    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    265      dgd_[i] = rng_.Rand16() % (1 << 12);
    266      src_[i] = rng_.Rand16() % (1 << 12);
    267      flt0_[i] = rng_.Rand15Signed();
    268      flt1_[i] = rng_.Rand15Signed();
    269    }
    270    xq[0] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    271    xq[1] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    272    params.r[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter % 2);
    273    params.r[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter / 2);
    274    params.s[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter % 2);
    275    params.s[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : (iter / 2);
    276    uint8_t *dgd8 = CONVERT_TO_BYTEPTR(dgd_);
    277    uint8_t *src8 = CONVERT_TO_BYTEPTR(src_);
    278 
    279    aom_usec_timer timer;
    280    aom_usec_timer_start(&timer);
    281    for (int i = 0; i < run_times; ++i) {
    282      err_ref = av1_highbd_pixel_proj_error_c(
    283          src8, h_end, v_end, src_stride, dgd8, dgd_stride, flt0_, flt0_stride,
    284          flt1_, flt1_stride, xq, &params);
    285    }
    286    aom_usec_timer_mark(&timer);
    287    const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    288    aom_usec_timer_start(&timer);
    289    for (int i = 0; i < run_times; ++i) {
    290      err_test =
    291          target_func_(src8, h_end, v_end, src_stride, dgd8, dgd_stride, flt0_,
    292                       flt0_stride, flt1_, flt1_stride, xq, &params);
    293    }
    294    aom_usec_timer_mark(&timer);
    295    const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    296    if (run_times > 10) {
    297      printf("r0 %d r1 %d %3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", params.r[0],
    298             params.r[1], h_end, v_end, time1, time2, time1 / time2);
    299    }
    300    ASSERT_EQ(err_ref, err_test);
    301  }
    302 }
    303 
    304 void PixelProjHighbdErrorTest::RunPixelProjErrorTest_ExtremeValues() {
    305  const int h_start = 0;
    306  int h_end = 192;
    307  const int v_start = 0;
    308  int v_end = 192;
    309  const int dgd_stride = MAX_DATA_BLOCK;
    310  const int src_stride = MAX_DATA_BLOCK;
    311  const int flt0_stride = MAX_DATA_BLOCK;
    312  const int flt1_stride = MAX_DATA_BLOCK;
    313  sgr_params_type params;
    314  int xq[2];
    315  const int iters = kIterations;
    316  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    317    int64_t err_ref = 0, err_test = 1;
    318    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    319      dgd_[i] = 0;
    320      src_[i] = (1 << 12) - 1;
    321      flt0_[i] = rng_.Rand15Signed();
    322      flt1_[i] = rng_.Rand15Signed();
    323    }
    324    xq[0] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    325    xq[1] = rng_.Rand8() % (1 << SGRPROJ_PRJ_BITS);
    326    params.r[0] = rng_.Rand8() % MAX_RADIUS;
    327    params.r[1] = rng_.Rand8() % MAX_RADIUS;
    328    params.s[0] = rng_.Rand8() % MAX_RADIUS;
    329    params.s[1] = rng_.Rand8() % MAX_RADIUS;
    330    uint8_t *dgd8 = CONVERT_TO_BYTEPTR(dgd_);
    331    uint8_t *src8 = CONVERT_TO_BYTEPTR(src_);
    332 
    333    err_ref = av1_highbd_pixel_proj_error_c(
    334        src8, h_end - h_start, v_end - v_start, src_stride, dgd8, dgd_stride,
    335        flt0_, flt0_stride, flt1_, flt1_stride, xq, &params);
    336 
    337    err_test = target_func_(src8, h_end - h_start, v_end - v_start, src_stride,
    338                            dgd8, dgd_stride, flt0_, flt0_stride, flt1_,
    339                            flt1_stride, xq, &params);
    340 
    341    ASSERT_EQ(err_ref, err_test);
    342  }
    343 }
    344 
    345 TEST_P(PixelProjHighbdErrorTest, RandomValues) { RunPixelProjErrorTest(1); }
    346 
    347 TEST_P(PixelProjHighbdErrorTest, ExtremeValues) {
    348  RunPixelProjErrorTest_ExtremeValues();
    349 }
    350 
    351 TEST_P(PixelProjHighbdErrorTest, DISABLED_Speed) {
    352  RunPixelProjErrorTest(200000);
    353 }
    354 
    355 #if HAVE_SSE4_1
    356 INSTANTIATE_TEST_SUITE_P(SSE4_1, PixelProjHighbdErrorTest,
    357                         ::testing::Values(av1_highbd_pixel_proj_error_sse4_1));
    358 #endif  // HAVE_SSE4_1
    359 
    360 #if HAVE_AVX2
    361 
    362 INSTANTIATE_TEST_SUITE_P(AVX2, PixelProjHighbdErrorTest,
    363                         ::testing::Values(av1_highbd_pixel_proj_error_avx2));
    364 #endif  // HAVE_AVX2
    365 
    366 #if HAVE_NEON
    367 
    368 INSTANTIATE_TEST_SUITE_P(NEON, PixelProjHighbdErrorTest,
    369                         ::testing::Values(av1_highbd_pixel_proj_error_neon));
    370 #endif  // HAVE_NEON
    371 
    372 }  // namespace pickrst_test_highbd
    373 #endif  // CONFIG_AV1_HIGHBITDEPTH
    374 
    375 ////////////////////////////////////////////////////////////////////////////////
    376 // Get_proj_subspace_Test
    377 ////////////////////////////////////////////////////////////////////////////////
    378 
    379 namespace get_proj_subspace_test_lowbd {
    380 static const int kIterations = 100;
    381 
    382 using set_get_proj_subspace = void (*)(const uint8_t *src8, int width,
    383                                       int height, int src_stride,
    384                                       const uint8_t *dat8, int dat_stride,
    385                                       int32_t *flt0, int flt0_stride,
    386                                       int32_t *flt1, int flt1_stride,
    387                                       int64_t H[2][2], int64_t C[2],
    388                                       const sgr_params_type *params);
    389 
    390 using GetProjSubspaceTestParam = std::tuple<const set_get_proj_subspace>;
    391 
    392 class GetProjSubspaceTest
    393    : public ::testing::TestWithParam<GetProjSubspaceTestParam> {
    394 public:
    395  void SetUp() override {
    396    target_func_ = GET_PARAM(0);
    397    src_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    398                                  sizeof(*src_)));
    399    ASSERT_NE(src_, nullptr);
    400    dgd_ = (uint8_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    401                                  sizeof(*dgd_)));
    402    ASSERT_NE(dgd_, nullptr);
    403    flt0_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    404                                   sizeof(*flt0_)));
    405    ASSERT_NE(flt0_, nullptr);
    406    flt1_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    407                                   sizeof(*flt1_)));
    408    ASSERT_NE(flt1_, nullptr);
    409  }
    410  void TearDown() override {
    411    aom_free(src_);
    412    aom_free(dgd_);
    413    aom_free(flt0_);
    414    aom_free(flt1_);
    415  }
    416  void RunGetProjSubspaceTest(int32_t run_times);
    417  void RunGetProjSubspaceTest_ExtremeValues();
    418 
    419 private:
    420  set_get_proj_subspace target_func_;
    421  libaom_test::ACMRandom rng_;
    422  uint8_t *src_;
    423  uint8_t *dgd_;
    424  int32_t *flt0_;
    425  int32_t *flt1_;
    426 };
    427 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetProjSubspaceTest);
    428 
    429 void GetProjSubspaceTest::RunGetProjSubspaceTest(int32_t run_times) {
    430  int h_end = run_times != 1
    431                  ? 128
    432                  : ((rng_.Rand16() % MAX_DATA_BLOCK) &
    433                     2147483640);  // We test for widths divisible by 8.
    434  int v_end =
    435      run_times != 1 ? 128 : ((rng_.Rand16() % MAX_DATA_BLOCK) & 2147483640);
    436  const int dgd_stride = MAX_DATA_BLOCK;
    437  const int src_stride = MAX_DATA_BLOCK;
    438  const int flt0_stride = MAX_DATA_BLOCK;
    439  const int flt1_stride = MAX_DATA_BLOCK;
    440  sgr_params_type params;
    441  const int iters = run_times == 1 ? kIterations : 3;
    442  static constexpr int kR0[3] = { 1, 1, 0 };
    443  static constexpr int kR1[3] = { 1, 0, 1 };
    444  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    445    int64_t C_ref[2] = { 0 }, C_test[2] = { 0 };
    446    int64_t H_ref[2][2] = { { 0, 0 }, { 0, 0 } };
    447    int64_t H_test[2][2] = { { 0, 0 }, { 0, 0 } };
    448    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    449      dgd_[i] = rng_.Rand8();
    450      src_[i] = rng_.Rand8();
    451      flt0_[i] = rng_.Rand15Signed();
    452      flt1_[i] = rng_.Rand15Signed();
    453    }
    454 
    455    params.r[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : kR0[iter];
    456    params.r[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : kR1[iter];
    457    uint8_t *dgd = dgd_;
    458    uint8_t *src = src_;
    459 
    460    aom_usec_timer timer;
    461    aom_usec_timer_start(&timer);
    462    for (int i = 0; i < run_times; ++i) {
    463      av1_calc_proj_params_c(src, v_end, h_end, src_stride, dgd, dgd_stride,
    464                             flt0_, flt0_stride, flt1_, flt1_stride, H_ref,
    465                             C_ref, &params);
    466    }
    467    aom_usec_timer_mark(&timer);
    468    const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    469    aom_usec_timer_start(&timer);
    470    for (int i = 0; i < run_times; ++i) {
    471      target_func_(src, v_end, h_end, src_stride, dgd, dgd_stride, flt0_,
    472                   flt0_stride, flt1_, flt1_stride, H_test, C_test, &params);
    473    }
    474    aom_usec_timer_mark(&timer);
    475    const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    476    if (run_times > 10) {
    477      printf("r0 %d r1 %d %3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", params.r[0],
    478             params.r[1], h_end, v_end, time1, time2, time1 / time2);
    479    } else {
    480      ASSERT_EQ(H_ref[0][0], H_test[0][0]);
    481      ASSERT_EQ(H_ref[0][1], H_test[0][1]);
    482      ASSERT_EQ(H_ref[1][0], H_test[1][0]);
    483      ASSERT_EQ(H_ref[1][1], H_test[1][1]);
    484      ASSERT_EQ(C_ref[0], C_test[0]);
    485      ASSERT_EQ(C_ref[1], C_test[1]);
    486    }
    487  }
    488 }
    489 
    490 void GetProjSubspaceTest::RunGetProjSubspaceTest_ExtremeValues() {
    491  const int h_start = 0;
    492  int h_end = MAX_DATA_BLOCK;
    493  const int v_start = 0;
    494  int v_end = MAX_DATA_BLOCK;
    495  const int dgd_stride = MAX_DATA_BLOCK;
    496  const int src_stride = MAX_DATA_BLOCK;
    497  const int flt0_stride = MAX_DATA_BLOCK;
    498  const int flt1_stride = MAX_DATA_BLOCK;
    499  sgr_params_type params;
    500  const int iters = kIterations;
    501  static constexpr int kR0[3] = { 1, 1, 0 };
    502  static constexpr int kR1[3] = { 1, 0, 1 };
    503  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    504    int64_t C_ref[2] = { 0 }, C_test[2] = { 0 };
    505    int64_t H_ref[2][2] = { { 0, 0 }, { 0, 0 } };
    506    int64_t H_test[2][2] = { { 0, 0 }, { 0, 0 } };
    507    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    508      dgd_[i] = 0;
    509      src_[i] = 255;
    510      flt0_[i] = rng_.Rand15Signed();
    511      flt1_[i] = rng_.Rand15Signed();
    512    }
    513    params.r[0] = kR0[iter % 3];
    514    params.r[1] = kR1[iter % 3];
    515    uint8_t *dgd = dgd_;
    516    uint8_t *src = src_;
    517 
    518    av1_calc_proj_params_c(src, h_end - h_start, v_end - v_start, src_stride,
    519                           dgd, dgd_stride, flt0_, flt0_stride, flt1_,
    520                           flt1_stride, H_ref, C_ref, &params);
    521 
    522    target_func_(src, h_end - h_start, v_end - v_start, src_stride, dgd,
    523                 dgd_stride, flt0_, flt0_stride, flt1_, flt1_stride, H_test,
    524                 C_test, &params);
    525 
    526    ASSERT_EQ(H_ref[0][0], H_test[0][0]);
    527    ASSERT_EQ(H_ref[0][1], H_test[0][1]);
    528    ASSERT_EQ(H_ref[1][0], H_test[1][0]);
    529    ASSERT_EQ(H_ref[1][1], H_test[1][1]);
    530    ASSERT_EQ(C_ref[0], C_test[0]);
    531    ASSERT_EQ(C_ref[1], C_test[1]);
    532  }
    533 }
    534 
    535 TEST_P(GetProjSubspaceTest, RandomValues) { RunGetProjSubspaceTest(1); }
    536 
    537 TEST_P(GetProjSubspaceTest, ExtremeValues) {
    538  RunGetProjSubspaceTest_ExtremeValues();
    539 }
    540 
    541 TEST_P(GetProjSubspaceTest, DISABLED_Speed) { RunGetProjSubspaceTest(200000); }
    542 
    543 #if HAVE_SSE4_1
    544 
    545 INSTANTIATE_TEST_SUITE_P(SSE4_1, GetProjSubspaceTest,
    546                         ::testing::Values(av1_calc_proj_params_sse4_1));
    547 #endif  // HAVE_SSE4_1
    548 
    549 #if HAVE_AVX2
    550 
    551 INSTANTIATE_TEST_SUITE_P(AVX2, GetProjSubspaceTest,
    552                         ::testing::Values(av1_calc_proj_params_avx2));
    553 #endif  // HAVE_AVX2
    554 
    555 #if HAVE_NEON
    556 
    557 INSTANTIATE_TEST_SUITE_P(NEON, GetProjSubspaceTest,
    558                         ::testing::Values(av1_calc_proj_params_neon));
    559 #endif  // HAVE_NEON
    560 
    561 }  // namespace get_proj_subspace_test_lowbd
    562 
    563 #if CONFIG_AV1_HIGHBITDEPTH
    564 namespace get_proj_subspace_test_hbd {
    565 static const int kIterations = 100;
    566 
    567 using set_get_proj_subspace_hbd = void (*)(const uint8_t *src8, int width,
    568                                           int height, int src_stride,
    569                                           const uint8_t *dat8, int dat_stride,
    570                                           int32_t *flt0, int flt0_stride,
    571                                           int32_t *flt1, int flt1_stride,
    572                                           int64_t H[2][2], int64_t C[2],
    573                                           const sgr_params_type *params);
    574 
    575 using GetProjSubspaceHBDTestParam = std::tuple<const set_get_proj_subspace_hbd>;
    576 
    577 class GetProjSubspaceTestHBD
    578    : public ::testing::TestWithParam<GetProjSubspaceHBDTestParam> {
    579 public:
    580  void SetUp() override {
    581    target_func_ = GET_PARAM(0);
    582    src_ = (uint16_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    583                                   sizeof(*src_)));
    584    ASSERT_NE(src_, nullptr);
    585    dgd_ = (uint16_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    586                                   sizeof(*dgd_)));
    587    ASSERT_NE(dgd_, nullptr);
    588    flt0_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    589                                   sizeof(*flt0_)));
    590    ASSERT_NE(flt0_, nullptr);
    591    flt1_ = (int32_t *)(aom_malloc(MAX_DATA_BLOCK * MAX_DATA_BLOCK *
    592                                   sizeof(*flt1_)));
    593    ASSERT_NE(flt1_, nullptr);
    594  }
    595  void TearDown() override {
    596    aom_free(src_);
    597    aom_free(dgd_);
    598    aom_free(flt0_);
    599    aom_free(flt1_);
    600  }
    601  void RunGetProjSubspaceTestHBD(int32_t run_times);
    602  void RunGetProjSubspaceTestHBD_ExtremeValues();
    603 
    604 private:
    605  set_get_proj_subspace_hbd target_func_;
    606  libaom_test::ACMRandom rng_;
    607  uint16_t *src_;
    608  uint16_t *dgd_;
    609  int32_t *flt0_;
    610  int32_t *flt1_;
    611 };
    612 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetProjSubspaceTestHBD);
    613 
    614 void GetProjSubspaceTestHBD::RunGetProjSubspaceTestHBD(int32_t run_times) {
    615  int h_end = run_times != 1
    616                  ? 128
    617                  : ((rng_.Rand16() % MAX_DATA_BLOCK) &
    618                     2147483640);  // We test for widths divisible by 8.
    619  int v_end =
    620      run_times != 1 ? 128 : ((rng_.Rand16() % MAX_DATA_BLOCK) & 2147483640);
    621  const int dgd_stride = MAX_DATA_BLOCK;
    622  const int src_stride = MAX_DATA_BLOCK;
    623  const int flt0_stride = MAX_DATA_BLOCK;
    624  const int flt1_stride = MAX_DATA_BLOCK;
    625  sgr_params_type params;
    626  const int iters = run_times == 1 ? kIterations : 3;
    627  static constexpr int kR0[3] = { 1, 1, 0 };
    628  static constexpr int kR1[3] = { 1, 0, 1 };
    629  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    630    int64_t C_ref[2] = { 0 }, C_test[2] = { 0 };
    631    int64_t H_ref[2][2] = { { 0, 0 }, { 0, 0 } };
    632    int64_t H_test[2][2] = { { 0, 0 }, { 0, 0 } };
    633    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    634      dgd_[i] = rng_.Rand16() % 4095;
    635      src_[i] = rng_.Rand16() % 4095;
    636      flt0_[i] = rng_.Rand15Signed();
    637      flt1_[i] = rng_.Rand15Signed();
    638    }
    639 
    640    params.r[0] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : kR0[iter];
    641    params.r[1] = run_times == 1 ? (rng_.Rand8() % MAX_RADIUS) : kR1[iter];
    642    uint8_t *dgd = CONVERT_TO_BYTEPTR(dgd_);
    643    uint8_t *src = CONVERT_TO_BYTEPTR(src_);
    644 
    645    aom_usec_timer timer;
    646    aom_usec_timer_start(&timer);
    647    for (int i = 0; i < run_times; ++i) {
    648      av1_calc_proj_params_high_bd_c(src, v_end, h_end, src_stride, dgd,
    649                                     dgd_stride, flt0_, flt0_stride, flt1_,
    650                                     flt1_stride, H_ref, C_ref, &params);
    651    }
    652    aom_usec_timer_mark(&timer);
    653    const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    654    aom_usec_timer_start(&timer);
    655    for (int i = 0; i < run_times; ++i) {
    656      target_func_(src, v_end, h_end, src_stride, dgd, dgd_stride, flt0_,
    657                   flt0_stride, flt1_, flt1_stride, H_test, C_test, &params);
    658    }
    659    aom_usec_timer_mark(&timer);
    660    const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
    661    if (run_times > 10) {
    662      printf("r0 %d r1 %d %3dx%-3d:%7.2f/%7.2fns (%3.2f)\n", params.r[0],
    663             params.r[1], h_end, v_end, time1, time2, time1 / time2);
    664    } else {
    665      ASSERT_EQ(H_ref[0][0], H_test[0][0]);
    666      ASSERT_EQ(H_ref[0][1], H_test[0][1]);
    667      ASSERT_EQ(H_ref[1][0], H_test[1][0]);
    668      ASSERT_EQ(H_ref[1][1], H_test[1][1]);
    669      ASSERT_EQ(C_ref[0], C_test[0]);
    670      ASSERT_EQ(C_ref[1], C_test[1]);
    671    }
    672  }
    673 }
    674 
    675 void GetProjSubspaceTestHBD::RunGetProjSubspaceTestHBD_ExtremeValues() {
    676  const int h_start = 0;
    677  int h_end = MAX_DATA_BLOCK;
    678  const int v_start = 0;
    679  int v_end = MAX_DATA_BLOCK;
    680  const int dgd_stride = MAX_DATA_BLOCK;
    681  const int src_stride = MAX_DATA_BLOCK;
    682  const int flt0_stride = MAX_DATA_BLOCK;
    683  const int flt1_stride = MAX_DATA_BLOCK;
    684  sgr_params_type params;
    685  const int iters = kIterations;
    686  static constexpr int kR0[3] = { 1, 1, 0 };
    687  static constexpr int kR1[3] = { 1, 0, 1 };
    688  for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
    689    int64_t C_ref[2] = { 0 }, C_test[2] = { 0 };
    690    int64_t H_ref[2][2] = { { 0, 0 }, { 0, 0 } };
    691    int64_t H_test[2][2] = { { 0, 0 }, { 0, 0 } };
    692    for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
    693      dgd_[i] = 0;
    694      src_[i] = 4095;
    695      flt0_[i] = rng_.Rand15Signed();
    696      flt1_[i] = rng_.Rand15Signed();
    697    }
    698    params.r[0] = kR0[iter % 3];
    699    params.r[1] = kR1[iter % 3];
    700    uint8_t *dgd = CONVERT_TO_BYTEPTR(dgd_);
    701    uint8_t *src = CONVERT_TO_BYTEPTR(src_);
    702 
    703    av1_calc_proj_params_high_bd_c(
    704        src, h_end - h_start, v_end - v_start, src_stride, dgd, dgd_stride,
    705        flt0_, flt0_stride, flt1_, flt1_stride, H_ref, C_ref, &params);
    706 
    707    target_func_(src, h_end - h_start, v_end - v_start, src_stride, dgd,
    708                 dgd_stride, flt0_, flt0_stride, flt1_, flt1_stride, H_test,
    709                 C_test, &params);
    710 
    711    ASSERT_EQ(H_ref[0][0], H_test[0][0]);
    712    ASSERT_EQ(H_ref[0][1], H_test[0][1]);
    713    ASSERT_EQ(H_ref[1][0], H_test[1][0]);
    714    ASSERT_EQ(H_ref[1][1], H_test[1][1]);
    715    ASSERT_EQ(C_ref[0], C_test[0]);
    716    ASSERT_EQ(C_ref[1], C_test[1]);
    717  }
    718 }
    719 
    720 TEST_P(GetProjSubspaceTestHBD, RandomValues) { RunGetProjSubspaceTestHBD(1); }
    721 
    722 TEST_P(GetProjSubspaceTestHBD, ExtremeValues) {
    723  RunGetProjSubspaceTestHBD_ExtremeValues();
    724 }
    725 
    726 TEST_P(GetProjSubspaceTestHBD, DISABLED_Speed) {
    727  RunGetProjSubspaceTestHBD(200000);
    728 }
    729 
    730 #if HAVE_SSE4_1
    731 
    732 INSTANTIATE_TEST_SUITE_P(
    733    SSE4_1, GetProjSubspaceTestHBD,
    734    ::testing::Values(av1_calc_proj_params_high_bd_sse4_1));
    735 #endif  // HAVE_SSE4_1
    736 
    737 #if HAVE_AVX2
    738 
    739 INSTANTIATE_TEST_SUITE_P(AVX2, GetProjSubspaceTestHBD,
    740                         ::testing::Values(av1_calc_proj_params_high_bd_avx2));
    741 #endif  // HAVE_AVX2
    742 
    743 #if HAVE_NEON
    744 
    745 INSTANTIATE_TEST_SUITE_P(NEON, GetProjSubspaceTestHBD,
    746                         ::testing::Values(av1_calc_proj_params_high_bd_neon));
    747 #endif  // HAVE_NEON
    748 }  // namespace get_proj_subspace_test_hbd
    749 
    750 #endif  // CONFIG_AV1_HIGHBITDEPTH