scale_argb_test.cc 18.2 KB
Newer Older
1
/*
2
 *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 4 5 6
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS. All contributing project authors may
8 9 10 11 12 13
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <stdlib.h>
#include <time.h>

Frank Barchard's avatar
Frank Barchard committed
14
#include "../unit_test/unit_test.h"
15
#include "libyuv/convert_argb.h"
16 17
#include "libyuv/cpu_id.h"
#include "libyuv/scale_argb.h"
18
#include "libyuv/video_common.h"
19 20 21

namespace libyuv {

22 23 24
#define STRINGIZE(line) #line
#define FILELINESTR(file, line) file ":" STRINGIZE(line)

25
// Test scaling with C vs Opt and return maximum pixel difference. 0 = exact.
Frank Barchard's avatar
Frank Barchard committed
26 27 28 29 30 31 32 33
static int ARGBTestFilter(int src_width,
                          int src_height,
                          int dst_width,
                          int dst_height,
                          FilterMode f,
                          int benchmark_iterations,
                          int disable_cpu_flags,
                          int benchmark_cpu_info) {
34 35 36 37
  if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
    return 0;
  }

38
  int i, j;
39
  const int b = 0;  // 128 to test for padding/stride.
Frank Barchard's avatar
Frank Barchard committed
40
  int64_t src_argb_plane_size =
Frank Barchard's avatar
Frank Barchard committed
41
      (Abs(src_width) + b * 2) * (Abs(src_height) + b * 2) * 4LL;
42
  int src_stride_argb = (b * 2 + Abs(src_width)) * 4;
43

44
  align_buffer_page_end(src_argb, src_argb_plane_size);
45 46 47 48
  if (!src_argb) {
    printf("Skipped.  Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
    return 0;
  }
49
  MemRandomize(src_argb, src_argb_plane_size);
50

51 52
  int64_t dst_argb_plane_size =
      (dst_width + b * 2) * (dst_height + b * 2) * 4LL;
53
  int dst_stride_argb = (b * 2 + dst_width) * 4;
54

55 56
  align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
  align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
57 58 59 60
  if (!dst_argb_c || !dst_argb_opt) {
    printf("Skipped.  Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
    return 0;
  }
fbarchard@google.com's avatar
fbarchard@google.com committed
61 62 63 64
  memset(dst_argb_c, 2, dst_argb_plane_size);
  memset(dst_argb_opt, 3, dst_argb_plane_size);

  // Warm up both versions for consistent benchmarks.
65
  MaskCpuFlags(disable_cpu_flags);  // Disable all CPU optimization.
fbarchard@google.com's avatar
fbarchard@google.com committed
66
  ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
Frank Barchard's avatar
Frank Barchard committed
67 68
            src_width, src_height, dst_argb_c + (dst_stride_argb * b) + b * 4,
            dst_stride_argb, dst_width, dst_height, f);
69
  MaskCpuFlags(benchmark_cpu_info);  // Enable all CPU optimization.
fbarchard@google.com's avatar
fbarchard@google.com committed
70
  ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
Frank Barchard's avatar
Frank Barchard committed
71 72
            src_width, src_height, dst_argb_opt + (dst_stride_argb * b) + b * 4,
            dst_stride_argb, dst_width, dst_height, f);
fbarchard@google.com's avatar
fbarchard@google.com committed
73

74
  MaskCpuFlags(disable_cpu_flags);  // Disable all CPU optimization.
75
  double c_time = get_time();
76
  ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
Frank Barchard's avatar
Frank Barchard committed
77 78
            src_width, src_height, dst_argb_c + (dst_stride_argb * b) + b * 4,
            dst_stride_argb, dst_width, dst_height, f);
79 80

  c_time = (get_time() - c_time);
81

82
  MaskCpuFlags(benchmark_cpu_info);  // Enable all CPU optimization.
83
  double opt_time = get_time();
84
  for (i = 0; i < benchmark_iterations; ++i) {
fbarchard@google.com's avatar
fbarchard@google.com committed
85
    ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
86
              src_width, src_height,
fbarchard@google.com's avatar
fbarchard@google.com committed
87
              dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
88
              dst_width, dst_height, f);
fbarchard@google.com's avatar
fbarchard@google.com committed
89
  }
90
  opt_time = (get_time() - opt_time) / benchmark_iterations;
91

fbarchard@google.com's avatar
fbarchard@google.com committed
92
  // Report performance of C vs OPT
Frank Barchard's avatar
Frank Barchard committed
93 94
  printf("filter %d - %8d us C - %8d us OPT\n", f,
         static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6));
95

96 97
  // C version may be a little off from the optimized. Order of
  //  operations may introduce rounding somewhere. So do a difference
98 99 100 101 102
  //  of the buffers and look to see that the max difference isn't
  //  over 2.
  int max_diff = 0;
  for (i = b; i < (dst_height + b); ++i) {
    for (j = b * 4; j < (dst_width + b) * 4; ++j) {
103
      int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] -
fbarchard@google.com's avatar
fbarchard@google.com committed
104
                         dst_argb_opt[(i * dst_stride_argb) + j]);
105
      if (abs_diff > max_diff) {
106
        max_diff = abs_diff;
107
      }
108 109 110
    }
  }

111 112 113
  free_aligned_buffer_page_end(dst_argb_c);
  free_aligned_buffer_page_end(dst_argb_opt);
  free_aligned_buffer_page_end(src_argb);
fbarchard@google.com's avatar
fbarchard@google.com committed
114
  return max_diff;
115 116
}

117 118
static const int kTileX = 8;
static const int kTileY = 8;
fbarchard@google.com's avatar
fbarchard@google.com committed
119

Frank Barchard's avatar
Frank Barchard committed
120
static int TileARGBScale(const uint8_t* src_argb,
Frank Barchard's avatar
Frank Barchard committed
121 122 123
                         int src_stride_argb,
                         int src_width,
                         int src_height,
Frank Barchard's avatar
Frank Barchard committed
124
                         uint8_t* dst_argb,
Frank Barchard's avatar
Frank Barchard committed
125 126 127
                         int dst_stride_argb,
                         int dst_width,
                         int dst_height,
fbarchard@google.com's avatar
fbarchard@google.com committed
128 129 130 131 132 133 134 135 136 137 138
                         FilterMode filtering) {
  for (int y = 0; y < dst_height; y += kTileY) {
    for (int x = 0; x < dst_width; x += kTileX) {
      int clip_width = kTileX;
      if (x + clip_width > dst_width) {
        clip_width = dst_width - x;
      }
      int clip_height = kTileY;
      if (y + clip_height > dst_height) {
        clip_height = dst_height - y;
      }
Frank Barchard's avatar
Frank Barchard committed
139 140 141
      int r = ARGBScaleClip(src_argb, src_stride_argb, src_width, src_height,
                            dst_argb, dst_stride_argb, dst_width, dst_height, x,
                            y, clip_width, clip_height, filtering);
fbarchard@google.com's avatar
fbarchard@google.com committed
142 143 144 145 146 147 148 149
      if (r) {
        return r;
      }
    }
  }
  return 0;
}

Frank Barchard's avatar
Frank Barchard committed
150 151 152 153 154 155
static int ARGBClipTestFilter(int src_width,
                              int src_height,
                              int dst_width,
                              int dst_height,
                              FilterMode f,
                              int benchmark_iterations) {
156 157 158 159
  if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
    return 0;
  }

fbarchard@google.com's avatar
fbarchard@google.com committed
160
  const int b = 128;
Frank Barchard's avatar
Frank Barchard committed
161
  int64_t src_argb_plane_size =
Frank Barchard's avatar
Frank Barchard committed
162
      (Abs(src_width) + b * 2) * (Abs(src_height) + b * 2) * 4;
fbarchard@google.com's avatar
fbarchard@google.com committed
163 164
  int src_stride_argb = (b * 2 + Abs(src_width)) * 4;

165
  align_buffer_page_end(src_argb, src_argb_plane_size);
166 167 168 169
  if (!src_argb) {
    printf("Skipped.  Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
    return 0;
  }
fbarchard@google.com's avatar
fbarchard@google.com committed
170 171
  memset(src_argb, 1, src_argb_plane_size);

Frank Barchard's avatar
Frank Barchard committed
172
  int64_t dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4;
fbarchard@google.com's avatar
fbarchard@google.com committed
173 174 175 176 177
  int dst_stride_argb = (b * 2 + dst_width) * 4;

  int i, j;
  for (i = b; i < (Abs(src_height) + b); ++i) {
    for (j = b; j < (Abs(src_width) + b) * 4; ++j) {
178
      src_argb[(i * src_stride_argb) + j] = (fastrand() & 0xff);
fbarchard@google.com's avatar
fbarchard@google.com committed
179 180 181
    }
  }

182 183
  align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
  align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
184 185 186 187
  if (!dst_argb_c || !dst_argb_opt) {
    printf("Skipped.  Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
    return 0;
  }
fbarchard@google.com's avatar
fbarchard@google.com committed
188 189 190 191 192 193
  memset(dst_argb_c, 2, dst_argb_plane_size);
  memset(dst_argb_opt, 3, dst_argb_plane_size);

  // Do full image, no clipping.
  double c_time = get_time();
  ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
Frank Barchard's avatar
Frank Barchard committed
194 195
            src_width, src_height, dst_argb_c + (dst_stride_argb * b) + b * 4,
            dst_stride_argb, dst_width, dst_height, f);
fbarchard@google.com's avatar
fbarchard@google.com committed
196 197 198 199 200 201 202 203 204 205 206 207 208
  c_time = (get_time() - c_time);

  // Do tiled image, clipping scale to a tile at a time.
  double opt_time = get_time();
  for (i = 0; i < benchmark_iterations; ++i) {
    TileARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
                  src_width, src_height,
                  dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
                  dst_width, dst_height, f);
  }
  opt_time = (get_time() - opt_time) / benchmark_iterations;

  // Report performance of Full vs Tiled.
Frank Barchard's avatar
Frank Barchard committed
209 210
  printf("filter %d - %8d us Full - %8d us Tiled\n", f,
         static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6));
fbarchard@google.com's avatar
fbarchard@google.com committed
211 212 213 214 215

  // Compare full scaled image vs tiled image.
  int max_diff = 0;
  for (i = b; i < (dst_height + b); ++i) {
    for (j = b * 4; j < (dst_width + b) * 4; ++j) {
216
      int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] -
fbarchard@google.com's avatar
fbarchard@google.com committed
217 218 219 220 221 222 223
                         dst_argb_opt[(i * dst_stride_argb) + j]);
      if (abs_diff > max_diff) {
        max_diff = abs_diff;
      }
    }
  }

224 225 226
  free_aligned_buffer_page_end(dst_argb_c);
  free_aligned_buffer_page_end(dst_argb_opt);
  free_aligned_buffer_page_end(src_argb);
fbarchard@google.com's avatar
fbarchard@google.com committed
227 228 229
  return max_diff;
}

230 231
// The following adjustments in dimensions ensure the scale factor will be
// exactly achieved.
232 233
#define DX(x, nom, denom) static_cast<int>((Abs(x) / nom) * nom)
#define SX(x, nom, denom) static_cast<int>((x / nom) * denom)
234

Frank Barchard's avatar
Frank Barchard committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
#define TEST_FACTOR1(name, filter, nom, denom, max_diff)                     \
  TEST_F(LibYUVScaleTest, ARGBScaleDownBy##name##_##filter) {                \
    int diff = ARGBTestFilter(                                               \
        SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
        DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
        kFilter##filter, benchmark_iterations_, disable_cpu_flags_,          \
        benchmark_cpu_info_);                                                \
    EXPECT_LE(diff, max_diff);                                               \
  }                                                                          \
  TEST_F(LibYUVScaleTest, ARGBScaleDownClipBy##name##_##filter) {            \
    int diff = ARGBClipTestFilter(                                           \
        SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
        DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
        kFilter##filter, benchmark_iterations_);                             \
    EXPECT_LE(diff, max_diff);                                               \
  }
fbarchard@google.com's avatar
fbarchard@google.com committed
251

252
// Test a scale factor with all 4 filters.  Expect unfiltered to be exact, but
253
// filtering is different fixed point implementations for SSSE3, Neon and C.
Frank Barchard's avatar
Frank Barchard committed
254 255 256 257 258
#define TEST_FACTOR(name, nom, denom)         \
  TEST_FACTOR1(name, None, nom, denom, 0)     \
  TEST_FACTOR1(name, Linear, nom, denom, 3)   \
  TEST_FACTOR1(name, Bilinear, nom, denom, 3) \
  TEST_FACTOR1(name, Box, nom, denom, 3)
259 260 261 262 263 264 265

TEST_FACTOR(2, 1, 2)
TEST_FACTOR(4, 1, 4)
TEST_FACTOR(8, 1, 8)
TEST_FACTOR(3by4, 3, 4)
TEST_FACTOR(3by8, 3, 8)
TEST_FACTOR(3, 1, 3)
266 267
#undef TEST_FACTOR1
#undef TEST_FACTOR
268 269
#undef SX
#undef DX
270

271
#define TEST_SCALETO1(name, width, height, filter, max_diff)                   \
Frank Barchard's avatar
Frank Barchard committed
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
  TEST_F(LibYUVScaleTest, name##To##width##x##height##_##filter) {             \
    int diff = ARGBTestFilter(benchmark_width_, benchmark_height_, width,      \
                              height, kFilter##filter, benchmark_iterations_,  \
                              disable_cpu_flags_, benchmark_cpu_info_);        \
    EXPECT_LE(diff, max_diff);                                                 \
  }                                                                            \
  TEST_F(LibYUVScaleTest, name##From##width##x##height##_##filter) {           \
    int diff = ARGBTestFilter(width, height, Abs(benchmark_width_),            \
                              Abs(benchmark_height_), kFilter##filter,         \
                              benchmark_iterations_, disable_cpu_flags_,       \
                              benchmark_cpu_info_);                            \
    EXPECT_LE(diff, max_diff);                                                 \
  }                                                                            \
  TEST_F(LibYUVScaleTest, name##ClipTo##width##x##height##_##filter) {         \
    int diff =                                                                 \
        ARGBClipTestFilter(benchmark_width_, benchmark_height_, width, height, \
                           kFilter##filter, benchmark_iterations_);            \
    EXPECT_LE(diff, max_diff);                                                 \
  }                                                                            \
  TEST_F(LibYUVScaleTest, name##ClipFrom##width##x##height##_##filter) {       \
    int diff = ARGBClipTestFilter(width, height, Abs(benchmark_width_),        \
                                  Abs(benchmark_height_), kFilter##filter,     \
                                  benchmark_iterations_);                      \
    EXPECT_LE(diff, max_diff);                                                 \
  }
fbarchard@google.com's avatar
fbarchard@google.com committed
297

fbarchard@google.com's avatar
fbarchard@google.com committed
298
/// Test scale to a specified size with all 4 filters.
Frank Barchard's avatar
Frank Barchard committed
299 300 301 302
#define TEST_SCALETO(name, width, height)       \
  TEST_SCALETO1(name, width, height, None, 0)   \
  TEST_SCALETO1(name, width, height, Linear, 3) \
  TEST_SCALETO1(name, width, height, Bilinear, 3)
303

304
TEST_SCALETO(ARGBScale, 1, 1)
305
TEST_SCALETO(ARGBScale, 320, 240)
306
TEST_SCALETO(ARGBScale, 352, 288)
307
TEST_SCALETO(ARGBScale, 569, 480)
fbarchard@google.com's avatar
fbarchard@google.com committed
308
TEST_SCALETO(ARGBScale, 640, 360)
309
TEST_SCALETO(ARGBScale, 1280, 720)
310 311
#undef TEST_SCALETO1
#undef TEST_SCALETO
fbarchard@google.com's avatar
fbarchard@google.com committed
312

313
// Scale with YUV conversion to ARGB and clipping.
314
// TODO(fbarchard): Add fourcc support.  All 4 ARGB formats is easy to support.
315
LIBYUV_API
Frank Barchard's avatar
Frank Barchard committed
316
int YUVToARGBScaleReference2(const uint8_t* src_y,
Frank Barchard's avatar
Frank Barchard committed
317
                             int src_stride_y,
Frank Barchard's avatar
Frank Barchard committed
318
                             const uint8_t* src_u,
Frank Barchard's avatar
Frank Barchard committed
319
                             int src_stride_u,
Frank Barchard's avatar
Frank Barchard committed
320
                             const uint8_t* src_v,
Frank Barchard's avatar
Frank Barchard committed
321
                             int src_stride_v,
322
                             uint32 /* src_fourcc */,
