10a39d0a697ff3603e8c100300fda363658e10b23James Zern/* 20a39d0a697ff3603e8c100300fda363658e10b23James Zern * Copyright (c) 2016 The WebM project authors. All Rights Reserved. 30a39d0a697ff3603e8c100300fda363658e10b23James Zern * 40a39d0a697ff3603e8c100300fda363658e10b23James Zern * Use of this source code is governed by a BSD-style license 50a39d0a697ff3603e8c100300fda363658e10b23James Zern * that can be found in the LICENSE file in the root of the source 60a39d0a697ff3603e8c100300fda363658e10b23James Zern * tree. An additional intellectual property rights grant can be found 70a39d0a697ff3603e8c100300fda363658e10b23James Zern * in the file PATENTS. All contributing project authors may 80a39d0a697ff3603e8c100300fda363658e10b23James Zern * be found in the AUTHORS file in the root of the source tree. 90a39d0a697ff3603e8c100300fda363658e10b23James Zern */ 100a39d0a697ff3603e8c100300fda363658e10b23James Zern 11df37111358d02836cb29bbcb9c6e4c95dff90a16Johann#include <limits> 12df37111358d02836cb29bbcb9c6e4c95dff90a16Johann 130a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "third_party/googletest/src/include/gtest/gtest.h" 140a39d0a697ff3603e8c100300fda363658e10b23James Zern 150a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "./vp9_rtcd.h" 160a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "test/acm_random.h" 170a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "test/buffer.h" 180a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "test/register_state_check.h" 190a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "vpx_ports/vpx_timer.h" 200a39d0a697ff3603e8c100300fda363658e10b23James Zern 210a39d0a697ff3603e8c100300fda363658e10b23James Zernnamespace { 220a39d0a697ff3603e8c100300fda363658e10b23James Zern 230a39d0a697ff3603e8c100300fda363658e10b23James Zernusing ::libvpx_test::ACMRandom; 240a39d0a697ff3603e8c100300fda363658e10b23James Zernusing ::libvpx_test::Buffer; 250a39d0a697ff3603e8c100300fda363658e10b23James Zern 260a39d0a697ff3603e8c100300fda363658e10b23James Zerntypedef void (*TemporalFilterFunc)(const uint8_t *a, unsigned int stride, 270a39d0a697ff3603e8c100300fda363658e10b23James Zern const uint8_t *b, unsigned int w, 280a39d0a697ff3603e8c100300fda363658e10b23James Zern unsigned int h, int filter_strength, 290a39d0a697ff3603e8c100300fda363658e10b23James Zern int filter_weight, unsigned int *accumulator, 300a39d0a697ff3603e8c100300fda363658e10b23James Zern uint16_t *count); 310a39d0a697ff3603e8c100300fda363658e10b23James Zern 320a39d0a697ff3603e8c100300fda363658e10b23James Zern// Calculate the difference between 'a' and 'b', sum in blocks of 9, and apply 330a39d0a697ff3603e8c100300fda363658e10b23James Zern// filter based on strength and weight. Store the resulting filter amount in 340a39d0a697ff3603e8c100300fda363658e10b23James Zern// 'count' and apply it to 'b' and store it in 'accumulator'. 350a39d0a697ff3603e8c100300fda363658e10b23James Zernvoid reference_filter(const Buffer<uint8_t> &a, const Buffer<uint8_t> &b, int w, 360a39d0a697ff3603e8c100300fda363658e10b23James Zern int h, int filter_strength, int filter_weight, 370a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> *accumulator, 380a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> *count) { 390a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<int> diff_sq = Buffer<int>(w, h, 0); 40df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(diff_sq.Init()); 410a39d0a697ff3603e8c100300fda363658e10b23James Zern diff_sq.Set(0); 420a39d0a697ff3603e8c100300fda363658e10b23James Zern 430a39d0a697ff3603e8c100300fda363658e10b23James Zern int rounding = 0; 440a39d0a697ff3603e8c100300fda363658e10b23James Zern if (filter_strength > 0) { 450a39d0a697ff3603e8c100300fda363658e10b23James Zern rounding = 1 << (filter_strength - 1); 460a39d0a697ff3603e8c100300fda363658e10b23James Zern } 470a39d0a697ff3603e8c100300fda363658e10b23James Zern 480a39d0a697ff3603e8c100300fda363658e10b23James Zern // Calculate all the differences. Avoids re-calculating a bunch of extra 490a39d0a697ff3603e8c100300fda363658e10b23James Zern // values. 500a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int height = 0; height < h; ++height) { 510a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int width = 0; width < w; ++width) { 520a39d0a697ff3603e8c100300fda363658e10b23James Zern int diff = a.TopLeftPixel()[height * a.stride() + width] - 530a39d0a697ff3603e8c100300fda363658e10b23James Zern b.TopLeftPixel()[height * b.stride() + width]; 540a39d0a697ff3603e8c100300fda363658e10b23James Zern diff_sq.TopLeftPixel()[height * diff_sq.stride() + width] = diff * diff; 550a39d0a697ff3603e8c100300fda363658e10b23James Zern } 560a39d0a697ff3603e8c100300fda363658e10b23James Zern } 570a39d0a697ff3603e8c100300fda363658e10b23James Zern 580a39d0a697ff3603e8c100300fda363658e10b23James Zern // For any given point, sum the neighboring values and calculate the 590a39d0a697ff3603e8c100300fda363658e10b23James Zern // modifier. 600a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int height = 0; height < h; ++height) { 610a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int width = 0; width < w; ++width) { 620a39d0a697ff3603e8c100300fda363658e10b23James Zern // Determine how many values are being summed. 630a39d0a697ff3603e8c100300fda363658e10b23James Zern int summed_values = 9; 640a39d0a697ff3603e8c100300fda363658e10b23James Zern 650a39d0a697ff3603e8c100300fda363658e10b23James Zern if (height == 0 || height == (h - 1)) { 660a39d0a697ff3603e8c100300fda363658e10b23James Zern summed_values -= 3; 670a39d0a697ff3603e8c100300fda363658e10b23James Zern } 680a39d0a697ff3603e8c100300fda363658e10b23James Zern 690a39d0a697ff3603e8c100300fda363658e10b23James Zern if (width == 0 || width == (w - 1)) { 700a39d0a697ff3603e8c100300fda363658e10b23James Zern if (summed_values == 6) { // corner 710a39d0a697ff3603e8c100300fda363658e10b23James Zern summed_values -= 2; 720a39d0a697ff3603e8c100300fda363658e10b23James Zern } else { 730a39d0a697ff3603e8c100300fda363658e10b23James Zern summed_values -= 3; 740a39d0a697ff3603e8c100300fda363658e10b23James Zern } 750a39d0a697ff3603e8c100300fda363658e10b23James Zern } 760a39d0a697ff3603e8c100300fda363658e10b23James Zern 770a39d0a697ff3603e8c100300fda363658e10b23James Zern // Sum the diff_sq of the surrounding values. 780a39d0a697ff3603e8c100300fda363658e10b23James Zern int sum = 0; 790a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int idy = -1; idy <= 1; ++idy) { 800a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int idx = -1; idx <= 1; ++idx) { 810a39d0a697ff3603e8c100300fda363658e10b23James Zern const int y = height + idy; 820a39d0a697ff3603e8c100300fda363658e10b23James Zern const int x = width + idx; 830a39d0a697ff3603e8c100300fda363658e10b23James Zern 840a39d0a697ff3603e8c100300fda363658e10b23James Zern // If inside the border. 850a39d0a697ff3603e8c100300fda363658e10b23James Zern if (y >= 0 && y < h && x >= 0 && x < w) { 860a39d0a697ff3603e8c100300fda363658e10b23James Zern sum += diff_sq.TopLeftPixel()[y * diff_sq.stride() + x]; 870a39d0a697ff3603e8c100300fda363658e10b23James Zern } 880a39d0a697ff3603e8c100300fda363658e10b23James Zern } 890a39d0a697ff3603e8c100300fda363658e10b23James Zern } 900a39d0a697ff3603e8c100300fda363658e10b23James Zern 910a39d0a697ff3603e8c100300fda363658e10b23James Zern sum *= 3; 920a39d0a697ff3603e8c100300fda363658e10b23James Zern sum /= summed_values; 930a39d0a697ff3603e8c100300fda363658e10b23James Zern sum += rounding; 940a39d0a697ff3603e8c100300fda363658e10b23James Zern sum >>= filter_strength; 950a39d0a697ff3603e8c100300fda363658e10b23James Zern 960a39d0a697ff3603e8c100300fda363658e10b23James Zern // Clamp the value and invert it. 970a39d0a697ff3603e8c100300fda363658e10b23James Zern if (sum > 16) sum = 16; 980a39d0a697ff3603e8c100300fda363658e10b23James Zern sum = 16 - sum; 990a39d0a697ff3603e8c100300fda363658e10b23James Zern 1000a39d0a697ff3603e8c100300fda363658e10b23James Zern sum *= filter_weight; 1010a39d0a697ff3603e8c100300fda363658e10b23James Zern 1020a39d0a697ff3603e8c100300fda363658e10b23James Zern count->TopLeftPixel()[height * count->stride() + width] += sum; 1030a39d0a697ff3603e8c100300fda363658e10b23James Zern accumulator->TopLeftPixel()[height * accumulator->stride() + width] += 1040a39d0a697ff3603e8c100300fda363658e10b23James Zern sum * b.TopLeftPixel()[height * b.stride() + width]; 1050a39d0a697ff3603e8c100300fda363658e10b23James Zern } 1060a39d0a697ff3603e8c100300fda363658e10b23James Zern } 1070a39d0a697ff3603e8c100300fda363658e10b23James Zern} 1080a39d0a697ff3603e8c100300fda363658e10b23James Zern 1090a39d0a697ff3603e8c100300fda363658e10b23James Zernclass TemporalFilterTest : public ::testing::TestWithParam<TemporalFilterFunc> { 1100a39d0a697ff3603e8c100300fda363658e10b23James Zern public: 1110a39d0a697ff3603e8c100300fda363658e10b23James Zern virtual void SetUp() { 1120a39d0a697ff3603e8c100300fda363658e10b23James Zern filter_func_ = GetParam(); 1130a39d0a697ff3603e8c100300fda363658e10b23James Zern rnd_.Reset(ACMRandom::DeterministicSeed()); 1140a39d0a697ff3603e8c100300fda363658e10b23James Zern } 1150a39d0a697ff3603e8c100300fda363658e10b23James Zern 1160a39d0a697ff3603e8c100300fda363658e10b23James Zern protected: 1170a39d0a697ff3603e8c100300fda363658e10b23James Zern TemporalFilterFunc filter_func_; 1180a39d0a697ff3603e8c100300fda363658e10b23James Zern ACMRandom rnd_; 1190a39d0a697ff3603e8c100300fda363658e10b23James Zern}; 1200a39d0a697ff3603e8c100300fda363658e10b23James Zern 1210a39d0a697ff3603e8c100300fda363658e10b23James ZernTEST_P(TemporalFilterTest, SizeCombinations) { 1220a39d0a697ff3603e8c100300fda363658e10b23James Zern // Depending on subsampling this function may be called with values of 8 or 16 1230a39d0a697ff3603e8c100300fda363658e10b23James Zern // for width and height, in any combination. 1240a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint8_t> a = Buffer<uint8_t>(16, 16, 8); 125df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(a.Init()); 1260a39d0a697ff3603e8c100300fda363658e10b23James Zern 1270a39d0a697ff3603e8c100300fda363658e10b23James Zern const int filter_weight = 2; 1280a39d0a697ff3603e8c100300fda363658e10b23James Zern const int filter_strength = 6; 1290a39d0a697ff3603e8c100300fda363658e10b23James Zern 1300a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int width = 8; width <= 16; width += 8) { 1310a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int height = 8; height <= 16; height += 8) { 1320a39d0a697ff3603e8c100300fda363658e10b23James Zern // The second buffer must not have any border. 1330a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0); 134df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(b.Init()); 1350a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0); 136df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(accum_ref.Init()); 1370a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0); 138df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(accum_chk.Init()); 1390a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0); 140df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(count_ref.Init()); 1410a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0); 142df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(count_chk.Init()); 1430a39d0a697ff3603e8c100300fda363658e10b23James Zern 144df37111358d02836cb29bbcb9c6e4c95dff90a16Johann // The difference between the buffers must be small to pass the threshold 145df37111358d02836cb29bbcb9c6e4c95dff90a16Johann // to apply the filter. 146df37111358d02836cb29bbcb9c6e4c95dff90a16Johann a.Set(&rnd_, 0, 7); 147df37111358d02836cb29bbcb9c6e4c95dff90a16Johann b.Set(&rnd_, 0, 7); 1480a39d0a697ff3603e8c100300fda363658e10b23James Zern 1490a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_ref.Set(rnd_.Rand8()); 1500a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.CopyFrom(accum_ref); 1510a39d0a697ff3603e8c100300fda363658e10b23James Zern count_ref.Set(rnd_.Rand8()); 1520a39d0a697ff3603e8c100300fda363658e10b23James Zern count_chk.CopyFrom(count_ref); 1530a39d0a697ff3603e8c100300fda363658e10b23James Zern reference_filter(a, b, width, height, filter_strength, filter_weight, 1540a39d0a697ff3603e8c100300fda363658e10b23James Zern &accum_ref, &count_ref); 1550a39d0a697ff3603e8c100300fda363658e10b23James Zern ASM_REGISTER_STATE_CHECK( 1560a39d0a697ff3603e8c100300fda363658e10b23James Zern filter_func_(a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width, 1570a39d0a697ff3603e8c100300fda363658e10b23James Zern height, filter_strength, filter_weight, 1580a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.TopLeftPixel(), count_chk.TopLeftPixel())); 1590a39d0a697ff3603e8c100300fda363658e10b23James Zern EXPECT_TRUE(accum_chk.CheckValues(accum_ref)); 1600a39d0a697ff3603e8c100300fda363658e10b23James Zern EXPECT_TRUE(count_chk.CheckValues(count_ref)); 1610a39d0a697ff3603e8c100300fda363658e10b23James Zern if (HasFailure()) { 1620a39d0a697ff3603e8c100300fda363658e10b23James Zern printf("Width: %d Height: %d\n", width, height); 1630a39d0a697ff3603e8c100300fda363658e10b23James Zern count_chk.PrintDifference(count_ref); 1640a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.PrintDifference(accum_ref); 1650a39d0a697ff3603e8c100300fda363658e10b23James Zern return; 1660a39d0a697ff3603e8c100300fda363658e10b23James Zern } 1670a39d0a697ff3603e8c100300fda363658e10b23James Zern } 1680a39d0a697ff3603e8c100300fda363658e10b23James Zern } 1690a39d0a697ff3603e8c100300fda363658e10b23James Zern} 1700a39d0a697ff3603e8c100300fda363658e10b23James Zern 1710a39d0a697ff3603e8c100300fda363658e10b23James ZernTEST_P(TemporalFilterTest, CompareReferenceRandom) { 1720a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int width = 8; width <= 16; width += 8) { 1730a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int height = 8; height <= 16; height += 8) { 1740a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint8_t> a = Buffer<uint8_t>(width, height, 8); 175df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(a.Init()); 1760a39d0a697ff3603e8c100300fda363658e10b23James Zern // The second buffer must not have any border. 1770a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0); 178df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(b.Init()); 1790a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0); 180df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(accum_ref.Init()); 1810a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0); 182df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(accum_chk.Init()); 1830a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0); 184df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(count_ref.Init()); 1850a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0); 186df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(count_chk.Init()); 1870a39d0a697ff3603e8c100300fda363658e10b23James Zern 1880a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int filter_strength = 0; filter_strength <= 6; ++filter_strength) { 1890a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int filter_weight = 0; filter_weight <= 2; ++filter_weight) { 190df37111358d02836cb29bbcb9c6e4c95dff90a16Johann for (int repeat = 0; repeat < 100; ++repeat) { 191df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (repeat < 50) { 192df37111358d02836cb29bbcb9c6e4c95dff90a16Johann a.Set(&rnd_, 0, 7); 193df37111358d02836cb29bbcb9c6e4c95dff90a16Johann b.Set(&rnd_, 0, 7); 194df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } else { 195df37111358d02836cb29bbcb9c6e4c95dff90a16Johann // Check large (but close) values as well. 196df37111358d02836cb29bbcb9c6e4c95dff90a16Johann a.Set(&rnd_, std::numeric_limits<uint8_t>::max() - 7, 197df37111358d02836cb29bbcb9c6e4c95dff90a16Johann std::numeric_limits<uint8_t>::max()); 198df37111358d02836cb29bbcb9c6e4c95dff90a16Johann b.Set(&rnd_, std::numeric_limits<uint8_t>::max() - 7, 199df37111358d02836cb29bbcb9c6e4c95dff90a16Johann std::numeric_limits<uint8_t>::max()); 200df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 2010a39d0a697ff3603e8c100300fda363658e10b23James Zern 2020a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_ref.Set(rnd_.Rand8()); 2030a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.CopyFrom(accum_ref); 2040a39d0a697ff3603e8c100300fda363658e10b23James Zern count_ref.Set(rnd_.Rand8()); 2050a39d0a697ff3603e8c100300fda363658e10b23James Zern count_chk.CopyFrom(count_ref); 2060a39d0a697ff3603e8c100300fda363658e10b23James Zern reference_filter(a, b, width, height, filter_strength, 2070a39d0a697ff3603e8c100300fda363658e10b23James Zern filter_weight, &accum_ref, &count_ref); 2080a39d0a697ff3603e8c100300fda363658e10b23James Zern ASM_REGISTER_STATE_CHECK(filter_func_( 2090a39d0a697ff3603e8c100300fda363658e10b23James Zern a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width, height, 2100a39d0a697ff3603e8c100300fda363658e10b23James Zern filter_strength, filter_weight, accum_chk.TopLeftPixel(), 2110a39d0a697ff3603e8c100300fda363658e10b23James Zern count_chk.TopLeftPixel())); 2120a39d0a697ff3603e8c100300fda363658e10b23James Zern EXPECT_TRUE(accum_chk.CheckValues(accum_ref)); 2130a39d0a697ff3603e8c100300fda363658e10b23James Zern EXPECT_TRUE(count_chk.CheckValues(count_ref)); 2140a39d0a697ff3603e8c100300fda363658e10b23James Zern if (HasFailure()) { 2150a39d0a697ff3603e8c100300fda363658e10b23James Zern printf("Weight: %d Strength: %d\n", filter_weight, 2160a39d0a697ff3603e8c100300fda363658e10b23James Zern filter_strength); 2170a39d0a697ff3603e8c100300fda363658e10b23James Zern count_chk.PrintDifference(count_ref); 2180a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.PrintDifference(accum_ref); 2190a39d0a697ff3603e8c100300fda363658e10b23James Zern return; 2200a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2210a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2220a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2230a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2240a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2250a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2260a39d0a697ff3603e8c100300fda363658e10b23James Zern} 2270a39d0a697ff3603e8c100300fda363658e10b23James Zern 2280a39d0a697ff3603e8c100300fda363658e10b23James ZernTEST_P(TemporalFilterTest, DISABLED_Speed) { 2290a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint8_t> a = Buffer<uint8_t>(16, 16, 8); 230df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(a.Init()); 2310a39d0a697ff3603e8c100300fda363658e10b23James Zern 2320a39d0a697ff3603e8c100300fda363658e10b23James Zern const int filter_weight = 2; 2330a39d0a697ff3603e8c100300fda363658e10b23James Zern const int filter_strength = 6; 2340a39d0a697ff3603e8c100300fda363658e10b23James Zern 2350a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int width = 8; width <= 16; width += 8) { 2360a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int height = 8; height <= 16; height += 8) { 2370a39d0a697ff3603e8c100300fda363658e10b23James Zern // The second buffer must not have any border. 2380a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0); 239df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(b.Init()); 2400a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0); 241df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(accum_ref.Init()); 2420a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0); 243df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(accum_chk.Init()); 2440a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0); 245df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(count_ref.Init()); 2460a39d0a697ff3603e8c100300fda363658e10b23James Zern Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0); 247df37111358d02836cb29bbcb9c6e4c95dff90a16Johann ASSERT_TRUE(count_chk.Init()); 2480a39d0a697ff3603e8c100300fda363658e10b23James Zern 249df37111358d02836cb29bbcb9c6e4c95dff90a16Johann a.Set(&rnd_, 0, 7); 250df37111358d02836cb29bbcb9c6e4c95dff90a16Johann b.Set(&rnd_, 0, 7); 2510a39d0a697ff3603e8c100300fda363658e10b23James Zern 2520a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.Set(0); 2530a39d0a697ff3603e8c100300fda363658e10b23James Zern count_chk.Set(0); 2540a39d0a697ff3603e8c100300fda363658e10b23James Zern 2550a39d0a697ff3603e8c100300fda363658e10b23James Zern vpx_usec_timer timer; 2560a39d0a697ff3603e8c100300fda363658e10b23James Zern vpx_usec_timer_start(&timer); 2570a39d0a697ff3603e8c100300fda363658e10b23James Zern for (int i = 0; i < 10000; ++i) { 2580a39d0a697ff3603e8c100300fda363658e10b23James Zern filter_func_(a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width, 2590a39d0a697ff3603e8c100300fda363658e10b23James Zern height, filter_strength, filter_weight, 2600a39d0a697ff3603e8c100300fda363658e10b23James Zern accum_chk.TopLeftPixel(), count_chk.TopLeftPixel()); 2610a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2620a39d0a697ff3603e8c100300fda363658e10b23James Zern vpx_usec_timer_mark(&timer); 2630a39d0a697ff3603e8c100300fda363658e10b23James Zern const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer)); 2640a39d0a697ff3603e8c100300fda363658e10b23James Zern printf("Temporal filter %dx%d time: %5d us\n", width, height, 2650a39d0a697ff3603e8c100300fda363658e10b23James Zern elapsed_time); 2660a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2670a39d0a697ff3603e8c100300fda363658e10b23James Zern } 2680a39d0a697ff3603e8c100300fda363658e10b23James Zern} 2690a39d0a697ff3603e8c100300fda363658e10b23James Zern 2700a39d0a697ff3603e8c100300fda363658e10b23James ZernINSTANTIATE_TEST_CASE_P(C, TemporalFilterTest, 2710a39d0a697ff3603e8c100300fda363658e10b23James Zern ::testing::Values(&vp9_temporal_filter_apply_c)); 2720a39d0a697ff3603e8c100300fda363658e10b23James Zern 2730a39d0a697ff3603e8c100300fda363658e10b23James Zern#if HAVE_SSE4_1 2740a39d0a697ff3603e8c100300fda363658e10b23James ZernINSTANTIATE_TEST_CASE_P(SSE4_1, TemporalFilterTest, 2750a39d0a697ff3603e8c100300fda363658e10b23James Zern ::testing::Values(&vp9_temporal_filter_apply_sse4_1)); 2760a39d0a697ff3603e8c100300fda363658e10b23James Zern#endif // HAVE_SSE4_1 2770a39d0a697ff3603e8c100300fda363658e10b23James Zern} // namespace 278