1 /*
2 * Copyright (c) 2012 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.h>
12
13 #include <memory>
14
15 #include "./vpx_config.h"
16 #include "./vpx_dsp_rtcd.h"
17 #include "gtest/gtest.h"
18 #include "test/acm_random.h"
19 #include "test/bench.h"
20 #include "test/buffer.h"
21 #include "test/clear_system_state.h"
22 #include "test/register_state_check.h"
23 #include "vpx/vpx_integer.h"
24 #include "vpx_mem/vpx_mem.h"
25
26 using libvpx_test::ACMRandom;
27 using libvpx_test::Buffer;
28
29 typedef void (*VpxPostProcDownAndAcrossMbRowFunc)(
30 unsigned char *src_ptr, unsigned char *dst_ptr, int src_pixels_per_line,
31 int dst_pixels_per_line, int cols, unsigned char *flimit, int size);
32
33 typedef void (*VpxMbPostProcAcrossIpFunc)(unsigned char *src, int pitch,
34 int rows, int cols, int flimit);
35
36 typedef void (*VpxMbPostProcDownFunc)(unsigned char *dst, int pitch, int rows,
37 int cols, int flimit);
38
39 namespace {
40 // Compute the filter level used in post proc from the loop filter strength
q2mbl(int x)41 int q2mbl(int x) {
42 if (x < 20) x = 20;
43
44 x = 50 + (x - 50) * 10 / 8;
45 return x * x / 3;
46 }
47
48 class VpxPostProcDownAndAcrossMbRowTest
49 : public AbstractBench,
50 public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
51 public:
VpxPostProcDownAndAcrossMbRowTest()52 VpxPostProcDownAndAcrossMbRowTest()
53 : mb_post_proc_down_and_across_(GetParam()) {}
TearDown()54 void TearDown() override { libvpx_test::ClearSystemState(); }
55
56 protected:
57 void Run() override;
58
59 const VpxPostProcDownAndAcrossMbRowFunc mb_post_proc_down_and_across_;
60 // Size of the underlying data block that will be filtered.
61 int block_width_;
62 int block_height_;
63 Buffer<uint8_t> *src_image_;
64 Buffer<uint8_t> *dst_image_;
65 uint8_t *flimits_;
66 };
67
Run()68 void VpxPostProcDownAndAcrossMbRowTest::Run() {
69 mb_post_proc_down_and_across_(
70 src_image_->TopLeftPixel(), dst_image_->TopLeftPixel(),
71 src_image_->stride(), dst_image_->stride(), block_width_, flimits_, 16);
72 }
73
74 // Test routine for the VPx post-processing function
75 // vpx_post_proc_down_and_across_mb_row_c.
76
TEST_P(VpxPostProcDownAndAcrossMbRowTest,CheckFilterOutput)77 TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
78 // Size of the underlying data block that will be filtered.
79 block_width_ = 16;
80 block_height_ = 16;
81
82 // 5-tap filter needs 2 padding rows above and below the block in the input.
83 Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
84 ASSERT_TRUE(src_image.Init());
85
86 // Filter extends output block by 8 samples at left and right edges.
87 // Though the left padding is only 8 bytes, the assembly code tries to
88 // read 16 bytes before the pointer.
89 Buffer<uint8_t> dst_image =
90 Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
91 ASSERT_TRUE(dst_image.Init());
92
93 flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
94 (void)memset(flimits_, 255, block_width_);
95
96 // Initialize pixels in the input:
97 // block pixels to value 1,
98 // border pixels to value 10.
99 src_image.SetPadding(10);
100 src_image.Set(1);
101
102 // Initialize pixels in the output to 99.
103 dst_image.Set(99);
104
105 ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
106 src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
107 dst_image.stride(), block_width_, flimits_, 16));
108
109 static const uint8_t kExpectedOutput[] = { 4, 3, 1, 1, 1, 1, 1, 1,
110 1, 1, 1, 1, 1, 1, 3, 4 };
111
112 uint8_t *pixel_ptr = dst_image.TopLeftPixel();
113 for (int i = 0; i < block_height_; ++i) {
114 for (int j = 0; j < block_width_; ++j) {
115 ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
116 << "at (" << i << ", " << j << ")";
117 }
118 pixel_ptr += dst_image.stride();
119 }
120
121 vpx_free(flimits_);
122 }
123
TEST_P(VpxPostProcDownAndAcrossMbRowTest,CheckCvsAssembly)124 TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
125 // Size of the underlying data block that will be filtered.
126 // Y blocks are always a multiple of 16 wide and exactly 16 high. U and V
127 // blocks are always a multiple of 8 wide and exactly 8 high.
128 block_width_ = 136;
129 block_height_ = 16;
130
131 // 5-tap filter needs 2 padding rows above and below the block in the input.
132 // SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
133 Buffer<uint8_t> src_image =
134 Buffer<uint8_t>(block_width_, block_height_, 2, 2, 10, 2);
135 ASSERT_TRUE(src_image.Init());
136
137 // Filter extends output block by 8 samples at left and right edges.
138 // Though the left padding is only 8 bytes, there is 'above' padding as well
139 // so when the assembly code tries to read 16 bytes before the pointer it is
140 // not a problem.
141 // SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
142 Buffer<uint8_t> dst_image =
143 Buffer<uint8_t>(block_width_, block_height_, 8, 8, 16, 8);
144 ASSERT_TRUE(dst_image.Init());
145 Buffer<uint8_t> dst_image_ref =
146 Buffer<uint8_t>(block_width_, block_height_, 8);
147 ASSERT_TRUE(dst_image_ref.Init());
148
149 // Filter values are set in blocks of 16 for Y and 8 for U/V. Each macroblock
150 // can have a different filter. SSE2 assembly reads flimits in blocks of 16 so
151 // it must be padded out.
152 const int flimits_width = block_width_ % 16 ? block_width_ + 8 : block_width_;
153 flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
154
155 ACMRandom rnd;
156 rnd.Reset(ACMRandom::DeterministicSeed());
157 // Initialize pixels in the input:
158 // block pixels to random values.
159 // border pixels to value 10.
160 src_image.SetPadding(10);
161 src_image.Set(&rnd, &ACMRandom::Rand8);
162
163 for (int blocks = 0; blocks < block_width_; blocks += 8) {
164 (void)memset(flimits_, 0, sizeof(*flimits_) * flimits_width);
165
166 for (int f = 0; f < 255; f++) {
167 (void)memset(flimits_ + blocks, f, sizeof(*flimits_) * 8);
168 dst_image.Set(0);
169 dst_image_ref.Set(0);
170
171 vpx_post_proc_down_and_across_mb_row_c(
172 src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(),
173 src_image.stride(), dst_image_ref.stride(), block_width_, flimits_,
174 block_height_);
175 ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
176 src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
177 src_image.stride(), dst_image.stride(), block_width_, flimits_,
178 block_height_));
179
180 ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
181 }
182 }
183
184 vpx_free(flimits_);
185 }
186
TEST_P(VpxPostProcDownAndAcrossMbRowTest,DISABLED_Speed)187 TEST_P(VpxPostProcDownAndAcrossMbRowTest, DISABLED_Speed) {
188 // Size of the underlying data block that will be filtered.
189 block_width_ = 16;
190 block_height_ = 16;
191
192 // 5-tap filter needs 2 padding rows above and below the block in the input.
193 Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
194 ASSERT_TRUE(src_image.Init());
195 this->src_image_ = &src_image;
196
197 // Filter extends output block by 8 samples at left and right edges.
198 // Though the left padding is only 8 bytes, the assembly code tries to
199 // read 16 bytes before the pointer.
200 Buffer<uint8_t> dst_image =
201 Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
202 ASSERT_TRUE(dst_image.Init());
203 this->dst_image_ = &dst_image;
204
205 flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
206 (void)memset(flimits_, 255, block_width_);
207
208 // Initialize pixels in the input:
209 // block pixels to value 1,
210 // border pixels to value 10.
211 src_image.SetPadding(10);
212 src_image.Set(1);
213
214 // Initialize pixels in the output to 99.
215 dst_image.Set(99);
216
217 RunNTimes(INT16_MAX);
218 PrintMedian("16x16");
219
220 vpx_free(flimits_);
221 }
222
223 class VpxMbPostProcAcrossIpTest
224 : public AbstractBench,
225 public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
226 public:
VpxMbPostProcAcrossIpTest()227 VpxMbPostProcAcrossIpTest()
228 : rows_(16), cols_(16), mb_post_proc_across_ip_(GetParam()),
229 src_(Buffer<uint8_t>(rows_, cols_, 8, 8, 17, 8)) {}
TearDown()230 void TearDown() override { libvpx_test::ClearSystemState(); }
231
232 protected:
233 void Run() override;
234
SetCols(unsigned char * s,int rows,int cols,int src_width)235 void SetCols(unsigned char *s, int rows, int cols, int src_width) {
236 for (int r = 0; r < rows; r++) {
237 for (int c = 0; c < cols; c++) {
238 s[c] = c;
239 }
240 s += src_width;
241 }
242 }
243
RunComparison(const unsigned char * expected_output,unsigned char * src_c,int rows,int cols,int src_pitch)244 void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
245 int rows, int cols, int src_pitch) {
246 for (int r = 0; r < rows; r++) {
247 for (int c = 0; c < cols; c++) {
248 ASSERT_EQ(expected_output[c], src_c[c])
249 << "at (" << r << ", " << c << ")";
250 }
251 src_c += src_pitch;
252 }
253 }
254
RunFilterLevel(unsigned char * s,int rows,int cols,int src_width,int filter_level,const unsigned char * expected_output)255 void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
256 int filter_level, const unsigned char *expected_output) {
257 ASM_REGISTER_STATE_CHECK(
258 GetParam()(s, src_width, rows, cols, filter_level));
259 RunComparison(expected_output, s, rows, cols, src_width);
260 }
261
262 const int rows_;
263 const int cols_;
264 const VpxMbPostProcAcrossIpFunc mb_post_proc_across_ip_;
265 Buffer<uint8_t> src_;
266 };
267
Run()268 void VpxMbPostProcAcrossIpTest::Run() {
269 mb_post_proc_across_ip_(src_.TopLeftPixel(), src_.stride(), rows_, cols_,
270 q2mbl(0));
271 }
272
TEST_P(VpxMbPostProcAcrossIpTest,CheckLowFilterOutput)273 TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
274 ASSERT_TRUE(src_.Init());
275 src_.SetPadding(10);
276 SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
277
278 Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols_, rows_, 0);
279 ASSERT_TRUE(expected_output.Init());
280 SetCols(expected_output.TopLeftPixel(), rows_, cols_,
281 expected_output.stride());
282
283 RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(0),
284 expected_output.TopLeftPixel());
285 }
286
TEST_P(VpxMbPostProcAcrossIpTest,CheckMediumFilterOutput)287 TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
288 ASSERT_TRUE(src_.Init());
289 src_.SetPadding(10);
290 SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
291
292 static const unsigned char kExpectedOutput[] = {
293 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
294 };
295
296 RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(70),
297 kExpectedOutput);
298 }
299
TEST_P(VpxMbPostProcAcrossIpTest,CheckHighFilterOutput)300 TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
301 ASSERT_TRUE(src_.Init());
302 src_.SetPadding(10);
303 SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
304
305 static const unsigned char kExpectedOutput[] = {
306 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
307 };
308
309 RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), INT_MAX,
310 kExpectedOutput);
311
312 SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
313
314 RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(100),
315 kExpectedOutput);
316 }
317
TEST_P(VpxMbPostProcAcrossIpTest,CheckCvsAssembly)318 TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
319 Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
320 ASSERT_TRUE(c_mem.Init());
321 Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
322 ASSERT_TRUE(asm_mem.Init());
323
324 // When level >= 100, the filter behaves the same as the level = INT_MAX
325 // When level < 20, it behaves the same as the level = 0
326 for (int level = 0; level < 100; level++) {
327 c_mem.SetPadding(10);
328 asm_mem.SetPadding(10);
329 SetCols(c_mem.TopLeftPixel(), rows_, cols_, c_mem.stride());
330 SetCols(asm_mem.TopLeftPixel(), rows_, cols_, asm_mem.stride());
331
332 vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows_,
333 cols_, q2mbl(level));
334 ASM_REGISTER_STATE_CHECK(GetParam()(
335 asm_mem.TopLeftPixel(), asm_mem.stride(), rows_, cols_, q2mbl(level)));
336
337 ASSERT_TRUE(asm_mem.CheckValues(c_mem));
338 }
339 }
340
TEST_P(VpxMbPostProcAcrossIpTest,DISABLED_Speed)341 TEST_P(VpxMbPostProcAcrossIpTest, DISABLED_Speed) {
342 ASSERT_TRUE(src_.Init());
343 src_.SetPadding(10);
344
345 SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
346
347 RunNTimes(100000);
348 PrintMedian("16x16");
349 }
350
351 class VpxMbPostProcDownTest
352 : public AbstractBench,
353 public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
354 public:
VpxMbPostProcDownTest()355 VpxMbPostProcDownTest()
356 : rows_(16), cols_(16), mb_post_proc_down_(GetParam()),
357 src_c_(Buffer<uint8_t>(rows_, cols_, 8, 8, 8, 17)) {}
358
TearDown()359 void TearDown() override { libvpx_test::ClearSystemState(); }
360
361 protected:
362 void Run() override;
363
SetRows(unsigned char * src_c,int rows,int cols,int src_width)364 void SetRows(unsigned char *src_c, int rows, int cols, int src_width) {
365 for (int r = 0; r < rows; r++) {
366 memset(src_c, r, cols);
367 src_c += src_width;
368 }
369 }
370
RunComparison(const unsigned char * expected_output,unsigned char * src_c,int rows,int cols,int src_pitch)371 void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
372 int rows, int cols, int src_pitch) {
373 for (int r = 0; r < rows; r++) {
374 for (int c = 0; c < cols; c++) {
375 ASSERT_EQ(expected_output[r * rows + c], src_c[c])
376 << "at (" << r << ", " << c << ")";
377 }
378 src_c += src_pitch;
379 }
380 }
381
RunFilterLevel(unsigned char * s,int rows,int cols,int src_width,int filter_level,const unsigned char * expected_output)382 void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
383 int filter_level, const unsigned char *expected_output) {
384 ASM_REGISTER_STATE_CHECK(
385 mb_post_proc_down_(s, src_width, rows, cols, filter_level));
386 RunComparison(expected_output, s, rows, cols, src_width);
387 }
388
389 const int rows_;
390 const int cols_;
391 const VpxMbPostProcDownFunc mb_post_proc_down_;
392 Buffer<uint8_t> src_c_;
393 };
394
Run()395 void VpxMbPostProcDownTest::Run() {
396 mb_post_proc_down_(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
397 q2mbl(0));
398 }
399
TEST_P(VpxMbPostProcDownTest,CheckHighFilterOutput)400 TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
401 ASSERT_TRUE(src_c_.Init());
402 src_c_.SetPadding(10);
403
404 SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
405
406 static const unsigned char kExpectedOutput[] = {
407 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
408 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3,
409 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 3, 3,
410 4, 4, 3, 4, 4, 3, 3, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4,
411 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
412 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
413 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
414 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 9,
415 9, 8, 9, 9, 8, 8, 8, 9, 9, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10,
416 9, 9, 9, 10, 10, 10, 11, 10, 10, 10, 11, 10, 11, 10, 11, 10, 10, 10, 11,
417 10, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 12, 11, 12,
418 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12,
419 13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
420 13, 13, 13, 13, 14, 13, 13, 13, 13
421 };
422
423 RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), INT_MAX,
424 kExpectedOutput);
425
426 src_c_.SetPadding(10);
427 SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
428 RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
429 q2mbl(100), kExpectedOutput);
430 }
431
TEST_P(VpxMbPostProcDownTest,CheckMediumFilterOutput)432 TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
433 ASSERT_TRUE(src_c_.Init());
434 src_c_.SetPadding(10);
435
436 SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
437
438 static const unsigned char kExpectedOutput[] = {
439 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
440 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
441 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
442 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
443 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
444 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
445 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
446 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
447 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
448 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
449 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
450 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 13, 12,
451 13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
452 13, 13, 13, 13, 14, 13, 13, 13, 13
453 };
454
455 RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
456 q2mbl(70), kExpectedOutput);
457 }
458
TEST_P(VpxMbPostProcDownTest,CheckLowFilterOutput)459 TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
460 ASSERT_TRUE(src_c_.Init());
461 src_c_.SetPadding(10);
462
463 SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
464
465 std::unique_ptr<unsigned char[]> expected_output(
466 new unsigned char[rows_ * cols_]);
467 ASSERT_NE(expected_output, nullptr);
468 SetRows(expected_output.get(), rows_, cols_, cols_);
469
470 RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), q2mbl(0),
471 expected_output.get());
472 }
473
TEST_P(VpxMbPostProcDownTest,CheckCvsAssembly)474 TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
475 ACMRandom rnd;
476 rnd.Reset(ACMRandom::DeterministicSeed());
477
478 ASSERT_TRUE(src_c_.Init());
479 Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols_, rows_, 8, 8, 8, 17);
480 ASSERT_TRUE(src_asm.Init());
481
482 for (int level = 0; level < 100; level++) {
483 src_c_.SetPadding(10);
484 src_asm.SetPadding(10);
485 src_c_.Set(&rnd, &ACMRandom::Rand8);
486 src_asm.CopyFrom(src_c_);
487
488 vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
489 q2mbl(level));
490 ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
491 src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
492 ASSERT_TRUE(src_asm.CheckValues(src_c_));
493
494 src_c_.SetPadding(10);
495 src_asm.SetPadding(10);
496 src_c_.Set(&rnd, &ACMRandom::Rand8Extremes);
497 src_asm.CopyFrom(src_c_);
498
499 vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
500 q2mbl(level));
501 ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
502 src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
503 ASSERT_TRUE(src_asm.CheckValues(src_c_));
504 }
505 }
506
TEST_P(VpxMbPostProcDownTest,DISABLED_Speed)507 TEST_P(VpxMbPostProcDownTest, DISABLED_Speed) {
508 ASSERT_TRUE(src_c_.Init());
509 src_c_.SetPadding(10);
510
511 SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
512
513 RunNTimes(100000);
514 PrintMedian("16x16");
515 }
516
517 INSTANTIATE_TEST_SUITE_P(
518 C, VpxPostProcDownAndAcrossMbRowTest,
519 ::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
520
521 INSTANTIATE_TEST_SUITE_P(C, VpxMbPostProcAcrossIpTest,
522 ::testing::Values(vpx_mbpost_proc_across_ip_c));
523
524 INSTANTIATE_TEST_SUITE_P(C, VpxMbPostProcDownTest,
525 ::testing::Values(vpx_mbpost_proc_down_c));
526
527 #if HAVE_SSE2
528 INSTANTIATE_TEST_SUITE_P(
529 SSE2, VpxPostProcDownAndAcrossMbRowTest,
530 ::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
531
532 INSTANTIATE_TEST_SUITE_P(SSE2, VpxMbPostProcAcrossIpTest,
533 ::testing::Values(vpx_mbpost_proc_across_ip_sse2));
534
535 INSTANTIATE_TEST_SUITE_P(SSE2, VpxMbPostProcDownTest,
536 ::testing::Values(vpx_mbpost_proc_down_sse2));
537 #endif // HAVE_SSE2
538
539 #if HAVE_NEON
540 INSTANTIATE_TEST_SUITE_P(
541 NEON, VpxPostProcDownAndAcrossMbRowTest,
542 ::testing::Values(vpx_post_proc_down_and_across_mb_row_neon));
543
544 INSTANTIATE_TEST_SUITE_P(NEON, VpxMbPostProcAcrossIpTest,
545 ::testing::Values(vpx_mbpost_proc_across_ip_neon));
546
547 INSTANTIATE_TEST_SUITE_P(NEON, VpxMbPostProcDownTest,
548 ::testing::Values(vpx_mbpost_proc_down_neon));
549 #endif // HAVE_NEON
550
551 #if HAVE_MSA
552 INSTANTIATE_TEST_SUITE_P(
553 MSA, VpxPostProcDownAndAcrossMbRowTest,
554 ::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
555
556 INSTANTIATE_TEST_SUITE_P(MSA, VpxMbPostProcAcrossIpTest,
557 ::testing::Values(vpx_mbpost_proc_across_ip_msa));
558
559 INSTANTIATE_TEST_SUITE_P(MSA, VpxMbPostProcDownTest,
560 ::testing::Values(vpx_mbpost_proc_down_msa));
561 #endif // HAVE_MSA
562
563 #if HAVE_VSX
564 INSTANTIATE_TEST_SUITE_P(
565 VSX, VpxPostProcDownAndAcrossMbRowTest,
566 ::testing::Values(vpx_post_proc_down_and_across_mb_row_vsx));
567
568 INSTANTIATE_TEST_SUITE_P(VSX, VpxMbPostProcAcrossIpTest,
569 ::testing::Values(vpx_mbpost_proc_across_ip_vsx));
570
571 INSTANTIATE_TEST_SUITE_P(VSX, VpxMbPostProcDownTest,
572 ::testing::Values(vpx_mbpost_proc_down_vsx));
573 #endif // HAVE_VSX
574
575 } // namespace
576