Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libyuv / unit_test / compare_test.cc
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  */
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14
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"
20
21 namespace libyuv {
22
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 }
33
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);
38
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);
45
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);
54
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);
60
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);
68
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);
74
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);
80
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);
87
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);
94
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);
101
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);
107
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);
113
114   free_aligned_buffer_64(src_a);
115   free_aligned_buffer_64(src_b);
116 }
117
118 TEST_F(libyuvTest, BenchmarkDjb2_Opt) {
119   const int kMaxTest = benchmark_width_ * benchmark_height_;
120   align_buffer_64(src_a, kMaxTest);
121
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 }
133
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 }
148
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);
155
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);
160
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);
167
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   }
173
174   EXPECT_EQ(0, h1);
175
176   free_aligned_buffer_64(src_a);
177   free_aligned_buffer_64(src_b);
178 }
179
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);
186
187   uint64 err;
188   err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
189
190   EXPECT_EQ(0, err);
191
192   memset(src_a, 1, kMaxWidth);
193   err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
194
195   EXPECT_EQ(err, kMaxWidth);
196
197   memset(src_a, 190, kMaxWidth);
198   memset(src_b, 193, kMaxWidth);
199   err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
200
201   EXPECT_EQ(kMaxWidth * 3 * 3, err);
202
203   srandom(time(NULL));
204
205   for (int i = 0; i < kMaxWidth; ++i) {
206     src_a[i] = (random() & 0xff);
207     src_b[i] = (random() & 0xff);
208   }
209
210   MaskCpuFlags(0);
211   uint64 c_err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
212
213   MaskCpuFlags(-1);
214   uint64 opt_err = ComputeSumSquareError(src_a, src_b, kMaxWidth);
215
216   EXPECT_EQ(c_err, opt_err);
217
218   free_aligned_buffer_64(src_a);
219   free_aligned_buffer_64(src_b);
220 }
221
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   }
229
230   MaskCpuFlags(-1);
231
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_);
237
238   opt_time = (get_time() - opt_time) / benchmark_iterations_;
239   printf("BenchmarkPsnr_Opt - %8.2f us opt\n", opt_time * 1e6);
240
241   EXPECT_EQ(0, 0);
242
243   free_aligned_buffer_64(src_a);
244   free_aligned_buffer_64(src_b);
245 }
246
247
248 TEST_F(libyuvTest, BenchmarkPsnr_Unaligned) {
249   align_buffer_64(src_a, benchmark_width_ * benchmark_height_ + 1);
250   align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
251   for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
252     src_a[i + 1] = i;
253     src_b[i] = i;
254   }
255
256   MaskCpuFlags(-1);
257
258   double opt_time = get_time();
259   for (int i = 0; i < benchmark_iterations_; ++i)
260     CalcFramePsnr(src_a + 1, benchmark_width_,
261                   src_b, benchmark_width_,
262                   benchmark_width_, benchmark_height_);
263
264   opt_time = (get_time() - opt_time) / benchmark_iterations_;
265   printf("BenchmarkPsnr_Opt - %8.2f us opt\n", opt_time * 1e6);
266
267   EXPECT_EQ(0, 0);
268
269   free_aligned_buffer_64(src_a);
270   free_aligned_buffer_64(src_b);
271 }
272
273 TEST_F(libyuvTest, Psnr) {
274   const int kSrcWidth = benchmark_width_;
275   const int kSrcHeight = benchmark_height_;
276   const int b = 128;
277   const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
278   const int kSrcStride = 2 * b + kSrcWidth;
279   align_buffer_64(src_a, kSrcPlaneSize);
280   align_buffer_64(src_b, kSrcPlaneSize);
281   memset(src_a, 0, kSrcPlaneSize);
282   memset(src_b, 0, kSrcPlaneSize);
283
284   double err;
285   err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
286                       src_b + kSrcStride * b + b, kSrcStride,
287                       kSrcWidth, kSrcHeight);
288
289   EXPECT_EQ(err, kMaxPsnr);
290
291   memset(src_a, 255, kSrcPlaneSize);
292
293   err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
294                       src_b + kSrcStride * b + b, kSrcStride,
295                       kSrcWidth, kSrcHeight);
296
297   EXPECT_EQ(err, 0.0);
298
299   memset(src_a, 1, kSrcPlaneSize);
300
301   err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
302                       src_b + kSrcStride * b + b, kSrcStride,
303                       kSrcWidth, kSrcHeight);
304
305   EXPECT_GT(err, 48.0);
306   EXPECT_LT(err, 49.0);
307
308   for (int i = 0; i < kSrcPlaneSize; ++i) {
309     src_a[i] = i;
310   }
311
312   err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
313                       src_b + kSrcStride * b + b, kSrcStride,
314                       kSrcWidth, kSrcHeight);
315
316   EXPECT_GT(err, 2.0);
317   if (kSrcWidth * kSrcHeight >= 256) {
318     EXPECT_LT(err, 6.0);
319   }
320
321   srandom(time(NULL));
322
323   memset(src_a, 0, kSrcPlaneSize);
324   memset(src_b, 0, kSrcPlaneSize);
325
326   for (int i = b; i < (kSrcHeight + b); ++i) {
327     for (int j = b; j < (kSrcWidth + b); ++j) {
328       src_a[(i * kSrcStride) + j] = (random() & 0xff);
329       src_b[(i * kSrcStride) + j] = (random() & 0xff);
330     }
331   }
332
333   MaskCpuFlags(0);
334   double c_err, opt_err;
335
336   c_err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
337                         src_b + kSrcStride * b + b, kSrcStride,
338                         kSrcWidth, kSrcHeight);
339
340   MaskCpuFlags(-1);
341
342   opt_err = CalcFramePsnr(src_a + kSrcStride * b + b, kSrcStride,
343                           src_b + kSrcStride * b + b, kSrcStride,
344                           kSrcWidth, kSrcHeight);
345
346   EXPECT_EQ(opt_err, c_err);
347
348   free_aligned_buffer_64(src_a);
349   free_aligned_buffer_64(src_b);
350 }
351
352 TEST_F(libyuvTest, DISABLED_BenchmarkSsim_Opt) {
353   align_buffer_64(src_a, benchmark_width_ * benchmark_height_);
354   align_buffer_64(src_b, benchmark_width_ * benchmark_height_);
355   for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
356     src_a[i] = i;
357     src_b[i] = i;
358   }
359
360   MaskCpuFlags(-1);
361
362   double opt_time = get_time();
363   for (int i = 0; i < benchmark_iterations_; ++i)
364     CalcFrameSsim(src_a, benchmark_width_,
365                   src_b, benchmark_width_,
366                   benchmark_width_, benchmark_height_);
367
368   opt_time = (get_time() - opt_time) / benchmark_iterations_;
369   printf("BenchmarkSsim_Opt - %8.2f us opt\n", opt_time * 1e6);
370
371   EXPECT_EQ(0, 0);  // Pass if we get this far.
372
373   free_aligned_buffer_64(src_a);
374   free_aligned_buffer_64(src_b);
375 }
376
377 TEST_F(libyuvTest, Ssim) {
378   const int kSrcWidth = benchmark_width_;
379   const int kSrcHeight = benchmark_height_;
380   const int b = 128;
381   const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
382   const int kSrcStride = 2 * b + kSrcWidth;
383   align_buffer_64(src_a, kSrcPlaneSize);
384   align_buffer_64(src_b, kSrcPlaneSize);
385   memset(src_a, 0, kSrcPlaneSize);
386   memset(src_b, 0, kSrcPlaneSize);
387
388   if (kSrcWidth <=8 || kSrcHeight <= 8) {
389     printf("warning - Ssim size too small.  Testing function executes.\n");
390   }
391
392   double err;
393   err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
394                       src_b + kSrcStride * b + b, kSrcStride,
395                       kSrcWidth, kSrcHeight);
396
397   if (kSrcWidth > 8 && kSrcHeight > 8) {
398     EXPECT_EQ(err, 1.0);
399   }
400
401   memset(src_a, 255, kSrcPlaneSize);
402
403   err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
404                       src_b + kSrcStride * b + b, kSrcStride,
405                       kSrcWidth, kSrcHeight);
406
407   if (kSrcWidth > 8 && kSrcHeight > 8) {
408     EXPECT_LT(err, 0.0001);
409   }
410
411   memset(src_a, 1, kSrcPlaneSize);
412
413   err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
414                       src_b + kSrcStride * b + b, kSrcStride,
415                       kSrcWidth, kSrcHeight);
416
417   if (kSrcWidth > 8 && kSrcHeight > 8) {
418     EXPECT_GT(err, 0.0001);
419     EXPECT_LT(err, 0.9);
420   }
421
422   for (int i = 0; i < kSrcPlaneSize; ++i) {
423     src_a[i] = i;
424   }
425
426   err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
427                       src_b + kSrcStride * b + b, kSrcStride,
428                       kSrcWidth, kSrcHeight);
429
430   if (kSrcWidth > 8 && kSrcHeight > 8) {
431     EXPECT_GT(err, 0.0);
432     EXPECT_LT(err, 0.01);
433   }
434
435   srandom(time(NULL));
436   for (int i = b; i < (kSrcHeight + b); ++i) {
437     for (int j = b; j < (kSrcWidth + b); ++j) {
438       src_a[(i * kSrcStride) + j] = (random() & 0xff);
439       src_b[(i * kSrcStride) + j] = (random() & 0xff);
440     }
441   }
442
443   MaskCpuFlags(0);
444   double c_err, opt_err;
445
446   c_err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
447                         src_b + kSrcStride * b + b, kSrcStride,
448                         kSrcWidth, kSrcHeight);
449
450   MaskCpuFlags(-1);
451
452   opt_err = CalcFrameSsim(src_a + kSrcStride * b + b, kSrcStride,
453                           src_b + kSrcStride * b + b, kSrcStride,
454                           kSrcWidth, kSrcHeight);
455
456   if (kSrcWidth > 8 && kSrcHeight > 8) {
457     EXPECT_EQ(opt_err, c_err);
458   }
459
460   free_aligned_buffer_64(src_a);
461   free_aligned_buffer_64(src_b);
462 }
463
464 }  // namespace libyuv