Frank Barchard's avatar
Frank Barchard committed
323 324
                             int src_width,
                             int src_height,
Frank Barchard's avatar
Frank Barchard committed
325
                             uint8_t* dst_argb,
Frank Barchard's avatar
Frank Barchard committed
326
                             int dst_stride_argb,
327
                             uint32 /* dst_fourcc */,
Frank Barchard's avatar
Frank Barchard committed
328 329 330 331 332 333
                             int dst_width,
                             int dst_height,
                             int clip_x,
                             int clip_y,
                             int clip_width,
                             int clip_height,
334
                             enum FilterMode filtering) {
335 336
  uint8_t* argb_buffer =
      static_cast<uint8_t*>(malloc(src_width * src_height * 4));
337
  int r;
Frank Barchard's avatar
Frank Barchard committed
338 339 340 341 342 343
  I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
             argb_buffer, src_width * 4, src_width, src_height);

  r = ARGBScaleClip(argb_buffer, src_width * 4, src_width, src_height, dst_argb,
                    dst_stride_argb, dst_width, dst_height, clip_x, clip_y,
                    clip_width, clip_height, filtering);
344 345 346 347
  free(argb_buffer);
  return r;
}

348 349 350 351 352 353
static void FillRamp(uint8_t* buf,
                     int width,
                     int height,
                     int v,
                     int dx,
                     int dy) {
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  int rv = v;
  for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
      *buf++ = v;
      v += dx;
      if (v < 0 || v > 255) {
        dx = -dx;
        v += dx;
      }
    }
    v = rv + dy;
    if (v < 0 || v > 255) {
      dy = -dy;
      v += dy;
    }
    rv = v;
  }
}

