/* * Copyright (c) 2024, Alliance for Open Media. All rights reserved * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ #include "config/av1_rtcd.h" #include "test/acm_random.h" #include "test/util.h" #include "aom_ports/aom_timer.h" #include "aom_ports/bitops.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" namespace { using ::testing::Combine; using ::testing::Values; using ::testing::ValuesIn; using std::make_tuple; using std::tuple; const int kIters = 1000; typedef tuple FrameDimension; // Resolutions (width x height) to be tested for resizing. const FrameDimension kFrameDim[] = { make_tuple(3840, 2160), make_tuple(2560, 1440), make_tuple(1920, 1080), make_tuple(1280, 720), make_tuple(640, 480), make_tuple(640, 360), make_tuple(256, 256), }; // Check that two 8-bit output buffers are identical. void AssertOutputBufferEq(const uint8_t *p1, const uint8_t *p2, int width, int height) { ASSERT_TRUE(p1 != p2) << "Buffers must be at different memory locations"; for (int j = 0; j < height; ++j) { if (memcmp(p1, p2, sizeof(*p1) * width) == 0) { p1 += width; p2 += width; continue; } for (int i = 0; i < width; ++i) { ASSERT_EQ(p1[i], p2[i]) << width << "x" << height << " Pixel mismatch at (" << i << ", " << j << ")"; } } } typedef bool (*LowBDResizeFunc)(uint8_t *intbuf, uint8_t *output, int out_stride, int height, int height2, int stride, int start_wd); // Test parameter list: // typedef tuple ResizeTestParams; class AV1ResizeYTest : public ::testing::TestWithParam { public: void SetUp() { test_fun_ = GET_PARAM(0); frame_dim_ = GET_PARAM(1); width_ = std::get<0>(frame_dim_); height_ = std::get<1>(frame_dim_); const int msb = get_msb(AOMMIN(width_, height_)); n_levels_ = AOMMAX(msb - MIN_PYRAMID_SIZE_LOG2, 1); src_ = (uint8_t *)aom_malloc((width_ / 2) * height_ * sizeof(*src_)); ref_dest_ = (uint8_t *)aom_calloc((width_ * height_) / 4, sizeof(*ref_dest_)); test_dest_ = (uint8_t *)aom_calloc((width_ * height_) / 4, sizeof(*test_dest_)); } void RunTest() { int width2 = width_, height2 = height_; for (int i = 0; i < (width_ / 2) * height_; i++) src_[i] = rng_.Rand8(); for (int level = 1; level < n_levels_; level++) { width2 = (width_ >> level); height2 = (height_ >> level); resize_vert_dir_c(src_, ref_dest_, width2, height2 << 1, height2, width2, 0); test_fun_(src_, test_dest_, width2, height2 << 1, height2, width2, 0); AssertOutputBufferEq(ref_dest_, test_dest_, width2, height2); } } void SpeedTest() { int width2 = width_, height2 = height_; for (int i = 0; i < (width_ / 2) * height_; i++) src_[i] = rng_.Rand8(); for (int level = 1; level < n_levels_; level++) { width2 = (width_ >> level); height2 = (height_ >> level); aom_usec_timer ref_timer; aom_usec_timer_start(&ref_timer); for (int j = 0; j < kIters; j++) { resize_vert_dir_c(src_, ref_dest_, width2, height2 << 1, height2, width2, 0); } aom_usec_timer_mark(&ref_timer); const int64_t ref_time = aom_usec_timer_elapsed(&ref_timer); aom_usec_timer tst_timer; aom_usec_timer_start(&tst_timer); for (int j = 0; j < kIters; j++) { test_fun_(src_, test_dest_, width2, height2 << 1, height2, width2, 0); } aom_usec_timer_mark(&tst_timer); const int64_t tst_time = aom_usec_timer_elapsed(&tst_timer); std::cout << "level: " << level << " [" << width2 << " x " << height2 << "] C time = " << ref_time << " , SIMD time = " << tst_time << " scaling=" << float(1.00) * ref_time / tst_time << "x \n"; } } void TearDown() { aom_free(src_); aom_free(ref_dest_); aom_free(test_dest_); } private: LowBDResizeFunc test_fun_; FrameDimension frame_dim_; int width_; int height_; int n_levels_; uint8_t *src_; uint8_t *ref_dest_; uint8_t *test_dest_; libaom_test::ACMRandom rng_; }; GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AV1ResizeYTest); TEST_P(AV1ResizeYTest, RunTest) { RunTest(); } TEST_P(AV1ResizeYTest, DISABLED_SpeedTest) { SpeedTest(); } #if HAVE_AVX2 INSTANTIATE_TEST_SUITE_P( AVX2, AV1ResizeYTest, ::testing::Combine(::testing::Values(resize_vert_dir_avx2), ::testing::ValuesIn(kFrameDim))); #endif } // namespace