ref: 3628975a15dbb02f1b61edc49b831c67ace278b4
parent: 70ead526f13e82e0c2e3ef9ea47543039190e20b
parent: 6886da75474fb9df9391f1688c32f3ff1d39b853
author: Johann Koenig <[email protected]>
date: Wed Jan 11 20:02:58 EST 2017
Merge "Create a class for buffers used in tests"
--- /dev/null
+++ b/test/buffer.h
@@ -1,0 +1,194 @@
+/*
+ * Copyright (c) 2016 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef TEST_BUFFER_H_
+#define TEST_BUFFER_H_
+
+#include <stdio.h>
+
+#include <limits>
+
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+#include "vpx/vpx_integer.h"
+
+namespace libvpx_test {
+
+template <typename T>
+class Buffer {
+ public:
+ Buffer(int width, int height, int top_padding, int left_padding,
+ int right_padding, int bottom_padding)
+ : width_(width), height_(height), top_padding_(top_padding),
+ left_padding_(left_padding), right_padding_(right_padding),
+ bottom_padding_(bottom_padding) {
+ Init();
+ }
+
+ Buffer(int width, int height, int padding)
+ : width_(width), height_(height), top_padding_(padding),
+ left_padding_(padding), right_padding_(padding),
+ bottom_padding_(padding) {
+ Init();
+ }
+
+ ~Buffer() { delete[] raw_buffer_; }
+
+ T *TopLeftPixel() const;
+
+ int stride() const { return stride_; }
+
+ // Set the buffer (excluding padding) to 'value'.
+ void Set(const int value);
+
+ void DumpBuffer() const;
+
+ bool HasPadding() const;
+
+ // Sets all the values in the buffer to 'padding_value'.
+ void SetPadding(const int padding_value);
+
+ // Checks if all the values (excluding padding) are equal to 'value'.
+ bool CheckValues(const int value) const;
+
+ // Check that padding matches the expected value or there is no padding.
+ bool CheckPadding() const;
+
+ private:
+ void Init() {
+ ASSERT_GT(width_, 0);
+ ASSERT_GT(height_, 0);
+ ASSERT_GE(top_padding_, 0);
+ ASSERT_GE(left_padding_, 0);
+ ASSERT_GE(right_padding_, 0);
+ ASSERT_GE(bottom_padding_, 0);
+ stride_ = left_padding_ + width_ + right_padding_;
+ raw_size_ = stride_ * (top_padding_ + height_ + bottom_padding_);
+ raw_buffer_ = new (std::nothrow) T[raw_size_];
+ ASSERT_TRUE(raw_buffer_ != NULL);
+ SetPadding(std::numeric_limits<T>::max());
+ }
+
+ const int width_;
+ const int height_;
+ const int top_padding_;
+ const int left_padding_;
+ const int right_padding_;
+ const int bottom_padding_;
+ int padding_value_;
+ int stride_;
+ int raw_size_;
+ T *raw_buffer_;
+};
+
+template <typename T>
+T *Buffer<T>::TopLeftPixel() const {
+ return raw_buffer_ + (top_padding_ * stride()) + left_padding_;
+}
+
+template <typename T>
+void Buffer<T>::Set(const int value) {
+ T *src = TopLeftPixel();
+ for (int height = 0; height < height_; ++height) {
+ for (int width = 0; width < width_; ++width) {
+ src[width] = value;
+ }
+ src += stride();
+ }
+}
+
+template <typename T>
+void Buffer<T>::DumpBuffer() const {
+ for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
+ ++height) {
+ for (int width = 0; width < stride(); ++width) {
+ printf("%4d", raw_buffer_[height + width * stride()]);
+ }
+ printf("\n");
+ }
+}
+
+template <typename T>
+bool Buffer<T>::HasPadding() const {
+ return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
+}
+
+template <typename T>
+void Buffer<T>::SetPadding(const int padding_value) {
+ padding_value_ = padding_value;
+
+ T *src = raw_buffer_;
+ for (int i = 0; i < raw_size_; ++i) {
+ src[i] = padding_value;
+ }
+}
+
+template <typename T>
+bool Buffer<T>::CheckValues(const int value) const {
+ T *src = TopLeftPixel();
+ for (int height = 0; height < height_; ++height) {
+ for (int width = 0; width < width_; ++width) {
+ if (value != src[width]) {
+ return false;
+ }
+ }
+ src += stride();
+ }
+ return true;
+}
+
+template <typename T>
+bool Buffer<T>::CheckPadding() const {
+ if (!HasPadding()) {
+ return true;
+ }
+
+ // Top padding.
+ T const *top = raw_buffer_;
+ for (int i = 0; i < stride() * top_padding_; ++i) {
+ if (padding_value_ != top[i]) {
+ return false;
+ }
+ }
+
+ // Left padding.
+ T const *left = TopLeftPixel() - left_padding_;
+ for (int height = 0; height < height_; ++height) {
+ for (int width = 0; width < left_padding_; ++width) {
+ if (padding_value_ != left[width]) {
+ return false;
+ }
+ }
+ left += stride();
+ }
+
+ // Right padding.
+ T const *right = TopLeftPixel() + width_;
+ for (int height = 0; height < height_; ++height) {
+ for (int width = 0; width < right_padding_; ++width) {
+ if (padding_value_ != right[width]) {
+ return false;
+ }
+ }
+ right += stride();
+ }
+
+ // Bottom padding
+ T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride();
+ for (int i = 0; i < stride() * bottom_padding_; ++i) {
+ if (padding_value_ != bottom[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+} // namespace libvpx_test
+#endif // TEST_BUFFER_H_
--- a/test/idct_test.cc
+++ b/test/idct_test.cc
@@ -13,6 +13,7 @@
#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "test/buffer.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "vpx/vpx_integer.h"
@@ -21,110 +22,148 @@
int pred_stride, unsigned char *dst_ptr,
int dst_stride);
namespace {
+
+using libvpx_test::Buffer;
+
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
protected:
virtual void SetUp() {
- int i;
-
UUT = GetParam();
- memset(input, 0, sizeof(input));
- /* Set up guard blocks */
- for (i = 0; i < 256; i++) output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1;
+
+ input = new (std::nothrow) Buffer<int16_t>(4, 4, 0);
+ ASSERT_TRUE(input != NULL);
+ predict = new (std::nothrow) Buffer<uint8_t>(4, 4, 3);
+ ASSERT_TRUE(predict != NULL);
+ output = new (std::nothrow) Buffer<uint8_t>(4, 4, 3);
+ ASSERT_TRUE(output != NULL);
}
- virtual void TearDown() { libvpx_test::ClearSystemState(); }
+ virtual void TearDown() {
+ delete input;
+ delete predict;
+ delete output;
+ libvpx_test::ClearSystemState();
+ }
IdctFunc UUT;
- int16_t input[16];
- unsigned char output[256];
- unsigned char predict[256];
+ Buffer<int16_t> *input;
+ Buffer<uint8_t> *predict;
+ Buffer<uint8_t> *output;
};
-TEST_P(IDCTTest, TestGuardBlocks) {
- int i;
-
- for (i = 0; i < 256; i++) {
- if ((i & 0xF) < 4 && i < 64)
- EXPECT_EQ(0, output[i]) << i;
- else
- EXPECT_EQ(255, output[i]);
- }
-}
-
TEST_P(IDCTTest, TestAllZeros) {
- int i;
+ // When the input is '0' the output will be '0'.
+ input->Set(0);
+ predict->Set(0);
+ output->Set(0);
- ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
+ ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
+ predict->stride(), output->TopLeftPixel(),
+ output->stride()));
- for (i = 0; i < 256; i++) {
- if ((i & 0xF) < 4 && i < 64)
- EXPECT_EQ(0, output[i]) << "i==" << i;
- else
- EXPECT_EQ(255, output[i]) << "i==" << i;
- }
+ ASSERT_TRUE(input->CheckValues(0));
+ ASSERT_TRUE(input->CheckPadding());
+ ASSERT_TRUE(output->CheckValues(0));
+ ASSERT_TRUE(output->CheckPadding());
}
TEST_P(IDCTTest, TestAllOnes) {
- int i;
+ input->Set(0);
+ // When the first element is '4' it will fill the output buffer with '1'.
+ input->TopLeftPixel()[0] = 4;
+ predict->Set(0);
+ output->Set(0);
- input[0] = 4;
- ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
+ ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
+ predict->stride(), output->TopLeftPixel(),
+ output->stride()));
- for (i = 0; i < 256; i++) {
- if ((i & 0xF) < 4 && i < 64)
- EXPECT_EQ(1, output[i]) << "i==" << i;
- else
- EXPECT_EQ(255, output[i]) << "i==" << i;
- }
+ ASSERT_TRUE(output->CheckValues(1));
+ ASSERT_TRUE(output->CheckPadding());
}
TEST_P(IDCTTest, TestAddOne) {
- int i;
+ // Set the transform output to '1' and make sure it gets added to the
+ // prediction buffer.
+ input->Set(0);
+ input->TopLeftPixel()[0] = 4;
+ output->Set(0);
- for (i = 0; i < 256; i++) predict[i] = i;
- input[0] = 4;
- ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
+ uint8_t *pred = predict->TopLeftPixel();
+ for (int y = 0; y < 4; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ pred[y * predict->stride() + x] = y * 4 + x;
+ }
+ }
- for (i = 0; i < 256; i++) {
- if ((i & 0xF) < 4 && i < 64)
- EXPECT_EQ(i + 1, output[i]) << "i==" << i;
- else
- EXPECT_EQ(255, output[i]) << "i==" << i;
+ ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
+ predict->stride(), output->TopLeftPixel(),
+ output->stride()));
+
+ uint8_t const *out = output->TopLeftPixel();
+ for (int y = 0; y < 4; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
+ }
}
+
+ if (HasFailure()) {
+ output->DumpBuffer();
+ }
+
+ ASSERT_TRUE(output->CheckPadding());
}
TEST_P(IDCTTest, TestWithData) {
- int i;
+ // Test a single known input.
+ predict->Set(0);
- for (i = 0; i < 16; i++) input[i] = i;
+ int16_t *in = input->TopLeftPixel();
+ for (int y = 0; y < 4; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ in[y * input->stride() + x] = y * 4 + x;
+ }
+ }
- ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
+ ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
+ predict->stride(), output->TopLeftPixel(),
+ output->stride()));
- for (i = 0; i < 256; i++) {
- if ((i & 0xF) > 3 || i > 63)
- EXPECT_EQ(255, output[i]) << "i==" << i;
- else if (i == 0)
- EXPECT_EQ(11, output[i]) << "i==" << i;
- else if (i == 34)
- EXPECT_EQ(1, output[i]) << "i==" << i;
- else if (i == 2 || i == 17 || i == 32)
- EXPECT_EQ(3, output[i]) << "i==" << i;
- else
- EXPECT_EQ(0, output[i]) << "i==" << i;
+ uint8_t *out = output->TopLeftPixel();
+ for (int y = 0; y < 4; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ switch (y * 4 + x) {
+ case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
+ case 2:
+ case 5:
+ case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
+ case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
+ default: EXPECT_EQ(0, out[y * output->stride() + x]);
+ }
+ }
}
+
+ if (HasFailure()) {
+ output->DumpBuffer();
+ }
+
+ ASSERT_TRUE(output->CheckPadding());
}
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
+
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, IDCTTest,
::testing::Values(vp8_short_idct4x4llm_neon));
-#endif
+#endif // HAVE_NEON
+
#if HAVE_MMX
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
::testing::Values(vp8_short_idct4x4llm_mmx));
-#endif
+#endif // HAVE_MMX
+
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
::testing::Values(vp8_short_idct4x4llm_msa));
-#endif
+#endif // HAVE_MSA
}
--- a/test/test.mk
+++ b/test/test.mk
@@ -1,4 +1,5 @@
LIBVPX_TEST_SRCS-yes += acm_random.h
+LIBVPX_TEST_SRCS-yes += buffer.h
LIBVPX_TEST_SRCS-yes += clear_system_state.h
LIBVPX_TEST_SRCS-yes += codec_factory.h
LIBVPX_TEST_SRCS-yes += md5_helper.h