• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016, 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 "third_party/googletest/src/googletest/include/gtest/gtest.h"
15 
16 #include "config/av1_rtcd.h"
17 
18 #include "test/acm_random.h"
19 #include "test/register_state_check.h"
20 #include "test/util.h"
21 #include "av1/common/enums.h"
22 
23 namespace {
24 
25 using libaom_test::ACMRandom;
26 using std::tuple;
27 
28 typedef void (*Predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
29                           const uint8_t *above, const uint8_t *left, int mode);
30 
31 // Note:
32 //  Test parameter list:
33 //  Reference predictor, optimized predictor, prediction mode, tx size
34 //
35 typedef tuple<Predictor, Predictor, int> PredFuncMode;
36 typedef tuple<PredFuncMode, TX_SIZE> PredParams;
37 
38 const int MaxTxSize = 32;
39 
40 const int MaxTestNum = 100;
41 
42 class AV1FilterIntraPredTest : public ::testing::TestWithParam<PredParams> {
43  public:
~AV1FilterIntraPredTest()44   virtual ~AV1FilterIntraPredTest() {}
SetUp()45   virtual void SetUp() {
46     PredFuncMode funcMode = GET_PARAM(0);
47     predFuncRef_ = std::get<0>(funcMode);
48     predFunc_ = std::get<1>(funcMode);
49     mode_ = std::get<2>(funcMode);
50     txSize_ = GET_PARAM(1);
51 
52     alloc_ = new uint8_t[2 * MaxTxSize + 1];
53     predRef_ = new uint8_t[MaxTxSize * MaxTxSize];
54     pred_ = new uint8_t[MaxTxSize * MaxTxSize];
55   }
56 
TearDown()57   virtual void TearDown() {
58     delete[] alloc_;
59     delete[] predRef_;
60     delete[] pred_;
61   }
62 
63  protected:
RunTest() const64   void RunTest() const {
65     int tstIndex = 0;
66     int stride = tx_size_wide[txSize_];
67     uint8_t *left = alloc_;
68     uint8_t *above = alloc_ + MaxTxSize;
69     while (tstIndex < MaxTestNum) {
70       PrepareBuffer();
71       predFuncRef_(predRef_, stride, txSize_, &above[1], left, mode_);
72       API_REGISTER_STATE_CHECK(
73           predFunc_(pred_, stride, txSize_, &above[1], left, mode_));
74       DiffPred(tstIndex);
75       tstIndex += 1;
76     }
77   }
RunSpeedTest() const78   void RunSpeedTest() const {
79     int stride = tx_size_wide[txSize_];
80     uint8_t *left = alloc_;
81     uint8_t *above = alloc_ + MaxTxSize;
82     const int numIter = 5000;
83 
84     PrepareBuffer();
85     aom_usec_timer ref_timer;
86     aom_usec_timer_start(&ref_timer);
87     for (int i = 0; i < numIter; i++) {
88       predFuncRef_(predRef_, stride, txSize_, &above[1], left, mode_);
89     }
90     aom_usec_timer_mark(&ref_timer);
91 
92     aom_usec_timer timer;
93     aom_usec_timer_start(&timer);
94     for (int i = 0; i < numIter; i++) {
95       predFunc_(pred_, stride, txSize_, &above[1], left, mode_);
96     }
97     aom_usec_timer_mark(&timer);
98 
99     const int ref_sum_time =
100         static_cast<int>(aom_usec_timer_elapsed(&ref_timer));
101     const int sum_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
102 
103     printf("c_time = %d \t simd_time = %d \t Gain = %4.2f \t mode =  %d \n",
104            ref_sum_time, sum_time,
105            (static_cast<float>(ref_sum_time) / static_cast<float>(sum_time)),
106            static_cast<int>(mode_));
107 
108     DiffPred(0);
109   }
110 
111  private:
PrepareBuffer() const112   void PrepareBuffer() const {
113     ACMRandom rnd(ACMRandom::DeterministicSeed());
114     int i = 0;
115     while (i < (2 * MaxTxSize + 1)) {
116       alloc_[i] = rnd.Rand8();
117       i++;
118     }
119   }
120 
DiffPred(int testNum) const121   void DiffPred(int testNum) const {
122     int i = 0;
123     while (i < tx_size_wide[txSize_] * tx_size_high[txSize_]) {
124       EXPECT_EQ(predRef_[i], pred_[i]) << "Error at position: " << i << " "
125                                        << "Tx size: " << tx_size_wide[txSize_]
126                                        << "x" << tx_size_high[txSize_] << " "
127                                        << "Test number: " << testNum;
128       i++;
129     }
130   }
131 
132   Predictor predFunc_;
133   Predictor predFuncRef_;
134   int mode_;
135   TX_SIZE txSize_;
136   uint8_t *alloc_;
137   uint8_t *pred_;
138   uint8_t *predRef_;
139 };
140 
TEST_P(AV1FilterIntraPredTest,BitExactCheck)141 TEST_P(AV1FilterIntraPredTest, BitExactCheck) { RunTest(); }
142 
TEST_P(AV1FilterIntraPredTest,DISABLED_Speed)143 TEST_P(AV1FilterIntraPredTest, DISABLED_Speed) { RunSpeedTest(); }
144 
145 using ::testing::make_tuple;
146 #if HAVE_SSE4_1
147 const PredFuncMode kPredFuncMdArray[] = {
148   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
149              FILTER_DC_PRED),
150   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
151              FILTER_V_PRED),
152   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
153              FILTER_H_PRED),
154   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
155              FILTER_D157_PRED),
156   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
157              FILTER_PAETH_PRED),
158 };
159 
160 const TX_SIZE kTxSize[] = { TX_4X4,  TX_8X8,  TX_16X16, TX_32X32, TX_4X8,
161                             TX_8X4,  TX_8X16, TX_16X8,  TX_16X32, TX_32X16,
162                             TX_4X16, TX_16X4, TX_8X32,  TX_32X8 };
163 
164 INSTANTIATE_TEST_SUITE_P(
165     SSE4_1, AV1FilterIntraPredTest,
166     ::testing::Combine(::testing::ValuesIn(kPredFuncMdArray),
167                        ::testing::ValuesIn(kTxSize)));
168 #endif  // HAVE_SSE4_1
169 
170 #if HAVE_NEON
171 const PredFuncMode kPredFuncMdArrayNEON[] = {
172   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
173              FILTER_DC_PRED),
174   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
175              FILTER_V_PRED),
176   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
177              FILTER_H_PRED),
178   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
179              FILTER_D157_PRED),
180   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
181              FILTER_PAETH_PRED),
182 };
183 
184 const TX_SIZE kTxSizeNEON[] = { TX_4X4,  TX_8X8,  TX_16X16, TX_32X32, TX_4X8,
185                                 TX_8X4,  TX_8X16, TX_16X8,  TX_16X32, TX_32X16,
186                                 TX_4X16, TX_16X4, TX_8X32,  TX_32X8 };
187 
188 INSTANTIATE_TEST_SUITE_P(
189     NEON, AV1FilterIntraPredTest,
190     ::testing::Combine(::testing::ValuesIn(kPredFuncMdArrayNEON),
191                        ::testing::ValuesIn(kTxSizeNEON)));
192 #endif  // HAVE_NEON
193 
194 }  // namespace
195