11b362b15af34006e6a11974088a46d42b903418eJohann/*
21b362b15af34006e6a11974088a46d42b903418eJohann *  Copyright (c) 2010 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
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_config.h"
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vp8_rtcd.h"
13da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
141b362b15af34006e6a11974088a46d42b903418eJohann#include "third_party/googletest/src/include/gtest/gtest.h"
151b362b15af34006e6a11974088a46d42b903418eJohann
160a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "test/buffer.h"
17da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#include "test/clear_system_state.h"
18da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#include "test/register_state_check.h"
191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#include "vpx/vpx_integer.h"
201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniantypedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int pred_stride, unsigned char *dst_ptr,
23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int dst_stride);
241b362b15af34006e6a11974088a46d42b903418eJohannnamespace {
250a39d0a697ff3603e8c100300fda363658e10b23James Zern
260a39d0a697ff3603e8c100300fda363658e10b23James Zernusing libvpx_test::Buffer;
270a39d0a697ff3603e8c100300fda363658e10b23James Zern
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianclass IDCTTest : public ::testing::TestWithParam<IdctFunc> {
2991037db265ecdd914a26e056cf69207b4f50924ehkuang protected:
3091037db265ecdd914a26e056cf69207b4f50924ehkuang  virtual void SetUp() {
3191037db265ecdd914a26e056cf69207b4f50924ehkuang    UUT = GetParam();
320a39d0a697ff3603e8c100300fda363658e10b23James Zern
330a39d0a697ff3603e8c100300fda363658e10b23James Zern    input = new (std::nothrow) Buffer<int16_t>(4, 4, 0);
340a39d0a697ff3603e8c100300fda363658e10b23James Zern    ASSERT_TRUE(input != NULL);
350a39d0a697ff3603e8c100300fda363658e10b23James Zern    predict = new (std::nothrow) Buffer<uint8_t>(4, 4, 3);
360a39d0a697ff3603e8c100300fda363658e10b23James Zern    ASSERT_TRUE(predict != NULL);
370a39d0a697ff3603e8c100300fda363658e10b23James Zern    output = new (std::nothrow) Buffer<uint8_t>(4, 4, 3);
380a39d0a697ff3603e8c100300fda363658e10b23James Zern    ASSERT_TRUE(output != NULL);
3991037db265ecdd914a26e056cf69207b4f50924ehkuang  }
4091037db265ecdd914a26e056cf69207b4f50924ehkuang
410a39d0a697ff3603e8c100300fda363658e10b23James Zern  virtual void TearDown() {
420a39d0a697ff3603e8c100300fda363658e10b23James Zern    delete input;
430a39d0a697ff3603e8c100300fda363658e10b23James Zern    delete predict;
440a39d0a697ff3603e8c100300fda363658e10b23James Zern    delete output;
450a39d0a697ff3603e8c100300fda363658e10b23James Zern    libvpx_test::ClearSystemState();
460a39d0a697ff3603e8c100300fda363658e10b23James Zern  }
4791037db265ecdd914a26e056cf69207b4f50924ehkuang
48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  IdctFunc UUT;
490a39d0a697ff3603e8c100300fda363658e10b23James Zern  Buffer<int16_t> *input;
500a39d0a697ff3603e8c100300fda363658e10b23James Zern  Buffer<uint8_t> *predict;
510a39d0a697ff3603e8c100300fda363658e10b23James Zern  Buffer<uint8_t> *output;
521b362b15af34006e6a11974088a46d42b903418eJohann};
531b362b15af34006e6a11974088a46d42b903418eJohann
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangTEST_P(IDCTTest, TestAllZeros) {
550a39d0a697ff3603e8c100300fda363658e10b23James Zern  // When the input is '0' the output will be '0'.
560a39d0a697ff3603e8c100300fda363658e10b23James Zern  input->Set(0);
570a39d0a697ff3603e8c100300fda363658e10b23James Zern  predict->Set(0);
580a39d0a697ff3603e8c100300fda363658e10b23James Zern  output->Set(0);
590a39d0a697ff3603e8c100300fda363658e10b23James Zern
600a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
610a39d0a697ff3603e8c100300fda363658e10b23James Zern                               predict->stride(), output->TopLeftPixel(),
620a39d0a697ff3603e8c100300fda363658e10b23James Zern                               output->stride()));
630a39d0a697ff3603e8c100300fda363658e10b23James Zern
640a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(input->CheckValues(0));
650a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(input->CheckPadding());
660a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(output->CheckValues(0));
670a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(output->CheckPadding());
681b362b15af34006e6a11974088a46d42b903418eJohann}
691b362b15af34006e6a11974088a46d42b903418eJohann
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangTEST_P(IDCTTest, TestAllOnes) {
710a39d0a697ff3603e8c100300fda363658e10b23James Zern  input->Set(0);
720a39d0a697ff3603e8c100300fda363658e10b23James Zern  // When the first element is '4' it will fill the output buffer with '1'.
730a39d0a697ff3603e8c100300fda363658e10b23James Zern  input->TopLeftPixel()[0] = 4;
740a39d0a697ff3603e8c100300fda363658e10b23James Zern  predict->Set(0);
750a39d0a697ff3603e8c100300fda363658e10b23James Zern  output->Set(0);
760a39d0a697ff3603e8c100300fda363658e10b23James Zern
770a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
780a39d0a697ff3603e8c100300fda363658e10b23James Zern                               predict->stride(), output->TopLeftPixel(),
790a39d0a697ff3603e8c100300fda363658e10b23James Zern                               output->stride()));
800a39d0a697ff3603e8c100300fda363658e10b23James Zern
810a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(output->CheckValues(1));
820a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(output->CheckPadding());
831b362b15af34006e6a11974088a46d42b903418eJohann}
841b362b15af34006e6a11974088a46d42b903418eJohann
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangTEST_P(IDCTTest, TestAddOne) {
860a39d0a697ff3603e8c100300fda363658e10b23James Zern  // Set the transform output to '1' and make sure it gets added to the
870a39d0a697ff3603e8c100300fda363658e10b23James Zern  // prediction buffer.
880a39d0a697ff3603e8c100300fda363658e10b23James Zern  input->Set(0);
890a39d0a697ff3603e8c100300fda363658e10b23James Zern  input->TopLeftPixel()[0] = 4;
900a39d0a697ff3603e8c100300fda363658e10b23James Zern  output->Set(0);
910a39d0a697ff3603e8c100300fda363658e10b23James Zern
920a39d0a697ff3603e8c100300fda363658e10b23James Zern  uint8_t *pred = predict->TopLeftPixel();
930a39d0a697ff3603e8c100300fda363658e10b23James Zern  for (int y = 0; y < 4; ++y) {
940a39d0a697ff3603e8c100300fda363658e10b23James Zern    for (int x = 0; x < 4; ++x) {
950a39d0a697ff3603e8c100300fda363658e10b23James Zern      pred[y * predict->stride() + x] = y * 4 + x;
960a39d0a697ff3603e8c100300fda363658e10b23James Zern    }
970a39d0a697ff3603e8c100300fda363658e10b23James Zern  }
981b362b15af34006e6a11974088a46d42b903418eJohann
990a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
1000a39d0a697ff3603e8c100300fda363658e10b23James Zern                               predict->stride(), output->TopLeftPixel(),
1010a39d0a697ff3603e8c100300fda363658e10b23James Zern                               output->stride()));
1020a39d0a697ff3603e8c100300fda363658e10b23James Zern
1030a39d0a697ff3603e8c100300fda363658e10b23James Zern  uint8_t const *out = output->TopLeftPixel();
1040a39d0a697ff3603e8c100300fda363658e10b23James Zern  for (int y = 0; y < 4; ++y) {
1050a39d0a697ff3603e8c100300fda363658e10b23James Zern    for (int x = 0; x < 4; ++x) {
1060a39d0a697ff3603e8c100300fda363658e10b23James Zern      EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
1070a39d0a697ff3603e8c100300fda363658e10b23James Zern    }
1080a39d0a697ff3603e8c100300fda363658e10b23James Zern  }
1091b362b15af34006e6a11974088a46d42b903418eJohann
1100a39d0a697ff3603e8c100300fda363658e10b23James Zern  if (HasFailure()) {
1110a39d0a697ff3603e8c100300fda363658e10b23James Zern    output->DumpBuffer();
1127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1130a39d0a697ff3603e8c100300fda363658e10b23James Zern
1140a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(output->CheckPadding());
1151b362b15af34006e6a11974088a46d42b903418eJohann}
1161b362b15af34006e6a11974088a46d42b903418eJohann
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangTEST_P(IDCTTest, TestWithData) {
1180a39d0a697ff3603e8c100300fda363658e10b23James Zern  // Test a single known input.
1190a39d0a697ff3603e8c100300fda363658e10b23James Zern  predict->Set(0);
1200a39d0a697ff3603e8c100300fda363658e10b23James Zern
1210a39d0a697ff3603e8c100300fda363658e10b23James Zern  int16_t *in = input->TopLeftPixel();
1220a39d0a697ff3603e8c100300fda363658e10b23James Zern  for (int y = 0; y < 4; ++y) {
1230a39d0a697ff3603e8c100300fda363658e10b23James Zern    for (int x = 0; x < 4; ++x) {
1240a39d0a697ff3603e8c100300fda363658e10b23James Zern      in[y * input->stride() + x] = y * 4 + x;
1250a39d0a697ff3603e8c100300fda363658e10b23James Zern    }
1260a39d0a697ff3603e8c100300fda363658e10b23James Zern  }
1270a39d0a697ff3603e8c100300fda363658e10b23James Zern
1280a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
1290a39d0a697ff3603e8c100300fda363658e10b23James Zern                               predict->stride(), output->TopLeftPixel(),
1300a39d0a697ff3603e8c100300fda363658e10b23James Zern                               output->stride()));
1310a39d0a697ff3603e8c100300fda363658e10b23James Zern
1320a39d0a697ff3603e8c100300fda363658e10b23James Zern  uint8_t *out = output->TopLeftPixel();
1330a39d0a697ff3603e8c100300fda363658e10b23James Zern  for (int y = 0; y < 4; ++y) {
1340a39d0a697ff3603e8c100300fda363658e10b23James Zern    for (int x = 0; x < 4; ++x) {
1350a39d0a697ff3603e8c100300fda363658e10b23James Zern      switch (y * 4 + x) {
1360a39d0a697ff3603e8c100300fda363658e10b23James Zern        case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
1370a39d0a697ff3603e8c100300fda363658e10b23James Zern        case 2:
1380a39d0a697ff3603e8c100300fda363658e10b23James Zern        case 5:
1390a39d0a697ff3603e8c100300fda363658e10b23James Zern        case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
1400a39d0a697ff3603e8c100300fda363658e10b23James Zern        case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
1410a39d0a697ff3603e8c100300fda363658e10b23James Zern        default: EXPECT_EQ(0, out[y * output->stride() + x]);
1420a39d0a697ff3603e8c100300fda363658e10b23James Zern      }
1430a39d0a697ff3603e8c100300fda363658e10b23James Zern    }
1447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1450a39d0a697ff3603e8c100300fda363658e10b23James Zern
1460a39d0a697ff3603e8c100300fda363658e10b23James Zern  if (HasFailure()) {
1470a39d0a697ff3603e8c100300fda363658e10b23James Zern    output->DumpBuffer();
1480a39d0a697ff3603e8c100300fda363658e10b23James Zern  }
1490a39d0a697ff3603e8c100300fda363658e10b23James Zern
1500a39d0a697ff3603e8c100300fda363658e10b23James Zern  ASSERT_TRUE(output->CheckPadding());
1511b362b15af34006e6a11974088a46d42b903418eJohann}
1521b362b15af34006e6a11974088a46d42b903418eJohann
15391037db265ecdd914a26e056cf69207b4f50924ehkuangINSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
1540a39d0a697ff3603e8c100300fda363658e10b23James Zern
155653cb5bbe266083a3c5c40eeafb5e88bededd566Johann#if HAVE_NEON
156653cb5bbe266083a3c5c40eeafb5e88bededd566JohannINSTANTIATE_TEST_CASE_P(NEON, IDCTTest,
157653cb5bbe266083a3c5c40eeafb5e88bededd566Johann                        ::testing::Values(vp8_short_idct4x4llm_neon));
1580a39d0a697ff3603e8c100300fda363658e10b23James Zern#endif  // HAVE_NEON
1590a39d0a697ff3603e8c100300fda363658e10b23James Zern
1601b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_MMX
1611b362b15af34006e6a11974088a46d42b903418eJohannINSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
1621b362b15af34006e6a11974088a46d42b903418eJohann                        ::testing::Values(vp8_short_idct4x4llm_mmx));
1630a39d0a697ff3603e8c100300fda363658e10b23James Zern#endif  // HAVE_MMX
1640a39d0a697ff3603e8c100300fda363658e10b23James Zern
165da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if HAVE_MSA
166da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh VenkatasubramanianINSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
167da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                        ::testing::Values(vp8_short_idct4x4llm_msa));
1680a39d0a697ff3603e8c100300fda363658e10b23James Zern#endif  // HAVE_MSA
1691b362b15af34006e6a11974088a46d42b903418eJohann}
170