Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2014 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 
     15 #include "third_party/googletest/src/include/gtest/gtest.h"
     16 
     17 #include "./vp9_rtcd.h"
     18 #include "./vpx_config.h"
     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 "vp9/common/vp9_entropy.h"
     26 #include "vp9/common/vp9_scan.h"
     27 #include "vpx/vpx_codec.h"
     28 #include "vpx/vpx_integer.h"
     29 #include "vpx_ports/vpx_timer.h"
     30 
     31 using libvpx_test::ACMRandom;
     32 using libvpx_test::Buffer;
     33 
     34 namespace {
     35 const int number_of_iterations = 100;
     36 
     37 typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
     38                              int skip_block, const int16_t *zbin,
     39                              const int16_t *round, const int16_t *quant,
     40                              const int16_t *quant_shift, tran_low_t *qcoeff,
     41                              tran_low_t *dqcoeff, const int16_t *dequant,
     42                              uint16_t *eob, const int16_t *scan,
     43                              const int16_t *iscan);
     44 typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t,
     45                         int /*max_size*/, bool /*is_fp*/>
     46     QuantizeParam;
     47 
     48 // Wrapper for FP version which does not use zbin or quant_shift.
     49 typedef void (*QuantizeFPFunc)(const tran_low_t *coeff, intptr_t count,
     50                                int skip_block, const int16_t *round,
     51                                const int16_t *quant, tran_low_t *qcoeff,
     52                                tran_low_t *dqcoeff, const int16_t *dequant,
     53                                uint16_t *eob, const int16_t *scan,
     54                                const int16_t *iscan);
     55 
     56 template <QuantizeFPFunc fn>
     57 void QuantFPWrapper(const tran_low_t *coeff, intptr_t count, int skip_block,
     58                     const int16_t *zbin, const int16_t *round,
     59                     const int16_t *quant, const int16_t *quant_shift,
     60                     tran_low_t *qcoeff, tran_low_t *dqcoeff,
     61                     const int16_t *dequant, uint16_t *eob, const int16_t *scan,
     62                     const int16_t *iscan) {
     63   (void)zbin;
     64   (void)quant_shift;
     65 
     66   fn(coeff, count, skip_block, round, quant, qcoeff, dqcoeff, dequant, eob,
     67      scan, iscan);
     68 }
     69 
     70 class VP9QuantizeBase {
     71  public:
     72   VP9QuantizeBase(vpx_bit_depth_t bit_depth, int max_size, bool is_fp)
     73       : bit_depth_(bit_depth), max_size_(max_size), is_fp_(is_fp) {
     74     max_value_ = (1 << bit_depth_) - 1;
     75     zbin_ptr_ =
     76         reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*zbin_ptr_)));
     77     round_fp_ptr_ = reinterpret_cast<int16_t *>(
     78         vpx_memalign(16, 8 * sizeof(*round_fp_ptr_)));
     79     quant_fp_ptr_ = reinterpret_cast<int16_t *>(
     80         vpx_memalign(16, 8 * sizeof(*quant_fp_ptr_)));
     81     round_ptr_ =
     82         reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*round_ptr_)));
     83     quant_ptr_ =
     84         reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*quant_ptr_)));
     85     quant_shift_ptr_ = reinterpret_cast<int16_t *>(
     86         vpx_memalign(16, 8 * sizeof(*quant_shift_ptr_)));
     87     dequant_ptr_ = reinterpret_cast<int16_t *>(
     88         vpx_memalign(16, 8 * sizeof(*dequant_ptr_)));
     89   }
     90 
     91   ~VP9QuantizeBase() {
     92     vpx_free(zbin_ptr_);
     93     vpx_free(round_fp_ptr_);
     94     vpx_free(quant_fp_ptr_);
     95     vpx_free(round_ptr_);
     96     vpx_free(quant_ptr_);
     97     vpx_free(quant_shift_ptr_);
     98     vpx_free(dequant_ptr_);
     99     zbin_ptr_ = NULL;
    100     round_fp_ptr_ = NULL;
    101     quant_fp_ptr_ = NULL;
    102     round_ptr_ = NULL;
    103     quant_ptr_ = NULL;
    104     quant_shift_ptr_ = NULL;
    105     dequant_ptr_ = NULL;
    106     libvpx_test::ClearSystemState();
    107   }
    108 
    109  protected:
    110   int16_t *zbin_ptr_;
    111   int16_t *round_fp_ptr_;
    112   int16_t *quant_fp_ptr_;
    113   int16_t *round_ptr_;
    114   int16_t *quant_ptr_;
    115   int16_t *quant_shift_ptr_;
    116   int16_t *dequant_ptr_;
    117   const vpx_bit_depth_t bit_depth_;
    118   int max_value_;
    119   const int max_size_;
    120   const bool is_fp_;
    121 };
    122 
    123 class VP9QuantizeTest : public VP9QuantizeBase,
    124                         public ::testing::TestWithParam<QuantizeParam> {
    125  public:
    126   VP9QuantizeTest()
    127       : VP9QuantizeBase(GET_PARAM(2), GET_PARAM(3), GET_PARAM(4)),
    128         quantize_op_(GET_PARAM(0)), ref_quantize_op_(GET_PARAM(1)) {}
    129 
    130  protected:
    131   const QuantizeFunc quantize_op_;
    132   const QuantizeFunc ref_quantize_op_;
    133 };
    134 
    135 // This quantizer compares the AC coefficients to the quantization step size to
    136 // determine if further multiplication operations are needed.
    137 // Based on vp9_quantize_fp_sse2().
    138 void quantize_fp_nz_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    139                       int skip_block, const int16_t *round_ptr,
    140                       const int16_t *quant_ptr, tran_low_t *qcoeff_ptr,
    141                       tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
    142                       uint16_t *eob_ptr, const int16_t *scan,
    143                       const int16_t *iscan) {
    144   int i, eob = -1;
    145   const int thr = dequant_ptr[1] >> 1;
    146   (void)iscan;
    147   (void)skip_block;
    148   assert(!skip_block);
    149 
    150   // Quantization pass: All coefficients with index >= zero_flag are
    151   // skippable. Note: zero_flag can be zero.
    152   for (i = 0; i < n_coeffs; i += 16) {
    153     int y;
    154     int nzflag_cnt = 0;
    155     int abs_coeff[16];
    156     int coeff_sign[16];
    157 
    158     // count nzflag for each row (16 tran_low_t)
    159     for (y = 0; y < 16; ++y) {
    160       const int rc = i + y;
    161       const int coeff = coeff_ptr[rc];
    162       coeff_sign[y] = (coeff >> 31);
    163       abs_coeff[y] = (coeff ^ coeff_sign[y]) - coeff_sign[y];
    164       // The first 16 are skipped in the sse2 code.  Do the same here to match.
    165       if (i >= 16 && (abs_coeff[y] <= thr)) {
    166         nzflag_cnt++;
    167       }
    168     }
    169 
    170     for (y = 0; y < 16; ++y) {
    171       const int rc = i + y;
    172       // If all of the AC coeffs in a row has magnitude less than the
    173       // quantization step_size/2, quantize to zero.
    174       if (nzflag_cnt < 16) {
    175         int tmp =
    176             clamp(abs_coeff[y] + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
    177         tmp = (tmp * quant_ptr[rc != 0]) >> 16;
    178         qcoeff_ptr[rc] = (tmp ^ coeff_sign[y]) - coeff_sign[y];
    179         dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
    180       } else {
    181         qcoeff_ptr[rc] = 0;
    182         dqcoeff_ptr[rc] = 0;
    183       }
    184     }
    185   }
    186 
    187   // Scan for eob.
    188   for (i = 0; i < n_coeffs; i++) {
    189     // Use the scan order to find the correct eob.
    190     const int rc = scan[i];
    191     if (qcoeff_ptr[rc]) {
    192       eob = i;
    193     }
    194   }
    195   *eob_ptr = eob + 1;
    196 }
    197 
    198 void GenerateHelperArrays(ACMRandom *rnd, int16_t *zbin, int16_t *round,
    199                           int16_t *quant, int16_t *quant_shift,
    200                           int16_t *dequant, int16_t *round_fp,
    201                           int16_t *quant_fp) {
    202   // Max when q == 0.  Otherwise, it is 48 for Y and 42 for U/V.
    203   const int max_qrounding_factor_fp = 64;
    204 
    205   for (int j = 0; j < 2; j++) {
    206     // The range is 4 to 1828 in the VP9 tables.
    207     const int qlookup = rnd->RandRange(1825) + 4;
    208     round_fp[j] = (max_qrounding_factor_fp * qlookup) >> 7;
    209     quant_fp[j] = (1 << 16) / qlookup;
    210 
    211     // Values determined by deconstructing vp9_init_quantizer().
    212     // zbin may be up to 1143 for 8 and 10 bit Y values, or 1200 for 12 bit Y
    213     // values or U/V values of any bit depth. This is because y_delta is not
    214     // factored into the vp9_ac_quant() call.
    215     zbin[j] = rnd->RandRange(1200);
    216 
    217     // round may be up to 685 for Y values or 914 for U/V.
    218     round[j] = rnd->RandRange(914);
    219     // quant ranges from 1 to -32703
    220     quant[j] = static_cast<int>(rnd->RandRange(32704)) - 32703;
    221     // quant_shift goes up to 1 << 16.
    222     quant_shift[j] = rnd->RandRange(16384);
    223     // dequant maxes out at 1828 for all cases.
    224     dequant[j] = rnd->RandRange(1828);
    225   }
    226   for (int j = 2; j < 8; j++) {
    227     zbin[j] = zbin[1];
    228     round_fp[j] = round_fp[1];
    229     quant_fp[j] = quant_fp[1];
    230     round[j] = round[1];
    231     quant[j] = quant[1];
    232     quant_shift[j] = quant_shift[1];
    233     dequant[j] = dequant[1];
    234   }
    235 }
    236 
    237 TEST_P(VP9QuantizeTest, OperationCheck) {
    238   ACMRandom rnd(ACMRandom::DeterministicSeed());
    239   Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
    240   ASSERT_TRUE(coeff.Init());
    241   Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    242   ASSERT_TRUE(qcoeff.Init());
    243   Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    244   ASSERT_TRUE(dqcoeff.Init());
    245   Buffer<tran_low_t> ref_qcoeff =
    246       Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    247   ASSERT_TRUE(ref_qcoeff.Init());
    248   Buffer<tran_low_t> ref_dqcoeff =
    249       Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    250   ASSERT_TRUE(ref_dqcoeff.Init());
    251   uint16_t eob, ref_eob;
    252 
    253   for (int i = 0; i < number_of_iterations; ++i) {
    254     // Test skip block for the first three iterations to catch all the different
    255     // sizes.
    256     const int skip_block = 0;
    257     TX_SIZE sz;
    258     if (max_size_ == 16) {
    259       sz = static_cast<TX_SIZE>(i % 3);  // TX_4X4, TX_8X8 TX_16X16
    260     } else {
    261       sz = TX_32X32;
    262     }
    263     const TX_TYPE tx_type = static_cast<TX_TYPE>((i >> 2) % 3);
    264     const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
    265     const int count = (4 << sz) * (4 << sz);
    266     coeff.Set(&rnd, -max_value_, max_value_);
    267     GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
    268                          quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
    269                          quant_fp_ptr_);
    270     int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
    271     int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
    272     ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
    273                      q_ptr, quant_shift_ptr_, ref_qcoeff.TopLeftPixel(),
    274                      ref_dqcoeff.TopLeftPixel(), dequant_ptr_, &ref_eob,
    275                      scan_order->scan, scan_order->iscan);
    276 
    277     ASM_REGISTER_STATE_CHECK(quantize_op_(
    278         coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr, q_ptr,
    279         quant_shift_ptr_, qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
    280         dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
    281 
    282     EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
    283     EXPECT_TRUE(dqcoeff.CheckValues(ref_dqcoeff));
    284 
    285     EXPECT_EQ(eob, ref_eob);
    286 
    287     if (HasFailure()) {
    288       printf("Failure on iteration %d.\n", i);
    289       qcoeff.PrintDifference(ref_qcoeff);
    290       dqcoeff.PrintDifference(ref_dqcoeff);
    291       return;
    292     }
    293   }
    294 }
    295 
    296 TEST_P(VP9QuantizeTest, EOBCheck) {
    297   ACMRandom rnd(ACMRandom::DeterministicSeed());
    298   Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
    299   ASSERT_TRUE(coeff.Init());
    300   Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    301   ASSERT_TRUE(qcoeff.Init());
    302   Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    303   ASSERT_TRUE(dqcoeff.Init());
    304   Buffer<tran_low_t> ref_qcoeff =
    305       Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    306   ASSERT_TRUE(ref_qcoeff.Init());
    307   Buffer<tran_low_t> ref_dqcoeff =
    308       Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    309   ASSERT_TRUE(ref_dqcoeff.Init());
    310   uint16_t eob, ref_eob;
    311 
    312   for (int i = 0; i < number_of_iterations; ++i) {
    313     const int skip_block = 0;
    314     TX_SIZE sz;
    315     if (max_size_ == 16) {
    316       sz = static_cast<TX_SIZE>(i % 3);  // TX_4X4, TX_8X8 TX_16X16
    317     } else {
    318       sz = TX_32X32;
    319     }
    320     const TX_TYPE tx_type = static_cast<TX_TYPE>((i >> 2) % 3);
    321     const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
    322     int count = (4 << sz) * (4 << sz);
    323     // Two random entries
    324     coeff.Set(0);
    325     coeff.TopLeftPixel()[rnd(count)] =
    326         static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
    327     coeff.TopLeftPixel()[rnd(count)] =
    328         static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
    329     GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
    330                          quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
    331                          quant_fp_ptr_);
    332     int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
    333     int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
    334     ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
    335                      q_ptr, quant_shift_ptr_, ref_qcoeff.TopLeftPixel(),
    336                      ref_dqcoeff.TopLeftPixel(), dequant_ptr_, &ref_eob,
    337                      scan_order->scan, scan_order->iscan);
    338 
    339     ASM_REGISTER_STATE_CHECK(quantize_op_(
    340         coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr, q_ptr,
    341         quant_shift_ptr_, qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
    342         dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
    343 
    344     EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
    345     EXPECT_TRUE(dqcoeff.CheckValues(ref_dqcoeff));
    346 
    347     EXPECT_EQ(eob, ref_eob);
    348 
    349     if (HasFailure()) {
    350       printf("Failure on iteration %d.\n", i);
    351       qcoeff.PrintDifference(ref_qcoeff);
    352       dqcoeff.PrintDifference(ref_dqcoeff);
    353       return;
    354     }
    355   }
    356 }
    357 
    358 TEST_P(VP9QuantizeTest, DISABLED_Speed) {
    359   ACMRandom rnd(ACMRandom::DeterministicSeed());
    360   Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
    361   ASSERT_TRUE(coeff.Init());
    362   Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    363   ASSERT_TRUE(qcoeff.Init());
    364   Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
    365   ASSERT_TRUE(dqcoeff.Init());
    366   uint16_t eob;
    367   TX_SIZE starting_sz, ending_sz;
    368 
    369   if (max_size_ == 16) {
    370     starting_sz = TX_4X4;
    371     ending_sz = TX_16X16;
    372   } else {
    373     starting_sz = TX_32X32;
    374     ending_sz = TX_32X32;
    375   }
    376 
    377   for (TX_SIZE sz = starting_sz; sz <= ending_sz; ++sz) {
    378     // zbin > coeff, zbin < coeff.
    379     for (int i = 0; i < 2; ++i) {
    380       const int skip_block = 0;
    381       // TX_TYPE defines the scan order. That is not relevant to the speed test.
    382       // Pick the first one.
    383       const TX_TYPE tx_type = DCT_DCT;
    384       const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
    385       const int count = (4 << sz) * (4 << sz);
    386 
    387       GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
    388                            quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
    389                            quant_fp_ptr_);
    390       int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
    391       int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
    392 
    393       if (i == 0) {
    394         // When |coeff values| are less than zbin the results are 0.
    395         int threshold = 100;
    396         if (max_size_ == 32) {
    397           // For 32x32, the threshold is halved. Double it to keep the values
    398           // from clearing it.
    399           threshold = 200;
    400         }
    401         for (int j = 0; j < 8; ++j) zbin_ptr_[j] = threshold;
    402         coeff.Set(&rnd, -99, 99);
    403       } else if (i == 1) {
    404         for (int j = 0; j < 8; ++j) zbin_ptr_[j] = 50;
    405         coeff.Set(&rnd, -500, 500);
    406       }
    407 
    408       vpx_usec_timer timer;
    409       vpx_usec_timer_start(&timer);
    410       for (int j = 0; j < 100000000 / count; ++j) {
    411         quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
    412                      q_ptr, quant_shift_ptr_, qcoeff.TopLeftPixel(),
    413                      dqcoeff.TopLeftPixel(), dequant_ptr_, &eob,
    414                      scan_order->scan, scan_order->iscan);
    415       }
    416       vpx_usec_timer_mark(&timer);
    417       const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
    418       if (i == 0) printf("Bypass calculations.\n");
    419       if (i == 1) printf("Full calculations.\n");
    420       printf("Quantize %dx%d time: %5d ms\n", 4 << sz, 4 << sz,
    421              elapsed_time / 1000);
    422     }
    423     printf("\n");
    424   }
    425 }
    426 
    427 using std::tr1::make_tuple;
    428 
    429 #if HAVE_SSE2
    430 #if CONFIG_VP9_HIGHBITDEPTH
    431 // TODO(johannkoenig): Fix vpx_quantize_b_sse2 in highbitdepth builds.
    432 // make_tuple(&vpx_quantize_b_sse2, &vpx_highbd_quantize_b_c, VPX_BITS_8),
    433 INSTANTIATE_TEST_CASE_P(
    434     SSE2, VP9QuantizeTest,
    435     ::testing::Values(
    436         make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
    437                    VPX_BITS_8, 16, false),
    438         make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
    439                    VPX_BITS_10, 16, false),
    440         make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
    441                    VPX_BITS_12, 16, false),
    442         make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
    443                    &vpx_highbd_quantize_b_32x32_c, VPX_BITS_8, 32, false),
    444         make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
    445                    &vpx_highbd_quantize_b_32x32_c, VPX_BITS_10, 32, false),
    446         make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
    447                    &vpx_highbd_quantize_b_32x32_c, VPX_BITS_12, 32, false)));
    448 
    449 #else
    450 INSTANTIATE_TEST_CASE_P(
    451     SSE2, VP9QuantizeTest,
    452     ::testing::Values(make_tuple(&vpx_quantize_b_sse2, &vpx_quantize_b_c,
    453                                  VPX_BITS_8, 16, false),
    454                       make_tuple(&QuantFPWrapper<vp9_quantize_fp_sse2>,
    455                                  &QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8,
    456                                  16, true)));
    457 #endif  // CONFIG_VP9_HIGHBITDEPTH
    458 #endif  // HAVE_SSE2
    459 
    460 #if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH
    461 #if ARCH_X86_64
    462 INSTANTIATE_TEST_CASE_P(
    463     SSSE3, VP9QuantizeTest,
    464     ::testing::Values(make_tuple(&vpx_quantize_b_ssse3, &vpx_quantize_b_c,
    465                                  VPX_BITS_8, 16, false),
    466                       make_tuple(&QuantFPWrapper<vp9_quantize_fp_ssse3>,
    467                                  &QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8,
    468                                  16, true)));
    469 #else
    470 INSTANTIATE_TEST_CASE_P(SSSE3, VP9QuantizeTest,
    471                         ::testing::Values(make_tuple(&vpx_quantize_b_ssse3,
    472                                                      &vpx_quantize_b_c,
    473                                                      VPX_BITS_8, 16, false)));
    474 #endif
    475 
    476 #if ARCH_X86_64
    477 // TODO(johannkoenig): SSSE3 optimizations do not yet pass this test.
    478 INSTANTIATE_TEST_CASE_P(
    479     DISABLED_SSSE3, VP9QuantizeTest,
    480     ::testing::Values(make_tuple(&vpx_quantize_b_32x32_ssse3,
    481                                  &vpx_quantize_b_32x32_c, VPX_BITS_8, 32,
    482                                  false),
    483                       make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_ssse3>,
    484                                  &QuantFPWrapper<vp9_quantize_fp_32x32_c>,
    485                                  VPX_BITS_8, 32, true)));
    486 #endif  // ARCH_X86_64
    487 #endif  // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH
    488 
    489 // TODO(johannkoenig): AVX optimizations do not yet pass the 32x32 test or
    490 // highbitdepth configurations.
    491 #if HAVE_AVX && !CONFIG_VP9_HIGHBITDEPTH
    492 INSTANTIATE_TEST_CASE_P(
    493     AVX, VP9QuantizeTest,
    494     ::testing::Values(make_tuple(&vpx_quantize_b_avx, &vpx_quantize_b_c,
    495                                  VPX_BITS_8, 16, false),
    496                       // Even though SSSE3 and AVX do not match the reference
    497                       // code, we can keep them in sync with each other.
    498                       make_tuple(&vpx_quantize_b_32x32_avx,
    499                                  &vpx_quantize_b_32x32_ssse3, VPX_BITS_8, 32,
    500                                  false)));
    501 #endif  // HAVE_AVX && !CONFIG_VP9_HIGHBITDEPTH
    502 
    503 // TODO(webm:1448): dqcoeff is not handled correctly in HBD builds.
    504 #if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH
    505 INSTANTIATE_TEST_CASE_P(
    506     NEON, VP9QuantizeTest,
    507     ::testing::Values(make_tuple(&vpx_quantize_b_neon, &vpx_quantize_b_c,
    508                                  VPX_BITS_8, 16, false),
    509                       make_tuple(&vpx_quantize_b_32x32_neon,
    510                                  &vpx_quantize_b_32x32_c, VPX_BITS_8, 32,
    511                                  false),
    512                       make_tuple(&QuantFPWrapper<vp9_quantize_fp_neon>,
    513                                  &QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8,
    514                                  16, true),
    515                       make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_neon>,
    516                                  &QuantFPWrapper<vp9_quantize_fp_32x32_c>,
    517                                  VPX_BITS_8, 32, true)));
    518 #endif  // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH
    519 
    520 // Only useful to compare "Speed" test results.
    521 INSTANTIATE_TEST_CASE_P(
    522     DISABLED_C, VP9QuantizeTest,
    523     ::testing::Values(
    524         make_tuple(&vpx_quantize_b_c, &vpx_quantize_b_c, VPX_BITS_8, 16, false),
    525         make_tuple(&vpx_quantize_b_32x32_c, &vpx_quantize_b_32x32_c, VPX_BITS_8,
    526                    32, false),
    527         make_tuple(&QuantFPWrapper<vp9_quantize_fp_c>,
    528                    &QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8, 16, true),
    529         make_tuple(&QuantFPWrapper<quantize_fp_nz_c>,
    530                    &QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8, 16, true),
    531         make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_c>,
    532                    &QuantFPWrapper<vp9_quantize_fp_32x32_c>, VPX_BITS_8, 32,
    533                    true)));
    534 }  // namespace
    535