Home | History | Annotate | Download | only in test
      1 /*
      2 *  Copyright (c) 2012 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 #include "test/acm_random.h"
     15 #include "test/clear_system_state.h"
     16 #include "test/register_state_check.h"
     17 #include "test/util.h"
     18 #include "third_party/googletest/src/include/gtest/gtest.h"
     19 extern "C" {
     20 #include "./vpx_config.h"
     21 #include "./vp8_rtcd.h"
     22 #include "vpx/vpx_integer.h"
     23 #include "vpx_mem/vpx_mem.h"
     24 }
     25 
     26 namespace {
     27 
     28 typedef void (*sixtap_predict_fn_t)(uint8_t *src_ptr,
     29                                     int  src_pixels_per_line,
     30                                     int  xoffset,
     31                                     int  yoffset,
     32                                     uint8_t *dst_ptr,
     33                                     int  dst_pitch);
     34 
     35 class SixtapPredictTest : public PARAMS(int, int, sixtap_predict_fn_t) {
     36  public:
     37   static void SetUpTestCase() {
     38     src_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kSrcSize));
     39     dst_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
     40     dst_c_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
     41   }
     42 
     43   static void TearDownTestCase() {
     44     vpx_free(src_);
     45     src_ = NULL;
     46     vpx_free(dst_);
     47     dst_ = NULL;
     48     vpx_free(dst_c_);
     49     dst_c_ = NULL;
     50   }
     51 
     52   virtual void TearDown() {
     53     libvpx_test::ClearSystemState();
     54   }
     55 
     56  protected:
     57   // Make test arrays big enough for 16x16 functions. Six-tap filters
     58   // need 5 extra pixels outside of the macroblock.
     59   static const int kSrcStride = 21;
     60   static const int kDstStride = 16;
     61   static const int kDataAlignment = 16;
     62   static const int kSrcSize = kSrcStride * kSrcStride + 1;
     63   static const int kDstSize = kDstStride * kDstStride;
     64 
     65   virtual void SetUp() {
     66     width_ = GET_PARAM(0);
     67     height_ = GET_PARAM(1);
     68     sixtap_predict_ = GET_PARAM(2);
     69     memset(src_, 0, kSrcSize);
     70     memset(dst_, 0, kDstSize);
     71     memset(dst_c_, 0, kDstSize);
     72   }
     73 
     74   int width_;
     75   int height_;
     76   sixtap_predict_fn_t sixtap_predict_;
     77   // The src stores the macroblock we will filter on, and makes it 1 byte larger
     78   // in order to test unaligned access. The result is stored in dst and dst_c(c
     79   // reference code result).
     80   static uint8_t* src_;
     81   static uint8_t* dst_;
     82   static uint8_t* dst_c_;
     83 };
     84 
     85 uint8_t* SixtapPredictTest::src_ = NULL;
     86 uint8_t* SixtapPredictTest::dst_ = NULL;
     87 uint8_t* SixtapPredictTest::dst_c_ = NULL;
     88 
     89 TEST_P(SixtapPredictTest, TestWithPresetData) {
     90   // Test input
     91   static const uint8_t test_data[kSrcSize] = {
     92     216, 184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226, 177,
     93     79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44, 233, 120,
     94     48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102, 171, 32,
     95     182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3, 99, 247, 124,
     96     148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58, 83, 155, 91, 10,
     97     166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16, 234, 4, 8, 103, 153,
     98     167, 174, 187, 26, 193, 109, 64, 141, 90, 48, 200, 174, 204, 36, 184,
     99     114, 237, 43, 238, 242, 207, 86, 245, 182, 247, 6, 161, 251, 14, 8, 148,
    100     182, 182, 79, 208, 120, 188, 17, 6, 23, 65, 206, 197, 13, 242, 126, 128,
    101     224, 170, 110, 211, 121, 197, 200, 47, 188, 207, 208, 184, 221, 216, 76,
    102     148, 143, 156, 100, 8, 89, 117, 14, 112, 183, 221, 54, 197, 208, 180, 69,
    103     176, 94, 180, 131, 215, 121, 76, 7, 54, 28, 216, 238, 249, 176, 58, 142,
    104     64, 215, 242, 72, 49, 104, 87, 161, 32, 52, 216, 230, 4, 141, 44, 181,
    105     235, 224, 57, 195, 89, 134, 203, 144, 162, 163, 126, 156, 84, 185, 42,
    106     148, 145, 29, 221, 194, 134, 52, 100, 166, 105, 60, 140, 110, 201, 184,
    107     35, 181, 153, 93, 121, 243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77,
    108     209, 76, 106, 174, 15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221,
    109     223, 47, 118, 61, 168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170,
    110     24, 226, 247, 131, 145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13,
    111     93, 209, 131, 154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69,
    112     49, 106, 200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215,
    113     135, 10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36,
    114     119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109, 35,
    115     93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101, 77, 67, 52,
    116     53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179, 115, 161, 17, 83,
    117     198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23, 201, 255, 91, 253, 52,
    118     134, 60, 138, 131, 208, 251, 101, 48, 2, 227, 228, 118, 132, 245, 202,
    119     75, 91, 44, 160, 231, 47, 41, 50, 147, 220, 74, 92, 219, 165, 89, 16
    120   };
    121 
    122   // Expected result
    123   static const uint8_t expected_dst[kDstSize] = {
    124     117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39, 49, 38,
    125     105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85, 177, 164, 79,
    126     208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91, 154, 102, 102,
    127     159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224, 186, 36, 231,
    128     208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73, 201, 78, 149, 184,
    129     100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120, 129, 49, 25, 133,
    130     113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140, 78, 6, 55, 65, 240,
    131     255, 245, 184, 72, 90, 100, 116, 131, 39, 60, 234, 167, 33, 160, 88, 185,
    132     200, 157, 159, 176, 127, 151, 138, 102, 168, 106, 170, 86, 82, 219, 189,
    133     76, 33, 115, 197, 106, 96, 198, 136, 97, 141, 237, 151, 98, 137, 191,
    134     185, 2, 57, 95, 142, 91, 255, 185, 97, 137, 76, 162, 94, 173, 131, 193,
    135     161, 81, 106, 72, 135, 222, 234, 137, 66, 137, 106, 243, 210, 147, 95,
    136     15, 137, 110, 85, 66, 16, 96, 167, 147, 150, 173, 203, 140, 118, 196,
    137     84, 147, 160, 19, 95, 101, 123, 74, 132, 202, 82, 166, 12, 131, 166,
    138     189, 170, 159, 85, 79, 66, 57, 152, 132, 203, 194, 0, 1, 56, 146, 180,
    139     224, 156, 28, 83, 181, 79, 76, 80, 46, 160, 175, 59, 106, 43, 87, 75,
    140     136, 85, 189, 46, 71, 200, 90
    141   };
    142 
    143   uint8_t *src = const_cast<uint8_t*>(test_data);
    144 
    145   REGISTER_STATE_CHECK(sixtap_predict_(&src[kSrcStride * 2 + 2 + 1], kSrcStride,
    146                                        2, 2, dst_, kDstStride));
    147 
    148   for (int i = 0; i < height_; ++i)
    149     for (int j = 0; j < width_; ++j)
    150       ASSERT_EQ(expected_dst[i * kDstStride + j], dst_[i * kDstStride + j])
    151           << "i==" << (i * width_ + j);
    152 }
    153 
    154 using libvpx_test::ACMRandom;
    155 
    156 TEST_P(SixtapPredictTest, TestWithRandomData) {
    157   ACMRandom rnd(ACMRandom::DeterministicSeed());
    158   for (int i = 0; i < kSrcSize; ++i)
    159     src_[i] = rnd.Rand8();
    160 
    161   // Run tests for all possible offsets.
    162   for (int xoffset = 0; xoffset < 8; ++xoffset) {
    163     for (int yoffset = 0; yoffset < 8; ++yoffset) {
    164       // Call c reference function.
    165       // Move start point to next pixel to test if the function reads
    166       // unaligned data correctly.
    167       vp8_sixtap_predict16x16_c(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
    168                                 xoffset, yoffset, dst_c_, kDstStride);
    169 
    170       // Run test.
    171       REGISTER_STATE_CHECK(
    172           sixtap_predict_(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
    173                           xoffset, yoffset, dst_, kDstStride));
    174 
    175       for (int i = 0; i < height_; ++i)
    176         for (int j = 0; j < width_; ++j)
    177           ASSERT_EQ(dst_c_[i * kDstStride + j], dst_[i * kDstStride + j])
    178               << "i==" << (i * width_ + j);
    179     }
    180   }
    181 }
    182 
    183 using std::tr1::make_tuple;
    184 
    185 const sixtap_predict_fn_t sixtap_16x16_c = vp8_sixtap_predict16x16_c;
    186 const sixtap_predict_fn_t sixtap_8x8_c = vp8_sixtap_predict8x8_c;
    187 const sixtap_predict_fn_t sixtap_8x4_c = vp8_sixtap_predict8x4_c;
    188 const sixtap_predict_fn_t sixtap_4x4_c = vp8_sixtap_predict4x4_c;
    189 INSTANTIATE_TEST_CASE_P(
    190     C, SixtapPredictTest, ::testing::Values(
    191         make_tuple(16, 16, sixtap_16x16_c),
    192         make_tuple(8, 8, sixtap_8x8_c),
    193         make_tuple(8, 4, sixtap_8x4_c),
    194         make_tuple(4, 4, sixtap_4x4_c)));
    195 #if HAVE_MMX
    196 const sixtap_predict_fn_t sixtap_16x16_mmx = vp8_sixtap_predict16x16_mmx;
    197 const sixtap_predict_fn_t sixtap_8x8_mmx = vp8_sixtap_predict8x8_mmx;
    198 const sixtap_predict_fn_t sixtap_8x4_mmx = vp8_sixtap_predict8x4_mmx;
    199 const sixtap_predict_fn_t sixtap_4x4_mmx = vp8_sixtap_predict4x4_mmx;
    200 INSTANTIATE_TEST_CASE_P(
    201     MMX, SixtapPredictTest, ::testing::Values(
    202         make_tuple(16, 16, sixtap_16x16_mmx),
    203         make_tuple(8, 8, sixtap_8x8_mmx),
    204         make_tuple(8, 4, sixtap_8x4_mmx),
    205         make_tuple(4, 4, sixtap_4x4_mmx)));
    206 #endif
    207 #if HAVE_SSE2
    208 const sixtap_predict_fn_t sixtap_16x16_sse2 = vp8_sixtap_predict16x16_sse2;
    209 const sixtap_predict_fn_t sixtap_8x8_sse2 = vp8_sixtap_predict8x8_sse2;
    210 const sixtap_predict_fn_t sixtap_8x4_sse2 = vp8_sixtap_predict8x4_sse2;
    211 INSTANTIATE_TEST_CASE_P(
    212     SSE2, SixtapPredictTest, ::testing::Values(
    213         make_tuple(16, 16, sixtap_16x16_sse2),
    214         make_tuple(8, 8, sixtap_8x8_sse2),
    215         make_tuple(8, 4, sixtap_8x4_sse2)));
    216 #endif
    217 #if HAVE_SSSE3
    218 const sixtap_predict_fn_t sixtap_16x16_ssse3 = vp8_sixtap_predict16x16_ssse3;
    219 const sixtap_predict_fn_t sixtap_8x8_ssse3 = vp8_sixtap_predict8x8_ssse3;
    220 const sixtap_predict_fn_t sixtap_8x4_ssse3 = vp8_sixtap_predict8x4_ssse3;
    221 const sixtap_predict_fn_t sixtap_4x4_ssse3 = vp8_sixtap_predict4x4_ssse3;
    222 INSTANTIATE_TEST_CASE_P(
    223     SSSE3, SixtapPredictTest, ::testing::Values(
    224         make_tuple(16, 16, sixtap_16x16_ssse3),
    225         make_tuple(8, 8, sixtap_8x8_ssse3),
    226         make_tuple(8, 4, sixtap_8x4_ssse3),
    227         make_tuple(4, 4, sixtap_4x4_ssse3)));
    228 #endif
    229 }  // namespace
    230