media/libyuv/unit_test/convert_test.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libyuv/unit_test/convert_test.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1033 @@
     1.4 +/*
     1.5 + *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
     1.6 + *
     1.7 + *  Use of this source code is governed by a BSD-style license
     1.8 + *  that can be found in the LICENSE file in the root of the source
     1.9 + *  tree. An additional intellectual property rights grant can be found
    1.10 + *  in the file PATENTS. All contributing project authors may
    1.11 + *  be found in the AUTHORS file in the root of the source tree.
    1.12 + */
    1.13 +
    1.14 +#include <stdlib.h>
    1.15 +#include <time.h>
    1.16 +
    1.17 +#include "libyuv/compare.h"
    1.18 +#include "libyuv/convert.h"
    1.19 +#include "libyuv/convert_argb.h"
    1.20 +#include "libyuv/convert_from.h"
    1.21 +#include "libyuv/convert_from_argb.h"
    1.22 +#include "libyuv/cpu_id.h"
    1.23 +#include "libyuv/format_conversion.h"
    1.24 +#ifdef HAVE_JPEG
    1.25 +#include "libyuv/mjpeg_decoder.h"
    1.26 +#endif
    1.27 +#include "libyuv/planar_functions.h"
    1.28 +#include "libyuv/rotate.h"
    1.29 +#include "libyuv/row.h"
    1.30 +#include "../unit_test/unit_test.h"
    1.31 +
    1.32 +#if defined(_MSC_VER)
    1.33 +#define SIMD_ALIGNED(var) __declspec(align(16)) var
    1.34 +#else  // __GNUC__
    1.35 +#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
    1.36 +#endif
    1.37 +
    1.38 +namespace libyuv {
    1.39 +
    1.40 +#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
    1.41 +
    1.42 +#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,           \
    1.43 +                       FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF)   \
    1.44 +TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {                        \
    1.45 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
    1.46 +  const int kHeight = benchmark_height_;                                       \
    1.47 +  align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
    1.48 +  align_buffer_64(src_u,                                                       \
    1.49 +                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
    1.50 +                  SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
    1.51 +  align_buffer_64(src_v,                                                       \
    1.52 +                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
    1.53 +                  SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
    1.54 +  align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
    1.55 +  align_buffer_64(dst_u_c,                                                     \
    1.56 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
    1.57 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
    1.58 +  align_buffer_64(dst_v_c,                                                     \
    1.59 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
    1.60 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
    1.61 +  align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
    1.62 +  align_buffer_64(dst_u_opt,                                                   \
    1.63 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
    1.64 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
    1.65 +  align_buffer_64(dst_v_opt,                                                   \
    1.66 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
    1.67 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
    1.68 +  srandom(time(NULL));                                                         \
    1.69 +  for (int i = 0; i < kHeight; ++i)                                            \
    1.70 +    for (int j = 0; j < kWidth; ++j)                                           \
    1.71 +      src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
    1.72 +  for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {                \
    1.73 +    for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {               \
    1.74 +      src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
    1.75 +          (random() & 0xff);                                                   \
    1.76 +      src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
    1.77 +          (random() & 0xff);                                                   \
    1.78 +    }                                                                          \
    1.79 +  }                                                                            \
    1.80 +  memset(dst_y_c, 1, kWidth * kHeight);                                        \
    1.81 +  memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
    1.82 +                     SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
    1.83 +  memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
    1.84 +                     SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
    1.85 +  memset(dst_y_opt, 101, kWidth * kHeight);                                    \
    1.86 +  memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
    1.87 +                         SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
    1.88 +  memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
    1.89 +                         SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
    1.90 +  MaskCpuFlags(0);                                                             \
    1.91 +  SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                          \
    1.92 +                                 src_u + OFF,                                  \
    1.93 +                                 SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
    1.94 +                                 src_v + OFF,                                  \
    1.95 +                                 SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
    1.96 +                                 dst_y_c, kWidth,                              \
    1.97 +                                 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
    1.98 +                                 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
    1.99 +                                 kWidth, NEG kHeight);                         \
   1.100 +  MaskCpuFlags(-1);                                                            \
   1.101 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.102 +    SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                        \
   1.103 +                                   src_u + OFF,                                \
   1.104 +                                       SUBSAMPLE(kWidth, SRC_SUBSAMP_X),       \
   1.105 +                                   src_v + OFF,                                \
   1.106 +                                       SUBSAMPLE(kWidth, SRC_SUBSAMP_X),       \
   1.107 +                                   dst_y_opt, kWidth,                          \
   1.108 +                                   dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
   1.109 +                                   dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
   1.110 +                                   kWidth, NEG kHeight);                       \
   1.111 +  }                                                                            \
   1.112 +  int max_diff = 0;                                                            \
   1.113 +  for (int i = 0; i < kHeight; ++i) {                                          \
   1.114 +    for (int j = 0; j < kWidth; ++j) {                                         \
   1.115 +      int abs_diff =                                                           \
   1.116 +          abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
   1.117 +              static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
   1.118 +      if (abs_diff > max_diff) {                                               \
   1.119 +        max_diff = abs_diff;                                                   \
   1.120 +      }                                                                        \
   1.121 +    }                                                                          \
   1.122 +  }                                                                            \
   1.123 +  EXPECT_LE(max_diff, 0);                                                      \
   1.124 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.125 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
   1.126 +      int abs_diff =                                                           \
   1.127 +          abs(static_cast<int>(dst_u_c[i *                                     \
   1.128 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
   1.129 +              static_cast<int>(dst_u_opt[i *                                   \
   1.130 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
   1.131 +      if (abs_diff > max_diff) {                                               \
   1.132 +        max_diff = abs_diff;                                                   \
   1.133 +      }                                                                        \
   1.134 +    }                                                                          \
   1.135 +  }                                                                            \
   1.136 +  EXPECT_LE(max_diff, 3);                                                      \
   1.137 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.138 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
   1.139 +      int abs_diff =                                                           \
   1.140 +          abs(static_cast<int>(dst_v_c[i *                                     \
   1.141 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
   1.142 +              static_cast<int>(dst_v_opt[i *                                   \
   1.143 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
   1.144 +      if (abs_diff > max_diff) {                                               \
   1.145 +        max_diff = abs_diff;                                                   \
   1.146 +      }                                                                        \
   1.147 +    }                                                                          \
   1.148 +  }                                                                            \
   1.149 +  EXPECT_LE(max_diff, 3);                                                      \
   1.150 +  free_aligned_buffer_64(dst_y_c);                                             \
   1.151 +  free_aligned_buffer_64(dst_u_c);                                             \
   1.152 +  free_aligned_buffer_64(dst_v_c);                                             \
   1.153 +  free_aligned_buffer_64(dst_y_opt);                                           \
   1.154 +  free_aligned_buffer_64(dst_u_opt);                                           \
   1.155 +  free_aligned_buffer_64(dst_v_opt);                                           \
   1.156 +  free_aligned_buffer_64(src_y);                                               \
   1.157 +  free_aligned_buffer_64(src_u);                                               \
   1.158 +  free_aligned_buffer_64(src_v);                                               \
   1.159 +}
   1.160 +
   1.161 +#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,            \
   1.162 +                      FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)                        \
   1.163 +    TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
   1.164 +                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
   1.165 +                   benchmark_width_ - 4, _Any, +, 0)                           \
   1.166 +    TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
   1.167 +                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
   1.168 +                   benchmark_width_, _Unaligned, +, 1)                         \
   1.169 +    TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
   1.170 +                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
   1.171 +                   benchmark_width_, _Invert, -, 0)                            \
   1.172 +    TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,               \
   1.173 +                   FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                           \
   1.174 +                   benchmark_width_, _Opt, +, 0)
   1.175 +
   1.176 +TESTPLANARTOP(I420, 2, 2, I420, 2, 2)
   1.177 +TESTPLANARTOP(I422, 2, 1, I420, 2, 2)
   1.178 +TESTPLANARTOP(I444, 1, 1, I420, 2, 2)
   1.179 +TESTPLANARTOP(I411, 4, 1, I420, 2, 2)
   1.180 +TESTPLANARTOP(I420, 2, 2, I422, 2, 1)
   1.181 +TESTPLANARTOP(I420, 2, 2, I444, 1, 1)
   1.182 +TESTPLANARTOP(I420, 2, 2, I411, 4, 1)
   1.183 +TESTPLANARTOP(I420, 2, 2, I420Mirror, 2, 2)
   1.184 +TESTPLANARTOP(I422, 2, 1, I422, 2, 1)
   1.185 +TESTPLANARTOP(I444, 1, 1, I444, 1, 1)
   1.186 +
   1.187 +#define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,          \
   1.188 +                       FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF)   \
   1.189 +TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {                        \
   1.190 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.191 +  const int kHeight = benchmark_height_;                                       \
   1.192 +  align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
   1.193 +  align_buffer_64(src_u,                                                       \
   1.194 +                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
   1.195 +                  SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
   1.196 +  align_buffer_64(src_v,                                                       \
   1.197 +                  SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *                           \
   1.198 +                  SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
   1.199 +  align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
   1.200 +  align_buffer_64(dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *                 \
   1.201 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.202 +  align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
   1.203 +  align_buffer_64(dst_uv_opt, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *               \
   1.204 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.205 +  srandom(time(NULL));                                                         \
   1.206 +  for (int i = 0; i < kHeight; ++i)                                            \
   1.207 +    for (int j = 0; j < kWidth; ++j)                                           \
   1.208 +      src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
   1.209 +  for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {                \
   1.210 +    for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {               \
   1.211 +      src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
   1.212 +          (random() & 0xff);                                                   \
   1.213 +      src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =                \
   1.214 +          (random() & 0xff);                                                   \
   1.215 +    }                                                                          \
   1.216 +  }                                                                            \
   1.217 +  memset(dst_y_c, 1, kWidth * kHeight);                                        \
   1.218 +  memset(dst_uv_c, 2, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *                       \
   1.219 +                      SUBSAMPLE(kHeight, SUBSAMP_Y));                          \
   1.220 +  memset(dst_y_opt, 101, kWidth * kHeight);                                    \
   1.221 +  memset(dst_uv_opt, 102, SUBSAMPLE(kWidth * 2, SUBSAMP_X) *                   \
   1.222 +                          SUBSAMPLE(kHeight, SUBSAMP_Y));                      \
   1.223 +  MaskCpuFlags(0);                                                             \
   1.224 +  SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                          \
   1.225 +                                 src_u + OFF,                                  \
   1.226 +                                 SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
   1.227 +                                 src_v + OFF,                                  \
   1.228 +                                 SUBSAMPLE(kWidth, SRC_SUBSAMP_X),             \
   1.229 +                                 dst_y_c, kWidth,                              \
   1.230 +                                 dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X),   \
   1.231 +                                 kWidth, NEG kHeight);                         \
   1.232 +  MaskCpuFlags(-1);                                                            \
   1.233 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.234 +    SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                        \
   1.235 +                                   src_u + OFF,                                \
   1.236 +                                   SUBSAMPLE(kWidth, SRC_SUBSAMP_X),           \
   1.237 +                                   src_v + OFF,                                \
   1.238 +                                   SUBSAMPLE(kWidth, SRC_SUBSAMP_X),           \
   1.239 +                                   dst_y_opt, kWidth,                          \
   1.240 +                                   dst_uv_opt,                                 \
   1.241 +                                   SUBSAMPLE(kWidth * 2, SUBSAMP_X),           \
   1.242 +                                   kWidth, NEG kHeight);                       \
   1.243 +  }                                                                            \
   1.244 +  int max_diff = 0;                                                            \
   1.245 +  for (int i = 0; i < kHeight; ++i) {                                          \
   1.246 +    for (int j = 0; j < kWidth; ++j) {                                         \
   1.247 +      int abs_diff =                                                           \
   1.248 +          abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
   1.249 +              static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
   1.250 +      if (abs_diff > max_diff) {                                               \
   1.251 +        max_diff = abs_diff;                                                   \
   1.252 +      }                                                                        \
   1.253 +    }                                                                          \
   1.254 +  }                                                                            \
   1.255 +  EXPECT_LE(max_diff, 1);                                                      \
   1.256 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.257 +    for (int j = 0; j < SUBSAMPLE(kWidth * 2, SUBSAMP_X); ++j) {               \
   1.258 +      int abs_diff =                                                           \
   1.259 +          abs(static_cast<int>(dst_uv_c[i *                                    \
   1.260 +                               SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]) -        \
   1.261 +              static_cast<int>(dst_uv_opt[i *                                  \
   1.262 +                               SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]));        \
   1.263 +      if (abs_diff > max_diff) {                                               \
   1.264 +        max_diff = abs_diff;                                                   \
   1.265 +      }                                                                        \
   1.266 +    }                                                                          \
   1.267 +  }                                                                            \
   1.268 +  EXPECT_LE(max_diff, 1);                                                      \
   1.269 +  free_aligned_buffer_64(dst_y_c);                                             \
   1.270 +  free_aligned_buffer_64(dst_uv_c);                                            \
   1.271 +  free_aligned_buffer_64(dst_y_opt);                                           \
   1.272 +  free_aligned_buffer_64(dst_uv_opt);                                          \
   1.273 +  free_aligned_buffer_64(src_y);                                               \
   1.274 +  free_aligned_buffer_64(src_u);                                               \
   1.275 +  free_aligned_buffer_64(src_v);                                               \
   1.276 +}
   1.277 +
   1.278 +#define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,           \
   1.279 +                       FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)                       \
   1.280 +    TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
   1.281 +                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
   1.282 +                    benchmark_width_ - 4, _Any, +, 0)                          \
   1.283 +    TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
   1.284 +                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
   1.285 +                    benchmark_width_, _Unaligned, +, 1)                        \
   1.286 +    TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
   1.287 +                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
   1.288 +                    benchmark_width_, _Invert, -, 0)                           \
   1.289 +    TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,              \
   1.290 +                    FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                          \
   1.291 +                    benchmark_width_, _Opt, +, 0)
   1.292 +
   1.293 +TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2)
   1.294 +TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2)
   1.295 +
   1.296 +#define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,         \
   1.297 +                         FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \
   1.298 +TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) {                        \
   1.299 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.300 +  const int kHeight = benchmark_height_;                                       \
   1.301 +  align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
   1.302 +  align_buffer_64(src_uv, 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X) *               \
   1.303 +                  SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF);                    \
   1.304 +  align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
   1.305 +  align_buffer_64(dst_u_c,                                                     \
   1.306 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.307 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.308 +  align_buffer_64(dst_v_c,                                                     \
   1.309 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.310 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.311 +  align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
   1.312 +  align_buffer_64(dst_u_opt,                                                   \
   1.313 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.314 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.315 +  align_buffer_64(dst_v_opt,                                                   \
   1.316 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.317 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.318 +  srandom(time(NULL));                                                         \
   1.319 +  for (int i = 0; i < kHeight; ++i)                                            \
   1.320 +    for (int j = 0; j < kWidth; ++j)                                           \
   1.321 +      src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
   1.322 +  for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) {                \
   1.323 +    for (int j = 0; j < 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) {           \
   1.324 +      src_uv[(i * 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] =           \
   1.325 +          (random() & 0xff);                                                   \
   1.326 +    }                                                                          \
   1.327 +  }                                                                            \
   1.328 +  memset(dst_y_c, 1, kWidth * kHeight);                                        \
   1.329 +  memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
   1.330 +                     SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
   1.331 +  memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) *                            \
   1.332 +                     SUBSAMPLE(kHeight, SUBSAMP_Y));                           \
   1.333 +  memset(dst_y_opt, 101, kWidth * kHeight);                                    \
   1.334 +  memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
   1.335 +                         SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
   1.336 +  memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) *                        \
   1.337 +                         SUBSAMPLE(kHeight, SUBSAMP_Y));                       \
   1.338 +  MaskCpuFlags(0);                                                             \
   1.339 +  SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                          \
   1.340 +                                 src_uv + OFF,                                 \
   1.341 +                                 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X),         \
   1.342 +                                 dst_y_c, kWidth,                              \
   1.343 +                                 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
   1.344 +                                 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X),        \
   1.345 +                                 kWidth, NEG kHeight);                         \
   1.346 +  MaskCpuFlags(-1);                                                            \
   1.347 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.348 +    SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth,                        \
   1.349 +                                   src_uv + OFF,                               \
   1.350 +                                   2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X),       \
   1.351 +                                   dst_y_opt, kWidth,                          \
   1.352 +                                   dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
   1.353 +                                   dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X),    \
   1.354 +                                   kWidth, NEG kHeight);                       \
   1.355 +  }                                                                            \
   1.356 +  int max_diff = 0;                                                            \
   1.357 +  for (int i = 0; i < kHeight; ++i) {                                          \
   1.358 +    for (int j = 0; j < kWidth; ++j) {                                         \
   1.359 +      int abs_diff =                                                           \
   1.360 +          abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
   1.361 +              static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
   1.362 +      if (abs_diff > max_diff) {                                               \
   1.363 +        max_diff = abs_diff;                                                   \
   1.364 +      }                                                                        \
   1.365 +    }                                                                          \
   1.366 +  }                                                                            \
   1.367 +  EXPECT_LE(max_diff, 1);                                                      \
   1.368 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.369 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
   1.370 +      int abs_diff =                                                           \
   1.371 +          abs(static_cast<int>(dst_u_c[i *                                     \
   1.372 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
   1.373 +              static_cast<int>(dst_u_opt[i *                                   \
   1.374 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
   1.375 +      if (abs_diff > max_diff) {                                               \
   1.376 +        max_diff = abs_diff;                                                   \
   1.377 +      }                                                                        \
   1.378 +    }                                                                          \
   1.379 +  }                                                                            \
   1.380 +  EXPECT_LE(max_diff, 1);                                                      \
   1.381 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.382 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
   1.383 +      int abs_diff =                                                           \
   1.384 +          abs(static_cast<int>(dst_v_c[i *                                     \
   1.385 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
   1.386 +              static_cast<int>(dst_v_opt[i *                                   \
   1.387 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
   1.388 +      if (abs_diff > max_diff) {                                               \
   1.389 +        max_diff = abs_diff;                                                   \
   1.390 +      }                                                                        \
   1.391 +    }                                                                          \
   1.392 +  }                                                                            \
   1.393 +  EXPECT_LE(max_diff, 1);                                                      \
   1.394 +  free_aligned_buffer_64(dst_y_c);                                             \
   1.395 +  free_aligned_buffer_64(dst_u_c);                                             \
   1.396 +  free_aligned_buffer_64(dst_v_c);                                             \
   1.397 +  free_aligned_buffer_64(dst_y_opt);                                           \
   1.398 +  free_aligned_buffer_64(dst_u_opt);                                           \
   1.399 +  free_aligned_buffer_64(dst_v_opt);                                           \
   1.400 +  free_aligned_buffer_64(src_y);                                               \
   1.401 +  free_aligned_buffer_64(src_uv);                                              \
   1.402 +}
   1.403 +
   1.404 +#define TESTBIPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,          \
   1.405 +                        FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)                      \
   1.406 +    TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
   1.407 +                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
   1.408 +                     benchmark_width_ - 4, _Any, +, 0)                         \
   1.409 +    TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
   1.410 +                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
   1.411 +                     benchmark_width_, _Unaligned, +, 1)                       \
   1.412 +    TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
   1.413 +                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
   1.414 +                     benchmark_width_, _Invert, -, 0)                          \
   1.415 +    TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y,             \
   1.416 +                     FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,                         \
   1.417 +                     benchmark_width_, _Opt, +, 0)
   1.418 +
   1.419 +TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2)
   1.420 +TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2)
   1.421 +
   1.422 +#define ALIGNINT(V, ALIGN) (((V) + (ALIGN) - 1) / (ALIGN) * (ALIGN))
   1.423 +
   1.424 +#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,  \
   1.425 +                       YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C)         \
   1.426 +TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) {                                 \
   1.427 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.428 +  const int kHeight = ALIGNINT(benchmark_height_, YALIGN);                     \
   1.429 +  const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN);                        \
   1.430 +  const int kSizeUV =                                                          \
   1.431 +    SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y);              \
   1.432 +  align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
   1.433 +  align_buffer_64(src_u, kSizeUV + OFF);                                       \
   1.434 +  align_buffer_64(src_v, kSizeUV + OFF);                                       \
   1.435 +  align_buffer_64(dst_argb_c, kStrideB * kHeight);                             \
   1.436 +  align_buffer_64(dst_argb_opt, kStrideB * kHeight);                           \
   1.437 +  srandom(time(NULL));                                                         \
   1.438 +  for (int i = 0; i < kWidth * kHeight; ++i) {                                 \
   1.439 +    src_y[i + OFF] = (random() & 0xff);                                        \
   1.440 +  }                                                                            \
   1.441 +  for (int i = 0; i < kSizeUV; ++i) {                                          \
   1.442 +    src_u[i + OFF] = (random() & 0xff);                                        \
   1.443 +    src_v[i + OFF] = (random() & 0xff);                                        \
   1.444 +  }                                                                            \
   1.445 +  memset(dst_argb_c, 1, kStrideB * kHeight);                                   \
   1.446 +  memset(dst_argb_opt, 101, kStrideB * kHeight);                               \
   1.447 +  MaskCpuFlags(0);                                                             \
   1.448 +  FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                   \
   1.449 +                        src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),             \
   1.450 +                        src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),             \
   1.451 +                        dst_argb_c, kStrideB,                                  \
   1.452 +                        kWidth, NEG kHeight);                                  \
   1.453 +  MaskCpuFlags(-1);                                                            \
   1.454 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.455 +    FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                 \
   1.456 +                          src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),           \
   1.457 +                          src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X),           \
   1.458 +                          dst_argb_opt, kStrideB,                              \
   1.459 +                          kWidth, NEG kHeight);                                \
   1.460 +  }                                                                            \
   1.461 +  int max_diff = 0;                                                            \
   1.462 +  /* Convert to ARGB so 565 is expanded to bytes that can be compared. */      \
   1.463 +  align_buffer_64(dst_argb32_c, kWidth * BPP_C  * kHeight);                    \
   1.464 +  align_buffer_64(dst_argb32_opt, kWidth * BPP_C  * kHeight);                  \
   1.465 +  memset(dst_argb32_c, 2, kWidth * BPP_C  * kHeight);                          \
   1.466 +  memset(dst_argb32_opt, 102, kWidth * BPP_C  * kHeight);                      \
   1.467 +  FMT_B##To##FMT_C(dst_argb_c, kStrideB,                                       \
   1.468 +                   dst_argb32_c, kWidth * BPP_C ,                              \
   1.469 +                   kWidth, kHeight);                                           \
   1.470 +  FMT_B##To##FMT_C(dst_argb_opt, kStrideB,                                     \
   1.471 +                   dst_argb32_opt, kWidth * BPP_C ,                            \
   1.472 +                   kWidth, kHeight);                                           \
   1.473 +  for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) {                         \
   1.474 +    int abs_diff =                                                             \
   1.475 +        abs(static_cast<int>(dst_argb32_c[i]) -                                \
   1.476 +            static_cast<int>(dst_argb32_opt[i]));                              \
   1.477 +    if (abs_diff > max_diff) {                                                 \
   1.478 +      max_diff = abs_diff;                                                     \
   1.479 +    }                                                                          \
   1.480 +  }                                                                            \
   1.481 +  EXPECT_LE(max_diff, DIFF);                                                   \
   1.482 +  free_aligned_buffer_64(src_y);                                               \
   1.483 +  free_aligned_buffer_64(src_u);                                               \
   1.484 +  free_aligned_buffer_64(src_v);                                               \
   1.485 +  free_aligned_buffer_64(dst_argb_c);                                          \
   1.486 +  free_aligned_buffer_64(dst_argb_opt);                                        \
   1.487 +  free_aligned_buffer_64(dst_argb32_c);                                        \
   1.488 +  free_aligned_buffer_64(dst_argb32_opt);                                      \
   1.489 +}
   1.490 +
   1.491 +#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,   \
   1.492 +                      YALIGN, DIFF, FMT_C, BPP_C)                              \
   1.493 +    TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
   1.494 +        YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C)          \
   1.495 +    TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
   1.496 +        YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, BPP_C)        \
   1.497 +    TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
   1.498 +        YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C)           \
   1.499 +    TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN,      \
   1.500 +        YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C)
   1.501 +
   1.502 +// TODO(fbarchard): Make vertical alignment unnecessary on bayer.
   1.503 +TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4)
   1.504 +TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1, 2, ARGB, 4)
   1.505 +TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4)
   1.506 +TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1, 2, ARGB, 4)
   1.507 +TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4)
   1.508 +TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4)
   1.509 +TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4)
   1.510 +TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1, 9, ARGB, 4)
   1.511 +TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1, 17, ARGB, 4)
   1.512 +TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
   1.513 +TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1, 2, ARGB, 4)
   1.514 +TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4)
   1.515 +TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1, 2, ARGB, 4)
   1.516 +TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
   1.517 +TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
   1.518 +TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1, 1, ARGB, 4)
   1.519 +TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1, 1, ARGB, 4)
   1.520 +TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4)
   1.521 +TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4)
   1.522 +TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4)
   1.523 +TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1, 2, 2, 2, ARGB, 4)
   1.524 +TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1, 2, 2, 2, ARGB, 4)
   1.525 +TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1, 2, 2, 2, ARGB, 4)
   1.526 +TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1, 2, 2, 2, ARGB, 4)
   1.527 +
   1.528 +#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,       \
   1.529 +                         W1280, DIFF, N, NEG, OFF)                             \
   1.530 +TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) {                                 \
   1.531 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.532 +  const int kHeight = benchmark_height_;                                       \
   1.533 +  const int kStrideB = kWidth * BPP_B;                                         \
   1.534 +  align_buffer_64(src_y, kWidth * kHeight + OFF);                              \
   1.535 +  align_buffer_64(src_uv,                                                      \
   1.536 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.537 +                  SUBSAMPLE(kHeight, SUBSAMP_Y) * 2 + OFF);                    \
   1.538 +  align_buffer_64(dst_argb_c, kStrideB * kHeight);                             \
   1.539 +  align_buffer_64(dst_argb_opt, kStrideB * kHeight);                           \
   1.540 +  srandom(time(NULL));                                                         \
   1.541 +  for (int i = 0; i < kHeight; ++i)                                            \
   1.542 +    for (int j = 0; j < kWidth; ++j)                                           \
   1.543 +      src_y[(i * kWidth) + j + OFF] = (random() & 0xff);                       \
   1.544 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.545 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) {               \
   1.546 +      src_uv[(i * SUBSAMPLE(kWidth, SUBSAMP_X)) * 2 + j + OFF] =               \
   1.547 +          (random() & 0xff);                                                   \
   1.548 +    }                                                                          \
   1.549 +  }                                                                            \
   1.550 +  memset(dst_argb_c, 1, kStrideB * kHeight);                                   \
   1.551 +  memset(dst_argb_opt, 101, kStrideB * kHeight);                               \
   1.552 +  MaskCpuFlags(0);                                                             \
   1.553 +  FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                   \
   1.554 +                        src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,        \
   1.555 +                        dst_argb_c, kWidth * BPP_B,                            \
   1.556 +                        kWidth, NEG kHeight);                                  \
   1.557 +  MaskCpuFlags(-1);                                                            \
   1.558 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.559 +    FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth,                                 \
   1.560 +                          src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,      \
   1.561 +                          dst_argb_opt, kWidth * BPP_B,                        \
   1.562 +                          kWidth, NEG kHeight);                                \
   1.563 +  }                                                                            \
   1.564 +  /* Convert to ARGB so 565 is expanded to bytes that can be compared. */      \
   1.565 +  align_buffer_64(dst_argb32_c, kWidth * 4 * kHeight);                         \
   1.566 +  align_buffer_64(dst_argb32_opt, kWidth * 4 * kHeight);                       \
   1.567 +  memset(dst_argb32_c, 2, kWidth * 4 * kHeight);                               \
   1.568 +  memset(dst_argb32_opt, 102, kWidth * 4 * kHeight);                           \
   1.569 +  FMT_B##ToARGB(dst_argb_c, kStrideB,                                          \
   1.570 +                dst_argb32_c, kWidth * 4,                                      \
   1.571 +                kWidth, kHeight);                                              \
   1.572 +  FMT_B##ToARGB(dst_argb_opt, kStrideB,                                        \
   1.573 +                dst_argb32_opt, kWidth * 4,                                    \
   1.574 +                kWidth, kHeight);                                              \
   1.575 +  int max_diff = 0;                                                            \
   1.576 +  for (int i = 0; i < kHeight; ++i) {                                          \
   1.577 +    for (int j = 0; j < kWidth * 4; ++j) {                                     \
   1.578 +      int abs_diff =                                                           \
   1.579 +          abs(static_cast<int>(dst_argb32_c[i * kWidth * 4 + j]) -             \
   1.580 +              static_cast<int>(dst_argb32_opt[i * kWidth * 4 + j]));           \
   1.581 +      if (abs_diff > max_diff) {                                               \
   1.582 +        max_diff = abs_diff;                                                   \
   1.583 +      }                                                                        \
   1.584 +    }                                                                          \
   1.585 +  }                                                                            \
   1.586 +  EXPECT_LE(max_diff, DIFF);                                                   \
   1.587 +  free_aligned_buffer_64(src_y);                                               \
   1.588 +  free_aligned_buffer_64(src_uv);                                              \
   1.589 +  free_aligned_buffer_64(dst_argb_c);                                          \
   1.590 +  free_aligned_buffer_64(dst_argb_opt);                                        \
   1.591 +  free_aligned_buffer_64(dst_argb32_c);                                        \
   1.592 +  free_aligned_buffer_64(dst_argb32_opt);                                      \
   1.593 +}
   1.594 +
   1.595 +#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, DIFF)  \
   1.596 +    TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
   1.597 +                     benchmark_width_ - 4, DIFF, _Any, +, 0)                   \
   1.598 +    TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
   1.599 +                     benchmark_width_, DIFF, _Unaligned, +, 1)                 \
   1.600 +    TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
   1.601 +                     benchmark_width_, DIFF, _Invert, -, 0)                    \
   1.602 +    TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B,           \
   1.603 +                     benchmark_width_, DIFF, _Opt, +, 0)
   1.604 +
   1.605 +TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2)
   1.606 +TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2)
   1.607 +TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9)
   1.608 +TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2, 9)
   1.609 +
   1.610 +#define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
   1.611 +                       W1280, DIFF, N, NEG, OFF)                               \
   1.612 +TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) {                                 \
   1.613 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.614 +  const int kHeight = ALIGNINT(benchmark_height_, YALIGN);                     \
   1.615 +  const int kStride =                                                          \
   1.616 +      (SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMP_X * 8 * BPP_A + 7) / 8;          \
   1.617 +  align_buffer_64(src_argb, kStride * kHeight + OFF);                          \
   1.618 +  align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
   1.619 +  align_buffer_64(dst_u_c,                                                     \
   1.620 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.621 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.622 +  align_buffer_64(dst_v_c,                                                     \
   1.623 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.624 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.625 +  align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
   1.626 +  align_buffer_64(dst_u_opt,                                                   \
   1.627 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.628 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.629 +  align_buffer_64(dst_v_opt,                                                   \
   1.630 +                  SUBSAMPLE(kWidth, SUBSAMP_X) *                               \
   1.631 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.632 +  memset(dst_y_c, 1, kWidth * kHeight);                                        \
   1.633 +  memset(dst_u_c, 2,                                                           \
   1.634 +         SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
   1.635 +  memset(dst_v_c, 3,                                                           \
   1.636 +         SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
   1.637 +  memset(dst_y_opt, 101, kWidth * kHeight);                                    \
   1.638 +  memset(dst_u_opt, 102,                                                       \
   1.639 +         SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
   1.640 +  memset(dst_v_opt, 103,                                                       \
   1.641 +         SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y));        \
   1.642 +  srandom(time(NULL));                                                         \
   1.643 +  for (int i = 0; i < kHeight; ++i)                                            \
   1.644 +    for (int j = 0; j < kStride; ++j)                                          \
   1.645 +      src_argb[(i * kStride) + j + OFF] = (random() & 0xff);                   \
   1.646 +  MaskCpuFlags(0);                                                             \
   1.647 +  FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                               \
   1.648 +                        dst_y_c, kWidth,                                       \
   1.649 +                        dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X),                 \
   1.650 +                        dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X),                 \
   1.651 +                        kWidth, NEG kHeight);                                  \
   1.652 +  MaskCpuFlags(-1);                                                            \
   1.653 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.654 +    FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                             \
   1.655 +                          dst_y_opt, kWidth,                                   \
   1.656 +                          dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X),             \
   1.657 +                          dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X),             \
   1.658 +                          kWidth, NEG kHeight);                                \
   1.659 +  }                                                                            \
   1.660 +  int max_diff = 0;                                                            \
   1.661 +  for (int i = 0; i < kHeight; ++i) {                                          \
   1.662 +    for (int j = 0; j < kWidth; ++j) {                                         \
   1.663 +      int abs_diff =                                                           \
   1.664 +          abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
   1.665 +              static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
   1.666 +      if (abs_diff > max_diff) {                                               \
   1.667 +        max_diff = abs_diff;                                                   \
   1.668 +      }                                                                        \
   1.669 +    }                                                                          \
   1.670 +  }                                                                            \
   1.671 +  EXPECT_LE(max_diff, DIFF);                                                   \
   1.672 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.673 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
   1.674 +      int abs_diff =                                                           \
   1.675 +          abs(static_cast<int>(dst_u_c[i *                                     \
   1.676 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
   1.677 +              static_cast<int>(dst_u_opt[i *                                   \
   1.678 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
   1.679 +      if (abs_diff > max_diff) {                                               \
   1.680 +        max_diff = abs_diff;                                                   \
   1.681 +      }                                                                        \
   1.682 +    }                                                                          \
   1.683 +  }                                                                            \
   1.684 +  EXPECT_LE(max_diff, DIFF);                                                   \
   1.685 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.686 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) {                   \
   1.687 +      int abs_diff =                                                           \
   1.688 +          abs(static_cast<int>(dst_v_c[i *                                     \
   1.689 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]) -            \
   1.690 +              static_cast<int>(dst_v_opt[i *                                   \
   1.691 +                               SUBSAMPLE(kWidth, SUBSAMP_X) + j]));            \
   1.692 +      if (abs_diff > max_diff) {                                               \
   1.693 +        max_diff = abs_diff;                                                   \
   1.694 +      }                                                                        \
   1.695 +    }                                                                          \
   1.696 +  }                                                                            \
   1.697 +  EXPECT_LE(max_diff, DIFF);                                                   \
   1.698 +  free_aligned_buffer_64(dst_y_c);                                             \
   1.699 +  free_aligned_buffer_64(dst_u_c);                                             \
   1.700 +  free_aligned_buffer_64(dst_v_c);                                             \
   1.701 +  free_aligned_buffer_64(dst_y_opt);                                           \
   1.702 +  free_aligned_buffer_64(dst_u_opt);                                           \
   1.703 +  free_aligned_buffer_64(dst_v_opt);                                           \
   1.704 +  free_aligned_buffer_64(src_argb);                                            \
   1.705 +}
   1.706 +
   1.707 +#define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,  \
   1.708 +                      DIFF)                                                    \
   1.709 +    TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
   1.710 +                   benchmark_width_ - 4, DIFF, _Any, +, 0)                     \
   1.711 +    TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
   1.712 +                   benchmark_width_, DIFF, _Unaligned, +, 1)                   \
   1.713 +    TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
   1.714 +                   benchmark_width_, DIFF, _Invert, -, 0)                      \
   1.715 +    TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,     \
   1.716 +                   benchmark_width_, DIFF, _Opt, +, 0)
   1.717 +
   1.718 +TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 4)
   1.719 +#ifdef __arm__
   1.720 +TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 4)
   1.721 +#else
   1.722 +TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0)
   1.723 +#endif
   1.724 +TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2, 4)
   1.725 +TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 4)
   1.726 +TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 4)
   1.727 +TESTATOPLANAR(RAW, 3, 1, I420, 2, 2, 4)
   1.728 +TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2, 4)
   1.729 +TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2, 5)
   1.730 +// TODO(fbarchard): Make 1555 neon work same as C code, reduce to diff 9.
   1.731 +TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 15)
   1.732 +TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2, 17)
   1.733 +TESTATOPLANAR(ARGB, 4, 1, I411, 4, 1, 4)
   1.734 +TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1, 2)
   1.735 +TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1, 2)
   1.736 +TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2, 2)
   1.737 +TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2, 2)
   1.738 +TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1, 2)
   1.739 +TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1, 2)
   1.740 +TESTATOPLANAR(I400, 1, 1, I420, 2, 2, 2)
   1.741 +TESTATOPLANAR(BayerBGGR, 1, 2, I420, 2, 2, 4)
   1.742 +TESTATOPLANAR(BayerRGGB, 1, 2, I420, 2, 2, 4)
   1.743 +TESTATOPLANAR(BayerGBRG, 1, 2, I420, 2, 2, 4)
   1.744 +TESTATOPLANAR(BayerGRBG, 1, 2, I420, 2, 2, 4)
   1.745 +
   1.746 +#define TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,       \
   1.747 +                       W1280, N, NEG, OFF)                                     \
   1.748 +TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) {                                 \
   1.749 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.750 +  const int kHeight = benchmark_height_;                                       \
   1.751 +  const int kStride = (kWidth * 8 * BPP_A + 7) / 8;                            \
   1.752 +  align_buffer_64(src_argb, kStride * kHeight + OFF);                          \
   1.753 +  align_buffer_64(dst_y_c, kWidth * kHeight);                                  \
   1.754 +  align_buffer_64(dst_uv_c,                                                    \
   1.755 +                  SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                           \
   1.756 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.757 +  align_buffer_64(dst_y_opt, kWidth * kHeight);                                \
   1.758 +  align_buffer_64(dst_uv_opt,                                                  \
   1.759 +                  SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                           \
   1.760 +                  SUBSAMPLE(kHeight, SUBSAMP_Y));                              \
   1.761 +  srandom(time(NULL));                                                         \
   1.762 +  for (int i = 0; i < kHeight; ++i)                                            \
   1.763 +    for (int j = 0; j < kStride; ++j)                                          \
   1.764 +      src_argb[(i * kStride) + j + OFF] = (random() & 0xff);                   \
   1.765 +  memset(dst_y_c, 1, kWidth * kHeight);                                        \
   1.766 +  memset(dst_uv_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                       \
   1.767 +                      SUBSAMPLE(kHeight, SUBSAMP_Y));                          \
   1.768 +  memset(dst_y_opt, 101, kWidth * kHeight);                                    \
   1.769 +  memset(dst_uv_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 *                   \
   1.770 +                        SUBSAMPLE(kHeight, SUBSAMP_Y));                        \
   1.771 +  MaskCpuFlags(0);                                                             \
   1.772 +  FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                               \
   1.773 +                        dst_y_c, kWidth,                                       \
   1.774 +                        dst_uv_c, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,            \
   1.775 +                        kWidth, NEG kHeight);                                  \
   1.776 +  MaskCpuFlags(-1);                                                            \
   1.777 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.778 +    FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride,                             \
   1.779 +                          dst_y_opt, kWidth,                                   \
   1.780 +                          dst_uv_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * 2,        \
   1.781 +                          kWidth, NEG kHeight);                                \
   1.782 +  }                                                                            \
   1.783 +  int max_diff = 0;                                                            \
   1.784 +  for (int i = 0; i < kHeight; ++i) {                                          \
   1.785 +    for (int j = 0; j < kWidth; ++j) {                                         \
   1.786 +      int abs_diff =                                                           \
   1.787 +          abs(static_cast<int>(dst_y_c[i * kWidth + j]) -                      \
   1.788 +              static_cast<int>(dst_y_opt[i * kWidth + j]));                    \
   1.789 +      if (abs_diff > max_diff) {                                               \
   1.790 +        max_diff = abs_diff;                                                   \
   1.791 +      }                                                                        \
   1.792 +    }                                                                          \
   1.793 +  }                                                                            \
   1.794 +  EXPECT_LE(max_diff, 4);                                                      \
   1.795 +  for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) {                    \
   1.796 +    for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) {               \
   1.797 +      int abs_diff =                                                           \
   1.798 +          abs(static_cast<int>(dst_uv_c[i *                                    \
   1.799 +                               SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]) -        \
   1.800 +              static_cast<int>(dst_uv_opt[i *                                  \
   1.801 +                               SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]));        \
   1.802 +      if (abs_diff > max_diff) {                                               \
   1.803 +        max_diff = abs_diff;                                                   \
   1.804 +      }                                                                        \
   1.805 +    }                                                                          \
   1.806 +  }                                                                            \
   1.807 +  EXPECT_LE(max_diff, 4);                                                      \
   1.808 +  free_aligned_buffer_64(dst_y_c);                                             \
   1.809 +  free_aligned_buffer_64(dst_uv_c);                                            \
   1.810 +  free_aligned_buffer_64(dst_y_opt);                                           \
   1.811 +  free_aligned_buffer_64(dst_uv_opt);                                          \
   1.812 +  free_aligned_buffer_64(src_argb);                                            \
   1.813 +}
   1.814 +
   1.815 +#define TESTATOBIPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y)        \
   1.816 +    TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
   1.817 +                   benchmark_width_ - 4, _Any, +, 0)                           \
   1.818 +    TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
   1.819 +                   benchmark_width_, _Unaligned, +, 1)                         \
   1.820 +    TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
   1.821 +                   benchmark_width_, _Invert, -, 0)                            \
   1.822 +    TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y,           \
   1.823 +                   benchmark_width_, _Opt, +, 0)
   1.824 +
   1.825 +TESTATOBIPLANAR(ARGB, 4, NV12, 2, 2)
   1.826 +TESTATOBIPLANAR(ARGB, 4, NV21, 2, 2)
   1.827 +
   1.828 +#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                            \
   1.829 +                  FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                            \
   1.830 +                  W1280, DIFF, N, NEG, OFF)                                    \
   1.831 +TEST_F(libyuvTest, FMT_A##To##FMT_B##N) {                                      \
   1.832 +  const int kWidth = ((W1280) > 0) ? (W1280) : 1;                              \
   1.833 +  const int kHeight = benchmark_height_;                                       \
   1.834 +  const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A;         \
   1.835 +  const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B;         \
   1.836 +  const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;  \
   1.837 +  const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;  \
   1.838 +  align_buffer_64(src_argb, kStrideA * kHeightA + OFF);                        \
   1.839 +  align_buffer_64(dst_argb_c, kStrideB * kHeightB);                            \
   1.840 +  align_buffer_64(dst_argb_opt, kStrideB * kHeightB);                          \
   1.841 +  srandom(time(NULL));                                                         \
   1.842 +  for (int i = 0; i < kStrideA * kHeightA; ++i) {                              \
   1.843 +    src_argb[i + OFF] = (random() & 0xff);                                     \
   1.844 +  }                                                                            \
   1.845 +  memset(dst_argb_c, 1, kStrideB * kHeightB);                                  \
   1.846 +  memset(dst_argb_opt, 101, kStrideB * kHeightB);                              \
   1.847 +  MaskCpuFlags(0);                                                             \
   1.848 +  FMT_A##To##FMT_B(src_argb + OFF, kStrideA,                                   \
   1.849 +                   dst_argb_c, kStrideB,                                       \
   1.850 +                   kWidth, NEG kHeight);                                       \
   1.851 +  MaskCpuFlags(-1);                                                            \
   1.852 +  for (int i = 0; i < benchmark_iterations_; ++i) {                            \
   1.853 +    FMT_A##To##FMT_B(src_argb + OFF, kStrideA,                                 \
   1.854 +                     dst_argb_opt, kStrideB,                                   \
   1.855 +                     kWidth, NEG kHeight);                                     \
   1.856 +  }                                                                            \
   1.857 +  int max_diff = 0;                                                            \
   1.858 +  for (int i = 0; i < kStrideB * kHeightB; ++i) {                              \
   1.859 +    int abs_diff =                                                             \
   1.860 +        abs(static_cast<int>(dst_argb_c[i]) -                                  \
   1.861 +            static_cast<int>(dst_argb_opt[i]));                                \
   1.862 +    if (abs_diff > max_diff) {                                                 \
   1.863 +      max_diff = abs_diff;                                                     \
   1.864 +    }                                                                          \
   1.865 +  }                                                                            \
   1.866 +  EXPECT_LE(max_diff, DIFF);                                                   \
   1.867 +  free_aligned_buffer_64(src_argb);                                            \
   1.868 +  free_aligned_buffer_64(dst_argb_c);                                          \
   1.869 +  free_aligned_buffer_64(dst_argb_opt);                                        \
   1.870 +}
   1.871 +
   1.872 +#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                       \
   1.873 +                       FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)                 \
   1.874 +TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) {                                \
   1.875 +  srandom(time(NULL));                                                         \
   1.876 +  for (int times = 0; times < benchmark_iterations_; ++times) {                \
   1.877 +    const int kWidth = (random() & 63) + 1;                                    \
   1.878 +    const int kHeight = (random() & 31) + 1;                                   \
   1.879 +    const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A;       \
   1.880 +    const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B;       \
   1.881 +    const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;\
   1.882 +    const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;\
   1.883 +    align_buffer_page_end(src_argb, kStrideA * kHeightA);                      \
   1.884 +    align_buffer_page_end(dst_argb_c, kStrideB * kHeightB);                    \
   1.885 +    align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB);                  \
   1.886 +    for (int i = 0; i < kStrideA * kHeightA; ++i) {                            \
   1.887 +      src_argb[i] = (random() & 0xff);                                         \
   1.888 +    }                                                                          \
   1.889 +    memset(dst_argb_c, 123, kStrideB * kHeightB);                              \
   1.890 +    memset(dst_argb_opt, 123, kStrideB * kHeightB);                            \
   1.891 +    MaskCpuFlags(0);                                                           \
   1.892 +    FMT_A##To##FMT_B(src_argb, kStrideA,                                       \
   1.893 +                     dst_argb_c, kStrideB,                                     \
   1.894 +                     kWidth, kHeight);                                         \
   1.895 +    MaskCpuFlags(-1);                                                          \
   1.896 +    FMT_A##To##FMT_B(src_argb, kStrideA,                                       \
   1.897 +                     dst_argb_opt, kStrideB,                                   \
   1.898 +                     kWidth, kHeight);                                         \
   1.899 +    int max_diff = 0;                                                          \
   1.900 +    for (int i = 0; i < kStrideB * kHeightB; ++i) {                            \
   1.901 +      int abs_diff =                                                           \
   1.902 +          abs(static_cast<int>(dst_argb_c[i]) -                                \
   1.903 +              static_cast<int>(dst_argb_opt[i]));                              \
   1.904 +      if (abs_diff > max_diff) {                                               \
   1.905 +        max_diff = abs_diff;                                                   \
   1.906 +      }                                                                        \
   1.907 +    }                                                                          \
   1.908 +    EXPECT_LE(max_diff, DIFF);                                                 \
   1.909 +    free_aligned_buffer_page_end(src_argb);                                    \
   1.910 +    free_aligned_buffer_page_end(dst_argb_c);                                  \
   1.911 +    free_aligned_buffer_page_end(dst_argb_opt);                                \
   1.912 +  }                                                                            \
   1.913 +}
   1.914 +
   1.915 +#define TESTATOB(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                             \
   1.916 +                 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)                       \
   1.917 +    TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
   1.918 +              FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
   1.919 +              benchmark_width_ - 4, DIFF, _Any, +, 0)                          \
   1.920 +    TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
   1.921 +              FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
   1.922 +              benchmark_width_, DIFF, _Unaligned, +, 1)                        \
   1.923 +    TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
   1.924 +              FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
   1.925 +              benchmark_width_, DIFF, _Invert, -, 0)                           \
   1.926 +    TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                                \
   1.927 +              FMT_B, BPP_B, STRIDE_B, HEIGHT_B,                                \
   1.928 +              benchmark_width_, DIFF, _Opt, +, 0)                              \
   1.929 +    TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A,                           \
   1.930 +                   FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)
   1.931 +
   1.932 +TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1, 0)
   1.933 +TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0)
   1.934 +TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1, 0)
   1.935 +TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1, 0)
   1.936 +TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0)
   1.937 +TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0)
   1.938 +TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0)
   1.939 +TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0)
   1.940 +TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0)
   1.941 +TESTATOB(ARGB, 4, 4, 1, BayerBGGR, 1, 1, 1, 0)
   1.942 +TESTATOB(ARGB, 4, 4, 1, BayerRGGB, 1, 1, 1, 0)
   1.943 +TESTATOB(ARGB, 4, 4, 1, BayerGBRG, 1, 1, 1, 0)
   1.944 +TESTATOB(ARGB, 4, 4, 1, BayerGRBG, 1, 1, 1, 0)
   1.945 +TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4)
   1.946 +TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4)
   1.947 +TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2)
   1.948 +TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2)
   1.949 +TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0)
   1.950 +TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0)
   1.951 +TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0)
   1.952 +TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0)
   1.953 +TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0)
   1.954 +TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0)
   1.955 +TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0)
   1.956 +TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0)
   1.957 +TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4)
   1.958 +TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4)
   1.959 +TESTATOB(BayerBGGR, 1, 2, 2, ARGB, 4, 4, 1, 0)
   1.960 +TESTATOB(BayerRGGB, 1, 2, 2, ARGB, 4, 4, 1, 0)
   1.961 +TESTATOB(BayerGBRG, 1, 2, 2, ARGB, 4, 4, 1, 0)
   1.962 +TESTATOB(BayerGRBG, 1, 2, 2, ARGB, 4, 4, 1, 0)
   1.963 +TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0)
   1.964 +TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0)
   1.965 +TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1, 0)
   1.966 +TESTATOB(Y, 1, 1, 1, ARGB, 4, 4, 1, 0)
   1.967 +TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0)
   1.968 +
   1.969 +TEST_F(libyuvTest, Test565) {
   1.970 +  SIMD_ALIGNED(uint8 orig_pixels[256][4]);
   1.971 +  SIMD_ALIGNED(uint8 pixels565[256][2]);
   1.972 +
   1.973 +  for (int i = 0; i < 256; ++i) {
   1.974 +    for (int j = 0; j < 4; ++j) {
   1.975 +      orig_pixels[i][j] = i;
   1.976 +    }
   1.977 +  }
   1.978 +  ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1);
   1.979 +  uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381);
   1.980 +  EXPECT_EQ(610919429u, checksum);
   1.981 +}
   1.982 +
   1.983 +#ifdef HAVE_JPEG
   1.984 +TEST_F(libyuvTest, ValidateJpeg) {
   1.985 +  const int kOff = 10;
   1.986 +  const int kMinJpeg = 64;
   1.987 +  const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
   1.988 +    benchmark_width_ * benchmark_height_ : kMinJpeg;
   1.989 +  const int kSize = kImageSize + kOff;
   1.990 +  align_buffer_64(orig_pixels, kSize);
   1.991 +
   1.992 +  // No SOI or EOI. Expect fail.
   1.993 +  memset(orig_pixels, 0, kSize);
   1.994 +
   1.995 +  // EOI, SOI. Expect pass.
   1.996 +  orig_pixels[0] = 0xff;
   1.997 +  orig_pixels[1] = 0xd8;  // SOI.
   1.998 +  orig_pixels[kSize - kOff + 0] = 0xff;
   1.999 +  orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
  1.1000 +  for (int times = 0; times < benchmark_iterations_; ++times) {
  1.1001 +    EXPECT_TRUE(ValidateJpeg(orig_pixels, kSize));
  1.1002 +  }
  1.1003 +  free_aligned_buffer_page_end(orig_pixels);
  1.1004 +}
  1.1005 +
  1.1006 +TEST_F(libyuvTest, InvalidateJpeg) {
  1.1007 +  const int kOff = 10;
  1.1008 +  const int kMinJpeg = 64;
  1.1009 +  const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
  1.1010 +    benchmark_width_ * benchmark_height_ : kMinJpeg;
  1.1011 +  const int kSize = kImageSize + kOff;
  1.1012 +  align_buffer_64(orig_pixels, kSize);
  1.1013 +
  1.1014 +  // No SOI or EOI. Expect fail.
  1.1015 +  memset(orig_pixels, 0, kSize);
  1.1016 +  EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
  1.1017 +
  1.1018 +  // SOI but no EOI. Expect fail.
  1.1019 +  orig_pixels[0] = 0xff;
  1.1020 +  orig_pixels[1] = 0xd8;  // SOI.
  1.1021 +  for (int times = 0; times < benchmark_iterations_; ++times) {
  1.1022 +    EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
  1.1023 +  }
  1.1024 +  // EOI but no SOI. Expect fail.
  1.1025 +  orig_pixels[0] = 0;
  1.1026 +  orig_pixels[1] = 0;
  1.1027 +  orig_pixels[kSize - kOff + 0] = 0xff;
  1.1028 +  orig_pixels[kSize - kOff + 1] = 0xd9;  // EOI.
  1.1029 +  EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
  1.1030 +
  1.1031 +  free_aligned_buffer_page_end(orig_pixels);
  1.1032 +}
  1.1033 +
  1.1034 +#endif
  1.1035 +
  1.1036 +}  // namespace libyuv

mercurial