Home | History | Annotate | Download | only in unit_test
      1 /*
      2  *  Copyright 2012 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/rotate_argb.h"
     16 #include "../unit_test/unit_test.h"
     17 
     18 namespace libyuv {
     19 
     20 static int ARGBTestRotate(int src_width, int src_height,
     21                           int dst_width, int dst_height,
     22                           libyuv::RotationMode mode, int runs) {
     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   ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     50              dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     51              src_width, src_height, mode);
     52   MaskCpuFlags(-1);  // Enable all CPU optimization.
     53   ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     54              dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     55              src_width, src_height, mode);
     56 
     57   MaskCpuFlags(0);  // Disable all CPU optimization.
     58   double c_time = get_time();
     59   for (i = 0; i < runs; ++i) {
     60     ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     61                dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     62                src_width, src_height, mode);
     63   }
     64   c_time = (get_time() - c_time) / runs;
     65 
     66   MaskCpuFlags(-1);  // Enable all CPU optimization.
     67   double opt_time = get_time();
     68   for (i = 0; i < runs; ++i) {
     69     ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
     70                dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
     71                src_width, src_height, mode);
     72   }
     73   opt_time = (get_time() - opt_time) / runs;
     74 
     75   // Report performance of C vs OPT
     76   printf("filter %d - %8d us C - %8d us OPT\n",
     77          mode, static_cast<int>(c_time*1e6), static_cast<int>(opt_time*1e6));
     78 
     79   // C version may be a little off from the optimized. Order of
     80   //  operations may introduce rounding somewhere. So do a difference
     81   //  of the buffers and look to see that the max difference isn't
     82   //  over 2.
     83   int max_diff = 0;
     84   for (i = b; i < (dst_height + b); ++i) {
     85     for (j = b * 4; j < (dst_width + b) * 4; ++j) {
     86       int abs_diff = abs(dst_argb_c[(i * dst_stride_argb) + j] -
     87                          dst_argb_opt[(i * dst_stride_argb) + j]);
     88       if (abs_diff > max_diff)
     89         max_diff = abs_diff;
     90     }
     91   }
     92 
     93   free_aligned_buffer_16(dst_argb_c)
     94   free_aligned_buffer_16(dst_argb_opt)
     95   free_aligned_buffer_16(src_argb)
     96   return max_diff;
     97 }
     98 
     99 TEST_F(libyuvTest, ARGBRotate0) {
    100   const int src_width = 1280;
    101   const int src_height = 720;
    102   const int dst_width = 1280;
    103   const int dst_height = 720;
    104 
    105   int err = ARGBTestRotate(src_width, src_height,
    106                            dst_width, dst_height, kRotate0,
    107                            benchmark_iterations_);
    108   EXPECT_GE(1, err);
    109 }
    110 
    111 TEST_F(libyuvTest, ARGBRotate90) {
    112   const int src_width = 1280;
    113   const int src_height = 720;
    114   const int dst_width = 720;
    115   const int dst_height = 1280;
    116 
    117   int err = ARGBTestRotate(src_width, src_height,
    118                            dst_width, dst_height, kRotate90,
    119                            benchmark_iterations_);
    120   EXPECT_GE(1, err);
    121 }
    122 
    123 TEST_F(libyuvTest, ARGBRotate180) {
    124   const int src_width = 1280;
    125   const int src_height = 720;
    126   const int dst_width = 1280;
    127   const int dst_height = 720;
    128 
    129   int err = ARGBTestRotate(src_width, src_height,
    130                            dst_width, dst_height, kRotate180,
    131                            benchmark_iterations_);
    132   EXPECT_GE(1, err);
    133 }
    134 
    135 TEST_F(libyuvTest, ARGBRotate270) {
    136   const int src_width = 1280;
    137   const int src_height = 720;
    138   const int dst_width = 720;
    139   const int dst_height = 1280;
    140 
    141   int err = ARGBTestRotate(src_width, src_height,
    142                            dst_width, dst_height, kRotate270,
    143                            benchmark_iterations_);
    144   EXPECT_GE(1, err);
    145 }
    146 
    147 TEST_F(libyuvTest, ARGBRotate0_Odd) {
    148   const int src_width = 1277;
    149   const int src_height = 719;
    150   const int dst_width = 1277;
    151   const int dst_height = 719;
    152 
    153   int err = ARGBTestRotate(src_width, src_height,
    154                            dst_width, dst_height, kRotate0,
    155                            benchmark_iterations_);
    156   EXPECT_GE(1, err);
    157 }
    158 
    159 TEST_F(libyuvTest, ARGBRotate90_Odd) {
    160   const int src_width = 1277;
    161   const int src_height = 719;
    162   const int dst_width = 719;
    163   const int dst_height = 1277;
    164 
    165   int err = ARGBTestRotate(src_width, src_height,
    166                            dst_width, dst_height, kRotate90,
    167                            benchmark_iterations_);
    168   EXPECT_GE(1, err);
    169 }
    170 
    171 TEST_F(libyuvTest, ARGBRotate180_Odd) {
    172   const int src_width = 1277;
    173   const int src_height = 719;
    174   const int dst_width = 1277;
    175   const int dst_height = 719;
    176 
    177   int err = ARGBTestRotate(src_width, src_height,
    178                            dst_width, dst_height, kRotate180,
    179                            benchmark_iterations_);
    180   EXPECT_GE(1, err);
    181 }
    182 
    183 TEST_F(libyuvTest, ARGBRotate270_Odd) {
    184   const int src_width = 1277;
    185   const int src_height = 719;
    186   const int dst_width = 719;
    187   const int dst_height = 1277;
    188 
    189   int err = ARGBTestRotate(src_width, src_height,
    190                            dst_width, dst_height, kRotate270,
    191                            benchmark_iterations_);
    192   EXPECT_GE(1, err);
    193 }
    194 
    195 }  // namespace libyuv
    196