Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /*
2 * Copyright 2011 The LibYuv 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 */
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
15 #include "../unit_test/unit_test.h"
16 #include "libyuv/basic_types.h"
17 #include "libyuv/compare.h"
18 #include "libyuv/cpu_id.h"
19 #include "libyuv/row.h"
21 namespace libyuv {
23 // hash seed of 5381 recommended.
24 static uint32 ReferenceHashDjb2(const uint8* src, uint64 count, uint32 seed) {
25 uint32 hash = seed;
26 if (count > 0) {
27 do {
28 hash = hash * 33 + *src++;
29 } while (--count);
30 }
31 return hash;
32 }
34 TEST_F(libyuvTest, Djb2_Test) {
35 const int kMaxTest = benchmark_width_ * benchmark_height_;
36 align_buffer_64(src_a, kMaxTest);
37 align_buffer_64(src_b, kMaxTest);
39 const char* fox = "The quick brown fox jumps over the lazy dog"
40 " and feels as if he were in the seventh heaven of typography"
41 " together with Hermann Zapf";
42 uint32 foxhash = HashDjb2(reinterpret_cast<const uint8*>(fox), 131, 5381);
43 const uint32 kExpectedFoxHash = 2611006483u;
44 EXPECT_EQ(kExpectedFoxHash, foxhash);
46 for (int i = 0; i < kMaxTest; ++i) {
47 src_a[i] = (random() & 0xff);
48 src_b[i] = (random() & 0xff);
49 }
50 // Compare different buffers. Expect hash is different.
51 uint32 h1 = HashDjb2(src_a, kMaxTest, 5381);
52 uint32 h2 = HashDjb2(src_b, kMaxTest, 5381);
53 EXPECT_NE(h1, h2);
55 // Make last half same. Expect hash is different.
56 memcpy(src_a + kMaxTest / 2, src_b + kMaxTest / 2, kMaxTest / 2);
57 h1 = HashDjb2(src_a, kMaxTest, 5381);
58 h2 = HashDjb2(src_b, kMaxTest, 5381);
59 EXPECT_NE(h1, h2);
61 // Make first half same. Expect hash is different.
62 memcpy(src_a + kMaxTest / 2, src_a, kMaxTest / 2);
63 memcpy(src_b + kMaxTest / 2, src_b, kMaxTest / 2);
64 memcpy(src_a, src_b, kMaxTest / 2);
65 h1 = HashDjb2(src_a, kMaxTest, 5381);
66 h2 = HashDjb2(src_b, kMaxTest, 5381);
67 EXPECT_NE(h1, h2);
69 // Make same. Expect hash is same.
70 memcpy(src_a, src_b, kMaxTest);
71 h1 = HashDjb2(src_a, kMaxTest, 5381);
72 h2 = HashDjb2(src_b, kMaxTest, 5381);
73 EXPECT_EQ(h1, h2);
75 // Mask seed different. Expect hash is different.
76 memcpy(src_a, src_b, kMaxTest);
77 h1 = HashDjb2(src_a, kMaxTest, 5381);
78 h2 = HashDjb2(src_b, kMaxTest, 1234);
79 EXPECT_NE(h1, h2);
81 // Make one byte different in middle. Expect hash is different.
82 memcpy(src_a, src_b, kMaxTest);
83 ++src_b[kMaxTest / 2];
84 h1 = HashDjb2(src_a, kMaxTest, 5381);
85 h2 = HashDjb2(src_b, kMaxTest, 5381);
86 EXPECT_NE(h1, h2);
88 // Make first byte different. Expect hash is different.
89 memcpy(src_a, src_b, kMaxTest);
90 ++src_b[0];
91 h1 = HashDjb2(src_a, kMaxTest, 5381);
92 h2 = HashDjb2(src_b, kMaxTest, 5381);
93 EXPECT_NE(h1, h2);
95 // Make last byte different. Expect hash is different.
96 memcpy(src_a, src_b, kMaxTest);
97 ++src_b[kMaxTest - 1];
98 h1 = HashDjb2(src_a, kMaxTest, 5381);
99 h2 = HashDjb2(src_b, kMaxTest, 5381);
100 EXPECT_NE(h1, h2);
102 // Make a zeros. Test different lengths. Expect hash is different.
103 memset(src_a, 0, kMaxTest);
104 h1 = HashDjb2(src_a, kMaxTest, 5381);
105 h2 = HashDjb2(src_a, kMaxTest / 2, 5381);
106 EXPECT_NE(h1, h2);
108 // Make a zeros and seed of zero. Test different lengths. Expect hash is same.
109 memset(src_a, 0, kMaxTest);
110 h1 = HashDjb2(src_a, kMaxTest, 0);
111 h2 = HashDjb2(src_a, kMaxTest / 2, 0);
112 EXPECT_EQ(h1, h2);
114 free_aligned_buffer_64(src_a);
115 free_aligned_buffer_64(src_b);
116 }
118 TEST_F(libyuvTest, BenchmarkDjb2_Opt) {
119 const int kMaxTest = benchmark_width_ * benchmark_height_;
120 align_buffer_64(src_a, kMaxTest);
122 for (int i = 0; i < kMaxTest; ++i) {
123 src_a[i] = i;
124 }
125 uint32 h2 = ReferenceHashDjb2(src_a, kMaxTest, 5381);
126 uint32 h1;
127 for (int i = 0; i < benchmark_iterations_; ++i) {
128 h1 = HashDjb2(src_a, kMaxTest, 5381);
129 }
130 EXPECT_EQ(h1, h2);
131 free_aligned_buffer_64(src_a);
132 }
134 TEST_F(libyuvTest, BenchmarkDjb2_Unaligned) {
135 const int kMaxTest = benchmark_width_ * benchmark_height_;
136 align_buffer_64(src_a, kMaxTest + 1);
137 for (int i = 0; i < kMaxTest; ++i) {
138 src_a[i + 1] = i;
139 }
140 uint32 h2 = ReferenceHashDjb2(src_a + 1, kMaxTest, 5381);
141 uint32 h1;
142 for (int i = 0; i < benchmark_iterations_; ++i) {
143 h1 = HashDjb2(src_a + 1, kMaxTest, 5381);
144 }
145 EXPECT_EQ(h1, h2);
146 free_aligned_buffer_64(src_a);
147 }
149 TEST_F(libyuvTest, BenchmarkSumSquareError_Opt) {
150 const int kMaxWidth = 4096 * 3;
151 align_buffer_64(src_a, kMaxWidth);
152 align_buffer_64(src_b, kMaxWidth);
153 memset(src_a, 0, kMaxWidth);
154 memset(src_b, 0, kMaxWidth);
156 memcpy(src_a, "test0123test4567", 16);
157 memcpy(src_b, "tick0123tock4567", 16);
158 uint64 h1 = ComputeSumSquareError(src_a, src_b, 16);
159 EXPECT_EQ(790u, h1);
161 for (int i = 0; i < kMaxWidth; ++i) {
162 src_a[i] = i;
163 src_b[i] = i;
164 }
165 memset(src_a, 0, kMaxWidth);
166 memset(src_b, 0, kMaxWidth);
168 int count = benchmark_iterations_ *
169 ((benchmark_width_ * benchmark_height_ + kMaxWidth - 1) / kMaxWidth);
170 for (int i = 0; i < count; ++i) {
171 h1 = ComputeSumSquareError(src_a, src_b, kMaxWidth);
172 }
174 EXPECT_EQ(0, h1);
176 free_aligned_buffer_64(src_a);
177 free_aligned_buffer_64(src_b);
178 }
180 TEST_F(libyuvTest, SumSquareError) {
181 const int kMaxWidth = 4096 * 3;
182 align_buffer_64(src_a, kMaxWidth);
183 align_buffer_64(src_b, kMaxWidth);
184 memset(src_a, 0, kMaxWidth);
185 memset(src_b, 0, kMaxWidth);
187 uint64 err;
188 err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
190 EXPECT_EQ(0, err);
192 memset(src_a, 1, kMaxWidth);
193 err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
195 EXPECT_EQ(err, kMaxWidth);
197 memset(src_a, 190, kMaxWidth);
198 memset(src_b, 193, kMaxWidth);
199 err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
201 EXPECT_EQ(kMaxWidth * 3 * 3, err);
203 srandom(time(NULL));
205 for (int i = 0; i < kMaxWidth; ++i) {
206 src_a[i] = (random() & 0xff);
207 src_b[i] = (random() & 0xff);
208 }
210 MaskCpuFlags(0);
211 uint64 c_err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
213 MaskCpuFlags(-1);
214 uint64 opt_err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
216 EXPECT_EQ(c_err, opt_err);
218 free_aligned_buffer_64(src_a);
219 free_aligned_buffer_64(src_b);
220 }
222 TEST_F(libyuvTest, BenchmarkPsnr_Opt) {
223 align_buffer_64(src_a, benchmark_width_ * benchmark_height_);
224 align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
225 for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
226 src_a[i] = i;
227 src_b[i] = i;
228 }
230 MaskCpuFlags(-1);
232 double opt_time = get_time();
233 for (int i = 0; i < benchmark_iterations_; ++i)
234 CalcFramePsnr(src_a, benchmark_width_,
235 src_b, benchmark_width_,
236 benchmark_width_, benchmark_height_);
238 opt_time = (get_time() - opt_time) / benchmark_iterations_;
239 printf("BenchmarkPsnr_Opt - %8.2f us opt\n", opt_time * 1e6);
241 EXPECT_EQ(0, 0);
243 free_aligned_buffer_64(src_a);
244 free_aligned_buffer_64(src_b);
245 }
247 TEST_F(libyuvTest, Psnr) {
248 const int kSrcWidth = benchmark_width_;
249 const int kSrcHeight = benchmark_height_;
250 const int b = 128;
251 const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
252 const int kSrcStride = 2 * b + kSrcWidth;
253 align_buffer_64(src_a, kSrcPlaneSize);
254 align_buffer_64(src_b, kSrcPlaneSize);
255 memset(src_a, 0, kSrcPlaneSize);
256 memset(src_b, 0, kSrcPlaneSize);
258 double err;
259 err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
260 src_b + kSrcStride * b + b, kSrcStride,
261 kSrcWidth, kSrcHeight);
263 EXPECT_EQ(err, kMaxPsnr);
265 memset(src_a, 255, kSrcPlaneSize);
267 err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
268 src_b + kSrcStride * b + b, kSrcStride,
269 kSrcWidth, kSrcHeight);
271 EXPECT_EQ(err, 0.0);
273 memset(src_a, 1, kSrcPlaneSize);
275 err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
276 src_b + kSrcStride * b + b, kSrcStride,
277 kSrcWidth, kSrcHeight);
279 EXPECT_GT(err, 48.0);
280 EXPECT_LT(err, 49.0);
282 for (int i = 0; i < kSrcPlaneSize; ++i) {
283 src_a[i] = i;
284 }
286 err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
287 src_b + kSrcStride * b + b, kSrcStride,
288 kSrcWidth, kSrcHeight);
290 EXPECT_GT(err, 2.0);
291 if (kSrcWidth * kSrcHeight >= 256) {
292 EXPECT_LT(err, 6.0);
293 }
295 srandom(time(NULL));
297 memset(src_a, 0, kSrcPlaneSize);
298 memset(src_b, 0, kSrcPlaneSize);
300 for (int i = b; i < (kSrcHeight + b); ++i) {
301 for (int j = b; j < (kSrcWidth + b); ++j) {
302 src_a[(i * kSrcStride) + j] = (random() & 0xff);
303 src_b[(i * kSrcStride) + j] = (random() & 0xff);
304 }
305 }
307 MaskCpuFlags(0);
308 double c_err, opt_err;
310 c_err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
311 src_b + kSrcStride * b + b, kSrcStride,
312 kSrcWidth, kSrcHeight);
314 MaskCpuFlags(-1);
316 opt_err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
317 src_b + kSrcStride * b + b, kSrcStride,
318 kSrcWidth, kSrcHeight);
320 EXPECT_EQ(opt_err, c_err);
322 free_aligned_buffer_64(src_a);
323 free_aligned_buffer_64(src_b);
324 }
326 TEST_F(libyuvTest, DISABLED_BenchmarkSsim_Opt) {
327 align_buffer_64(src_a, benchmark_width_ * benchmark_height_);
328 align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
329 for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
330 src_a[i] = i;
331 src_b[i] = i;
332 }
334 MaskCpuFlags(-1);
336 double opt_time = get_time();
337 for (int i = 0; i < benchmark_iterations_; ++i)
338 CalcFrameSsim(src_a, benchmark_width_,
339 src_b, benchmark_width_,
340 benchmark_width_, benchmark_height_);
342 opt_time = (get_time() - opt_time) / benchmark_iterations_;
343 printf("BenchmarkSsim_Opt - %8.2f us opt\n", opt_time * 1e6);
345 EXPECT_EQ(0, 0); // Pass if we get this far.
347 free_aligned_buffer_64(src_a);
348 free_aligned_buffer_64(src_b);
349 }
351 TEST_F(libyuvTest, Ssim) {
352 const int kSrcWidth = benchmark_width_;
353 const int kSrcHeight = benchmark_height_;
354 const int b = 128;
355 const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
356 const int kSrcStride = 2 * b + kSrcWidth;
357 align_buffer_64(src_a, kSrcPlaneSize);
358 align_buffer_64(src_b, kSrcPlaneSize);
359 memset(src_a, 0, kSrcPlaneSize);
360 memset(src_b, 0, kSrcPlaneSize);
362 if (kSrcWidth <=8 || kSrcHeight <= 8) {
363 printf("warning - Ssim size too small. Testing function executes.\n");
364 }
366 double err;
367 err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
368 src_b + kSrcStride * b + b, kSrcStride,
369 kSrcWidth, kSrcHeight);
371 if (kSrcWidth > 8 && kSrcHeight > 8) {
372 EXPECT_EQ(err, 1.0);
373 }
375 memset(src_a, 255, kSrcPlaneSize);
377 err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
378 src_b + kSrcStride * b + b, kSrcStride,
379 kSrcWidth, kSrcHeight);
381 if (kSrcWidth > 8 && kSrcHeight > 8) {
382 EXPECT_LT(err, 0.0001);
383 }
385 memset(src_a, 1, kSrcPlaneSize);
387 err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
388 src_b + kSrcStride * b + b, kSrcStride,
389 kSrcWidth, kSrcHeight);
391 if (kSrcWidth > 8 && kSrcHeight > 8) {
392 EXPECT_GT(err, 0.0001);
393 EXPECT_LT(err, 0.9);
394 }
396 for (int i = 0; i < kSrcPlaneSize; ++i) {
397 src_a[i] = i;
398 }
400 err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
401 src_b + kSrcStride * b + b, kSrcStride,
402 kSrcWidth, kSrcHeight);
404 if (kSrcWidth > 8 && kSrcHeight > 8) {
405 EXPECT_GT(err, 0.0);
406 EXPECT_LT(err, 0.01);
407 }
409 srandom(time(NULL));
410 for (int i = b; i < (kSrcHeight + b); ++i) {
411 for (int j = b; j < (kSrcWidth + b); ++j) {
412 src_a[(i * kSrcStride) + j] = (random() & 0xff);
413 src_b[(i * kSrcStride) + j] = (random() & 0xff);
414 }
415 }
417 MaskCpuFlags(0);
418 double c_err, opt_err;
420 c_err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
421 src_b + kSrcStride * b + b, kSrcStride,
422 kSrcWidth, kSrcHeight);
424 MaskCpuFlags(-1);
426 opt_err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
427 src_b + kSrcStride * b + b, kSrcStride,
428 kSrcWidth, kSrcHeight);
430 if (kSrcWidth > 8 && kSrcHeight > 8) {
431 EXPECT_EQ(opt_err, c_err);
432 }
434 free_aligned_buffer_64(src_a);
435 free_aligned_buffer_64(src_b);
436 }
438 } // namespace libyuv