History

Add unit test for temporal filter on VP9

The current unit tests for temporal filtering only tests single channel version of temporal filter. Since VP9 currently uses both luma and chroma channel information for temporal filtering on low bitdepth, there is no unit case in this scenario. This commit adds some basic unit tests to facilitate further development on temporal filtering. BUG=webm:1591

chiyotsai committed 7 years ago

Commit da5e2461 parent c1827254 files · +488 −6Browse files

Showing the changes to test (2 of 4 files). Show all

Unified · Split

2 files
  1. test/test.mk +1 −0
  2. test/yuv_temporal_filter_test.cc +479 −0
test/test.mk+1−0
@@ -171,6 +171,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc · 170 unmodified lines
171171 LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc
172172 ifneq ($(CONFIG_REALTIME_ONLY),yes)
173173 LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += temporal_filter_test.cc
174+LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc
174175 endif
175176 LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
176177 LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
test/yuv_temporal_filter_test.cc+479−0
@@ -0,0 +1,479 @@
1+/*
2+ * Copyright (c) 2019 The WebM project authors. All Rights Reserved.
3+ *
4+ * Use of this source code is governed by a BSD-style license
5+ * that can be found in the LICENSE file in the root of the source
6+ * tree. An additional intellectual property rights grant can be found
7+ * in the file PATENTS. All contributing project authors may
8+ * be found in the AUTHORS file in the root of the source tree.
9+ */
10+
11+#include <limits>
12+
13+#include "third_party/googletest/src/include/gtest/gtest.h"
14+
15+#include "./vp9_rtcd.h"
16+#include "test/acm_random.h"
17+#include "test/buffer.h"
18+#include "test/register_state_check.h"
19+#include "vpx_ports/vpx_timer.h"
20+
21+namespace {
22+
23+using ::libvpx_test::ACMRandom;
24+using ::libvpx_test::Buffer;
25+
26+typedef void (*YUVTemporalFilterFunc)(
27+ const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre,
28+ int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src,
29+ int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre,
30+ int uv_pre_stride, unsigned int block_width, unsigned int block_height,
31+ int ss_x, int ss_y, int strength, const int *const blk_fw, int use_32x32,
32+ uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator,
33+ uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count);
34+
35+static INLINE int get_filter_weight(unsigned int row, unsigned int col,
36+ unsigned int block_height,
37+ unsigned int block_width,
38+ const int *const blk_fw, int use_32x32) {
39+ if (use_32x32) {
40+ return blk_fw[0];
41+ }
42+
43+ return blk_fw[2 * (row >= block_height / 2) + (col >= block_width / 2)];
44+}
45+
46+static INLINE int mod_index(int sum_dist, int index, int rounding, int strength,
47+ int filter_weight) {
48+ int mod = (sum_dist * 3) / index;
49+ mod += rounding;
50+ mod >>= strength;
51+
52+ mod = VPXMIN(16, mod);
53+
54+ mod = 16 - mod;
55+ mod *= filter_weight;
56+
57+ return mod;
58+}
59+
60+void reference_filter(
61+ const Buffer<uint8_t> &y_src, const Buffer<uint8_t> &y_pre,
62+ const Buffer<uint8_t> &u_src, const Buffer<uint8_t> &v_src,
63+ const Buffer<uint8_t> &u_pre, const Buffer<uint8_t> &v_pre,
64+ unsigned int block_width, unsigned int block_height, int ss_x, int ss_y,
65+ int strength, const int *const blk_fw, int use_32x32,
66+ Buffer<uint32_t> *y_accumulator, Buffer<uint16_t> *y_count,
67+ Buffer<uint32_t> *u_accumulator, Buffer<uint16_t> *u_count,
68+ Buffer<uint32_t> *v_accumulator, Buffer<uint16_t> *v_count) {
69+ // blk_fw means block_filter_weight
70+ // Set up buffer to store squared_diffs
71+ Buffer<int> y_dif = Buffer<int>(block_width, block_height, 0);
72+ const int uv_block_width = block_width >> ss_x;
73+ const int uv_block_height = block_height >> ss_y;
74+ Buffer<int> u_dif = Buffer<int>(uv_block_width, uv_block_height, 0);
75+ Buffer<int> v_dif = Buffer<int>(uv_block_width, uv_block_height, 0);
76+ ASSERT_TRUE(y_dif.Init());
77+ ASSERT_TRUE(u_dif.Init());
78+ ASSERT_TRUE(v_dif.Init());
79+ y_dif.Set(0);
80+ u_dif.Set(0);
81+ v_dif.Set(0);
82+
83+ // How many bits to we want round
84+ ASSERT_GE(strength, 0);
85+ ASSERT_LE(strength, 6);
86+ int rounding = 0;
87+ if (strength > 0) {
88+ rounding = 1 << (strength - 1);
89+ }
90+
91+ // Check that the buffers are valid
92+ ASSERT_TRUE(y_src.TopLeftPixel() != NULL);
93+ ASSERT_TRUE(y_pre.TopLeftPixel() != NULL);
94+ ASSERT_TRUE(y_dif.TopLeftPixel() != NULL);
95+ ASSERT_TRUE(u_src.TopLeftPixel() != NULL);
96+ ASSERT_TRUE(u_pre.TopLeftPixel() != NULL);
97+ ASSERT_TRUE(u_dif.TopLeftPixel() != NULL);
98+ ASSERT_TRUE(v_src.TopLeftPixel() != NULL);
99+ ASSERT_TRUE(v_pre.TopLeftPixel() != NULL);
100+ ASSERT_TRUE(v_dif.TopLeftPixel() != NULL);
101+
102+ // Get the square diffs
103+ for (int row = 0; row < (int)block_height; row++) {
104+ for (int col = 0; col < (int)block_width; col++) {
105+ int diff = y_src.TopLeftPixel()[row * y_src.stride() + col] -
106+ y_pre.TopLeftPixel()[row * y_pre.stride() + col];
107+ y_dif.TopLeftPixel()[row * y_dif.stride() + col] = diff * diff;
108+ }
109+ }
110+
111+ for (int row = 0; row < uv_block_height; row++) {
112+ for (int col = 0; col < uv_block_width; col++) {
113+ int u_diff = u_src.TopLeftPixel()[row * u_src.stride() + col] -
114+ u_pre.TopLeftPixel()[row * u_pre.stride() + col];
115+ int v_diff = v_src.TopLeftPixel()[row * v_src.stride() + col] -
116+ v_pre.TopLeftPixel()[row * v_pre.stride() + col];
117+ u_dif.TopLeftPixel()[row * u_dif.stride() + col] = u_diff * u_diff;
118+ v_dif.TopLeftPixel()[row * v_dif.stride() + col] = v_diff * v_diff;
119+ }
120+ }
121+
122+ // Apply the filter
123+ for (int row = 0; row < (int)block_height; row++) {
124+ for (int col = 0; col < (int)block_width; col++) {
125+ const int uv_r = row >> ss_y;
126+ const int uv_c = col >> ss_x;
127+ int filter_weight = get_filter_weight(row, col, block_height, block_width,
128+ blk_fw, use_32x32);
129+
130+ // First we get the modifier for the current y pixel
131+ const int y_pixel = y_pre.TopLeftPixel()[row * y_pre.stride() + col];
132+ int y_num_used = 0;
133+ int y_mod = 0;
134+
135+ // Sum the neighboring 3x3 y pixels
136+ for (int row_step = -1; row_step <= 1; row_step++) {
137+ for (int col_step = -1; col_step <= 1; col_step++) {
138+ const int sub_row = row + row_step;
139+ const int sub_col = col + col_step;
140+
141+ if (sub_row >= 0 && sub_row < (int)block_height && sub_col >= 0 &&
142+ sub_col < (int)block_width) {
143+ y_mod += y_dif.TopLeftPixel()[sub_row * y_dif.stride() + sub_col];
144+ y_num_used++;
145+ }
146+ }
147+ }
148+
149+ ASSERT_GE(y_num_used, 0);
150+
151+ // Sum the corresponding uv pixels to the current y modifier
152+ // Note we are rounding down instead of rounding to the nearest pixel.
153+ y_mod += u_dif.TopLeftPixel()[uv_r * uv_block_width + uv_c];
154+ y_mod += v_dif.TopLeftPixel()[uv_r * uv_block_width + uv_c];
155+
156+ y_num_used += 2;
157+
158+ // Set the modifier
159+ y_mod = mod_index(y_mod, y_num_used, rounding, strength, filter_weight);
160+
161+ // Accumulate the result
162+ y_count->TopLeftPixel()[row * y_count->stride() + col] += y_mod;
163+ y_accumulator->TopLeftPixel()[row * y_accumulator->stride() + col] +=
164+ y_mod * y_pixel;
165+
166+ // Get the modifier for chroma components
167+ if (!(row & ss_y) && !(col & ss_x)) {
168+ const int u_pixel = u_pre.TopLeftPixel()[uv_r * u_pre.stride() + uv_c];
169+ const int v_pixel = v_pre.TopLeftPixel()[uv_r * v_pre.stride() + uv_c];
170+
171+ int uv_num_used = 0;
172+ int u_mod = 0, v_mod = 0;
173+
174+ // Sum the neighboring 3x3 chromal pixels to the chroma modifier
175+ for (int row_step = -1; row_step <= 1; row_step++) {
176+ for (int col_step = -1; col_step <= 1; col_step++) {
177+ const int sub_row = uv_r + row_step;
178+ const int sub_col = uv_c + col_step;
179+
180+ if (sub_row >= 0 && sub_row < uv_block_height && sub_col >= 0 &&
181+ sub_col < uv_block_width) {
182+ u_mod += u_dif.TopLeftPixel()[sub_row * uv_block_width + sub_col];
183+ v_mod += v_dif.TopLeftPixel()[sub_row * uv_block_width + sub_col];
184+ uv_num_used++;
185+ }
186+ }
187+ }
188+
189+ assert(uv_num_used > 0);
190+
191+ // Sum all the luma pixels associated with the current luma pixel
192+ for (int row_step = 0; row_step < 1 + ss_y; row_step++) {
193+ for (int col_step = 0; col_step < 1 + ss_x; col_step++) {
194+ const int sub_row = (uv_r << ss_y) + row_step;
195+ const int sub_col = (uv_c << ss_x) + col_step;
196+ const int y_diff =
197+ y_dif.TopLeftPixel()[sub_row * y_dif.stride() + sub_col];
198+
199+ u_mod += y_diff;
200+ v_mod += y_diff;
201+ uv_num_used++;
202+ }
203+ }
204+
205+ // Set the modifier
206+ u_mod =
207+ mod_index(u_mod, uv_num_used, rounding, strength, filter_weight);
208+ v_mod =
209+ mod_index(v_mod, uv_num_used, rounding, strength, filter_weight);
210+
211+ // Accumuate the result
212+ u_count->TopLeftPixel()[uv_r * u_count->stride() + uv_c] += u_mod;
213+ u_accumulator->TopLeftPixel()[uv_r * u_accumulator->stride() + uv_c] +=
214+ u_mod * u_pixel;
215+ v_count->TopLeftPixel()[uv_r * u_count->stride() + uv_c] += v_mod;
216+ v_accumulator->TopLeftPixel()[uv_r * v_accumulator->stride() + uv_c] +=
217+ v_mod * v_pixel;
218+ }
219+ }
220+ }
221+}
222+
223+class YUVTemporalFilterTest
224+ : public ::testing::TestWithParam<YUVTemporalFilterFunc> {
225+ public:
226+ virtual void SetUp() {
227+ filter_func_ = GetParam();
228+ rnd_.Reset(ACMRandom::DeterministicSeed());
229+ }
230+
231+ protected:
232+ YUVTemporalFilterFunc filter_func_;
233+ ACMRandom rnd_;
234+};
235+
236+TEST_P(YUVTemporalFilterTest, USE_32X32) {
237+ const int width = 32, height = 32;
238+ Buffer<uint8_t> y_src = Buffer<uint8_t>(width, height, 8);
239+ Buffer<uint8_t> y_pre = Buffer<uint8_t>(width, height, 0);
240+ Buffer<uint16_t> y_count_ref = Buffer<uint16_t>(width, height, 0);
241+ Buffer<uint32_t> y_accum_ref = Buffer<uint32_t>(width, height, 0);
242+ Buffer<uint16_t> y_count_tst = Buffer<uint16_t>(width, height, 0);
243+ Buffer<uint32_t> y_accum_tst = Buffer<uint32_t>(width, height, 0);
244+ ASSERT_TRUE(y_src.Init());
245+ ASSERT_TRUE(y_pre.Init());
246+ ASSERT_TRUE(y_count_ref.Init());
247+ ASSERT_TRUE(y_accum_ref.Init());
248+ ASSERT_TRUE(y_count_tst.Init());
249+ ASSERT_TRUE(y_accum_tst.Init());
250+
251+ const int use_32x32 = 1;
252+
253+ for (int ss_x = 0; ss_x <= 1; ss_x++) {
254+ for (int ss_y = 0; ss_y <= 1; ss_y++) {
255+ for (int filter_strength = 0; filter_strength <= 6;
256+ filter_strength += 2) {
257+ for (int filter_weight = 0; filter_weight <= 2; filter_weight++) {
258+ const int uv_width = width >> ss_x, uv_height = height >> ss_y;
259+ Buffer<uint8_t> u_src = Buffer<uint8_t>(uv_width, uv_height, 8);
260+ Buffer<uint8_t> u_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
261+ Buffer<uint16_t> u_count_ref =
262+ Buffer<uint16_t>(uv_width, uv_height, 0);
263+ Buffer<uint32_t> u_accum_ref =
264+ Buffer<uint32_t>(uv_width, uv_height, 0);
265+ Buffer<uint16_t> u_count_tst =
266+ Buffer<uint16_t>(uv_width, uv_height, 0);
267+ Buffer<uint32_t> u_accum_tst =
268+ Buffer<uint32_t>(uv_width, uv_height, 0);
269+ ASSERT_TRUE(u_src.Init());
270+ ASSERT_TRUE(u_pre.Init());
271+ ASSERT_TRUE(u_count_ref.Init());
272+ ASSERT_TRUE(u_accum_ref.Init());
273+ ASSERT_TRUE(u_count_tst.Init());
274+ ASSERT_TRUE(u_accum_tst.Init());
275+ Buffer<uint8_t> v_src = Buffer<uint8_t>(uv_width, uv_height, 8);
276+ Buffer<uint8_t> v_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
277+ Buffer<uint16_t> v_count_ref =
278+ Buffer<uint16_t>(uv_width, uv_height, 0);
279+ Buffer<uint32_t> v_accum_ref =
280+ Buffer<uint32_t>(uv_width, uv_height, 0);
281+ Buffer<uint16_t> v_count_tst =
282+ Buffer<uint16_t>(uv_width, uv_height, 0);
283+ Buffer<uint32_t> v_accum_tst =
284+ Buffer<uint32_t>(uv_width, uv_height, 0);
285+ ASSERT_TRUE(v_src.Init());
286+ ASSERT_TRUE(v_pre.Init());
287+ ASSERT_TRUE(v_count_ref.Init());
288+ ASSERT_TRUE(v_accum_ref.Init());
289+ ASSERT_TRUE(v_count_tst.Init());
290+ ASSERT_TRUE(v_accum_tst.Init());
291+
292+ // The difference between the buffers must be small to pass the
293+ // threshold to apply the filter.
294+ y_src.Set(&rnd_, 0, 7);
295+ y_pre.Set(&rnd_, 0, 7);
296+ u_src.Set(&rnd_, 0, 7);
297+ u_pre.Set(&rnd_, 0, 7);
298+ v_src.Set(&rnd_, 0, 7);
299+ v_pre.Set(&rnd_, 0, 7);
300+
301+ y_accum_ref.Set(rnd_.Rand8());
302+ y_accum_tst.CopyFrom(y_accum_ref);
303+ y_count_ref.Set(rnd_.Rand8());
304+ y_count_tst.CopyFrom(y_count_ref);
305+ u_accum_ref.Set(rnd_.Rand8());
306+ u_accum_tst.CopyFrom(u_accum_ref);
307+ u_count_ref.Set(rnd_.Rand8());
308+ u_count_tst.CopyFrom(u_count_ref);
309+ v_accum_ref.Set(rnd_.Rand8());
310+ v_accum_tst.CopyFrom(v_accum_ref);
311+ v_count_ref.Set(rnd_.Rand8());
312+ v_count_tst.CopyFrom(v_count_ref);
313+
314+ reference_filter(y_src, y_pre, u_src, v_src, u_pre, v_pre, width,
315+ height, ss_x, ss_y, filter_strength, &filter_weight,
316+ use_32x32, &y_accum_ref, &y_count_ref, &u_accum_ref,
317+ &u_count_ref, &v_accum_ref, &v_count_ref);
318+ ASM_REGISTER_STATE_CHECK(filter_func_(
319+ y_src.TopLeftPixel(), y_src.stride(), y_pre.TopLeftPixel(),
320+ y_pre.stride(), u_src.TopLeftPixel(), v_src.TopLeftPixel(),
321+ u_src.stride(), u_pre.TopLeftPixel(), v_pre.TopLeftPixel(),
322+ u_pre.stride(), width, height, ss_x, ss_y, filter_strength,
323+ &filter_weight, use_32x32, y_accum_tst.TopLeftPixel(),
324+ y_count_tst.TopLeftPixel(), u_accum_tst.TopLeftPixel(),
325+ u_count_tst.TopLeftPixel(), v_accum_tst.TopLeftPixel(),
326+ v_count_tst.TopLeftPixel()));
327+
328+ EXPECT_TRUE(y_accum_tst.CheckValues(y_accum_ref));
329+ EXPECT_TRUE(y_count_tst.CheckValues(y_count_ref));
330+ EXPECT_TRUE(u_accum_tst.CheckValues(u_accum_ref));
331+ EXPECT_TRUE(u_count_tst.CheckValues(u_count_ref));
332+ EXPECT_TRUE(v_accum_tst.CheckValues(v_accum_ref));
333+ EXPECT_TRUE(v_count_tst.CheckValues(v_count_ref));
334+
335+ if (HasFailure()) {
336+ printf("SS_X: %d, SS_Y: %d, Weight: %d, Strength: %d\n", ss_x, ss_y,
337+ filter_weight, filter_strength);
338+ y_accum_tst.PrintDifference(y_accum_ref);
339+ y_count_tst.PrintDifference(y_count_ref);
340+ u_accum_tst.PrintDifference(u_accum_ref);
341+ u_count_tst.PrintDifference(u_count_ref);
342+ v_accum_tst.PrintDifference(v_accum_ref);
343+ v_count_tst.PrintDifference(v_count_ref);
344+ return;
345+ }
346+ }
347+ }
348+ }
349+ }
350+}
351+
352+TEST_P(YUVTemporalFilterTest, USE_16X16) {
353+ const int width = 32, height = 32;
354+ Buffer<uint8_t> y_src = Buffer<uint8_t>(width, height, 8);
355+ Buffer<uint8_t> y_pre = Buffer<uint8_t>(width, height, 0);
356+ Buffer<uint16_t> y_count_ref = Buffer<uint16_t>(width, height, 0);
357+ Buffer<uint32_t> y_accum_ref = Buffer<uint32_t>(width, height, 0);
358+ Buffer<uint16_t> y_count_tst = Buffer<uint16_t>(width, height, 0);
359+ Buffer<uint32_t> y_accum_tst = Buffer<uint32_t>(width, height, 0);
360+ ASSERT_TRUE(y_src.Init());
361+ ASSERT_TRUE(y_pre.Init());
362+ ASSERT_TRUE(y_count_ref.Init());
363+ ASSERT_TRUE(y_accum_ref.Init());
364+ ASSERT_TRUE(y_count_tst.Init());
365+ ASSERT_TRUE(y_accum_tst.Init());
366+
367+ const int use_32x32 = 0;
368+
369+ for (int ss_x = 0; ss_x <= 1; ss_x++) {
370+ for (int ss_y = 0; ss_y <= 1; ss_y++) {
371+ for (int filter_idx = 0; filter_idx < 3 * 3 * 3 * 3; filter_idx++) {
372+ // Set up the filter
373+ int filter_weight[4];
374+ int filter_idx_cp = filter_idx;
375+ for (int idx = 0; idx < 4; idx++) {
376+ filter_weight[idx] = filter_idx_cp % 3;
377+ filter_idx_cp /= 3;
378+ }
379+
380+ // Test each parameter
381+ for (int filter_strength = 0; filter_strength <= 6;
382+ filter_strength += 2) {
383+ const int uv_width = width >> ss_x, uv_height = height >> ss_y;
384+ Buffer<uint8_t> u_src = Buffer<uint8_t>(uv_width, uv_height, 8);
385+ Buffer<uint8_t> u_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
386+ Buffer<uint16_t> u_count_ref =
387+ Buffer<uint16_t>(uv_width, uv_height, 0);
388+ Buffer<uint32_t> u_accum_ref =
389+ Buffer<uint32_t>(uv_width, uv_height, 0);
390+ Buffer<uint16_t> u_count_tst =
391+ Buffer<uint16_t>(uv_width, uv_height, 0);
392+ Buffer<uint32_t> u_accum_tst =
393+ Buffer<uint32_t>(uv_width, uv_height, 0);
394+ ASSERT_TRUE(u_src.Init());
395+ ASSERT_TRUE(u_pre.Init());
396+ ASSERT_TRUE(u_count_ref.Init());
397+ ASSERT_TRUE(u_accum_ref.Init());
398+ ASSERT_TRUE(u_count_tst.Init());
399+ ASSERT_TRUE(u_accum_tst.Init());
400+ Buffer<uint8_t> v_src = Buffer<uint8_t>(uv_width, uv_height, 8);
401+ Buffer<uint8_t> v_pre = Buffer<uint8_t>(uv_width, uv_height, 0);
402+ Buffer<uint16_t> v_count_ref =
403+ Buffer<uint16_t>(uv_width, uv_height, 0);
404+ Buffer<uint32_t> v_accum_ref =
405+ Buffer<uint32_t>(uv_width, uv_height, 0);
406+ Buffer<uint16_t> v_count_tst =
407+ Buffer<uint16_t>(uv_width, uv_height, 0);
408+ Buffer<uint32_t> v_accum_tst =
409+ Buffer<uint32_t>(uv_width, uv_height, 0);
410+ ASSERT_TRUE(v_src.Init());
411+ ASSERT_TRUE(v_pre.Init());
412+ ASSERT_TRUE(v_count_ref.Init());
413+ ASSERT_TRUE(v_accum_ref.Init());
414+ ASSERT_TRUE(v_count_tst.Init());
415+ ASSERT_TRUE(v_accum_tst.Init());
416+
417+ // The difference between the buffers must be small to pass the
418+ // threshold to apply the filter.
419+ y_src.Set(&rnd_, 0, 7);
420+ y_pre.Set(&rnd_, 0, 7);
421+ u_src.Set(&rnd_, 0, 7);
422+ u_pre.Set(&rnd_, 0, 7);
423+ v_src.Set(&rnd_, 0, 7);
424+ v_pre.Set(&rnd_, 0, 7);
425+
426+ y_accum_ref.Set(rnd_.Rand8());
427+ y_accum_tst.CopyFrom(y_accum_ref);
428+ y_count_ref.Set(rnd_.Rand8());
429+ y_count_tst.CopyFrom(y_count_ref);
430+ u_accum_ref.Set(rnd_.Rand8());
431+ u_accum_tst.CopyFrom(u_accum_ref);
432+ u_count_ref.Set(rnd_.Rand8());
433+ u_count_tst.CopyFrom(u_count_ref);
434+ v_accum_ref.Set(rnd_.Rand8());
435+ v_accum_tst.CopyFrom(v_accum_ref);
436+ v_count_ref.Set(rnd_.Rand8());
437+ v_count_tst.CopyFrom(v_count_ref);
438+
439+ reference_filter(y_src, y_pre, u_src, v_src, u_pre, v_pre, width,
440+ height, ss_x, ss_y, filter_strength, filter_weight,
441+ use_32x32, &y_accum_ref, &y_count_ref, &u_accum_ref,
442+ &u_count_ref, &v_accum_ref, &v_count_ref);
443+ ASM_REGISTER_STATE_CHECK(filter_func_(
444+ y_src.TopLeftPixel(), y_src.stride(), y_pre.TopLeftPixel(),
445+ y_pre.stride(), u_src.TopLeftPixel(), v_src.TopLeftPixel(),
446+ u_src.stride(), u_pre.TopLeftPixel(), v_pre.TopLeftPixel(),
447+ u_pre.stride(), width, height, ss_x, ss_y, filter_strength,
448+ filter_weight, use_32x32, y_accum_tst.TopLeftPixel(),
449+ y_count_tst.TopLeftPixel(), u_accum_tst.TopLeftPixel(),
450+ u_count_tst.TopLeftPixel(), v_accum_tst.TopLeftPixel(),
451+ v_count_tst.TopLeftPixel()));
452+
453+ EXPECT_TRUE(y_accum_tst.CheckValues(y_accum_ref));
454+ EXPECT_TRUE(y_count_tst.CheckValues(y_count_ref));
455+ EXPECT_TRUE(u_accum_tst.CheckValues(u_accum_ref));
456+ EXPECT_TRUE(u_count_tst.CheckValues(u_count_ref));
457+ EXPECT_TRUE(v_accum_tst.CheckValues(v_accum_ref));
458+ EXPECT_TRUE(v_count_tst.CheckValues(v_count_ref));
459+
460+ if (HasFailure()) {
461+ printf("SS_X: %d, SS_Y: %d, Weight Idx: %d, Strength: %d\n", ss_x,
462+ ss_y, filter_idx, filter_strength);
463+ y_accum_tst.PrintDifference(y_accum_ref);
464+ y_count_tst.PrintDifference(y_count_ref);
465+ u_accum_tst.PrintDifference(u_accum_ref);
466+ u_count_tst.PrintDifference(u_count_ref);
467+ v_accum_tst.PrintDifference(v_accum_ref);
468+ v_count_tst.PrintDifference(v_count_ref);
469+ return;
470+ }
471+ }
472+ }
473+ }
474+ }
475+}
476+
477+INSTANTIATE_TEST_CASE_P(C, YUVTemporalFilterTest,
478+ ::testing::Values(&vp9_apply_temporal_filter));
479+} // namespace

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t