Home | History | Annotate | Download | only in unit_test
      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 <time.h>
     13 
     14 #include "libyuv/cpu_id.h"
     15 #include "libyuv/scale_argb.h"
     16 #include "../unit_test/unit_test.h"
     17 
     18 namespace libyuv {
     19 
     20 static int ARGBTestFilter(int src_width, int src_height,
     21                           int dst_width, int dst_height,
     22                           FilterMode f, int benchmark_iterations) {
     23   const int b = 128;
     24   int src_argb_plane_size = (src_width + b * 2) * (src_height + b * 2) * 4;
     25   int src_stride_argb = (b * 2 + src_width) * 4;
     26 
     27   align_buffer_16(src_argb, src_argb_plane_size)
     28   memset(src_argb, 1, src_argb_plane_size);
     29 
     30   int dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4;
     31   int dst_stride_argb = (b * 2 + dst_width) * 4;
     32 
     33   srandom(time(NULL));
     34 
     35   int i, j;
     36   for (i = b; i < (src_height + b); ++i) {
     37     for (j = b; j < (src_width + b) * 4; ++j) {
     38       src_argb[(i * src_stride_argb) + j] = (random() & 0xff);
     39     }
     40   }
     41 
     42   align_buffer_16(dst_argb_c, dst_argb_plane_size)
     43   align_buffer_16(dst_argb_opt, dst_argb_plane_size)
     44   memset(dst_argb_c, 2, dst_argb_plane_size);
     45   memset(dst_argb_opt, 3, dst_argb_plane_size);
     46 
     47   // Warm up both versions for consistent benchmarks.
     48   MaskCpuFlags(0);  // Disable all CPU optimization.
     49   ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     50             src_width, src_height,
     51             dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     52             dst_width, dst_height, f);
     53   MaskCpuFlags(-1);  // Enable all CPU optimization.
     54   ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     55             src_width, src_height,
     56             dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     57             dst_width, dst_height, f);
     58 
     59   MaskCpuFlags(0);  // Disable all CPU optimization.
     60   double c_time = get_time();
     61   for (i = 0; i < benchmark_iterations; ++i) {
     62     ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     63               src_width, src_height,
     64               dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     65               dst_width, dst_height, f);
     66   }
     67   c_time = (get_time() - c_time) / benchmark_iterations;
     68 
     69   MaskCpuFlags(-1);  // Enable all CPU optimization.
     70   double opt_time = get_time();
     71   for (i = 0; i < benchmark_iterations; ++i) {
     72     ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     73               src_width, src_height,
     74               dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     75               dst_width, dst_height, f);
     76   }
     77   opt_time = (get_time() - opt_time) / benchmark_iterations;
     78 
     79   // Report performance of C vs OPT
     80   printf("filter %d - %8d us C - %8d us OPT\n",
     81          f, static_cast<int>(c_time*1e6), static_cast<int>(opt_time*1e6));
     82 
     83   // C version may be a little off from the optimized. Order of
     84   //  operations may introduce rounding somewhere. So do a difference
     85   //  of the buffers and look to see that the max difference isn't
     86   //  over 2.
     87   int max_diff = 0;
     88   for (i = b; i < (dst_height + b); ++i) {
     89     for (j = b * 4; j < (dst_width + b) * 4; ++j) {
     90       int abs_diff = abs(dst_argb_c[(i * dst_stride_argb) + j] -
     91                          dst_argb_opt[(i * dst_stride_argb) + j]);
     92       if (abs_diff > max_diff) {
     93         max_diff = abs_diff;
     94       }
     95     }
     96   }
     97 
     98   free_aligned_buffer_16(dst_argb_c)
     99   free_aligned_buffer_16(dst_argb_opt)
    100   free_aligned_buffer_16(src_argb)
    101   return max_diff;
    102 }
    103 
    104 TEST_F(libyuvTest, ARGBScaleDownBy2) {
    105   const int src_width = 1280;
    106   const int src_height = 720;
    107   const int dst_width = src_width / 2;
    108   const int dst_height = src_height / 2;
    109 
    110   for (int f = 0; f < 2; ++f) {
    111     int max_diff = ARGBTestFilter(src_width, src_height,
    112                                   dst_width, dst_height,
    113                                   static_cast<FilterMode>(f),
    114                                   benchmark_iterations_);
    115     EXPECT_LE(max_diff, 1);
    116   }
    117 }
    118 
    119 TEST_F(libyuvTest, ARGBScaleDownBy4) {
    120   const int src_width = 1280;
    121   const int src_height = 720;
    122   const int dst_width = src_width / 4;
    123   const int dst_height = src_height / 4;
    124 
    125   for (int f = 0; f < 2; ++f) {
    126     int max_diff = ARGBTestFilter(src_width, src_height,
    127                                   dst_width, dst_height,
    128                                   static_cast<FilterMode>(f),
    129                                   benchmark_iterations_);
    130     EXPECT_LE(max_diff, 1);
    131   }
    132 }
    133 
    134 TEST_F(libyuvTest, ARGBScaleDownBy5) {
    135   const int src_width = 1280;
    136   const int src_height = 720;
    137   const int dst_width = src_width / 5;
    138   const int dst_height = src_height / 5;
    139 
    140   for (int f = 0; f < 2; ++f) {
    141     int max_diff = ARGBTestFilter(src_width, src_height,
    142                                   dst_width, dst_height,
    143                                   static_cast<FilterMode>(f),
    144                                   benchmark_iterations_);
    145     EXPECT_LE(max_diff, 1);
    146   }
    147 }
    148 
    149 TEST_F(libyuvTest, ARGBScaleDownBy8) {
    150   const int src_width = 1280;
    151   const int src_height = 720;
    152   const int dst_width = src_width / 8;
    153   const int dst_height = src_height / 8;
    154 
    155   for (int f = 0; f < 2; ++f) {
    156     int max_diff = ARGBTestFilter(src_width, src_height,
    157                                   dst_width, dst_height,
    158                                   static_cast<FilterMode>(f),
    159                                   benchmark_iterations_);
    160     EXPECT_LE(max_diff, 1);
    161   }
    162 }
    163 
    164 TEST_F(libyuvTest, ARGBScaleDownBy16) {
    165   const int src_width = 1280;
    166   const int src_height = 720;
    167   const int dst_width = src_width / 16;
    168   const int dst_height = src_height / 16;
    169 
    170   for (int f = 0; f < 2; ++f) {
    171     int max_diff = ARGBTestFilter(src_width, src_height,
    172                                   dst_width, dst_height,
    173                                   static_cast<FilterMode>(f),
    174                                   benchmark_iterations_);
    175     EXPECT_LE(max_diff, 1);
    176   }
    177 }
    178 
    179 TEST_F(libyuvTest, ARGBScaleDownBy34) {
    180   const int src_width = 1280;
    181   const int src_height = 720;
    182   const int dst_width = src_width * 3 / 4;
    183   const int dst_height = src_height * 3 / 4;
    184 
    185   for (int f = 0; f < 2; ++f) {
    186     int max_diff = ARGBTestFilter(src_width, src_height,
    187                                   dst_width, dst_height,
    188                                   static_cast<FilterMode>(f),
    189                                   benchmark_iterations_);
    190     EXPECT_LE(max_diff, 1);
    191   }
    192 }
    193 
    194 TEST_F(libyuvTest, ARGBScaleDownBy38) {
    195   int src_width = 1280;
    196   int src_height = 720;
    197   int dst_width = src_width * 3 / 8;
    198   int dst_height = src_height * 3 / 8;
    199 
    200   for (int f = 0; f < 2; ++f) {
    201     int max_diff = ARGBTestFilter(src_width, src_height,
    202                                   dst_width, dst_height,
    203                                   static_cast<FilterMode>(f),
    204                                   benchmark_iterations_);
    205     EXPECT_LE(max_diff, 1);
    206   }
    207 }
    208 
    209 TEST_F(libyuvTest, ARGBScaleTo1366) {
    210   int src_width = 1280;
    211   int src_height = 720;
    212   int dst_width = 1366;
    213   int dst_height = 768;
    214 
    215   for (int f = 0; f < 2; ++f) {
    216     int max_diff = ARGBTestFilter(src_width, src_height,
    217                                   dst_width, dst_height,
    218                                   static_cast<FilterMode>(f),
    219                                   benchmark_iterations_);
    220     EXPECT_LE(max_diff, 1);
    221   }
    222 }
    223 
    224 TEST_F(libyuvTest, ARGBScaleTo4074) {
    225   int src_width = 2880 * 2;
    226   int src_height = 1800;
    227   int dst_width = 4074;
    228   int dst_height = 1272;
    229 
    230   for (int f = 0; f < 2; ++f) {
    231     int max_diff = ARGBTestFilter(src_width, src_height,
    232                                   dst_width, dst_height,
    233                                   static_cast<FilterMode>(f),
    234                                   benchmark_iterations_);
    235     EXPECT_LE(max_diff, 1);
    236   }
    237 }
    238 
    239 
    240 TEST_F(libyuvTest, ARGBScaleTo853) {
    241   int src_width = 1280;
    242   int src_height = 720;
    243   int dst_width = 853;
    244   int dst_height = 480;
    245 
    246   for (int f = 0; f < 2; ++f) {
    247     int max_diff = ARGBTestFilter(src_width, src_height,
    248                                   dst_width, dst_height,
    249                                   static_cast<FilterMode>(f),
    250                                   benchmark_iterations_);
    251     EXPECT_LE(max_diff, 1);
    252   }
    253 }
    254 
    255 }  // namespace libyuv
    256