// Test scaling with C vs Opt and return maximum pixel difference. 0 = exact.
Frank Barchard's avatar
Frank Barchard committed
374 375 376 377 378
static int YUVToARGBTestFilter(int src_width,
                               int src_height,
                               int dst_width,
                               int dst_height,
                               FilterMode f,
379
                               int benchmark_iterations) {
Frank Barchard's avatar
Frank Barchard committed
380 381
  int64_t src_y_plane_size = Abs(src_width) * Abs(src_height);
  int64_t src_uv_plane_size =
Frank Barchard's avatar
Frank Barchard committed
382
      ((Abs(src_width) + 1) / 2) * ((Abs(src_height) + 1) / 2);
383 384 385 386 387 388 389
  int src_stride_y = Abs(src_width);
  int src_stride_uv = (Abs(src_width) + 1) / 2;

  align_buffer_page_end(src_y, src_y_plane_size);
  align_buffer_page_end(src_u, src_uv_plane_size);
  align_buffer_page_end(src_v, src_uv_plane_size);

Frank Barchard's avatar
Frank Barchard committed
390
  int64_t dst_argb_plane_size = (dst_width) * (dst_height)*4LL;
Frank Barchard's avatar
Frank Barchard committed
391
  int dst_stride_argb = (dst_width)*4;
392 393 394 395 396 397 398 399 400 401 402 403 404 405
  align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
  align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
  if (!dst_argb_c || !dst_argb_opt || !src_y || !src_u || !src_v) {
    printf("Skipped.  Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
    return 0;
  }
  // Fill YUV image with continuous ramp, which is less sensitive to
  // subsampling and filtering differences for test purposes.
  FillRamp(src_y, Abs(src_width), Abs(src_height), 128, 1, 1);
  FillRamp(src_u, (Abs(src_width) + 1) / 2, (Abs(src_height) + 1) / 2, 3, 1, 1);
  FillRamp(src_v, (Abs(src_width) + 1) / 2, (Abs(src_height) + 1) / 2, 4, 1, 1);
  memset(dst_argb_c, 2, dst_argb_plane_size);
  memset(dst_argb_opt, 3, dst_argb_plane_size);

Frank Barchard's avatar
Frank Barchard committed
406 407 408 409 410
  YUVToARGBScaleReference2(src_y, src_stride_y, src_u, src_stride_uv, src_v,
                           src_stride_uv, libyuv::FOURCC_I420, src_width,
                           src_height, dst_argb_c, dst_stride_argb,
                           libyuv::FOURCC_I420, dst_width, dst_height, 0, 0,
                           dst_width, dst_height, f);
411 412

  for (int i = 0; i < benchmark_iterations; ++i) {
Frank Barchard's avatar
Frank Barchard committed
413 414 415 416 417
    YUVToARGBScaleClip(src_y, src_stride_y, src_u, src_stride_uv, src_v,
                       src_stride_uv, libyuv::FOURCC_I420, src_width,
                       src_height, dst_argb_opt, dst_stride_argb,
                       libyuv::FOURCC_I420, dst_width, dst_height, 0, 0,
                       dst_width, dst_height, f);
418 419 420 421 422 423 424
  }
  int max_diff = 0;
  for (int i = 0; i < dst_height; ++i) {
    for (int j = 0; j < dst_width * 4; ++j) {
      int abs_diff = Abs(dst_argb_c[(i * dst_stride_argb) + j] -
                         dst_argb_opt[(i * dst_stride_argb) + j]);
      if (abs_diff > max_diff) {
Frank Barchard's avatar
Frank Barchard committed
425
        printf("error %d at %d,%d c %d opt %d", abs_diff, j, i,
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
               dst_argb_c[(i * dst_stride_argb) + j],
               dst_argb_opt[(i * dst_stride_argb) + j]);
        EXPECT_LE(abs_diff, 40);
        max_diff = abs_diff;
      }
    }
  }

  free_aligned_buffer_page_end(dst_argb_c);
  free_aligned_buffer_page_end(dst_argb_opt);
  free_aligned_buffer_page_end(src_y);
  free_aligned_buffer_page_end(src_u);
  free_aligned_buffer_page_end(src_v);
  return max_diff;
}

TEST_F(LibYUVScaleTest, YUVToRGBScaleUp) {
443 444 445 446
  int diff =
      YUVToARGBTestFilter(benchmark_width_, benchmark_height_,
                          benchmark_width_ * 3 / 2, benchmark_height_ * 3 / 2,
                          libyuv::kFilterBilinear, benchmark_iterations_);
447 448 449 450
  EXPECT_LE(diff, 10);
}

TEST_F(LibYUVScaleTest, YUVToRGBScaleDown) {
Frank Barchard's avatar
Frank Barchard committed
451 452
  int diff = YUVToARGBTestFilter(
      benchmark_width_ * 3 / 2, benchmark_height_ * 3 / 2, benchmark_width_,
453
      benchmark_height_, libyuv::kFilterBilinear, benchmark_iterations_);
454 455 456
  EXPECT_LE(diff, 10);
}

457
}  // namespace libyuv