2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
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.
13 #include "third_party/googletest/src/include/gtest/gtest.h"
15 #include "./vpx_config.h"
16 #include "./vp8_rtcd.h"
17 #include "test/acm_random.h"
18 #include "test/clear_system_state.h"
19 #include "test/register_state_check.h"
20 #include "vp8/common/blockd.h"
21 #include "vpx_mem/vpx_mem.h"
25 using libvpx_test::ACMRandom;
29 virtual ~IntraPredBase() { libvpx_test::ClearSystemState(); }
32 void SetupMacroblock(MACROBLOCKD *mbptr,
40 mbptr_->up_available = 1;
41 mbptr_->left_available = 1;
42 mbptr_->mode_info_context = miptr_;
44 block_size_ = block_size;
45 num_planes_ = num_planes;
46 for (int p = 0; p < num_planes; p++)
47 data_ptr_[p] = data + stride * (block_size + 1) * p +
52 // Fill edges with random data
53 ACMRandom rnd(ACMRandom::DeterministicSeed());
54 for (int p = 0; p < num_planes_; p++) {
55 for (int x = -1 ; x <= block_size_; x++)
56 data_ptr_[p][x - stride_] = rnd.Rand8();
57 for (int y = 0; y < block_size_; y++)
58 data_ptr_[p][y * stride_ - 1] = rnd.Rand8();
62 virtual void Predict(MB_PREDICTION_MODE mode) = 0;
64 void SetLeftUnavailable() {
65 mbptr_->left_available = 0;
66 for (int p = 0; p < num_planes_; p++)
67 for (int i = -1; i < block_size_; ++i)
68 data_ptr_[p][stride_ * i - 1] = 129;
71 void SetTopUnavailable() {
72 mbptr_->up_available = 0;
73 for (int p = 0; p < num_planes_; p++)
74 memset(&data_ptr_[p][-1 - stride_], 127, block_size_ + 2);
77 void SetTopLeftUnavailable() {
82 int BlockSizeLog2Min1() const {
83 switch (block_size_) {
93 // check DC prediction output against a reference
94 void CheckDCPrediction() const {
95 for (int p = 0; p < num_planes_; p++) {
96 // calculate expected DC
98 if (mbptr_->up_available || mbptr_->left_available) {
99 int sum = 0, shift = BlockSizeLog2Min1() + mbptr_->up_available +
100 mbptr_->left_available;
101 if (mbptr_->up_available)
102 for (int x = 0; x < block_size_; x++)
103 sum += data_ptr_[p][x - stride_];
104 if (mbptr_->left_available)
105 for (int y = 0; y < block_size_; y++)
106 sum += data_ptr_[p][y * stride_ - 1];
107 expected = (sum + (1 << (shift - 1))) >> shift;
111 // check that all subsequent lines are equal to the first
112 for (int y = 1; y < block_size_; ++y)
113 ASSERT_EQ(0, memcmp(data_ptr_[p], &data_ptr_[p][y * stride_],
115 // within the first line, ensure that each pixel has the same value
116 for (int x = 1; x < block_size_; ++x)
117 ASSERT_EQ(data_ptr_[p][0], data_ptr_[p][x]);
118 // now ensure that that pixel has the expected (DC) value
119 ASSERT_EQ(expected, data_ptr_[p][0]);
123 // check V prediction output against a reference
124 void CheckVPrediction() const {
125 // check that all lines equal the top border
126 for (int p = 0; p < num_planes_; p++)
127 for (int y = 0; y < block_size_; y++)
128 ASSERT_EQ(0, memcmp(&data_ptr_[p][-stride_],
129 &data_ptr_[p][y * stride_], block_size_));
132 // check H prediction output against a reference
133 void CheckHPrediction() const {
134 // for each line, ensure that each pixel is equal to the left border
135 for (int p = 0; p < num_planes_; p++)
136 for (int y = 0; y < block_size_; y++)
137 for (int x = 0; x < block_size_; x++)
138 ASSERT_EQ(data_ptr_[p][-1 + y * stride_],
139 data_ptr_[p][x + y * stride_]);
142 static int ClipByte(int value) {
150 // check TM prediction output against a reference
151 void CheckTMPrediction() const {
152 for (int p = 0; p < num_planes_; p++)
153 for (int y = 0; y < block_size_; y++)
154 for (int x = 0; x < block_size_; x++) {
155 const int expected = ClipByte(data_ptr_[p][x - stride_]
156 + data_ptr_[p][stride_ * y - 1]
157 - data_ptr_[p][-1 - stride_]);
158 ASSERT_EQ(expected, data_ptr_[p][y * stride_ + x]);
165 SCOPED_TRACE("DC_PRED");
171 SCOPED_TRACE("DC_PRED LEFT");
173 SetLeftUnavailable();
178 SCOPED_TRACE("DC_PRED TOP");
185 SCOPED_TRACE("DC_PRED TOP_LEFT");
187 SetTopLeftUnavailable();
192 SCOPED_TRACE("H_PRED");
198 SCOPED_TRACE("V_PRED");
204 SCOPED_TRACE("TM_PRED");
213 uint8_t *data_ptr_[2]; // in the case of Y, only [0] is used
219 typedef void (*IntraPredYFunc)(MACROBLOCKD *x,
227 : public IntraPredBase,
228 public ::testing::TestWithParam<IntraPredYFunc> {
230 static void SetUpTestCase() {
231 mb_ = reinterpret_cast<MACROBLOCKD*>(
232 vpx_memalign(32, sizeof(MACROBLOCKD)));
233 mi_ = reinterpret_cast<MODE_INFO*>(
234 vpx_memalign(32, sizeof(MODE_INFO)));
235 data_array_ = reinterpret_cast<uint8_t*>(
236 vpx_memalign(kDataAlignment, kDataBufferSize));
239 static void TearDownTestCase() {
240 vpx_free(data_array_);
247 static const int kBlockSize = 16;
248 static const int kDataAlignment = 16;
249 static const int kStride = kBlockSize * 3;
250 // We use 48 so that the data pointer of the first pixel in each row of
251 // each macroblock is 16-byte aligned, and this gives us access to the
252 // top-left and top-right corner pixels belonging to the top-left/right
254 // We use 17 lines so we have one line above us for top-prediction.
255 static const int kDataBufferSize = kStride * (kBlockSize + 1);
257 virtual void SetUp() {
258 pred_fn_ = GetParam();
259 SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 1);
262 virtual void Predict(MB_PREDICTION_MODE mode) {
263 mbptr_->mode_info_context->mbmi.mode = mode;
264 ASM_REGISTER_STATE_CHECK(pred_fn_(mbptr_,
265 data_ptr_[0] - kStride,
266 data_ptr_[0] - 1, kStride,
267 data_ptr_[0], kStride));
270 IntraPredYFunc pred_fn_;
271 static uint8_t* data_array_;
272 static MACROBLOCKD * mb_;
273 static MODE_INFO *mi_;
276 MACROBLOCKD* IntraPredYTest::mb_ = NULL;
277 MODE_INFO* IntraPredYTest::mi_ = NULL;
278 uint8_t* IntraPredYTest::data_array_ = NULL;
280 TEST_P(IntraPredYTest, IntraPredTests) {
284 INSTANTIATE_TEST_CASE_P(C, IntraPredYTest,
286 vp8_build_intra_predictors_mby_s_c));
288 INSTANTIATE_TEST_CASE_P(SSE2, IntraPredYTest,
290 vp8_build_intra_predictors_mby_s_sse2));
293 INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredYTest,
295 vp8_build_intra_predictors_mby_s_ssse3));
298 INSTANTIATE_TEST_CASE_P(NEON, IntraPredYTest,
300 vp8_build_intra_predictors_mby_s_neon));
303 INSTANTIATE_TEST_CASE_P(MSA, IntraPredYTest,
305 vp8_build_intra_predictors_mby_s_msa));
308 typedef void (*IntraPredUvFunc)(MACROBLOCKD *x,
318 class IntraPredUVTest
319 : public IntraPredBase,
320 public ::testing::TestWithParam<IntraPredUvFunc> {
322 static void SetUpTestCase() {
323 mb_ = reinterpret_cast<MACROBLOCKD*>(
324 vpx_memalign(32, sizeof(MACROBLOCKD)));
325 mi_ = reinterpret_cast<MODE_INFO*>(
326 vpx_memalign(32, sizeof(MODE_INFO)));
327 data_array_ = reinterpret_cast<uint8_t*>(
328 vpx_memalign(kDataAlignment, kDataBufferSize));
331 static void TearDownTestCase() {
332 vpx_free(data_array_);
339 static const int kBlockSize = 8;
340 static const int kDataAlignment = 8;
341 static const int kStride = kBlockSize * 3;
342 // We use 24 so that the data pointer of the first pixel in each row of
343 // each macroblock is 8-byte aligned, and this gives us access to the
344 // top-left and top-right corner pixels belonging to the top-left/right
346 // We use 9 lines so we have one line above us for top-prediction.
348 static const int kDataBufferSize = 2 * kStride * (kBlockSize + 1);
350 virtual void SetUp() {
351 pred_fn_ = GetParam();
352 SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 2);
355 virtual void Predict(MB_PREDICTION_MODE mode) {
356 mbptr_->mode_info_context->mbmi.uv_mode = mode;
357 pred_fn_(mbptr_, data_ptr_[0] - kStride, data_ptr_[1] - kStride,
358 data_ptr_[0] - 1, data_ptr_[1] - 1, kStride,
359 data_ptr_[0], data_ptr_[1], kStride);
362 IntraPredUvFunc pred_fn_;
363 // We use 24 so that the data pointer of the first pixel in each row of
364 // each macroblock is 8-byte aligned, and this gives us access to the
365 // top-left and top-right corner pixels belonging to the top-left/right
367 // We use 9 lines so we have one line above us for top-prediction.
369 static uint8_t* data_array_;
370 static MACROBLOCKD* mb_;
371 static MODE_INFO* mi_;
374 MACROBLOCKD* IntraPredUVTest::mb_ = NULL;
375 MODE_INFO* IntraPredUVTest::mi_ = NULL;
376 uint8_t* IntraPredUVTest::data_array_ = NULL;
378 TEST_P(IntraPredUVTest, IntraPredTests) {
382 INSTANTIATE_TEST_CASE_P(C, IntraPredUVTest,
384 vp8_build_intra_predictors_mbuv_s_c));
386 INSTANTIATE_TEST_CASE_P(SSE2, IntraPredUVTest,
388 vp8_build_intra_predictors_mbuv_s_sse2));
391 INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredUVTest,
393 vp8_build_intra_predictors_mbuv_s_ssse3));
396 INSTANTIATE_TEST_CASE_P(NEON, IntraPredUVTest,
398 vp8_build_intra_predictors_mbuv_s_neon));
401 INSTANTIATE_TEST_CASE_P(MSA, IntraPredUVTest,
403 vp8_build_intra_predictors_mbuv_s_msa));