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