11b362b15af34006e6a11974088a46d42b903418eJohann/*
21b362b15af34006e6a11974088a46d42b903418eJohann *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
31b362b15af34006e6a11974088a46d42b903418eJohann *
41b362b15af34006e6a11974088a46d42b903418eJohann *  Use of this source code is governed by a BSD-style license
51b362b15af34006e6a11974088a46d42b903418eJohann *  that can be found in the LICENSE file in the root of the source
61b362b15af34006e6a11974088a46d42b903418eJohann *  tree. An additional intellectual property rights grant can be found
71b362b15af34006e6a11974088a46d42b903418eJohann *  in the file PATENTS.  All contributing project authors may
81b362b15af34006e6a11974088a46d42b903418eJohann *  be found in the AUTHORS file in the root of the source tree.
91b362b15af34006e6a11974088a46d42b903418eJohann */
101b362b15af34006e6a11974088a46d42b903418eJohann
111b362b15af34006e6a11974088a46d42b903418eJohann
121b362b15af34006e6a11974088a46d42b903418eJohann#include <string.h>
131b362b15af34006e6a11974088a46d42b903418eJohann#include "test/acm_random.h"
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/clear_system_state.h"
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/register_state_check.h"
161b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/googletest/src/include/gtest/gtest.h"
171b362b15af34006e6a11974088a46d42b903418eJohannextern "C" {
181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "./vpx_config.h"
191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "./vp8_rtcd.h"
201b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/blockd.h"
211b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h"
221b362b15af34006e6a11974088a46d42b903418eJohann}
231b362b15af34006e6a11974088a46d42b903418eJohann
241b362b15af34006e6a11974088a46d42b903418eJohannnamespace {
251b362b15af34006e6a11974088a46d42b903418eJohann
261b362b15af34006e6a11974088a46d42b903418eJohannusing libvpx_test::ACMRandom;
271b362b15af34006e6a11974088a46d42b903418eJohann
281b362b15af34006e6a11974088a46d42b903418eJohannclass IntraPredBase {
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang public:
3091037db265ecdd914a26e056cf69207b4f50924ehkuang  virtual ~IntraPredBase() {}
3191037db265ecdd914a26e056cf69207b4f50924ehkuang
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  virtual void TearDown() {
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    libvpx_test::ClearSystemState();
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
361b362b15af34006e6a11974088a46d42b903418eJohann protected:
375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  void SetupMacroblock(MACROBLOCKD *mbptr,
385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       MODE_INFO *miptr,
395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       uint8_t *data,
405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       int block_size,
415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       int stride,
421b362b15af34006e6a11974088a46d42b903418eJohann                       int num_planes) {
435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_ = mbptr;
445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    miptr_ = miptr;
455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->up_available = 1;
465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->left_available = 1;
475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->mode_info_context = miptr_;
481b362b15af34006e6a11974088a46d42b903418eJohann    stride_ = stride;
491b362b15af34006e6a11974088a46d42b903418eJohann    block_size_ = block_size;
501b362b15af34006e6a11974088a46d42b903418eJohann    num_planes_ = num_planes;
511b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes; p++)
521b362b15af34006e6a11974088a46d42b903418eJohann      data_ptr_[p] = data + stride * (block_size + 1) * p +
531b362b15af34006e6a11974088a46d42b903418eJohann                     stride + block_size;
541b362b15af34006e6a11974088a46d42b903418eJohann  }
551b362b15af34006e6a11974088a46d42b903418eJohann
561b362b15af34006e6a11974088a46d42b903418eJohann  void FillRandom() {
571b362b15af34006e6a11974088a46d42b903418eJohann    // Fill edges with random data
581b362b15af34006e6a11974088a46d42b903418eJohann    ACMRandom rnd(ACMRandom::DeterministicSeed());
591b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++) {
601b362b15af34006e6a11974088a46d42b903418eJohann      for (int x = -1 ; x <= block_size_; x++)
611b362b15af34006e6a11974088a46d42b903418eJohann        data_ptr_[p][x - stride_] = rnd.Rand8();
621b362b15af34006e6a11974088a46d42b903418eJohann      for (int y = 0; y < block_size_; y++)
631b362b15af34006e6a11974088a46d42b903418eJohann        data_ptr_[p][y * stride_ - 1] = rnd.Rand8();
641b362b15af34006e6a11974088a46d42b903418eJohann    }
651b362b15af34006e6a11974088a46d42b903418eJohann  }
661b362b15af34006e6a11974088a46d42b903418eJohann
671b362b15af34006e6a11974088a46d42b903418eJohann  virtual void Predict(MB_PREDICTION_MODE mode) = 0;
681b362b15af34006e6a11974088a46d42b903418eJohann
691b362b15af34006e6a11974088a46d42b903418eJohann  void SetLeftUnavailable() {
705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->left_available = 0;
711b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++)
721b362b15af34006e6a11974088a46d42b903418eJohann      for (int i = -1; i < block_size_; ++i)
731b362b15af34006e6a11974088a46d42b903418eJohann        data_ptr_[p][stride_ * i - 1] = 129;
741b362b15af34006e6a11974088a46d42b903418eJohann  }
751b362b15af34006e6a11974088a46d42b903418eJohann
761b362b15af34006e6a11974088a46d42b903418eJohann  void SetTopUnavailable() {
775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->up_available = 0;
781b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++)
791b362b15af34006e6a11974088a46d42b903418eJohann      memset(&data_ptr_[p][-1 - stride_], 127, block_size_ + 2);
801b362b15af34006e6a11974088a46d42b903418eJohann  }
811b362b15af34006e6a11974088a46d42b903418eJohann
821b362b15af34006e6a11974088a46d42b903418eJohann  void SetTopLeftUnavailable() {
831b362b15af34006e6a11974088a46d42b903418eJohann    SetLeftUnavailable();
841b362b15af34006e6a11974088a46d42b903418eJohann    SetTopUnavailable();
851b362b15af34006e6a11974088a46d42b903418eJohann  }
861b362b15af34006e6a11974088a46d42b903418eJohann
871b362b15af34006e6a11974088a46d42b903418eJohann  int BlockSizeLog2Min1() const {
881b362b15af34006e6a11974088a46d42b903418eJohann    switch (block_size_) {
891b362b15af34006e6a11974088a46d42b903418eJohann      case 16:
901b362b15af34006e6a11974088a46d42b903418eJohann        return 3;
911b362b15af34006e6a11974088a46d42b903418eJohann      case 8:
921b362b15af34006e6a11974088a46d42b903418eJohann        return 2;
931b362b15af34006e6a11974088a46d42b903418eJohann      default:
941b362b15af34006e6a11974088a46d42b903418eJohann        return 0;
951b362b15af34006e6a11974088a46d42b903418eJohann    }
961b362b15af34006e6a11974088a46d42b903418eJohann  }
971b362b15af34006e6a11974088a46d42b903418eJohann
981b362b15af34006e6a11974088a46d42b903418eJohann  // check DC prediction output against a reference
991b362b15af34006e6a11974088a46d42b903418eJohann  void CheckDCPrediction() const {
1001b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++) {
1011b362b15af34006e6a11974088a46d42b903418eJohann      // calculate expected DC
1021b362b15af34006e6a11974088a46d42b903418eJohann      int expected;
1035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mbptr_->up_available || mbptr_->left_available) {
1045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        int sum = 0, shift = BlockSizeLog2Min1() + mbptr_->up_available +
1055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             mbptr_->left_available;
1065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (mbptr_->up_available)
1071b362b15af34006e6a11974088a46d42b903418eJohann          for (int x = 0; x < block_size_; x++)
1081b362b15af34006e6a11974088a46d42b903418eJohann            sum += data_ptr_[p][x - stride_];
1095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (mbptr_->left_available)
1101b362b15af34006e6a11974088a46d42b903418eJohann          for (int y = 0; y < block_size_; y++)
1111b362b15af34006e6a11974088a46d42b903418eJohann            sum += data_ptr_[p][y * stride_ - 1];
1121b362b15af34006e6a11974088a46d42b903418eJohann        expected = (sum + (1 << (shift - 1))) >> shift;
1131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      } else {
1141b362b15af34006e6a11974088a46d42b903418eJohann        expected = 0x80;
1151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
1161b362b15af34006e6a11974088a46d42b903418eJohann      // check that all subsequent lines are equal to the first
1171b362b15af34006e6a11974088a46d42b903418eJohann      for (int y = 1; y < block_size_; ++y)
1181b362b15af34006e6a11974088a46d42b903418eJohann        ASSERT_EQ(0, memcmp(data_ptr_[p], &data_ptr_[p][y * stride_],
1191b362b15af34006e6a11974088a46d42b903418eJohann                            block_size_));
1201b362b15af34006e6a11974088a46d42b903418eJohann      // within the first line, ensure that each pixel has the same value
1211b362b15af34006e6a11974088a46d42b903418eJohann      for (int x = 1; x < block_size_; ++x)
1221b362b15af34006e6a11974088a46d42b903418eJohann        ASSERT_EQ(data_ptr_[p][0], data_ptr_[p][x]);
1231b362b15af34006e6a11974088a46d42b903418eJohann      // now ensure that that pixel has the expected (DC) value
1241b362b15af34006e6a11974088a46d42b903418eJohann      ASSERT_EQ(expected, data_ptr_[p][0]);
1251b362b15af34006e6a11974088a46d42b903418eJohann    }
1261b362b15af34006e6a11974088a46d42b903418eJohann  }
1271b362b15af34006e6a11974088a46d42b903418eJohann
1281b362b15af34006e6a11974088a46d42b903418eJohann  // check V prediction output against a reference
1291b362b15af34006e6a11974088a46d42b903418eJohann  void CheckVPrediction() const {
1301b362b15af34006e6a11974088a46d42b903418eJohann    // check that all lines equal the top border
1311b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++)
1321b362b15af34006e6a11974088a46d42b903418eJohann      for (int y = 0; y < block_size_; y++)
1331b362b15af34006e6a11974088a46d42b903418eJohann        ASSERT_EQ(0, memcmp(&data_ptr_[p][-stride_],
1341b362b15af34006e6a11974088a46d42b903418eJohann                            &data_ptr_[p][y * stride_], block_size_));
1351b362b15af34006e6a11974088a46d42b903418eJohann  }
1361b362b15af34006e6a11974088a46d42b903418eJohann
1371b362b15af34006e6a11974088a46d42b903418eJohann  // check H prediction output against a reference
1381b362b15af34006e6a11974088a46d42b903418eJohann  void CheckHPrediction() const {
1391b362b15af34006e6a11974088a46d42b903418eJohann    // for each line, ensure that each pixel is equal to the left border
1401b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++)
1411b362b15af34006e6a11974088a46d42b903418eJohann      for (int y = 0; y < block_size_; y++)
1421b362b15af34006e6a11974088a46d42b903418eJohann        for (int x = 0; x < block_size_; x++)
1431b362b15af34006e6a11974088a46d42b903418eJohann          ASSERT_EQ(data_ptr_[p][-1 + y * stride_],
1441b362b15af34006e6a11974088a46d42b903418eJohann                    data_ptr_[p][x + y * stride_]);
1451b362b15af34006e6a11974088a46d42b903418eJohann  }
1461b362b15af34006e6a11974088a46d42b903418eJohann
1471b362b15af34006e6a11974088a46d42b903418eJohann  static int ClipByte(int value) {
1481b362b15af34006e6a11974088a46d42b903418eJohann    if (value > 255)
1491b362b15af34006e6a11974088a46d42b903418eJohann      return 255;
1501b362b15af34006e6a11974088a46d42b903418eJohann    else if (value < 0)
1511b362b15af34006e6a11974088a46d42b903418eJohann      return 0;
1521b362b15af34006e6a11974088a46d42b903418eJohann    return value;
1531b362b15af34006e6a11974088a46d42b903418eJohann  }
1541b362b15af34006e6a11974088a46d42b903418eJohann
1551b362b15af34006e6a11974088a46d42b903418eJohann  // check TM prediction output against a reference
1561b362b15af34006e6a11974088a46d42b903418eJohann  void CheckTMPrediction() const {
1571b362b15af34006e6a11974088a46d42b903418eJohann    for (int p = 0; p < num_planes_; p++)
1581b362b15af34006e6a11974088a46d42b903418eJohann      for (int y = 0; y < block_size_; y++)
1591b362b15af34006e6a11974088a46d42b903418eJohann        for (int x = 0; x < block_size_; x++) {
1601b362b15af34006e6a11974088a46d42b903418eJohann          const int expected = ClipByte(data_ptr_[p][x - stride_]
1611b362b15af34006e6a11974088a46d42b903418eJohann                                      + data_ptr_[p][stride_ * y - 1]
1621b362b15af34006e6a11974088a46d42b903418eJohann                                      - data_ptr_[p][-1 - stride_]);
1631b362b15af34006e6a11974088a46d42b903418eJohann          ASSERT_EQ(expected, data_ptr_[p][y * stride_ + x]);
1641b362b15af34006e6a11974088a46d42b903418eJohann       }
1651b362b15af34006e6a11974088a46d42b903418eJohann  }
1661b362b15af34006e6a11974088a46d42b903418eJohann
1671b362b15af34006e6a11974088a46d42b903418eJohann  // Actual test
1681b362b15af34006e6a11974088a46d42b903418eJohann  void RunTest() {
1691b362b15af34006e6a11974088a46d42b903418eJohann    {
1701b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("DC_PRED");
1711b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
1721b362b15af34006e6a11974088a46d42b903418eJohann      Predict(DC_PRED);
1731b362b15af34006e6a11974088a46d42b903418eJohann      CheckDCPrediction();
1741b362b15af34006e6a11974088a46d42b903418eJohann    }
1751b362b15af34006e6a11974088a46d42b903418eJohann    {
1761b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("DC_PRED LEFT");
1771b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
1781b362b15af34006e6a11974088a46d42b903418eJohann      SetLeftUnavailable();
1791b362b15af34006e6a11974088a46d42b903418eJohann      Predict(DC_PRED);
1801b362b15af34006e6a11974088a46d42b903418eJohann      CheckDCPrediction();
1811b362b15af34006e6a11974088a46d42b903418eJohann    }
1821b362b15af34006e6a11974088a46d42b903418eJohann    {
1831b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("DC_PRED TOP");
1841b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
1851b362b15af34006e6a11974088a46d42b903418eJohann      SetTopUnavailable();
1861b362b15af34006e6a11974088a46d42b903418eJohann      Predict(DC_PRED);
1871b362b15af34006e6a11974088a46d42b903418eJohann      CheckDCPrediction();
1881b362b15af34006e6a11974088a46d42b903418eJohann    }
1891b362b15af34006e6a11974088a46d42b903418eJohann    {
1901b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("DC_PRED TOP_LEFT");
1911b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
1921b362b15af34006e6a11974088a46d42b903418eJohann      SetTopLeftUnavailable();
1931b362b15af34006e6a11974088a46d42b903418eJohann      Predict(DC_PRED);
1941b362b15af34006e6a11974088a46d42b903418eJohann      CheckDCPrediction();
1951b362b15af34006e6a11974088a46d42b903418eJohann    }
1961b362b15af34006e6a11974088a46d42b903418eJohann    {
1971b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("H_PRED");
1981b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
1991b362b15af34006e6a11974088a46d42b903418eJohann      Predict(H_PRED);
2001b362b15af34006e6a11974088a46d42b903418eJohann      CheckHPrediction();
2011b362b15af34006e6a11974088a46d42b903418eJohann    }
2021b362b15af34006e6a11974088a46d42b903418eJohann    {
2031b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("V_PRED");
2041b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
2051b362b15af34006e6a11974088a46d42b903418eJohann      Predict(V_PRED);
2061b362b15af34006e6a11974088a46d42b903418eJohann      CheckVPrediction();
2071b362b15af34006e6a11974088a46d42b903418eJohann    }
2081b362b15af34006e6a11974088a46d42b903418eJohann    {
2091b362b15af34006e6a11974088a46d42b903418eJohann      SCOPED_TRACE("TM_PRED");
2101b362b15af34006e6a11974088a46d42b903418eJohann      FillRandom();
2111b362b15af34006e6a11974088a46d42b903418eJohann      Predict(TM_PRED);
2121b362b15af34006e6a11974088a46d42b903418eJohann      CheckTMPrediction();
2131b362b15af34006e6a11974088a46d42b903418eJohann    }
2141b362b15af34006e6a11974088a46d42b903418eJohann  }
2151b362b15af34006e6a11974088a46d42b903418eJohann
2165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *mbptr_;
2175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MODE_INFO *miptr_;
2181b362b15af34006e6a11974088a46d42b903418eJohann  uint8_t *data_ptr_[2];  // in the case of Y, only [0] is used
2191b362b15af34006e6a11974088a46d42b903418eJohann  int stride_;
2201b362b15af34006e6a11974088a46d42b903418eJohann  int block_size_;
2211b362b15af34006e6a11974088a46d42b903418eJohann  int num_planes_;
2221b362b15af34006e6a11974088a46d42b903418eJohann};
2231b362b15af34006e6a11974088a46d42b903418eJohann
2241b362b15af34006e6a11974088a46d42b903418eJohanntypedef void (*intra_pred_y_fn_t)(MACROBLOCKD *x,
2251b362b15af34006e6a11974088a46d42b903418eJohann                                  uint8_t *yabove_row,
2261b362b15af34006e6a11974088a46d42b903418eJohann                                  uint8_t *yleft,
2271b362b15af34006e6a11974088a46d42b903418eJohann                                  int left_stride,
2281b362b15af34006e6a11974088a46d42b903418eJohann                                  uint8_t *ypred_ptr,
2291b362b15af34006e6a11974088a46d42b903418eJohann                                  int y_stride);
2301b362b15af34006e6a11974088a46d42b903418eJohann
2311b362b15af34006e6a11974088a46d42b903418eJohannclass IntraPredYTest : public ::testing::TestWithParam<intra_pred_y_fn_t>,
2321b362b15af34006e6a11974088a46d42b903418eJohann    protected IntraPredBase {
2331b362b15af34006e6a11974088a46d42b903418eJohann public:
2341b362b15af34006e6a11974088a46d42b903418eJohann  static void SetUpTestCase() {
2355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mb_ = reinterpret_cast<MACROBLOCKD*>(
2365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memalign(32, sizeof(MACROBLOCKD)));
2375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mi_ = reinterpret_cast<MODE_INFO*>(
2385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memalign(32, sizeof(MODE_INFO)));
2391b362b15af34006e6a11974088a46d42b903418eJohann    data_array_ = reinterpret_cast<uint8_t*>(
2401b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memalign(kDataAlignment, kDataBufferSize));
2411b362b15af34006e6a11974088a46d42b903418eJohann  }
2421b362b15af34006e6a11974088a46d42b903418eJohann
2431b362b15af34006e6a11974088a46d42b903418eJohann  static void TearDownTestCase() {
2441b362b15af34006e6a11974088a46d42b903418eJohann    vpx_free(data_array_);
2455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_free(mi_);
2465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_free(mb_);
2471b362b15af34006e6a11974088a46d42b903418eJohann    data_array_ = NULL;
2481b362b15af34006e6a11974088a46d42b903418eJohann  }
2491b362b15af34006e6a11974088a46d42b903418eJohann
2501b362b15af34006e6a11974088a46d42b903418eJohann protected:
2511b362b15af34006e6a11974088a46d42b903418eJohann  static const int kBlockSize = 16;
2521b362b15af34006e6a11974088a46d42b903418eJohann  static const int kDataAlignment = 16;
2531b362b15af34006e6a11974088a46d42b903418eJohann  static const int kStride = kBlockSize * 3;
2541b362b15af34006e6a11974088a46d42b903418eJohann  // We use 48 so that the data pointer of the first pixel in each row of
2551b362b15af34006e6a11974088a46d42b903418eJohann  // each macroblock is 16-byte aligned, and this gives us access to the
2561b362b15af34006e6a11974088a46d42b903418eJohann  // top-left and top-right corner pixels belonging to the top-left/right
2571b362b15af34006e6a11974088a46d42b903418eJohann  // macroblocks.
2581b362b15af34006e6a11974088a46d42b903418eJohann  // We use 17 lines so we have one line above us for top-prediction.
2591b362b15af34006e6a11974088a46d42b903418eJohann  static const int kDataBufferSize = kStride * (kBlockSize + 1);
2601b362b15af34006e6a11974088a46d42b903418eJohann
2611b362b15af34006e6a11974088a46d42b903418eJohann  virtual void SetUp() {
2621b362b15af34006e6a11974088a46d42b903418eJohann    pred_fn_ = GetParam();
2635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 1);
2641b362b15af34006e6a11974088a46d42b903418eJohann  }
2651b362b15af34006e6a11974088a46d42b903418eJohann
2661b362b15af34006e6a11974088a46d42b903418eJohann  virtual void Predict(MB_PREDICTION_MODE mode) {
2675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->mode_info_context->mbmi.mode = mode;
2685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    REGISTER_STATE_CHECK(pred_fn_(mbptr_,
269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  data_ptr_[0] - kStride,
270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  data_ptr_[0] - 1, kStride,
271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  data_ptr_[0], kStride));
2721b362b15af34006e6a11974088a46d42b903418eJohann  }
2731b362b15af34006e6a11974088a46d42b903418eJohann
2741b362b15af34006e6a11974088a46d42b903418eJohann  intra_pred_y_fn_t pred_fn_;
2751b362b15af34006e6a11974088a46d42b903418eJohann  static uint8_t* data_array_;
2765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  static MACROBLOCKD * mb_;
2775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  static MODE_INFO *mi_;
2781b362b15af34006e6a11974088a46d42b903418eJohann};
2791b362b15af34006e6a11974088a46d42b903418eJohann
2805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangMACROBLOCKD* IntraPredYTest::mb_ = NULL;
2815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangMODE_INFO* IntraPredYTest::mi_ = NULL;
2821b362b15af34006e6a11974088a46d42b903418eJohannuint8_t* IntraPredYTest::data_array_ = NULL;
2831b362b15af34006e6a11974088a46d42b903418eJohann
2841b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(IntraPredYTest, IntraPredTests) {
2851b362b15af34006e6a11974088a46d42b903418eJohann  RunTest();
2861b362b15af34006e6a11974088a46d42b903418eJohann}
2871b362b15af34006e6a11974088a46d42b903418eJohann
2881b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(C, IntraPredYTest,
2891b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(
2901b362b15af34006e6a11974088a46d42b903418eJohann                            vp8_build_intra_predictors_mby_s_c));
2911b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_SSE2
2921b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(SSE2, IntraPredYTest,
2931b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(
2941b362b15af34006e6a11974088a46d42b903418eJohann                            vp8_build_intra_predictors_mby_s_sse2));
2951b362b15af34006e6a11974088a46d42b903418eJohann#endif
2961b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_SSSE3
2971b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(SSSE3, IntraPredYTest,
2981b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(
2991b362b15af34006e6a11974088a46d42b903418eJohann                            vp8_build_intra_predictors_mby_s_ssse3));
3001b362b15af34006e6a11974088a46d42b903418eJohann#endif
3011b362b15af34006e6a11974088a46d42b903418eJohann
3021b362b15af34006e6a11974088a46d42b903418eJohanntypedef void (*intra_pred_uv_fn_t)(MACROBLOCKD *x,
3031b362b15af34006e6a11974088a46d42b903418eJohann                                   uint8_t *uabove_row,
3041b362b15af34006e6a11974088a46d42b903418eJohann                                   uint8_t *vabove_row,
3051b362b15af34006e6a11974088a46d42b903418eJohann                                   uint8_t *uleft,
3061b362b15af34006e6a11974088a46d42b903418eJohann                                   uint8_t *vleft,
3071b362b15af34006e6a11974088a46d42b903418eJohann                                   int left_stride,
3081b362b15af34006e6a11974088a46d42b903418eJohann                                   uint8_t *upred_ptr,
3091b362b15af34006e6a11974088a46d42b903418eJohann                                   uint8_t *vpred_ptr,
3101b362b15af34006e6a11974088a46d42b903418eJohann                                   int pred_stride);
3111b362b15af34006e6a11974088a46d42b903418eJohann
3121b362b15af34006e6a11974088a46d42b903418eJohannclass IntraPredUVTest : public ::testing::TestWithParam<intra_pred_uv_fn_t>,
3131b362b15af34006e6a11974088a46d42b903418eJohann    protected IntraPredBase {
3141b362b15af34006e6a11974088a46d42b903418eJohann public:
3151b362b15af34006e6a11974088a46d42b903418eJohann  static void SetUpTestCase() {
3165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mb_ = reinterpret_cast<MACROBLOCKD*>(
3175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memalign(32, sizeof(MACROBLOCKD)));
3185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mi_ = reinterpret_cast<MODE_INFO*>(
3195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memalign(32, sizeof(MODE_INFO)));
3201b362b15af34006e6a11974088a46d42b903418eJohann    data_array_ = reinterpret_cast<uint8_t*>(
3211b362b15af34006e6a11974088a46d42b903418eJohann        vpx_memalign(kDataAlignment, kDataBufferSize));
3221b362b15af34006e6a11974088a46d42b903418eJohann  }
3231b362b15af34006e6a11974088a46d42b903418eJohann
3241b362b15af34006e6a11974088a46d42b903418eJohann  static void TearDownTestCase() {
3251b362b15af34006e6a11974088a46d42b903418eJohann    vpx_free(data_array_);
3265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_free(mi_);
3275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_free(mb_);
3281b362b15af34006e6a11974088a46d42b903418eJohann    data_array_ = NULL;
3291b362b15af34006e6a11974088a46d42b903418eJohann  }
3301b362b15af34006e6a11974088a46d42b903418eJohann
3311b362b15af34006e6a11974088a46d42b903418eJohann protected:
3321b362b15af34006e6a11974088a46d42b903418eJohann  static const int kBlockSize = 8;
3331b362b15af34006e6a11974088a46d42b903418eJohann  static const int kDataAlignment = 8;
3341b362b15af34006e6a11974088a46d42b903418eJohann  static const int kStride = kBlockSize * 3;
3351b362b15af34006e6a11974088a46d42b903418eJohann  // We use 24 so that the data pointer of the first pixel in each row of
3361b362b15af34006e6a11974088a46d42b903418eJohann  // each macroblock is 8-byte aligned, and this gives us access to the
3371b362b15af34006e6a11974088a46d42b903418eJohann  // top-left and top-right corner pixels belonging to the top-left/right
3381b362b15af34006e6a11974088a46d42b903418eJohann  // macroblocks.
3391b362b15af34006e6a11974088a46d42b903418eJohann  // We use 9 lines so we have one line above us for top-prediction.
3401b362b15af34006e6a11974088a46d42b903418eJohann  // [0] = U, [1] = V
3411b362b15af34006e6a11974088a46d42b903418eJohann  static const int kDataBufferSize = 2 * kStride * (kBlockSize + 1);
3421b362b15af34006e6a11974088a46d42b903418eJohann
3431b362b15af34006e6a11974088a46d42b903418eJohann  virtual void SetUp() {
3441b362b15af34006e6a11974088a46d42b903418eJohann    pred_fn_ = GetParam();
3455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 2);
3461b362b15af34006e6a11974088a46d42b903418eJohann  }
3471b362b15af34006e6a11974088a46d42b903418eJohann
3481b362b15af34006e6a11974088a46d42b903418eJohann  virtual void Predict(MB_PREDICTION_MODE mode) {
3495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbptr_->mode_info_context->mbmi.uv_mode = mode;
3505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    pred_fn_(mbptr_, data_ptr_[0] - kStride, data_ptr_[1] - kStride,
3511b362b15af34006e6a11974088a46d42b903418eJohann             data_ptr_[0] - 1, data_ptr_[1] - 1, kStride,
3521b362b15af34006e6a11974088a46d42b903418eJohann             data_ptr_[0], data_ptr_[1], kStride);
3531b362b15af34006e6a11974088a46d42b903418eJohann  }
3541b362b15af34006e6a11974088a46d42b903418eJohann
3551b362b15af34006e6a11974088a46d42b903418eJohann  intra_pred_uv_fn_t pred_fn_;
3561b362b15af34006e6a11974088a46d42b903418eJohann  // We use 24 so that the data pointer of the first pixel in each row of
3571b362b15af34006e6a11974088a46d42b903418eJohann  // each macroblock is 8-byte aligned, and this gives us access to the
3581b362b15af34006e6a11974088a46d42b903418eJohann  // top-left and top-right corner pixels belonging to the top-left/right
3591b362b15af34006e6a11974088a46d42b903418eJohann  // macroblocks.
3601b362b15af34006e6a11974088a46d42b903418eJohann  // We use 9 lines so we have one line above us for top-prediction.
3611b362b15af34006e6a11974088a46d42b903418eJohann  // [0] = U, [1] = V
3621b362b15af34006e6a11974088a46d42b903418eJohann  static uint8_t* data_array_;
3635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  static MACROBLOCKD* mb_;
3645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  static MODE_INFO* mi_;
3651b362b15af34006e6a11974088a46d42b903418eJohann};
3661b362b15af34006e6a11974088a46d42b903418eJohann
3675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangMACROBLOCKD* IntraPredUVTest::mb_ = NULL;
3685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangMODE_INFO* IntraPredUVTest::mi_ = NULL;
3691b362b15af34006e6a11974088a46d42b903418eJohannuint8_t* IntraPredUVTest::data_array_ = NULL;
3701b362b15af34006e6a11974088a46d42b903418eJohann
3711b362b15af34006e6a11974088a46d42b903418eJohannTEST_P(IntraPredUVTest, IntraPredTests) {
3721b362b15af34006e6a11974088a46d42b903418eJohann  RunTest();
3731b362b15af34006e6a11974088a46d42b903418eJohann}
3741b362b15af34006e6a11974088a46d42b903418eJohann
3751b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(C, IntraPredUVTest,
3761b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(
3771b362b15af34006e6a11974088a46d42b903418eJohann                            vp8_build_intra_predictors_mbuv_s_c));
3781b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_SSE2
3791b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(SSE2, IntraPredUVTest,
3801b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(
3811b362b15af34006e6a11974088a46d42b903418eJohann                            vp8_build_intra_predictors_mbuv_s_sse2));
3821b362b15af34006e6a11974088a46d42b903418eJohann#endif
3831b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_SSSE3
3841b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(SSSE3, IntraPredUVTest,
3851b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(
3861b362b15af34006e6a11974088a46d42b903418eJohann                            vp8_build_intra_predictors_mbuv_s_ssse3));
3871b362b15af34006e6a11974088a46d42b903418eJohann#endif
3881b362b15af34006e6a11974088a46d42b903418eJohann
3891b362b15af34006e6a11974088a46d42b903418eJohann}  // namespace
390