summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/blockiness_test.cc5
-rw-r--r--test/convolve_test.cc6
-rw-r--r--test/external_frame_buffer_test.cc8
-rw-r--r--test/invalid_file_test.cc4
-rw-r--r--test/test-data.mk12
-rw-r--r--test/test-data.sha112
-rw-r--r--test/test.mk1
-rw-r--r--test/vp9_end_to_end_test.cc14
-rw-r--r--test/vp9_ethread_test.cc2
-rw-r--r--test/vp9_intrapred_test.cc6
-rw-r--r--test/y4m_test.cc24
-rw-r--r--test/yuv_temporal_filter_test.cc697
12 files changed, 749 insertions, 42 deletions
diff --git a/test/blockiness_test.cc b/test/blockiness_test.cc
index 38b4b5886..128b50397 100644
--- a/test/blockiness_test.cc
+++ b/test/blockiness_test.cc
@@ -26,10 +26,7 @@
#include "test/util.h"
#include "vpx_mem/vpx_mem.h"
-
-extern "C" double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
- const unsigned char *img2, int img2_pitch,
- int width, int height);
+#include "vp9/encoder/vp9_blockiness.h"
using libvpx_test::ACMRandom;
diff --git a/test/convolve_test.cc b/test/convolve_test.cc
index 02cc7ff5c..cef602eec 100644
--- a/test/convolve_test.cc
+++ b/test/convolve_test.cc
@@ -416,8 +416,14 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
for (int i = 0; i < kOutputBufferSize; ++i) {
if (IsIndexInBorder(i)) {
output_[i] = 255;
+#if CONFIG_VP9_HIGHBITDEPTH
+ output16_[i] = mask_;
+#endif
} else {
output_[i] = 0;
+#if CONFIG_VP9_HIGHBITDEPTH
+ output16_[i] = 0;
+#endif
}
}
diff --git a/test/external_frame_buffer_test.cc b/test/external_frame_buffer_test.cc
index b0ea61f9d..438eeb3ec 100644
--- a/test/external_frame_buffer_test.cc
+++ b/test/external_frame_buffer_test.cc
@@ -114,9 +114,9 @@ class ExternalFrameBufferList {
return 0;
}
- // Checks that the ximage data is contained within the external frame buffer
- // private data passed back in the ximage.
- void CheckXImageFrameBuffer(const vpx_image_t *img) {
+ // Checks that the vpx_image_t data is contained within the external frame
+ // buffer private data passed back in the vpx_image_t.
+ void CheckImageFrameBuffer(const vpx_image_t *img) {
if (img->fb_priv != NULL) {
const struct ExternalFrameBuffer *const ext_fb =
reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
@@ -342,7 +342,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
// Get decompressed data
while ((img = dec_iter.Next()) != NULL) {
- fb_list_.CheckXImageFrameBuffer(img);
+ fb_list_.CheckImageFrameBuffer(img);
}
}
diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc
index a92612af4..8eed05eb4 100644
--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -123,9 +123,9 @@ TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
#if CONFIG_VP8_DECODER
const DecodeParam kVP8InvalidFileTests[] = {
- { 1, "invalid-bug-1443-v2.ivf" },
+ { 1, "invalid-bug-1443.ivf" },
{ 1, "invalid-token-partition.ivf" },
- { 1, "invalid-vp80-00-comprehensive-s17661_r01-05_b6-.v2.ivf" },
+ { 1, "invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf" },
};
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
diff --git a/test/test-data.mk b/test/test-data.mk
index 88f3c658f..27a955760 100644
--- a/test/test-data.mk
+++ b/test/test-data.mk
@@ -6,13 +6,13 @@ LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktop_office1.1280_720-020.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += slides_code_term_web_plot.1920_1080.yuv
-LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420.y4m
-LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422.y4m
-LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444.y4m
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420_20f.y4m
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422_20f.y4m
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_440.yuv
-LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420.y4m
-LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422.y4m
-LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444.y4m
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420_20f.y4m
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422_20f.y4m
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420_a10-1.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m
diff --git a/test/test-data.sha1 b/test/test-data.sha1
index cfe4df40d..88f1e10d7 100644
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -17,13 +17,13 @@ df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
9aa21d8b2cb9d39abe8a7bb6032dc66955fb4342 *noisy_clip_640_360.y4m
-a432f96ff0a787268e2f94a8092ab161a18d1b06 *park_joy_90p_10_420.y4m
-0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
-ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
+0936b837708ae68c034719f8e07596021c2c214f *park_joy_90p_10_420_20f.y4m
+5727a853c083c1099f837d27967bc1322d50ed4f *park_joy_90p_10_422_20f.y4m
+e13489470ef8e8b2a871a5640d795a42a39be58d *park_joy_90p_10_444_20f.y4m
c934da6fb8cc54ee2a8c17c54cf6076dac37ead0 *park_joy_90p_10_440.yuv
-614c32ae1eca391e867c70d19974f0d62664dd99 *park_joy_90p_12_420.y4m
-c92825f1ea25c5c37855083a69faac6ac4641a9e *park_joy_90p_12_422.y4m
-b592189b885b6cc85db55cc98512a197d73d3b34 *park_joy_90p_12_444.y4m
+79b0dc1784635a7f291e21c4e8d66a29c496ab99 *park_joy_90p_12_420_20f.y4m
+9cf22b0f809f7464c8b9058f0cfa9d905921cbd1 *park_joy_90p_12_422_20f.y4m
+22b2a4abaecc4a9ade6bb503d25fb82367947e85 *park_joy_90p_12_444_20f.y4m
82c1bfcca368c2f22bad7d693d690d5499ecdd11 *park_joy_90p_12_440.yuv
b9e1e90aece2be6e2c90d89e6ab2372d5f8c792d *park_joy_90p_8_420_a10-1.y4m
4e0eb61e76f0684188d9bc9f3ce61f6b6b77bb2c *park_joy_90p_8_420.y4m
diff --git a/test/test.mk b/test/test.mk
index 3cf3202b8..2b7636185 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -171,6 +171,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc
ifneq ($(CONFIG_REALTIME_ONLY),yes)
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += temporal_filter_test.cc
+LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc
endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
diff --git a/test/vp9_end_to_end_test.cc b/test/vp9_end_to_end_test.cc
index 20ea83ab6..76fc5b4d8 100644
--- a/test/vp9_end_to_end_test.cc
+++ b/test/vp9_end_to_end_test.cc
@@ -24,7 +24,7 @@ namespace {
const unsigned int kWidth = 160;
const unsigned int kHeight = 90;
const unsigned int kFramerate = 50;
-const unsigned int kFrames = 10;
+const unsigned int kFrames = 20;
const int kBitrate = 500;
// List of psnr thresholds for speed settings 0-7 and 5 encoding modes
const double kPsnrThreshold[][5] = {
@@ -48,13 +48,13 @@ const TestVideoParam kTestVectors[] = {
{ "park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1 },
{ "park_joy_90p_8_440.yuv", 8, VPX_IMG_FMT_I440, VPX_BITS_8, 1 },
#if CONFIG_VP9_HIGHBITDEPTH
- { "park_joy_90p_10_420.y4m", 10, VPX_IMG_FMT_I42016, VPX_BITS_10, 2 },
- { "park_joy_90p_10_422.y4m", 10, VPX_IMG_FMT_I42216, VPX_BITS_10, 3 },
- { "park_joy_90p_10_444.y4m", 10, VPX_IMG_FMT_I44416, VPX_BITS_10, 3 },
+ { "park_joy_90p_10_420_20f.y4m", 10, VPX_IMG_FMT_I42016, VPX_BITS_10, 2 },
+ { "park_joy_90p_10_422_20f.y4m", 10, VPX_IMG_FMT_I42216, VPX_BITS_10, 3 },
+ { "park_joy_90p_10_444_20f.y4m", 10, VPX_IMG_FMT_I44416, VPX_BITS_10, 3 },
{ "park_joy_90p_10_440.yuv", 10, VPX_IMG_FMT_I44016, VPX_BITS_10, 3 },
- { "park_joy_90p_12_420.y4m", 12, VPX_IMG_FMT_I42016, VPX_BITS_12, 2 },
- { "park_joy_90p_12_422.y4m", 12, VPX_IMG_FMT_I42216, VPX_BITS_12, 3 },
- { "park_joy_90p_12_444.y4m", 12, VPX_IMG_FMT_I44416, VPX_BITS_12, 3 },
+ { "park_joy_90p_12_420_20f.y4m", 12, VPX_IMG_FMT_I42016, VPX_BITS_12, 2 },
+ { "park_joy_90p_12_422_20f.y4m", 12, VPX_IMG_FMT_I42216, VPX_BITS_12, 3 },
+ { "park_joy_90p_12_444_20f.y4m", 12, VPX_IMG_FMT_I44416, VPX_BITS_12, 3 },
{ "park_joy_90p_12_440.yuv", 12, VPX_IMG_FMT_I44016, VPX_BITS_12, 3 },
#endif // CONFIG_VP9_HIGHBITDEPTH
};
diff --git a/test/vp9_ethread_test.cc b/test/vp9_ethread_test.cc
index 44659904f..6de76e9e5 100644
--- a/test/vp9_ethread_test.cc
+++ b/test/vp9_ethread_test.cc
@@ -387,7 +387,7 @@ TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
const double multi_thr_psnr = GetAveragePsnr();
- EXPECT_NEAR(single_thr_psnr, multi_thr_psnr, 0.1);
+ EXPECT_NEAR(single_thr_psnr, multi_thr_psnr, 0.2);
}
INSTANTIATE_TEST_CASE_P(
diff --git a/test/vp9_intrapred_test.cc b/test/vp9_intrapred_test.cc
index 39c5e79eb..89b1cd86a 100644
--- a/test/vp9_intrapred_test.cc
+++ b/test/vp9_intrapred_test.cc
@@ -130,6 +130,12 @@ TEST_P(VP9IntraPredTest, IntraPredTests) {
RunTest(left_col, above_data, dst, ref_dst);
}
+// Instantiate a token test to avoid -Wuninitialized warnings when none of the
+// other tests are enabled.
+INSTANTIATE_TEST_CASE_P(
+ C, VP9IntraPredTest,
+ ::testing::Values(IntraPredParam(&vpx_d45_predictor_4x4_c,
+ &vpx_d45_predictor_4x4_c, 4, 8)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, VP9IntraPredTest,
diff --git a/test/y4m_test.cc b/test/y4m_test.cc
index ced717a7c..76d033d52 100644
--- a/test/y4m_test.cc
+++ b/test/y4m_test.cc
@@ -40,18 +40,18 @@ const Y4mTestParam kY4mTestVectors[] = {
"284a47a47133b12884ec3a14e959a0b6" },
{ "park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444,
"90517ff33843d85de712fd4fe60dbed0" },
- { "park_joy_90p_10_420.y4m", 10, VPX_IMG_FMT_I42016,
- "63f21f9f717d8b8631bd2288ee87137b" },
- { "park_joy_90p_10_422.y4m", 10, VPX_IMG_FMT_I42216,
- "48ab51fb540aed07f7ff5af130c9b605" },
- { "park_joy_90p_10_444.y4m", 10, VPX_IMG_FMT_I44416,
- "067bfd75aa85ff9bae91fa3e0edd1e3e" },
- { "park_joy_90p_12_420.y4m", 12, VPX_IMG_FMT_I42016,
- "9e6d8f6508c6e55625f6b697bc461cef" },
- { "park_joy_90p_12_422.y4m", 12, VPX_IMG_FMT_I42216,
- "b239c6b301c0b835485be349ca83a7e3" },
- { "park_joy_90p_12_444.y4m", 12, VPX_IMG_FMT_I44416,
- "5a6481a550821dab6d0192f5c63845e9" },
+ { "park_joy_90p_10_420_20f.y4m", 10, VPX_IMG_FMT_I42016,
+ "2f56ab9809269f074df7e3daf1ce0be6" },
+ { "park_joy_90p_10_422_20f.y4m", 10, VPX_IMG_FMT_I42216,
+ "1b5c73d2e8e8c4e02dc4889ecac41c83" },
+ { "park_joy_90p_10_444_20f.y4m", 10, VPX_IMG_FMT_I44416,
+ "ec4ab5be53195c5b838d1d19e1bc2674" },
+ { "park_joy_90p_12_420_20f.y4m", 12, VPX_IMG_FMT_I42016,
+ "3370856c8ddebbd1f9bb2e66f97677f4" },
+ { "park_joy_90p_12_422_20f.y4m", 12, VPX_IMG_FMT_I42216,
+ "4eab364318dd8201acbb182e43bd4966" },
+ { "park_joy_90p_12_444_20f.y4m", 12, VPX_IMG_FMT_I44416,
+ "f189dfbbd92119fc8e5f211a550166be" },
};
static void write_image_file(const vpx_image_t *img, FILE *file) {
diff --git a/test/yuv_temporal_filter_test.cc b/test/yuv_temporal_filter_test.cc
new file mode 100644
index 000000000..8d68e4abe
--- /dev/null
+++ b/test/yuv_temporal_filter_test.cc
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+#include "./vp9_rtcd.h"
+#include "test/acm_random.h"
+#include "test/buffer.h"
+#include "test/register_state_check.h"
+#include "vpx_ports/vpx_timer.h"
+
+namespace {
+
+using ::libvpx_test::ACMRandom;
+using ::libvpx_test::Buffer;
+
+typedef void (*YUVTemporalFilterFunc)(
+ const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre,
+ int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src,
+ int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre,
+ int uv_pre_stride, unsigned int block_width, unsigned int block_height,
+ int ss_x, int ss_y, int strength, const int *const blk_fw, int use_32x32,
+ uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator,
+ uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count);
+
+int GetFilterWeight(unsigned int row, unsigned int col,
+ unsigned int block_height, unsigned int block_width,
+ const int *const blk_fw, int use_32x32) {
+ if (use_32x32) {
+ return blk_fw[0];
+ }
+
+ return blk_fw[2 * (row >= block_height / 2) + (col >= block_width / 2)];
+}
+
+int GetModIndex(int sum_dist, int index, int rounding, int strength,
+ int filter_weight) {
+ unsigned int index_mult[14] = {
+ 0, 0, 0, 0, 49152, 39322, 32768, 28087, 24576, 21846, 19661, 17874, 0, 15124
+ };
+
+ assert(index >= 0 && index <= 13);
+ assert(index_mult[index] != 0);
+
+ int mod = (clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16;
+ mod += rounding;
+ mod >>= strength;
+
+ mod = VPXMIN(16, mod);
+
+ mod = 16 - mod;
+ mod *= filter_weight;
+
+ return mod;
+}
+
+void ApplyReferenceFilter(
+ const Buffer<uint8_t> &y_src, const Buffer<uint8_t> &y_pre,
+ const Buffer<uint8_t> &u_src, const Buffer<uint8_t> &v_src,
+ const Buffer<uint8_t> &u_pre, const Buffer<uint8_t> &v_pre,
+ unsigned int block_width, unsigned int block_height, int ss_x, int ss_y,
+ int strength, const int *const blk_fw, int use_32x32,
+ Buffer<uint32_t> *y_accumulator, Buffer<uint16_t> *y_count,
+ Buffer<uint32_t> *u_accumulator, Buffer<uint16_t> *u_count,
+ Buffer<uint32_t> *v_accumulator, Buffer<uint16_t> *v_count) {
+ // blk_fw means block_filter_weight
+ // Set up buffer to store squared_diffs
+ Buffer<int> y_dif = Buffer<int>(block_width, block_height, 0);
+ const int uv_block_width = block_width >> ss_x;
+ const int uv_block_height = block_height >> ss_y;
+ Buffer<int> u_dif = Buffer<int>(uv_block_width, uv_block_height, 0);
+ Buffer<int> v_dif = Buffer<int>(uv_block_width, uv_block_height, 0);
+ ASSERT_TRUE(y_dif.Init());
+ ASSERT_TRUE(u_dif.Init());
+ ASSERT_TRUE(v_dif.Init());
+ y_dif.Set(0);
+ u_dif.Set(0);
+ v_dif.Set(0);
+
+ // How many bits do we want to round
+ ASSERT_GE(strength, 0);
+ ASSERT_LE(strength, 6);
+ int rounding = 0;
+ if (strength > 0) {
+ rounding = 1 << (strength - 1);
+ }
+
+ // Check that the buffers are valid
+ ASSERT_TRUE(y_src.TopLeftPixel() != NULL);
+ ASSERT_TRUE(y_pre.TopLeftPixel() != NULL);
+ ASSERT_TRUE(y_dif.TopLeftPixel() != NULL);
+ ASSERT_TRUE(u_src.TopLeftPixel() != NULL);
+ ASSERT_TRUE(u_pre.TopLeftPixel() != NULL);
+ ASSERT_TRUE(u_dif.TopLeftPixel() != NULL);
+ ASSERT_TRUE(v_src.TopLeftPixel() != NULL);
+ ASSERT_TRUE(v_pre.TopLeftPixel() != NULL);
+ ASSERT_TRUE(v_dif.TopLeftPixel() != NULL);
+
+ // Get the square diffs
+ for (int row = 0; row < static_cast<int>(block_height); row++) {
+ for (int col = 0; col < static_cast<int>(block_width); col++) {
+ const int diff = y_src.TopLeftPixel()[row * y_src.stride() + col] -
+ y_pre.TopLeftPixel()[row * y_pre.stride() + col];
+ y_dif.TopLeftPixel()[row * y_dif.stride() + col] = diff * diff;
+ }
+ }
+
+ for (int row = 0; row < uv_block_height; row++) {
+ for (int col = 0; col < uv_block_width; col++) {
+ const int u_diff = u_src.TopLeftPixel()[row * u_src.stride() + col] -
+ u_pre.TopLeftPixel()[row * u_pre.stride() + col];
+ const int v_diff = v_src.TopLeftPixel()[row * v_src.stride() + col] -
+ v_pre.TopLeftPixel()[row * v_pre.stride() + col];
+ u_dif.TopLeftPixel()[row * u_dif.stride() + col] = u_diff * u_diff;
+ v_dif.TopLeftPixel()[row * v_dif.stride() + col] = v_diff * v_diff;
+ }
+ }
+
+ // Apply the filter
+ for (int row = 0; row < static_cast<int>(block_height); row++) {
+ for (int col = 0; col < static_cast<int>(block_width); col++) {
+ const int uv_r = row >> ss_y;
+ const int uv_c = col >> ss_x;
+ const int filter_weight = GetFilterWeight(row, col, block_height,
+ block_width, blk_fw, use_32x32);
+
+ // First we get the modifier for the current y pixel
+ const int y_pixel = y_pre.TopLeftPixel()[row * y_pre.stride() + col];
+ int y_num_used = 0;
+ int y_mod = 0;
+
+ // Sum the neighboring 3x3 y pixels
+ for (int row_step = -1; row_step <= 1; row_step++) {
+ for (int col_step = -1; col_step <= 1; col_step++) {
+ const int sub_row = row + row_step;
+ const int sub_col = col + col_step;
+
+ if (sub_row >= 0 && sub_row < static_cast<int>(block_height) &&
+ sub_col >= 0 && sub_col < static_cast<int>(block_width)) {
+ y_mod += y_dif.TopLeftPixel()[sub_row * y_dif.stride() + sub_col];
+ y_num_used++;
+ }
+ }
+ }
+
+ ASSERT_GE(y_num_used, 0);
+
+ // Sum the corresponding uv pixels to the current y modifier
+ // Note we are rounding down instead of rounding to the nearest pixel.
+ y_mod += u_dif.TopLeftPixel()[uv_r * uv_block_width + uv_c];
+ y_mod += v_dif.TopLeftPixel()[uv_r * uv_block_width + uv_c];
+
+ y_num_used += 2;
+
+ // Set the modifier
+ y_mod = GetModIndex(y_mod, y_num_used, rounding, strength, filter_weight);
+
+ // Accumulate the result
+ y_count->TopLeftPixel()[row * y_count->stride() + col] += y_mod;
+ y_accumulator->TopLeftPixel()[row * y_accumulator->stride() + col] +=
+ y_mod * y_pixel;
+
+ // Get the modifier for chroma components
+ if (!(row & ss_y) && !(col & ss_x)) {
+ const int u_pixel = u_pre.TopLeftPixel()[uv_r * u_pre.stride() + uv_c];
+ const int v_pixel = v_pre.TopLeftPixel()[uv_r * v_pre.stride() + uv_c];
+
+ int uv_num_used = 0;
+ int u_mod = 0, v_mod = 0;
+
+ // Sum the neighboring 3x3 chromal pixels to the chroma modifier
+ for (int row_step = -1; row_step <= 1; row_step++) {
+ for (int col_step = -1; col_step <= 1; col_step++) {
+ const int sub_row = uv_r + row_step;
+ const int sub_col = uv_c + col_step;
+
+ if (sub_row >= 0 && sub_row < uv_block_height && sub_col >= 0 &&
+ sub_col < uv_block_width) {
+ u_mod += u_dif.TopLeftPixel()[sub_row * uv_block_width + sub_col];
+ v_mod += v_dif.TopLeftPixel()[sub_row * uv_block_width + sub_col];
+ uv_num_used++;
+ }
+ }
+ }
+
+ ASSERT_GT(uv_num_used, 0);
+
+ // Sum all the luma pixels associated with the current luma pixel
+ for (int row_step = 0; row_step < 1 + ss_y; row_step++) {
+ for (int col_step = 0; col_step < 1 + ss_x; col_step++) {
+ const int sub_row = (uv_r << ss_y) + row_step;
+ const int sub_col = (uv_c << ss_x) + col_step;
+ const int y_diff =
+ y_dif.TopLeftPixel()[sub_row * y_dif.stride() + sub_col];
+
+ u_mod += y_diff;
+ v_mod += y_diff;
+ uv_num_used++;
+ }
+ }
+
+ // Set the modifier
+ u_mod =
+ GetModIndex(u_mod, uv_num_used, rounding, strength, filter_weight);
+ v_mod =
+ GetModIndex(v_mod, uv_num_used, rounding, strength, filter_weight);
+
+ // Accumulate the result
+ u_count->TopLeftPixel()[uv_r * u_count->stride() + uv_c] += u_mod;
+ u_accumulator->TopLeftPixel()[uv_r * u_accumulator->stride() + uv_c] +=
+ u_mod * u_pixel;
+ v_count->TopLeftPixel()[uv_r * u_count->stride() + uv_c] += v_mod;
+ v_accumulator->TopLeftPixel()[uv_r * v_accumulator->stride() + uv_c] +=
+ v_mod * v_pixel;
+ }
+ }
+ }
+}
+
+class YUVTemporalFilterTest
+ : public ::testing::TestWithParam<YUVTemporalFilterFunc> {
+ public:
+ virtual void SetUp() {
+ filter_func_ = GetParam();
+ rnd_.Reset(ACMRandom::DeterministicSeed());
+ }
+
+ protected:
+ YUVTemporalFilterFunc filter_func_;
+ ACMRandom rnd_;
+};
+
+TEST_P(YUVTemporalFilterTest, Use32x32) {
+ const int width = 32, height = 32;
+ Buffer<uint8_t> y_src = Buffer<uint8_t>(width, height, 8);
+ Buffer<uint8_t> y_pre = Buffer<uint8_t>(width, height, 0);
+ Buffer<uint16_t> y_count_ref = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum_ref = Buffer<uint32_t>(width, height, 0);
+ Buffer<uint16_t> y_count_tst = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum_tst = Buffer<uint32_t>(width, height, 0);
+ ASSERT_TRUE(y_src.Init());
+ ASSERT_TRUE(y_pre.Init());
+ ASSERT_TRUE(y_count_ref.Init());
+ ASSERT_TRUE(y_accum_ref.Init());
+ ASSERT_TRUE(y_count_tst.Init());
+ ASSERT_TRUE(y_accum_tst.Init());
+
+ const int use_32x32 = 1;
+
+ for (int ss_x = 0; ss_x <= 1; ss_x++) {
+ for (int ss_y = 0; ss_y <= 1; ss_y++) {
+ for (int filter_strength = 0; filter_strength <= 6;
+ filter_strength += 2) {
+ for (int filter_weight = 0; filter_weight <= 2; filter_weight++) {
+ const int uv_width = width >> ss_x, uv_height = height >> ss_y;
+ Buffer<uint8_t> u_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> u_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count_ref =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum_ref =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count_tst =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum_tst =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(u_src.Init());
+ ASSERT_TRUE(u_pre.Init());
+ ASSERT_TRUE(u_count_ref.Init());
+ ASSERT_TRUE(u_accum_ref.Init());
+ ASSERT_TRUE(u_count_tst.Init());
+ ASSERT_TRUE(u_accum_tst.Init());
+ Buffer<uint8_t> v_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> v_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count_ref =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum_ref =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count_tst =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum_tst =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(v_src.Init());
+ ASSERT_TRUE(v_pre.Init());
+ ASSERT_TRUE(v_count_ref.Init());
+ ASSERT_TRUE(v_accum_ref.Init());
+ ASSERT_TRUE(v_count_tst.Init());
+ ASSERT_TRUE(v_accum_tst.Init());
+
+ // The difference between the buffers must be small to pass the
+ // threshold to apply the filter.
+ y_src.Set(&rnd_, 0, 7);
+ y_pre.Set(&rnd_, 0, 7);
+ u_src.Set(&rnd_, 0, 7);
+ u_pre.Set(&rnd_, 0, 7);
+ v_src.Set(&rnd_, 0, 7);
+ v_pre.Set(&rnd_, 0, 7);
+
+ y_accum_ref.Set(rnd_.Rand8());
+ y_accum_tst.CopyFrom(y_accum_ref);
+ y_count_ref.Set(rnd_.Rand8());
+ y_count_tst.CopyFrom(y_count_ref);
+ u_accum_ref.Set(rnd_.Rand8());
+ u_accum_tst.CopyFrom(u_accum_ref);
+ u_count_ref.Set(rnd_.Rand8());
+ u_count_tst.CopyFrom(u_count_ref);
+ v_accum_ref.Set(rnd_.Rand8());
+ v_accum_tst.CopyFrom(v_accum_ref);
+ v_count_ref.Set(rnd_.Rand8());
+ v_count_tst.CopyFrom(v_count_ref);
+
+ ApplyReferenceFilter(y_src, y_pre, u_src, v_src, u_pre, v_pre, width,
+ height, ss_x, ss_y, filter_strength,
+ &filter_weight, use_32x32, &y_accum_ref,
+ &y_count_ref, &u_accum_ref, &u_count_ref,
+ &v_accum_ref, &v_count_ref);
+ ASM_REGISTER_STATE_CHECK(filter_func_(
+ y_src.TopLeftPixel(), y_src.stride(), y_pre.TopLeftPixel(),
+ y_pre.stride(), u_src.TopLeftPixel(), v_src.TopLeftPixel(),
+ u_src.stride(), u_pre.TopLeftPixel(), v_pre.TopLeftPixel(),
+ u_pre.stride(), width, height, ss_x, ss_y, filter_strength,
+ &filter_weight, use_32x32, y_accum_tst.TopLeftPixel(),
+ y_count_tst.TopLeftPixel(), u_accum_tst.TopLeftPixel(),
+ u_count_tst.TopLeftPixel(), v_accum_tst.TopLeftPixel(),
+ v_count_tst.TopLeftPixel()));
+
+ EXPECT_TRUE(y_accum_tst.CheckValues(y_accum_ref));
+ EXPECT_TRUE(y_count_tst.CheckValues(y_count_ref));
+ EXPECT_TRUE(u_accum_tst.CheckValues(u_accum_ref));
+ EXPECT_TRUE(u_count_tst.CheckValues(u_count_ref));
+ EXPECT_TRUE(v_accum_tst.CheckValues(v_accum_ref));
+ EXPECT_TRUE(v_count_tst.CheckValues(v_count_ref));
+
+ if (HasFailure()) {
+ printf("SS_X: %d, SS_Y: %d, Weight: %d, Strength: %d\n", ss_x, ss_y,
+ filter_weight, filter_strength);
+ y_accum_tst.PrintDifference(y_accum_ref);
+ y_count_tst.PrintDifference(y_count_ref);
+ u_accum_tst.PrintDifference(u_accum_ref);
+ u_count_tst.PrintDifference(u_count_ref);
+ v_accum_tst.PrintDifference(v_accum_ref);
+ v_count_tst.PrintDifference(v_count_ref);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+TEST_P(YUVTemporalFilterTest, Use16x16) {
+ const int width = 32, height = 32;
+ Buffer<uint8_t> y_src = Buffer<uint8_t>(width, height, 8);
+ Buffer<uint8_t> y_pre = Buffer<uint8_t>(width, height, 0);
+ Buffer<uint16_t> y_count_ref = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum_ref = Buffer<uint32_t>(width, height, 0);
+ Buffer<uint16_t> y_count_tst = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum_tst = Buffer<uint32_t>(width, height, 0);
+ ASSERT_TRUE(y_src.Init());
+ ASSERT_TRUE(y_pre.Init());
+ ASSERT_TRUE(y_count_ref.Init());
+ ASSERT_TRUE(y_accum_ref.Init());
+ ASSERT_TRUE(y_count_tst.Init());
+ ASSERT_TRUE(y_accum_tst.Init());
+
+ const int use_32x32 = 0;
+
+ for (int ss_x = 0; ss_x <= 1; ss_x++) {
+ for (int ss_y = 0; ss_y <= 1; ss_y++) {
+ for (int filter_idx = 0; filter_idx < 3 * 3 * 3 * 3; filter_idx++) {
+ // Set up the filter
+ int filter_weight[4];
+ int filter_idx_cp = filter_idx;
+ for (int idx = 0; idx < 4; idx++) {
+ filter_weight[idx] = filter_idx_cp % 3;
+ filter_idx_cp /= 3;
+ }
+
+ // Test each parameter
+ for (int filter_strength = 0; filter_strength <= 6;
+ filter_strength += 2) {
+ const int uv_width = width >> ss_x, uv_height = height >> ss_y;
+ Buffer<uint8_t> u_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> u_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count_ref =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum_ref =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count_tst =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum_tst =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(u_src.Init());
+ ASSERT_TRUE(u_pre.Init());
+ ASSERT_TRUE(u_count_ref.Init());
+ ASSERT_TRUE(u_accum_ref.Init());
+ ASSERT_TRUE(u_count_tst.Init());
+ ASSERT_TRUE(u_accum_tst.Init());
+ Buffer<uint8_t> v_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> v_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count_ref =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum_ref =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count_tst =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum_tst =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(v_src.Init());
+ ASSERT_TRUE(v_pre.Init());
+ ASSERT_TRUE(v_count_ref.Init());
+ ASSERT_TRUE(v_accum_ref.Init());
+ ASSERT_TRUE(v_count_tst.Init());
+ ASSERT_TRUE(v_accum_tst.Init());
+
+ // The difference between the buffers must be small to pass the
+ // threshold to apply the filter.
+ y_src.Set(&rnd_, 0, 7);
+ y_pre.Set(&rnd_, 0, 7);
+ u_src.Set(&rnd_, 0, 7);
+ u_pre.Set(&rnd_, 0, 7);
+ v_src.Set(&rnd_, 0, 7);
+ v_pre.Set(&rnd_, 0, 7);
+
+ y_accum_ref.Set(rnd_.Rand8());
+ y_accum_tst.CopyFrom(y_accum_ref);
+ y_count_ref.Set(rnd_.Rand8());
+ y_count_tst.CopyFrom(y_count_ref);
+ u_accum_ref.Set(rnd_.Rand8());
+ u_accum_tst.CopyFrom(u_accum_ref);
+ u_count_ref.Set(rnd_.Rand8());
+ u_count_tst.CopyFrom(u_count_ref);
+ v_accum_ref.Set(rnd_.Rand8());
+ v_accum_tst.CopyFrom(v_accum_ref);
+ v_count_ref.Set(rnd_.Rand8());
+ v_count_tst.CopyFrom(v_count_ref);
+
+ ApplyReferenceFilter(y_src, y_pre, u_src, v_src, u_pre, v_pre, width,
+ height, ss_x, ss_y, filter_strength,
+ filter_weight, use_32x32, &y_accum_ref,
+ &y_count_ref, &u_accum_ref, &u_count_ref,
+ &v_accum_ref, &v_count_ref);
+ ASM_REGISTER_STATE_CHECK(filter_func_(
+ y_src.TopLeftPixel(), y_src.stride(), y_pre.TopLeftPixel(),
+ y_pre.stride(), u_src.TopLeftPixel(), v_src.TopLeftPixel(),
+ u_src.stride(), u_pre.TopLeftPixel(), v_pre.TopLeftPixel(),
+ u_pre.stride(), width, height, ss_x, ss_y, filter_strength,
+ filter_weight, use_32x32, y_accum_tst.TopLeftPixel(),
+ y_count_tst.TopLeftPixel(), u_accum_tst.TopLeftPixel(),
+ u_count_tst.TopLeftPixel(), v_accum_tst.TopLeftPixel(),
+ v_count_tst.TopLeftPixel()));
+
+ EXPECT_TRUE(y_accum_tst.CheckValues(y_accum_ref));
+ EXPECT_TRUE(y_count_tst.CheckValues(y_count_ref));
+ EXPECT_TRUE(u_accum_tst.CheckValues(u_accum_ref));
+ EXPECT_TRUE(u_count_tst.CheckValues(u_count_ref));
+ EXPECT_TRUE(v_accum_tst.CheckValues(v_accum_ref));
+ EXPECT_TRUE(v_count_tst.CheckValues(v_count_ref));
+
+ if (HasFailure()) {
+ printf("SS_X: %d, SS_Y: %d, Weight Idx: %d, Strength: %d\n", ss_x,
+ ss_y, filter_idx, filter_strength);
+ y_accum_tst.PrintDifference(y_accum_ref);
+ y_count_tst.PrintDifference(y_count_ref);
+ u_accum_tst.PrintDifference(u_accum_ref);
+ u_count_tst.PrintDifference(u_count_ref);
+ v_accum_tst.PrintDifference(v_accum_ref);
+ v_count_tst.PrintDifference(v_count_ref);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+TEST_P(YUVTemporalFilterTest, SaturationTest) {
+ const int width = 32, height = 32;
+ const int use_32x32 = 1;
+
+ Buffer<uint8_t> y_src = Buffer<uint8_t>(width, height, 8);
+ Buffer<uint8_t> y_pre = Buffer<uint8_t>(width, height, 0);
+ Buffer<uint16_t> y_count_ref = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum_ref = Buffer<uint32_t>(width, height, 0);
+ Buffer<uint16_t> y_count_tst = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum_tst = Buffer<uint32_t>(width, height, 0);
+ ASSERT_TRUE(y_src.Init());
+ ASSERT_TRUE(y_pre.Init());
+ ASSERT_TRUE(y_count_ref.Init());
+ ASSERT_TRUE(y_accum_ref.Init());
+ ASSERT_TRUE(y_count_tst.Init());
+ ASSERT_TRUE(y_accum_tst.Init());
+
+ for (int ss_x = 0; ss_x <= 1; ss_x++) {
+ for (int ss_y = 0; ss_y <= 1; ss_y++) {
+ for (int filter_strength = 0; filter_strength <= 6;
+ filter_strength += 2) {
+ for (int filter_weight = 0; filter_weight <= 2; filter_weight++) {
+ const int uv_width = width >> ss_x, uv_height = height >> ss_y;
+ Buffer<uint8_t> u_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> u_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count_ref =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum_ref =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count_tst =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum_tst =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(u_src.Init());
+ ASSERT_TRUE(u_pre.Init());
+ ASSERT_TRUE(u_count_ref.Init());
+ ASSERT_TRUE(u_accum_ref.Init());
+ ASSERT_TRUE(u_count_tst.Init());
+ ASSERT_TRUE(u_accum_tst.Init());
+ Buffer<uint8_t> v_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> v_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count_ref =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum_ref =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count_tst =
+ Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum_tst =
+ Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(v_src.Init());
+ ASSERT_TRUE(v_pre.Init());
+ ASSERT_TRUE(v_count_ref.Init());
+ ASSERT_TRUE(v_accum_ref.Init());
+ ASSERT_TRUE(v_count_tst.Init());
+ ASSERT_TRUE(v_accum_tst.Init());
+
+ // The difference between the buffers must be small to pass the
+ // threshold to apply the filter.
+ y_src.Set(255);
+ y_pre.Set(0);
+ u_src.Set(255);
+ u_pre.Set(0);
+ v_src.Set(255);
+ v_pre.Set(0);
+
+ y_accum_ref.Set(rnd_.Rand8());
+ y_accum_tst.CopyFrom(y_accum_ref);
+ y_count_ref.Set(rnd_.Rand8());
+ y_count_tst.CopyFrom(y_count_ref);
+ u_accum_ref.Set(rnd_.Rand8());
+ u_accum_tst.CopyFrom(u_accum_ref);
+ u_count_ref.Set(rnd_.Rand8());
+ u_count_tst.CopyFrom(u_count_ref);
+ v_accum_ref.Set(rnd_.Rand8());
+ v_accum_tst.CopyFrom(v_accum_ref);
+ v_count_ref.Set(rnd_.Rand8());
+ v_count_tst.CopyFrom(v_count_ref);
+
+ ApplyReferenceFilter(y_src, y_pre, u_src, v_src, u_pre, v_pre, width,
+ height, ss_x, ss_y, filter_strength,
+ &filter_weight, use_32x32, &y_accum_ref,
+ &y_count_ref, &u_accum_ref, &u_count_ref,
+ &v_accum_ref, &v_count_ref);
+ ASM_REGISTER_STATE_CHECK(filter_func_(
+ y_src.TopLeftPixel(), y_src.stride(), y_pre.TopLeftPixel(),
+ y_pre.stride(), u_src.TopLeftPixel(), v_src.TopLeftPixel(),
+ u_src.stride(), u_pre.TopLeftPixel(), v_pre.TopLeftPixel(),
+ u_pre.stride(), width, height, ss_x, ss_y, filter_strength,
+ &filter_weight, use_32x32, y_accum_tst.TopLeftPixel(),
+ y_count_tst.TopLeftPixel(), u_accum_tst.TopLeftPixel(),
+ u_count_tst.TopLeftPixel(), v_accum_tst.TopLeftPixel(),
+ v_count_tst.TopLeftPixel()));
+
+ EXPECT_TRUE(y_accum_tst.CheckValues(y_accum_ref));
+ EXPECT_TRUE(y_count_tst.CheckValues(y_count_ref));
+ EXPECT_TRUE(u_accum_tst.CheckValues(u_accum_ref));
+ EXPECT_TRUE(u_count_tst.CheckValues(u_count_ref));
+ EXPECT_TRUE(v_accum_tst.CheckValues(v_accum_ref));
+ EXPECT_TRUE(v_count_tst.CheckValues(v_count_ref));
+
+ if (HasFailure()) {
+ printf("SS_X: %d, SS_Y: %d, Weight: %d, Strength: %d\n", ss_x, ss_y,
+ filter_weight, filter_strength);
+ y_accum_tst.PrintDifference(y_accum_ref);
+ y_count_tst.PrintDifference(y_count_ref);
+ u_accum_tst.PrintDifference(u_accum_ref);
+ u_count_tst.PrintDifference(u_count_ref);
+ v_accum_tst.PrintDifference(v_accum_ref);
+ v_count_tst.PrintDifference(v_count_ref);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+TEST_P(YUVTemporalFilterTest, DISABLED_Speed) {
+ const int width = 32, height = 32;
+ Buffer<uint8_t> y_src = Buffer<uint8_t>(width, height, 8);
+ Buffer<uint8_t> y_pre = Buffer<uint8_t>(width, height, 0);
+ Buffer<uint16_t> y_count = Buffer<uint16_t>(width, height, 0);
+ Buffer<uint32_t> y_accum = Buffer<uint32_t>(width, height, 0);
+ ASSERT_TRUE(y_src.Init());
+ ASSERT_TRUE(y_pre.Init());
+ ASSERT_TRUE(y_count.Init());
+ ASSERT_TRUE(y_accum.Init());
+
+ for (int use_32x32 = 0; use_32x32 <= 1; use_32x32++) {
+ const int num_filter_weights = use_32x32 ? 3 : 3 * 3 * 3 * 3;
+ for (int ss_x = 0; ss_x <= 1; ss_x++) {
+ for (int ss_y = 0; ss_y <= 1; ss_y++) {
+ for (int filter_idx = 0; filter_idx < num_filter_weights;
+ filter_idx++) {
+ // Set up the filter
+ int filter_weight[4];
+ int filter_idx_cp = filter_idx;
+ for (int idx = 0; idx < 4; idx++) {
+ filter_weight[idx] = filter_idx_cp % 3;
+ filter_idx_cp /= 3;
+ }
+
+ // Test each parameter
+ for (int filter_strength = 0; filter_strength <= 6;
+ filter_strength += 2) {
+ const int uv_width = width >> ss_x, uv_height = height >> ss_y;
+ Buffer<uint8_t> u_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> u_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> u_count = Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> u_accum = Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(u_src.Init());
+ ASSERT_TRUE(u_pre.Init());
+ ASSERT_TRUE(u_count.Init());
+ ASSERT_TRUE(u_accum.Init());
+ Buffer<uint8_t> v_src = Buffer<uint8_t>(uv_width, uv_height, 8);
+ Buffer<uint8_t> v_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
+ Buffer<uint16_t> v_count = Buffer<uint16_t>(uv_width, uv_height, 0);
+ Buffer<uint32_t> v_accum = Buffer<uint32_t>(uv_width, uv_height, 0);
+ ASSERT_TRUE(v_src.Init());
+ ASSERT_TRUE(v_pre.Init());
+ ASSERT_TRUE(v_count.Init());
+ ASSERT_TRUE(v_accum.Init());
+
+ y_src.Set(&rnd_, 0, 7);
+ y_pre.Set(&rnd_, 0, 7);
+ u_src.Set(&rnd_, 0, 7);
+ u_pre.Set(&rnd_, 0, 7);
+ v_src.Set(&rnd_, 0, 7);
+ v_pre.Set(&rnd_, 0, 7);
+
+ y_accum.Set(0);
+ y_count.Set(0);
+ u_accum.Set(0);
+ u_count.Set(0);
+ v_accum.Set(0);
+ v_count.Set(0);
+
+ vpx_usec_timer timer;
+ vpx_usec_timer_start(&timer);
+ for (int num_calls = 0; num_calls < 1000; num_calls++) {
+ filter_func_(
+ y_src.TopLeftPixel(), y_src.stride(), y_pre.TopLeftPixel(),
+ y_pre.stride(), u_src.TopLeftPixel(), v_src.TopLeftPixel(),
+ u_src.stride(), u_pre.TopLeftPixel(), v_pre.TopLeftPixel(),
+ u_pre.stride(), width, height, ss_x, ss_y, filter_strength,
+ filter_weight, use_32x32, y_accum.TopLeftPixel(),
+ y_count.TopLeftPixel(), u_accum.TopLeftPixel(),
+ u_count.TopLeftPixel(), v_accum.TopLeftPixel(),
+ v_count.TopLeftPixel());
+ }
+
+ vpx_usec_timer_mark(&timer);
+ const int elapsed_time =
+ static_cast<int>(vpx_usec_timer_elapsed(&timer));
+
+ printf(
+ "Use 32X32: %d, SS_X: %d, SS_Y: %d, Weight Idx: %d, Strength: "
+ "%d, Time: %5d\n",
+ use_32x32, ss_x, ss_y, filter_idx, filter_strength,
+ elapsed_time);
+ }
+ }
+ }
+ }
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(C, YUVTemporalFilterTest,
+ ::testing::Values(&vp9_apply_temporal_filter_c));
+
+#if HAVE_SSE4_1
+INSTANTIATE_TEST_CASE_P(SSE4_1, YUVTemporalFilterTest,
+ ::testing::Values(&vp9_apply_temporal_filter_sse4_1));
+#endif // HAVE_SSE4_1
+} // namespace