media/libyuv/unit_test/compare_test.cc

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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

mercurial