• 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     ASSERT_NE(alloc_, nullptr);
56     ASSERT_NE(predRef_, nullptr);
57     ASSERT_NE(pred_, nullptr);
58   }
59 
TearDown()60   virtual void TearDown() {
61     delete[] alloc_;
62     delete[] predRef_;
63     delete[] pred_;
64   }
65 
66  protected:
RunTest() const67   void RunTest() const {
68     int tstIndex = 0;
69     int stride = tx_size_wide[txSize_];
70     uint8_t *left = alloc_;
71     uint8_t *above = alloc_ + MaxTxSize;
72     while (tstIndex < MaxTestNum) {
73       PrepareBuffer();
74       predFuncRef_(predRef_, stride, txSize_, &above[1], left, mode_);
75       API_REGISTER_STATE_CHECK(
76           predFunc_(pred_, stride, txSize_, &above[1], left, mode_));
77       DiffPred(tstIndex);
78       tstIndex += 1;
79     }
80   }
RunSpeedTest() const81   void RunSpeedTest() const {
82     int stride = tx_size_wide[txSize_];
83     uint8_t *left = alloc_;
84     uint8_t *above = alloc_ + MaxTxSize;
85     const int numIter = 5000;
86 
87     PrepareBuffer();
88     aom_usec_timer ref_timer;
89     aom_usec_timer_start(&ref_timer);
90     for (int i = 0; i < numIter; i++) {
91       predFuncRef_(predRef_, stride, txSize_, &above[1], left, mode_);
92     }
93     aom_usec_timer_mark(&ref_timer);
94 
95     aom_usec_timer timer;
96     aom_usec_timer_start(&timer);
97     for (int i = 0; i < numIter; i++) {
98       predFunc_(pred_, stride, txSize_, &above[1], left, mode_);
99     }
100     aom_usec_timer_mark(&timer);
101 
102     const int ref_sum_time =
103         static_cast<int>(aom_usec_timer_elapsed(&ref_timer));
104     const int sum_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
105 
106     printf("c_time = %d \t simd_time = %d \t Gain = %4.2f \t mode =  %d \n",
107            ref_sum_time, sum_time,
108            (static_cast<float>(ref_sum_time) / static_cast<float>(sum_time)),
109            static_cast<int>(mode_));
110 
111     DiffPred(0);
112   }
113 
114  private:
PrepareBuffer() const115   void PrepareBuffer() const {
116     ACMRandom rnd(ACMRandom::DeterministicSeed());
117     int i = 0;
118     while (i < (2 * MaxTxSize + 1)) {
119       alloc_[i] = rnd.Rand8();
120       i++;
121     }
122   }
123 
DiffPred(int testNum) const124   void DiffPred(int testNum) const {
125     int i = 0;
126     while (i < tx_size_wide[txSize_] * tx_size_high[txSize_]) {
127       EXPECT_EQ(predRef_[i], pred_[i]) << "Error at position: " << i << " "
128                                        << "Tx size: " << tx_size_wide[txSize_]
129                                        << "x" << tx_size_high[txSize_] << " "
130                                        << "Test number: " << testNum;
131       i++;
132     }
133   }
134 
135   Predictor predFunc_;
136   Predictor predFuncRef_;
137   int mode_;
138   TX_SIZE txSize_;
139   uint8_t *alloc_;
140   uint8_t *pred_;
141   uint8_t *predRef_;
142 };
143 
TEST_P(AV1FilterIntraPredTest,BitExactCheck)144 TEST_P(AV1FilterIntraPredTest, BitExactCheck) { RunTest(); }
145 
TEST_P(AV1FilterIntraPredTest,DISABLED_Speed)146 TEST_P(AV1FilterIntraPredTest, DISABLED_Speed) { RunSpeedTest(); }
147 
148 using ::testing::make_tuple;
149 #if HAVE_SSE4_1
150 const PredFuncMode kPredFuncMdArray[] = {
151   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
152              FILTER_DC_PRED),
153   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
154              FILTER_V_PRED),
155   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
156              FILTER_H_PRED),
157   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
158              FILTER_D157_PRED),
159   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
160              FILTER_PAETH_PRED),
161 };
162 
163 const TX_SIZE kTxSize[] = { TX_4X4,  TX_8X8,  TX_16X16, TX_32X32, TX_4X8,
164                             TX_8X4,  TX_8X16, TX_16X8,  TX_16X32, TX_32X16,
165                             TX_4X16, TX_16X4, TX_8X32,  TX_32X8 };
166 
167 INSTANTIATE_TEST_SUITE_P(
168     SSE4_1, AV1FilterIntraPredTest,
169     ::testing::Combine(::testing::ValuesIn(kPredFuncMdArray),
170                        ::testing::ValuesIn(kTxSize)));
171 #endif  // HAVE_SSE4_1
172 
173 #if HAVE_NEON
174 const PredFuncMode kPredFuncMdArrayNEON[] = {
175   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
176              FILTER_DC_PRED),
177   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
178              FILTER_V_PRED),
179   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
180              FILTER_H_PRED),
181   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
182              FILTER_D157_PRED),
183   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
184              FILTER_PAETH_PRED),
185 };
186 
187 const TX_SIZE kTxSizeNEON[] = { TX_4X4,  TX_8X8,  TX_16X16, TX_32X32, TX_4X8,
188                                 TX_8X4,  TX_8X16, TX_16X8,  TX_16X32, TX_32X16,
189                                 TX_4X16, TX_16X4, TX_8X32,  TX_32X8 };
190 
191 INSTANTIATE_TEST_SUITE_P(
192     NEON, AV1FilterIntraPredTest,
193     ::testing::Combine(::testing::ValuesIn(kPredFuncMdArrayNEON),
194                        ::testing::ValuesIn(kTxSizeNEON)));
195 #endif  // HAVE_NEON
196 
197 }  // namespace
198