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 "third_party/googletest/src/googletest/include/gtest/gtest.h"
13 
14 #include "config/av1_rtcd.h"
15 
16 #include "test/acm_random.h"
17 #include "test/clear_system_state.h"
18 #include "test/register_state_check.h"
19 #include "test/util.h"
20 #include "av1/common/enums.h"
21 
22 namespace {
23 
24 using ::testing::tuple;
25 using libaom_test::ACMRandom;
26 
27 typedef void (*Predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
28                           const uint8_t *above, const uint8_t *left, int mode);
29 
30 // Note:
31 //  Test parameter list:
32 //  Reference predictor, optimized predictor, prediction mode, tx size
33 //
34 typedef tuple<Predictor, Predictor, int> PredFuncMode;
35 typedef tuple<PredFuncMode, TX_SIZE> PredParams;
36 
37 const int MaxTxSize = 32;
38 
39 const int MaxTestNum = 100;
40 
41 class AV1FilterIntraPredTest : public ::testing::TestWithParam<PredParams> {
42  public:
~AV1FilterIntraPredTest()43   virtual ~AV1FilterIntraPredTest() {}
SetUp()44   virtual void SetUp() {
45     PredFuncMode funcMode = GET_PARAM(0);
46     predFuncRef_ = ::testing::get<0>(funcMode);
47     predFunc_ = ::testing::get<1>(funcMode);
48     mode_ = ::testing::get<2>(funcMode);
49     txSize_ = GET_PARAM(1);
50 
51     alloc_ = new uint8_t[2 * MaxTxSize + 1];
52     predRef_ = new uint8_t[MaxTxSize * MaxTxSize];
53     pred_ = new uint8_t[MaxTxSize * MaxTxSize];
54   }
55 
TearDown()56   virtual void TearDown() {
57     delete[] alloc_;
58     delete[] predRef_;
59     delete[] pred_;
60     libaom_test::ClearSystemState();
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       ASM_REGISTER_STATE_CHECK(
73           predFunc_(pred_, stride, txSize_, &above[1], left, mode_));
74       DiffPred(tstIndex);
75       tstIndex += 1;
76     }
77   }
78 
79  private:
PrepareBuffer() const80   void PrepareBuffer() const {
81     ACMRandom rnd(ACMRandom::DeterministicSeed());
82     int i = 0;
83     while (i < (2 * MaxTxSize + 1)) {
84       alloc_[i] = rnd.Rand8();
85       i++;
86     }
87   }
88 
DiffPred(int testNum) const89   void DiffPred(int testNum) const {
90     int i = 0;
91     while (i < tx_size_wide[txSize_] * tx_size_high[txSize_]) {
92       EXPECT_EQ(predRef_[i], pred_[i]) << "Error at position: " << i << " "
93                                        << "Tx size: " << tx_size_wide[txSize_]
94                                        << "x" << tx_size_high[txSize_] << " "
95                                        << "Test number: " << testNum;
96       i++;
97     }
98   }
99 
100   Predictor predFunc_;
101   Predictor predFuncRef_;
102   int mode_;
103   TX_SIZE txSize_;
104   uint8_t *alloc_;
105   uint8_t *pred_;
106   uint8_t *predRef_;
107 };
108 
TEST_P(AV1FilterIntraPredTest,BitExactCheck)109 TEST_P(AV1FilterIntraPredTest, BitExactCheck) { RunTest(); }
110 
111 using ::testing::make_tuple;
112 
113 const PredFuncMode kPredFuncMdArray[] = {
114   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
115              FILTER_DC_PRED),
116   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
117              FILTER_V_PRED),
118   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
119              FILTER_H_PRED),
120   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
121              FILTER_D157_PRED),
122   make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
123              FILTER_PAETH_PRED),
124 };
125 
126 const TX_SIZE kTxSize[] = { TX_4X4,  TX_8X8,  TX_16X16, TX_32X32, TX_4X8,
127                             TX_8X4,  TX_8X16, TX_16X8,  TX_16X32, TX_32X16,
128                             TX_4X16, TX_16X4, TX_8X32,  TX_32X8 };
129 
130 INSTANTIATE_TEST_CASE_P(
131     SSE4_1, AV1FilterIntraPredTest,
132     ::testing::Combine(::testing::ValuesIn(kPredFuncMdArray),
133                        ::testing::ValuesIn(kTxSize)));
134 }  // namespace
135