| @@ -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 |