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