1/* 2 * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <stdlib.h> 12#include <time.h> 13 14#include "libyuv/basic_types.h" 15#include "libyuv/compare.h" 16#include "libyuv/convert.h" 17#include "libyuv/convert_argb.h" 18#include "libyuv/convert_from.h" 19#include "libyuv/convert_from_argb.h" 20#include "libyuv/cpu_id.h" 21#ifdef HAVE_JPEG 22#include "libyuv/mjpeg_decoder.h" 23#endif 24#include "libyuv/planar_functions.h" 25#include "libyuv/rotate.h" 26#include "libyuv/video_common.h" 27#include "../unit_test/unit_test.h" 28 29namespace libyuv { 30 31#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) 32 33#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 34 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 35TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ 36 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 37 const int kHeight = benchmark_height_; \ 38 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 39 align_buffer_page_end(src_u, \ 40 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 41 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 42 align_buffer_page_end(src_v, \ 43 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 44 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 45 align_buffer_page_end(dst_y_c, kWidth * kHeight); \ 46 align_buffer_page_end(dst_u_c, \ 47 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 48 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 49 align_buffer_page_end(dst_v_c, \ 50 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 51 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 52 align_buffer_page_end(dst_y_opt, kWidth * kHeight); \ 53 align_buffer_page_end(dst_u_opt, \ 54 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 55 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 56 align_buffer_page_end(dst_v_opt, \ 57 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 58 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 59 for (int i = 0; i < kHeight; ++i) \ 60 for (int j = 0; j < kWidth; ++j) \ 61 src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \ 62 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ 63 for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ 64 src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 65 (fastrand() & 0xff); \ 66 src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 67 (fastrand() & 0xff); \ 68 } \ 69 } \ 70 memset(dst_y_c, 1, kWidth * kHeight); \ 71 memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 72 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 73 memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 74 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 75 memset(dst_y_opt, 101, kWidth * kHeight); \ 76 memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 77 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 78 memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 79 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 80 MaskCpuFlags(disable_cpu_flags_); \ 81 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 82 src_u + OFF, \ 83 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 84 src_v + OFF, \ 85 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 86 dst_y_c, kWidth, \ 87 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 88 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 89 kWidth, NEG kHeight); \ 90 MaskCpuFlags(benchmark_cpu_info_); \ 91 for (int i = 0; i < benchmark_iterations_; ++i) { \ 92 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 93 src_u + OFF, \ 94 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 95 src_v + OFF, \ 96 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 97 dst_y_opt, kWidth, \ 98 dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 99 dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 100 kWidth, NEG kHeight); \ 101 } \ 102 int max_diff = 0; \ 103 for (int i = 0; i < kHeight; ++i) { \ 104 for (int j = 0; j < kWidth; ++j) { \ 105 int abs_diff = \ 106 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 107 static_cast<int>(dst_y_opt[i * kWidth + j])); \ 108 if (abs_diff > max_diff) { \ 109 max_diff = abs_diff; \ 110 } \ 111 } \ 112 } \ 113 EXPECT_EQ(0, max_diff); \ 114 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 115 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 116 int abs_diff = \ 117 abs(static_cast<int>(dst_u_c[i * \ 118 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 119 static_cast<int>(dst_u_opt[i * \ 120 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 121 if (abs_diff > max_diff) { \ 122 max_diff = abs_diff; \ 123 } \ 124 } \ 125 } \ 126 EXPECT_LE(max_diff, 3); \ 127 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 128 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 129 int abs_diff = \ 130 abs(static_cast<int>(dst_v_c[i * \ 131 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 132 static_cast<int>(dst_v_opt[i * \ 133 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 134 if (abs_diff > max_diff) { \ 135 max_diff = abs_diff; \ 136 } \ 137 } \ 138 } \ 139 EXPECT_LE(max_diff, 3); \ 140 free_aligned_buffer_page_end(dst_y_c); \ 141 free_aligned_buffer_page_end(dst_u_c); \ 142 free_aligned_buffer_page_end(dst_v_c); \ 143 free_aligned_buffer_page_end(dst_y_opt); \ 144 free_aligned_buffer_page_end(dst_u_opt); \ 145 free_aligned_buffer_page_end(dst_v_opt); \ 146 free_aligned_buffer_page_end(src_y); \ 147 free_aligned_buffer_page_end(src_u); \ 148 free_aligned_buffer_page_end(src_v); \ 149} 150 151#define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 152 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 153 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 154 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 155 benchmark_width_ - 4, _Any, +, 0) \ 156 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 157 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 158 benchmark_width_, _Unaligned, +, 1) \ 159 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 160 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 161 benchmark_width_, _Invert, -, 0) \ 162 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 163 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 164 benchmark_width_, _Opt, +, 0) 165 166TESTPLANARTOP(I420, 2, 2, I420, 2, 2) 167TESTPLANARTOP(I422, 2, 1, I420, 2, 2) 168TESTPLANARTOP(I444, 1, 1, I420, 2, 2) 169TESTPLANARTOP(I411, 4, 1, I420, 2, 2) 170TESTPLANARTOP(I420, 2, 2, I422, 2, 1) 171TESTPLANARTOP(I420, 2, 2, I444, 1, 1) 172TESTPLANARTOP(I420, 2, 2, I411, 4, 1) 173TESTPLANARTOP(I420, 2, 2, I420Mirror, 2, 2) 174TESTPLANARTOP(I422, 2, 1, I422, 2, 1) 175TESTPLANARTOP(I444, 1, 1, I444, 1, 1) 176 177#define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 178 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 179TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ 180 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 181 const int kHeight = benchmark_height_; \ 182 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 183 align_buffer_page_end(src_u, \ 184 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 185 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 186 align_buffer_page_end(src_v, \ 187 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 188 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 189 align_buffer_page_end(dst_y_c, kWidth * kHeight); \ 190 align_buffer_page_end(dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 191 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 192 align_buffer_page_end(dst_y_opt, kWidth * kHeight); \ 193 align_buffer_page_end(dst_uv_opt, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 194 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 195 for (int i = 0; i < kHeight; ++i) \ 196 for (int j = 0; j < kWidth; ++j) \ 197 src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \ 198 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ 199 for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ 200 src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 201 (fastrand() & 0xff); \ 202 src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 203 (fastrand() & 0xff); \ 204 } \ 205 } \ 206 memset(dst_y_c, 1, kWidth * kHeight); \ 207 memset(dst_uv_c, 2, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 208 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 209 memset(dst_y_opt, 101, kWidth * kHeight); \ 210 memset(dst_uv_opt, 102, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \ 211 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 212 MaskCpuFlags(disable_cpu_flags_); \ 213 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 214 src_u + OFF, \ 215 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 216 src_v + OFF, \ 217 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 218 dst_y_c, kWidth, \ 219 dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X), \ 220 kWidth, NEG kHeight); \ 221 MaskCpuFlags(benchmark_cpu_info_); \ 222 for (int i = 0; i < benchmark_iterations_; ++i) { \ 223 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 224 src_u + OFF, \ 225 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 226 src_v + OFF, \ 227 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 228 dst_y_opt, kWidth, \ 229 dst_uv_opt, \ 230 SUBSAMPLE(kWidth * 2, SUBSAMP_X), \ 231 kWidth, NEG kHeight); \ 232 } \ 233 int max_diff = 0; \ 234 for (int i = 0; i < kHeight; ++i) { \ 235 for (int j = 0; j < kWidth; ++j) { \ 236 int abs_diff = \ 237 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 238 static_cast<int>(dst_y_opt[i * kWidth + j])); \ 239 if (abs_diff > max_diff) { \ 240 max_diff = abs_diff; \ 241 } \ 242 } \ 243 } \ 244 EXPECT_LE(max_diff, 1); \ 245 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 246 for (int j = 0; j < SUBSAMPLE(kWidth * 2, SUBSAMP_X); ++j) { \ 247 int abs_diff = \ 248 abs(static_cast<int>(dst_uv_c[i * \ 249 SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]) - \ 250 static_cast<int>(dst_uv_opt[i * \ 251 SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j])); \ 252 if (abs_diff > max_diff) { \ 253 max_diff = abs_diff; \ 254 } \ 255 } \ 256 } \ 257 EXPECT_LE(max_diff, 1); \ 258 free_aligned_buffer_page_end(dst_y_c); \ 259 free_aligned_buffer_page_end(dst_uv_c); \ 260 free_aligned_buffer_page_end(dst_y_opt); \ 261 free_aligned_buffer_page_end(dst_uv_opt); \ 262 free_aligned_buffer_page_end(src_y); \ 263 free_aligned_buffer_page_end(src_u); \ 264 free_aligned_buffer_page_end(src_v); \ 265} 266 267#define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 268 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 269 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 270 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 271 benchmark_width_ - 4, _Any, +, 0) \ 272 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 273 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 274 benchmark_width_, _Unaligned, +, 1) \ 275 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 276 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 277 benchmark_width_, _Invert, -, 0) \ 278 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 279 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 280 benchmark_width_, _Opt, +, 0) 281 282TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2) 283TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2) 284 285#define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 286 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 287TEST_F(LibYUVConvertTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \ 288 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 289 const int kHeight = benchmark_height_; \ 290 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 291 align_buffer_page_end(src_uv, 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \ 292 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \ 293 align_buffer_page_end(dst_y_c, kWidth * kHeight); \ 294 align_buffer_page_end(dst_u_c, \ 295 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 296 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 297 align_buffer_page_end(dst_v_c, \ 298 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 299 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 300 align_buffer_page_end(dst_y_opt, kWidth * kHeight); \ 301 align_buffer_page_end(dst_u_opt, \ 302 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 303 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 304 align_buffer_page_end(dst_v_opt, \ 305 SUBSAMPLE(kWidth, SUBSAMP_X) * \ 306 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 307 for (int i = 0; i < kHeight; ++i) \ 308 for (int j = 0; j < kWidth; ++j) \ 309 src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \ 310 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \ 311 for (int j = 0; j < 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \ 312 src_uv[(i * 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \ 313 (fastrand() & 0xff); \ 314 } \ 315 } \ 316 memset(dst_y_c, 1, kWidth * kHeight); \ 317 memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 318 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 319 memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 320 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 321 memset(dst_y_opt, 101, kWidth * kHeight); \ 322 memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 323 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 324 memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) * \ 325 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 326 MaskCpuFlags(disable_cpu_flags_); \ 327 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 328 src_uv + OFF, \ 329 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 330 dst_y_c, kWidth, \ 331 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 332 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \ 333 kWidth, NEG kHeight); \ 334 MaskCpuFlags(benchmark_cpu_info_); \ 335 for (int i = 0; i < benchmark_iterations_; ++i) { \ 336 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \ 337 src_uv + OFF, \ 338 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \ 339 dst_y_opt, kWidth, \ 340 dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 341 dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \ 342 kWidth, NEG kHeight); \ 343 } \ 344 int max_diff = 0; \ 345 for (int i = 0; i < kHeight; ++i) { \ 346 for (int j = 0; j < kWidth; ++j) { \ 347 int abs_diff = \ 348 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 349 static_cast<int>(dst_y_opt[i * kWidth + j])); \ 350 if (abs_diff > max_diff) { \ 351 max_diff = abs_diff; \ 352 } \ 353 } \ 354 } \ 355 EXPECT_LE(max_diff, 1); \ 356 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 357 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 358 int abs_diff = \ 359 abs(static_cast<int>(dst_u_c[i * \ 360 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 361 static_cast<int>(dst_u_opt[i * \ 362 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 363 if (abs_diff > max_diff) { \ 364 max_diff = abs_diff; \ 365 } \ 366 } \ 367 } \ 368 EXPECT_LE(max_diff, 1); \ 369 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 370 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \ 371 int abs_diff = \ 372 abs(static_cast<int>(dst_v_c[i * \ 373 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \ 374 static_cast<int>(dst_v_opt[i * \ 375 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \ 376 if (abs_diff > max_diff) { \ 377 max_diff = abs_diff; \ 378 } \ 379 } \ 380 } \ 381 EXPECT_LE(max_diff, 1); \ 382 free_aligned_buffer_page_end(dst_y_c); \ 383 free_aligned_buffer_page_end(dst_u_c); \ 384 free_aligned_buffer_page_end(dst_v_c); \ 385 free_aligned_buffer_page_end(dst_y_opt); \ 386 free_aligned_buffer_page_end(dst_u_opt); \ 387 free_aligned_buffer_page_end(dst_v_opt); \ 388 free_aligned_buffer_page_end(src_y); \ 389 free_aligned_buffer_page_end(src_uv); \ 390} 391 392#define TESTBIPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 393 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 394 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 395 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 396 benchmark_width_ - 4, _Any, +, 0) \ 397 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 398 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 399 benchmark_width_, _Unaligned, +, 1) \ 400 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 401 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 402 benchmark_width_, _Invert, -, 0) \ 403 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \ 404 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 405 benchmark_width_, _Opt, +, 0) 406 407TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2) 408TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2) 409 410#define ALIGNINT(V, ALIGN) (((V) + (ALIGN) - 1) / (ALIGN) * (ALIGN)) 411 412#define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 413 YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C) \ 414TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \ 415 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 416 const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ 417 const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ 418 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 419 const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ 420 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 421 align_buffer_page_end(src_u, kSizeUV + OFF); \ 422 align_buffer_page_end(src_v, kSizeUV + OFF); \ 423 align_buffer_page_end(dst_argb_c, kStrideB * kHeight + OFF); \ 424 align_buffer_page_end(dst_argb_opt, kStrideB * kHeight + OFF); \ 425 for (int i = 0; i < kWidth * kHeight; ++i) { \ 426 src_y[i + OFF] = (fastrand() & 0xff); \ 427 } \ 428 for (int i = 0; i < kSizeUV; ++i) { \ 429 src_u[i + OFF] = (fastrand() & 0xff); \ 430 src_v[i + OFF] = (fastrand() & 0xff); \ 431 } \ 432 memset(dst_argb_c + OFF, 1, kStrideB * kHeight); \ 433 memset(dst_argb_opt + OFF, 101, kStrideB * kHeight); \ 434 MaskCpuFlags(disable_cpu_flags_); \ 435 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 436 src_u + OFF, kStrideUV, \ 437 src_v + OFF, kStrideUV, \ 438 dst_argb_c + OFF, kStrideB, \ 439 kWidth, NEG kHeight); \ 440 MaskCpuFlags(benchmark_cpu_info_); \ 441 for (int i = 0; i < benchmark_iterations_; ++i) { \ 442 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 443 src_u + OFF, kStrideUV, \ 444 src_v + OFF, kStrideUV, \ 445 dst_argb_opt + OFF, kStrideB, \ 446 kWidth, NEG kHeight); \ 447 } \ 448 int max_diff = 0; \ 449 /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \ 450 align_buffer_page_end(dst_argb32_c, kWidth * BPP_C * kHeight); \ 451 align_buffer_page_end(dst_argb32_opt, kWidth * BPP_C * kHeight); \ 452 memset(dst_argb32_c, 2, kWidth * BPP_C * kHeight); \ 453 memset(dst_argb32_opt, 102, kWidth * BPP_C * kHeight); \ 454 FMT_B##To##FMT_C(dst_argb_c + OFF, kStrideB, \ 455 dst_argb32_c, kWidth * BPP_C , \ 456 kWidth, kHeight); \ 457 FMT_B##To##FMT_C(dst_argb_opt + OFF, kStrideB, \ 458 dst_argb32_opt, kWidth * BPP_C , \ 459 kWidth, kHeight); \ 460 for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) { \ 461 int abs_diff = \ 462 abs(static_cast<int>(dst_argb32_c[i]) - \ 463 static_cast<int>(dst_argb32_opt[i])); \ 464 if (abs_diff > max_diff) { \ 465 max_diff = abs_diff; \ 466 } \ 467 } \ 468 EXPECT_LE(max_diff, DIFF); \ 469 free_aligned_buffer_page_end(src_y); \ 470 free_aligned_buffer_page_end(src_u); \ 471 free_aligned_buffer_page_end(src_v); \ 472 free_aligned_buffer_page_end(dst_argb_c); \ 473 free_aligned_buffer_page_end(dst_argb_opt); \ 474 free_aligned_buffer_page_end(dst_argb32_c); \ 475 free_aligned_buffer_page_end(dst_argb32_opt); \ 476} 477 478#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 479 YALIGN, DIFF, FMT_C, BPP_C) \ 480 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 481 YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C) \ 482 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 483 YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, BPP_C) \ 484 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 485 YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C) \ 486 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 487 YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C) 488 489TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) 490TESTPLANARTOB(J420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) 491TESTPLANARTOB(J420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) 492TESTPLANARTOB(H420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4) 493TESTPLANARTOB(H420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) 494TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1, 2, ARGB, 4) 495TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4) 496TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1, 2, ARGB, 4) 497TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4) 498TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4) 499TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4) 500TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1, 9, ARGB, 4) 501TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1, 17, ARGB, 4) 502TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 503TESTPLANARTOB(J422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 504TESTPLANARTOB(J422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) 505TESTPLANARTOB(H422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 506TESTPLANARTOB(H422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) 507TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1, 2, ARGB, 4) 508TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4) 509TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1, 2, ARGB, 4) 510TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 511TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 512TESTPLANARTOB(J444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4) 513TESTPLANARTOB(I444, 1, 1, ABGR, 4, 4, 1, 2, ARGB, 4) 514TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1, 1, ARGB, 4) 515TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1, 1, ARGB, 4) 516TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4) 517TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4) 518TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4) 519TESTPLANARTOB(J420, 2, 2, J400, 1, 1, 1, 0, ARGB, 4) 520 521#define TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 522 YALIGN, W1280, DIFF, N, NEG, OFF, ATTEN) \ 523TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \ 524 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 525 const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ 526 const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ 527 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 528 const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ 529 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 530 align_buffer_page_end(src_u, kSizeUV + OFF); \ 531 align_buffer_page_end(src_v, kSizeUV + OFF); \ 532 align_buffer_page_end(src_a, kWidth * kHeight + OFF); \ 533 align_buffer_page_end(dst_argb_c, kStrideB * kHeight + OFF); \ 534 align_buffer_page_end(dst_argb_opt, kStrideB * kHeight + OFF); \ 535 for (int i = 0; i < kWidth * kHeight; ++i) { \ 536 src_y[i + OFF] = (fastrand() & 0xff); \ 537 src_a[i + OFF] = (fastrand() & 0xff); \ 538 } \ 539 for (int i = 0; i < kSizeUV; ++i) { \ 540 src_u[i + OFF] = (fastrand() & 0xff); \ 541 src_v[i + OFF] = (fastrand() & 0xff); \ 542 } \ 543 memset(dst_argb_c + OFF, 1, kStrideB * kHeight); \ 544 memset(dst_argb_opt + OFF, 101, kStrideB * kHeight); \ 545 MaskCpuFlags(disable_cpu_flags_); \ 546 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 547 src_u + OFF, kStrideUV, \ 548 src_v + OFF, kStrideUV, \ 549 src_a + OFF, kWidth, \ 550 dst_argb_c + OFF, kStrideB, \ 551 kWidth, NEG kHeight, ATTEN); \ 552 MaskCpuFlags(benchmark_cpu_info_); \ 553 for (int i = 0; i < benchmark_iterations_; ++i) { \ 554 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 555 src_u + OFF, kStrideUV, \ 556 src_v + OFF, kStrideUV, \ 557 src_a + OFF, kWidth, \ 558 dst_argb_opt + OFF, kStrideB, \ 559 kWidth, NEG kHeight, ATTEN); \ 560 } \ 561 int max_diff = 0; \ 562 for (int i = 0; i < kWidth * BPP_B * kHeight; ++i) { \ 563 int abs_diff = \ 564 abs(static_cast<int>(dst_argb_c[i + OFF]) - \ 565 static_cast<int>(dst_argb_opt[i + OFF])); \ 566 if (abs_diff > max_diff) { \ 567 max_diff = abs_diff; \ 568 } \ 569 } \ 570 EXPECT_LE(max_diff, DIFF); \ 571 free_aligned_buffer_page_end(src_y); \ 572 free_aligned_buffer_page_end(src_u); \ 573 free_aligned_buffer_page_end(src_v); \ 574 free_aligned_buffer_page_end(src_a); \ 575 free_aligned_buffer_page_end(dst_argb_c); \ 576 free_aligned_buffer_page_end(dst_argb_opt); \ 577} 578 579#define TESTQPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 580 YALIGN, DIFF) \ 581 TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 582 YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, 0) \ 583 TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 584 YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, 0) \ 585 TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 586 YALIGN, benchmark_width_, DIFF, _Invert, -, 0, 0) \ 587 TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 588 YALIGN, benchmark_width_, DIFF, _Opt, +, 0, 0) \ 589 TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 590 YALIGN, benchmark_width_, DIFF, _Premult, +, 0, 1) 591 592TESTQPLANARTOB(I420Alpha, 2, 2, ARGB, 4, 4, 1, 2) 593TESTQPLANARTOB(I420Alpha, 2, 2, ABGR, 4, 4, 1, 2) 594 595#define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 596 W1280, DIFF, N, NEG, OFF) \ 597TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##N) { \ 598 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 599 const int kHeight = benchmark_height_; \ 600 const int kStrideB = kWidth * BPP_B; \ 601 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 602 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 603 align_buffer_page_end(src_uv, \ 604 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y) * 2 + OFF); \ 605 align_buffer_page_end(dst_argb_c, kStrideB * kHeight); \ 606 align_buffer_page_end(dst_argb_opt, kStrideB * kHeight); \ 607 for (int i = 0; i < kHeight; ++i) \ 608 for (int j = 0; j < kWidth; ++j) \ 609 src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \ 610 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 611 for (int j = 0; j < kStrideUV * 2; ++j) { \ 612 src_uv[i * kStrideUV * 2 + j + OFF] = (fastrand() & 0xff); \ 613 } \ 614 } \ 615 memset(dst_argb_c, 1, kStrideB * kHeight); \ 616 memset(dst_argb_opt, 101, kStrideB * kHeight); \ 617 MaskCpuFlags(disable_cpu_flags_); \ 618 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 619 src_uv + OFF, kStrideUV * 2, \ 620 dst_argb_c, kWidth * BPP_B, \ 621 kWidth, NEG kHeight); \ 622 MaskCpuFlags(benchmark_cpu_info_); \ 623 for (int i = 0; i < benchmark_iterations_; ++i) { \ 624 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 625 src_uv + OFF, kStrideUV * 2, \ 626 dst_argb_opt, kWidth * BPP_B, \ 627 kWidth, NEG kHeight); \ 628 } \ 629 /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \ 630 align_buffer_page_end(dst_argb32_c, kWidth * 4 * kHeight); \ 631 align_buffer_page_end(dst_argb32_opt, kWidth * 4 * kHeight); \ 632 memset(dst_argb32_c, 2, kWidth * 4 * kHeight); \ 633 memset(dst_argb32_opt, 102, kWidth * 4 * kHeight); \ 634 FMT_B##ToARGB(dst_argb_c, kStrideB, \ 635 dst_argb32_c, kWidth * 4, \ 636 kWidth, kHeight); \ 637 FMT_B##ToARGB(dst_argb_opt, kStrideB, \ 638 dst_argb32_opt, kWidth * 4, \ 639 kWidth, kHeight); \ 640 int max_diff = 0; \ 641 for (int i = 0; i < kHeight; ++i) { \ 642 for (int j = 0; j < kWidth * 4; ++j) { \ 643 int abs_diff = \ 644 abs(static_cast<int>(dst_argb32_c[i * kWidth * 4 + j]) - \ 645 static_cast<int>(dst_argb32_opt[i * kWidth * 4 + j])); \ 646 if (abs_diff > max_diff) { \ 647 max_diff = abs_diff; \ 648 } \ 649 } \ 650 } \ 651 EXPECT_LE(max_diff, DIFF); \ 652 free_aligned_buffer_page_end(src_y); \ 653 free_aligned_buffer_page_end(src_uv); \ 654 free_aligned_buffer_page_end(dst_argb_c); \ 655 free_aligned_buffer_page_end(dst_argb_opt); \ 656 free_aligned_buffer_page_end(dst_argb32_c); \ 657 free_aligned_buffer_page_end(dst_argb32_opt); \ 658} 659 660#define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, DIFF) \ 661 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 662 benchmark_width_ - 4, DIFF, _Any, +, 0) \ 663 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 664 benchmark_width_, DIFF, _Unaligned, +, 1) \ 665 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 666 benchmark_width_, DIFF, _Invert, -, 0) \ 667 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \ 668 benchmark_width_, DIFF, _Opt, +, 0) 669 670TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2) 671TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2) 672TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9) 673 674#define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 675 W1280, DIFF, N, NEG, OFF) \ 676TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \ 677 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 678 const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ 679 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 680 const int kStride = \ 681 (kStrideUV * SUBSAMP_X * 8 * BPP_A + 7) / 8; \ 682 align_buffer_page_end(src_argb, kStride * kHeight + OFF); \ 683 align_buffer_page_end(dst_y_c, kWidth * kHeight); \ 684 align_buffer_page_end(dst_u_c, \ 685 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 686 align_buffer_page_end(dst_v_c, \ 687 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 688 align_buffer_page_end(dst_y_opt, kWidth * kHeight); \ 689 align_buffer_page_end(dst_u_opt, \ 690 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 691 align_buffer_page_end(dst_v_opt, \ 692 kStrideUV * \ 693 SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 694 memset(dst_y_c, 1, kWidth * kHeight); \ 695 memset(dst_u_c, 2, \ 696 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 697 memset(dst_v_c, 3, \ 698 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 699 memset(dst_y_opt, 101, kWidth * kHeight); \ 700 memset(dst_u_opt, 102, \ 701 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 702 memset(dst_v_opt, 103, \ 703 kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 704 for (int i = 0; i < kHeight; ++i) \ 705 for (int j = 0; j < kStride; ++j) \ 706 src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff); \ 707 MaskCpuFlags(disable_cpu_flags_); \ 708 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 709 dst_y_c, kWidth, \ 710 dst_u_c, kStrideUV, \ 711 dst_v_c, kStrideUV, \ 712 kWidth, NEG kHeight); \ 713 MaskCpuFlags(benchmark_cpu_info_); \ 714 for (int i = 0; i < benchmark_iterations_; ++i) { \ 715 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 716 dst_y_opt, kWidth, \ 717 dst_u_opt, kStrideUV, \ 718 dst_v_opt, kStrideUV, \ 719 kWidth, NEG kHeight); \ 720 } \ 721 for (int i = 0; i < kHeight; ++i) { \ 722 for (int j = 0; j < kWidth; ++j) { \ 723 EXPECT_NEAR(static_cast<int>(dst_y_c[i * kWidth + j]), \ 724 static_cast<int>(dst_y_opt[i * kWidth + j]), DIFF); \ 725 } \ 726 } \ 727 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 728 for (int j = 0; j < kStrideUV; ++j) { \ 729 EXPECT_NEAR(static_cast<int>(dst_u_c[i * kStrideUV + j]), \ 730 static_cast<int>(dst_u_opt[i * kStrideUV + j]), DIFF); \ 731 } \ 732 } \ 733 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 734 for (int j = 0; j < kStrideUV; ++j) { \ 735 EXPECT_NEAR(static_cast<int>(dst_v_c[i * \ 736 kStrideUV + j]), \ 737 static_cast<int>(dst_v_opt[i * \ 738 kStrideUV + j]), DIFF); \ 739 } \ 740 } \ 741 free_aligned_buffer_page_end(dst_y_c); \ 742 free_aligned_buffer_page_end(dst_u_c); \ 743 free_aligned_buffer_page_end(dst_v_c); \ 744 free_aligned_buffer_page_end(dst_y_opt); \ 745 free_aligned_buffer_page_end(dst_u_opt); \ 746 free_aligned_buffer_page_end(dst_v_opt); \ 747 free_aligned_buffer_page_end(src_argb); \ 748} 749 750#define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 751 DIFF) \ 752 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 753 benchmark_width_ - 4, DIFF, _Any, +, 0) \ 754 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 755 benchmark_width_, DIFF, _Unaligned, +, 1) \ 756 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 757 benchmark_width_, DIFF, _Invert, -, 0) \ 758 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 759 benchmark_width_, DIFF, _Opt, +, 0) 760 761TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 4) 762#if defined(__arm__) || defined (__aarch64__) 763// arm version subsamples by summing 4 pixels then multiplying by matrix with 764// 4x smaller coefficients which are rounded to nearest integer. 765TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 4) 766TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, 4) 767#else 768TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0) 769TESTATOPLANAR(ARGB, 4, 1, J422, 2, 1, 0) 770#endif 771TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2, 4) 772TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 4) 773TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 4) 774TESTATOPLANAR(RAW, 3, 1, I420, 2, 2, 4) 775TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2, 4) 776TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2, 5) 777// TODO(fbarchard): Make 1555 neon work same as C code, reduce to diff 9. 778TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 15) 779TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2, 17) 780TESTATOPLANAR(ARGB, 4, 1, I411, 4, 1, 4) 781TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1, 2) 782TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1, 2) 783TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2, 2) 784TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2, 2) 785TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1, 2) 786TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1, 2) 787TESTATOPLANAR(I400, 1, 1, I420, 2, 2, 2) 788TESTATOPLANAR(J400, 1, 1, J420, 2, 2, 2) 789 790#define TESTATOBIPLANARI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, \ 791 SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \ 792TEST_F(LibYUVConvertTest, FMT_A##To##FMT_PLANAR##N) { \ 793 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 794 const int kHeight = benchmark_height_; \ 795 const int kStride = SUBSAMPLE(kWidth, SUB_A) * BPP_A; \ 796 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 797 align_buffer_page_end(src_argb, kStride * kHeight + OFF); \ 798 align_buffer_page_end(dst_y_c, kWidth * kHeight); \ 799 align_buffer_page_end(dst_uv_c, \ 800 kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 801 align_buffer_page_end(dst_y_opt, kWidth * kHeight); \ 802 align_buffer_page_end(dst_uv_opt, \ 803 kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 804 for (int i = 0; i < kHeight; ++i) \ 805 for (int j = 0; j < kStride; ++j) \ 806 src_argb[(i * kStride) + j + OFF] = (fastrand() & 0xff); \ 807 memset(dst_y_c, 1, kWidth * kHeight); \ 808 memset(dst_uv_c, 2, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 809 memset(dst_y_opt, 101, kWidth * kHeight); \ 810 memset(dst_uv_opt, 102, kStrideUV * 2 * SUBSAMPLE(kHeight, SUBSAMP_Y)); \ 811 MaskCpuFlags(disable_cpu_flags_); \ 812 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 813 dst_y_c, kWidth, dst_uv_c, kStrideUV * 2, \ 814 kWidth, NEG kHeight); \ 815 MaskCpuFlags(benchmark_cpu_info_); \ 816 for (int i = 0; i < benchmark_iterations_; ++i) { \ 817 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \ 818 dst_y_opt, kWidth, \ 819 dst_uv_opt, kStrideUV * 2, kWidth, NEG kHeight); \ 820 } \ 821 int max_diff = 0; \ 822 for (int i = 0; i < kHeight; ++i) { \ 823 for (int j = 0; j < kWidth; ++j) { \ 824 int abs_diff = \ 825 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \ 826 static_cast<int>(dst_y_opt[i * kWidth + j])); \ 827 if (abs_diff > max_diff) { \ 828 max_diff = abs_diff; \ 829 } \ 830 } \ 831 } \ 832 EXPECT_LE(max_diff, 4); \ 833 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \ 834 for (int j = 0; j < kStrideUV * 2; ++j) { \ 835 int abs_diff = \ 836 abs(static_cast<int>(dst_uv_c[i * kStrideUV * 2 + j]) - \ 837 static_cast<int>(dst_uv_opt[i * kStrideUV * 2 + j])); \ 838 if (abs_diff > max_diff) { \ 839 max_diff = abs_diff; \ 840 } \ 841 } \ 842 } \ 843 EXPECT_LE(max_diff, 4); \ 844 free_aligned_buffer_page_end(dst_y_c); \ 845 free_aligned_buffer_page_end(dst_uv_c); \ 846 free_aligned_buffer_page_end(dst_y_opt); \ 847 free_aligned_buffer_page_end(dst_uv_opt); \ 848 free_aligned_buffer_page_end(src_argb); \ 849} 850 851#define TESTATOBIPLANAR(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \ 852 TESTATOBIPLANARI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 853 benchmark_width_ - 4, _Any, +, 0) \ 854 TESTATOBIPLANARI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 855 benchmark_width_, _Unaligned, +, 1) \ 856 TESTATOBIPLANARI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 857 benchmark_width_, _Invert, -, 0) \ 858 TESTATOBIPLANARI(FMT_A, SUB_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \ 859 benchmark_width_, _Opt, +, 0) 860 861TESTATOBIPLANAR(ARGB, 1, 4, NV12, 2, 2) 862TESTATOBIPLANAR(ARGB, 1, 4, NV21, 2, 2) 863TESTATOBIPLANAR(YUY2, 2, 4, NV12, 2, 2) 864TESTATOBIPLANAR(UYVY, 2, 4, NV12, 2, 2) 865 866#define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 867 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 868 W1280, DIFF, N, NEG, OFF) \ 869TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##N) { \ 870 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 871 const int kHeight = benchmark_height_; \ 872 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 873 const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \ 874 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ 875 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \ 876 align_buffer_page_end(src_argb, kStrideA * kHeightA + OFF); \ 877 align_buffer_page_end(dst_argb_c, kStrideB * kHeightB); \ 878 align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB); \ 879 for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 880 src_argb[i + OFF] = (fastrand() & 0xff); \ 881 } \ 882 memset(dst_argb_c, 1, kStrideB * kHeightB); \ 883 memset(dst_argb_opt, 101, kStrideB * kHeightB); \ 884 MaskCpuFlags(disable_cpu_flags_); \ 885 FMT_A##To##FMT_B(src_argb + OFF, kStrideA, \ 886 dst_argb_c, kStrideB, \ 887 kWidth, NEG kHeight); \ 888 MaskCpuFlags(benchmark_cpu_info_); \ 889 for (int i = 0; i < benchmark_iterations_; ++i) { \ 890 FMT_A##To##FMT_B(src_argb + OFF, kStrideA, \ 891 dst_argb_opt, kStrideB, \ 892 kWidth, NEG kHeight); \ 893 } \ 894 int max_diff = 0; \ 895 for (int i = 0; i < kStrideB * kHeightB; ++i) { \ 896 int abs_diff = \ 897 abs(static_cast<int>(dst_argb_c[i]) - \ 898 static_cast<int>(dst_argb_opt[i])); \ 899 if (abs_diff > max_diff) { \ 900 max_diff = abs_diff; \ 901 } \ 902 } \ 903 EXPECT_LE(max_diff, DIFF); \ 904 free_aligned_buffer_page_end(src_argb); \ 905 free_aligned_buffer_page_end(dst_argb_c); \ 906 free_aligned_buffer_page_end(dst_argb_opt); \ 907} 908 909#define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 910 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \ 911TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##_Random) { \ 912 for (int times = 0; times < benchmark_iterations_; ++times) { \ 913 const int kWidth = (fastrand() & 63) + 1; \ 914 const int kHeight = (fastrand() & 31) + 1; \ 915 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 916 const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \ 917 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;\ 918 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;\ 919 align_buffer_page_end(src_argb, kStrideA * kHeightA); \ 920 align_buffer_page_end(dst_argb_c, kStrideB * kHeightB); \ 921 align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB); \ 922 for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 923 src_argb[i] = (fastrand() & 0xff); \ 924 } \ 925 memset(dst_argb_c, 123, kStrideB * kHeightB); \ 926 memset(dst_argb_opt, 123, kStrideB * kHeightB); \ 927 MaskCpuFlags(disable_cpu_flags_); \ 928 FMT_A##To##FMT_B(src_argb, kStrideA, \ 929 dst_argb_c, kStrideB, \ 930 kWidth, kHeight); \ 931 MaskCpuFlags(benchmark_cpu_info_); \ 932 FMT_A##To##FMT_B(src_argb, kStrideA, \ 933 dst_argb_opt, kStrideB, \ 934 kWidth, kHeight); \ 935 int max_diff = 0; \ 936 for (int i = 0; i < kStrideB * kHeightB; ++i) { \ 937 int abs_diff = \ 938 abs(static_cast<int>(dst_argb_c[i]) - \ 939 static_cast<int>(dst_argb_opt[i])); \ 940 if (abs_diff > max_diff) { \ 941 max_diff = abs_diff; \ 942 } \ 943 } \ 944 EXPECT_LE(max_diff, DIFF); \ 945 free_aligned_buffer_page_end(src_argb); \ 946 free_aligned_buffer_page_end(dst_argb_c); \ 947 free_aligned_buffer_page_end(dst_argb_opt); \ 948 } \ 949} 950 951#define TESTATOB(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 952 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \ 953 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 954 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 955 benchmark_width_ - 4, DIFF, _Any, +, 0) \ 956 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 957 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 958 benchmark_width_, DIFF, _Unaligned, +, 1) \ 959 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 960 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 961 benchmark_width_, DIFF, _Invert, -, 0) \ 962 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 963 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 964 benchmark_width_, DIFF, _Opt, +, 0) \ 965 TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 966 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) 967 968TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1, 0) 969TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0) 970TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1, 0) 971TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1, 0) 972TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0) 973TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0) 974TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0) 975TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0) 976TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0) 977TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4) 978TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4) 979TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2) 980TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2) 981TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0) 982TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0) 983TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0) 984TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0) 985TESTATOB(RAW, 3, 3, 1, RGB24, 3, 3, 1, 0) 986TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0) 987TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0) 988TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0) 989TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0) 990TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4) 991TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4) 992TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0) 993TESTATOB(J400, 1, 1, 1, ARGB, 4, 4, 1, 0) 994TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0) 995TESTATOB(J400, 1, 1, 1, J400, 1, 1, 1, 0) 996TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1, 0) 997TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0) 998 999#define TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1000 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1001 W1280, DIFF, N, NEG, OFF) \ 1002TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##Dither##N) { \ 1003 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1004 const int kHeight = benchmark_height_; \ 1005 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 1006 const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \ 1007 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ 1008 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \ 1009 align_buffer_page_end(src_argb, kStrideA * kHeightA + OFF); \ 1010 align_buffer_page_end(dst_argb_c, kStrideB * kHeightB); \ 1011 align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB); \ 1012 for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 1013 src_argb[i + OFF] = (fastrand() & 0xff); \ 1014 } \ 1015 memset(dst_argb_c, 1, kStrideB * kHeightB); \ 1016 memset(dst_argb_opt, 101, kStrideB * kHeightB); \ 1017 MaskCpuFlags(disable_cpu_flags_); \ 1018 FMT_A##To##FMT_B##Dither(src_argb + OFF, kStrideA, \ 1019 dst_argb_c, kStrideB, \ 1020 NULL, kWidth, NEG kHeight); \ 1021 MaskCpuFlags(benchmark_cpu_info_); \ 1022 for (int i = 0; i < benchmark_iterations_; ++i) { \ 1023 FMT_A##To##FMT_B##Dither(src_argb + OFF, kStrideA, \ 1024 dst_argb_opt, kStrideB, \ 1025 NULL, kWidth, NEG kHeight); \ 1026 } \ 1027 int max_diff = 0; \ 1028 for (int i = 0; i < kStrideB * kHeightB; ++i) { \ 1029 int abs_diff = \ 1030 abs(static_cast<int>(dst_argb_c[i]) - \ 1031 static_cast<int>(dst_argb_opt[i])); \ 1032 if (abs_diff > max_diff) { \ 1033 max_diff = abs_diff; \ 1034 } \ 1035 } \ 1036 EXPECT_LE(max_diff, DIFF); \ 1037 free_aligned_buffer_page_end(src_argb); \ 1038 free_aligned_buffer_page_end(dst_argb_c); \ 1039 free_aligned_buffer_page_end(dst_argb_opt); \ 1040} 1041 1042#define TESTATOBDRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1043 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \ 1044TEST_F(LibYUVConvertTest, FMT_A##To##FMT_B##Dither_Random) { \ 1045 for (int times = 0; times < benchmark_iterations_; ++times) { \ 1046 const int kWidth = (fastrand() & 63) + 1; \ 1047 const int kHeight = (fastrand() & 31) + 1; \ 1048 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 1049 const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \ 1050 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;\ 1051 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;\ 1052 align_buffer_page_end(src_argb, kStrideA * kHeightA); \ 1053 align_buffer_page_end(dst_argb_c, kStrideB * kHeightB); \ 1054 align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB); \ 1055 for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 1056 src_argb[i] = (fastrand() & 0xff); \ 1057 } \ 1058 memset(dst_argb_c, 123, kStrideB * kHeightB); \ 1059 memset(dst_argb_opt, 123, kStrideB * kHeightB); \ 1060 MaskCpuFlags(disable_cpu_flags_); \ 1061 FMT_A##To##FMT_B##Dither(src_argb, kStrideA, \ 1062 dst_argb_c, kStrideB, \ 1063 NULL, kWidth, kHeight); \ 1064 MaskCpuFlags(benchmark_cpu_info_); \ 1065 FMT_A##To##FMT_B##Dither(src_argb, kStrideA, \ 1066 dst_argb_opt, kStrideB, \ 1067 NULL, kWidth, kHeight); \ 1068 int max_diff = 0; \ 1069 for (int i = 0; i < kStrideB * kHeightB; ++i) { \ 1070 int abs_diff = \ 1071 abs(static_cast<int>(dst_argb_c[i]) - \ 1072 static_cast<int>(dst_argb_opt[i])); \ 1073 if (abs_diff > max_diff) { \ 1074 max_diff = abs_diff; \ 1075 } \ 1076 } \ 1077 EXPECT_LE(max_diff, DIFF); \ 1078 free_aligned_buffer_page_end(src_argb); \ 1079 free_aligned_buffer_page_end(dst_argb_c); \ 1080 free_aligned_buffer_page_end(dst_argb_opt); \ 1081 } \ 1082} 1083 1084#define TESTATOBD(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1085 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \ 1086 TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1087 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1088 benchmark_width_ - 4, DIFF, _Any, +, 0) \ 1089 TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1090 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1091 benchmark_width_, DIFF, _Unaligned, +, 1) \ 1092 TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1093 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1094 benchmark_width_, DIFF, _Invert, -, 0) \ 1095 TESTATOBDI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1096 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \ 1097 benchmark_width_, DIFF, _Opt, +, 0) \ 1098 TESTATOBDRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \ 1099 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) 1100 1101TESTATOBD(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0) 1102 1103#define TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A, \ 1104 W1280, N, NEG, OFF) \ 1105TEST_F(LibYUVConvertTest, FMT_ATOB##_Symetric##N) { \ 1106 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1107 const int kHeight = benchmark_height_; \ 1108 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \ 1109 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ 1110 align_buffer_page_end(src_argb, kStrideA * kHeightA + OFF); \ 1111 align_buffer_page_end(dst_argb_c, kStrideA * kHeightA); \ 1112 align_buffer_page_end(dst_argb_opt, kStrideA * kHeightA); \ 1113 for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 1114 src_argb[i + OFF] = (fastrand() & 0xff); \ 1115 } \ 1116 memset(dst_argb_c, 1, kStrideA * kHeightA); \ 1117 memset(dst_argb_opt, 101, kStrideA * kHeightA); \ 1118 MaskCpuFlags(disable_cpu_flags_); \ 1119 FMT_ATOB(src_argb + OFF, kStrideA, \ 1120 dst_argb_c, kStrideA, \ 1121 kWidth, NEG kHeight); \ 1122 MaskCpuFlags(benchmark_cpu_info_); \ 1123 for (int i = 0; i < benchmark_iterations_; ++i) { \ 1124 FMT_ATOB(src_argb + OFF, kStrideA, \ 1125 dst_argb_opt, kStrideA, \ 1126 kWidth, NEG kHeight); \ 1127 } \ 1128 MaskCpuFlags(disable_cpu_flags_); \ 1129 FMT_ATOB(dst_argb_c, kStrideA, \ 1130 dst_argb_c, kStrideA, \ 1131 kWidth, NEG kHeight); \ 1132 MaskCpuFlags(benchmark_cpu_info_); \ 1133 FMT_ATOB(dst_argb_opt, kStrideA, \ 1134 dst_argb_opt, kStrideA, \ 1135 kWidth, NEG kHeight); \ 1136 for (int i = 0; i < kStrideA * kHeightA; ++i) { \ 1137 EXPECT_EQ(src_argb[i + OFF], dst_argb_opt[i]); \ 1138 EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \ 1139 } \ 1140 free_aligned_buffer_page_end(src_argb); \ 1141 free_aligned_buffer_page_end(dst_argb_c); \ 1142 free_aligned_buffer_page_end(dst_argb_opt); \ 1143} 1144 1145#define TESTSYM(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A) \ 1146 TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A, \ 1147 benchmark_width_ - 4, _Any, +, 0) \ 1148 TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A, \ 1149 benchmark_width_, _Unaligned, +, 1) \ 1150 TESTSYMI(FMT_ATOB, BPP_A, STRIDE_A, HEIGHT_A, \ 1151 benchmark_width_, _Opt, +, 0) 1152 1153TESTSYM(ARGBToARGB, 4, 4, 1) 1154TESTSYM(ARGBToBGRA, 4, 4, 1) 1155TESTSYM(ARGBToABGR, 4, 4, 1) 1156TESTSYM(BGRAToARGB, 4, 4, 1) 1157TESTSYM(ABGRToARGB, 4, 4, 1) 1158 1159TEST_F(LibYUVConvertTest, Test565) { 1160 SIMD_ALIGNED(uint8 orig_pixels[256][4]); 1161 SIMD_ALIGNED(uint8 pixels565[256][2]); 1162 1163 for (int i = 0; i < 256; ++i) { 1164 for (int j = 0; j < 4; ++j) { 1165 orig_pixels[i][j] = i; 1166 } 1167 } 1168 ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1); 1169 uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381); 1170 EXPECT_EQ(610919429u, checksum); 1171} 1172 1173#ifdef HAVE_JPEG 1174TEST_F(LibYUVConvertTest, ValidateJpeg) { 1175 const int kOff = 10; 1176 const int kMinJpeg = 64; 1177 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1178 benchmark_width_ * benchmark_height_ : kMinJpeg; 1179 const int kSize = kImageSize + kOff; 1180 align_buffer_page_end(orig_pixels, kSize); 1181 1182 // No SOI or EOI. Expect fail. 1183 memset(orig_pixels, 0, kSize); 1184 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1185 1186 // Test special value that matches marker start. 1187 memset(orig_pixels, 0xff, kSize); 1188 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1189 1190 // EOI, SOI. Expect pass. 1191 orig_pixels[0] = 0xff; 1192 orig_pixels[1] = 0xd8; // SOI. 1193 orig_pixels[kSize - kOff + 0] = 0xff; 1194 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1195 for (int times = 0; times < benchmark_iterations_; ++times) { 1196 EXPECT_TRUE(ValidateJpeg(orig_pixels, kSize)); 1197 } 1198 free_aligned_buffer_page_end(orig_pixels); 1199} 1200 1201TEST_F(LibYUVConvertTest, ValidateJpegLarge) { 1202 const int kOff = 10; 1203 const int kMinJpeg = 64; 1204 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1205 benchmark_width_ * benchmark_height_ : kMinJpeg; 1206 const int kSize = kImageSize + kOff; 1207 const int kMultiple = 10; 1208 const int kBufSize = kImageSize * kMultiple + kOff; 1209 align_buffer_page_end(orig_pixels, kBufSize); 1210 1211 // No SOI or EOI. Expect fail. 1212 memset(orig_pixels, 0, kBufSize); 1213 EXPECT_FALSE(ValidateJpeg(orig_pixels, kBufSize)); 1214 1215 // EOI, SOI. Expect pass. 1216 orig_pixels[0] = 0xff; 1217 orig_pixels[1] = 0xd8; // SOI. 1218 orig_pixels[kSize - kOff + 0] = 0xff; 1219 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1220 for (int times = 0; times < benchmark_iterations_; ++times) { 1221 EXPECT_TRUE(ValidateJpeg(orig_pixels, kBufSize)); 1222 } 1223 free_aligned_buffer_page_end(orig_pixels); 1224} 1225 1226TEST_F(LibYUVConvertTest, InvalidateJpeg) { 1227 const int kOff = 10; 1228 const int kMinJpeg = 64; 1229 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1230 benchmark_width_ * benchmark_height_ : kMinJpeg; 1231 const int kSize = kImageSize + kOff; 1232 align_buffer_page_end(orig_pixels, kSize); 1233 1234 // NULL pointer. Expect fail. 1235 EXPECT_FALSE(ValidateJpeg(NULL, kSize)); 1236 1237 // Negative size. Expect fail. 1238 EXPECT_FALSE(ValidateJpeg(orig_pixels, -1)); 1239 1240 // Too large size. Expect fail. 1241 EXPECT_FALSE(ValidateJpeg(orig_pixels, 0xfb000000ull)); 1242 1243 // No SOI or EOI. Expect fail. 1244 memset(orig_pixels, 0, kSize); 1245 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1246 1247 // SOI but no EOI. Expect fail. 1248 orig_pixels[0] = 0xff; 1249 orig_pixels[1] = 0xd8; // SOI. 1250 for (int times = 0; times < benchmark_iterations_; ++times) { 1251 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1252 } 1253 1254 // EOI but no SOI. Expect fail. 1255 orig_pixels[0] = 0; 1256 orig_pixels[1] = 0; 1257 orig_pixels[kSize - kOff + 0] = 0xff; 1258 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1259 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize)); 1260 1261 free_aligned_buffer_page_end(orig_pixels); 1262} 1263 1264TEST_F(LibYUVConvertTest, FuzzJpeg) { 1265 // SOI but no EOI. Expect fail. 1266 for (int times = 0; times < benchmark_iterations_; ++times) { 1267 const int kSize = fastrand() % 5000 + 2; 1268 align_buffer_page_end(orig_pixels, kSize); 1269 MemRandomize(orig_pixels, kSize); 1270 1271 // Add SOI so frame will be scanned. 1272 orig_pixels[0] = 0xff; 1273 orig_pixels[1] = 0xd8; // SOI. 1274 orig_pixels[kSize - 1] = 0xff; 1275 ValidateJpeg(orig_pixels, kSize); // Failure normally expected. 1276 free_aligned_buffer_page_end(orig_pixels); 1277 } 1278} 1279 1280TEST_F(LibYUVConvertTest, MJPGToI420) { 1281 const int kOff = 10; 1282 const int kMinJpeg = 64; 1283 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1284 benchmark_width_ * benchmark_height_ : kMinJpeg; 1285 const int kSize = kImageSize + kOff; 1286 align_buffer_page_end(orig_pixels, kSize); 1287 align_buffer_page_end(dst_y_opt, benchmark_width_ * benchmark_height_); 1288 align_buffer_page_end(dst_u_opt, 1289 SUBSAMPLE(benchmark_width_, 2) * 1290 SUBSAMPLE(benchmark_height_, 2)); 1291 align_buffer_page_end(dst_v_opt, 1292 SUBSAMPLE(benchmark_width_, 2) * 1293 SUBSAMPLE(benchmark_height_, 2)); 1294 1295 // EOI, SOI to make MJPG appear valid. 1296 memset(orig_pixels, 0, kSize); 1297 orig_pixels[0] = 0xff; 1298 orig_pixels[1] = 0xd8; // SOI. 1299 orig_pixels[kSize - kOff + 0] = 0xff; 1300 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1301 1302 for (int times = 0; times < benchmark_iterations_; ++times) { 1303 int ret = MJPGToI420(orig_pixels, kSize, 1304 dst_y_opt, benchmark_width_, 1305 dst_u_opt, SUBSAMPLE(benchmark_width_, 2), 1306 dst_v_opt, SUBSAMPLE(benchmark_width_, 2), 1307 benchmark_width_, benchmark_height_, 1308 benchmark_width_, benchmark_height_); 1309 // Expect failure because image is not really valid. 1310 EXPECT_EQ(1, ret); 1311 } 1312 1313 free_aligned_buffer_page_end(dst_y_opt); 1314 free_aligned_buffer_page_end(dst_u_opt); 1315 free_aligned_buffer_page_end(dst_v_opt); 1316 free_aligned_buffer_page_end(orig_pixels); 1317} 1318 1319TEST_F(LibYUVConvertTest, MJPGToARGB) { 1320 const int kOff = 10; 1321 const int kMinJpeg = 64; 1322 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ? 1323 benchmark_width_ * benchmark_height_ : kMinJpeg; 1324 const int kSize = kImageSize + kOff; 1325 align_buffer_page_end(orig_pixels, kSize); 1326 align_buffer_page_end(dst_argb_opt, benchmark_width_ * benchmark_height_ * 4); 1327 1328 // EOI, SOI to make MJPG appear valid. 1329 memset(orig_pixels, 0, kSize); 1330 orig_pixels[0] = 0xff; 1331 orig_pixels[1] = 0xd8; // SOI. 1332 orig_pixels[kSize - kOff + 0] = 0xff; 1333 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI. 1334 1335 for (int times = 0; times < benchmark_iterations_; ++times) { 1336 int ret = MJPGToARGB(orig_pixels, kSize, 1337 dst_argb_opt, benchmark_width_ * 4, 1338 benchmark_width_, benchmark_height_, 1339 benchmark_width_, benchmark_height_); 1340 // Expect failure because image is not really valid. 1341 EXPECT_EQ(1, ret); 1342 } 1343 1344 free_aligned_buffer_page_end(dst_argb_opt); 1345 free_aligned_buffer_page_end(orig_pixels); 1346} 1347 1348#endif // HAVE_JPEG 1349 1350TEST_F(LibYUVConvertTest, NV12Crop) { 1351 const int SUBSAMP_X = 2; 1352 const int SUBSAMP_Y = 2; 1353 const int kWidth = benchmark_width_; 1354 const int kHeight = benchmark_height_; 1355 const int crop_y = 1356 ((benchmark_height_ - (benchmark_height_ * 360 / 480)) / 2 + 1) & ~1; 1357 const int kDestWidth = benchmark_width_; 1358 const int kDestHeight = benchmark_height_ - crop_y * 2; 1359 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); 1360 const int sample_size = kWidth * kHeight + 1361 kStrideUV * 1362 SUBSAMPLE(kHeight, SUBSAMP_Y) * 2; 1363 align_buffer_page_end(src_y, sample_size); 1364 uint8* src_uv = src_y + kWidth * kHeight; 1365 1366 align_buffer_page_end(dst_y, kDestWidth * kDestHeight); 1367 align_buffer_page_end(dst_u, 1368 SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1369 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1370 align_buffer_page_end(dst_v, 1371 SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1372 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1373 1374 align_buffer_page_end(dst_y_2, kDestWidth * kDestHeight); 1375 align_buffer_page_end(dst_u_2, 1376 SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1377 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1378 align_buffer_page_end(dst_v_2, 1379 SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1380 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1381 1382 for (int i = 0; i < kHeight * kWidth; ++i) { 1383 src_y[i] = (fastrand() & 0xff); 1384 } 1385 for (int i = 0; i < (SUBSAMPLE(kHeight, SUBSAMP_Y) * 1386 kStrideUV) * 2; ++i) { 1387 src_uv[i] = (fastrand() & 0xff); 1388 } 1389 memset(dst_y, 1, kDestWidth * kDestHeight); 1390 memset(dst_u, 2, SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1391 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1392 memset(dst_v, 3, SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1393 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1394 memset(dst_y_2, 1, kDestWidth * kDestHeight); 1395 memset(dst_u_2, 2, SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1396 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1397 memset(dst_v_2, 3, SUBSAMPLE(kDestWidth, SUBSAMP_X) * 1398 SUBSAMPLE(kDestHeight, SUBSAMP_Y)); 1399 1400 ConvertToI420(src_y, sample_size, 1401 dst_y_2, kDestWidth, 1402 dst_u_2, SUBSAMPLE(kDestWidth, SUBSAMP_X), 1403 dst_v_2, SUBSAMPLE(kDestWidth, SUBSAMP_X), 1404 0, crop_y, 1405 kWidth, kHeight, 1406 kDestWidth, kDestHeight, 1407 libyuv::kRotate0, libyuv::FOURCC_NV12); 1408 1409 NV12ToI420(src_y + crop_y * kWidth, kWidth, 1410 src_uv + (crop_y / 2) * kStrideUV * 2, 1411 kStrideUV * 2, 1412 dst_y, kDestWidth, 1413 dst_u, SUBSAMPLE(kDestWidth, SUBSAMP_X), 1414 dst_v, SUBSAMPLE(kDestWidth, SUBSAMP_X), 1415 kDestWidth, kDestHeight); 1416 1417 for (int i = 0; i < kDestHeight; ++i) { 1418 for (int j = 0; j < kDestWidth; ++j) { 1419 EXPECT_EQ(dst_y[i * kWidth + j], dst_y_2[i * kWidth + j]); 1420 } 1421 } 1422 for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) { 1423 for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) { 1424 EXPECT_EQ(dst_u[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j], 1425 dst_u_2[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]); 1426 } 1427 } 1428 for (int i = 0; i < SUBSAMPLE(kDestHeight, SUBSAMP_Y); ++i) { 1429 for (int j = 0; j < SUBSAMPLE(kDestWidth, SUBSAMP_X); ++j) { 1430 EXPECT_EQ(dst_v[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j], 1431 dst_v_2[i * SUBSAMPLE(kDestWidth, SUBSAMP_X) + j]); 1432 } 1433 } 1434 free_aligned_buffer_page_end(dst_y); 1435 free_aligned_buffer_page_end(dst_u); 1436 free_aligned_buffer_page_end(dst_v); 1437 free_aligned_buffer_page_end(dst_y_2); 1438 free_aligned_buffer_page_end(dst_u_2); 1439 free_aligned_buffer_page_end(dst_v_2); 1440 free_aligned_buffer_page_end(src_y); 1441} 1442 1443TEST_F(LibYUVConvertTest, TestYToARGB) { 1444 uint8 y[32]; 1445 uint8 expectedg[32]; 1446 for (int i = 0; i < 32; ++i) { 1447 y[i] = i * 5 + 17; 1448 expectedg[i] = static_cast<int>((y[i] - 16) * 1.164f + 0.5f); 1449 } 1450 uint8 argb[32 * 4]; 1451 YToARGB(y, 0, argb, 0, 32, 1); 1452 1453 for (int i = 0; i < 32; ++i) { 1454 printf("%2d %d: %d <-> %d,%d,%d,%d\n", i, y[i], expectedg[i], 1455 argb[i * 4 + 0], 1456 argb[i * 4 + 1], 1457 argb[i * 4 + 2], 1458 argb[i * 4 + 3]); 1459 } 1460 for (int i = 0; i < 32; ++i) { 1461 EXPECT_EQ(expectedg[i], argb[i * 4 + 0]); 1462 } 1463} 1464 1465static const uint8 kNoDither4x4[16] = { 1466 0, 0, 0, 0, 1467 0, 0, 0, 0, 1468 0, 0, 0, 0, 1469 0, 0, 0, 0, 1470}; 1471 1472TEST_F(LibYUVConvertTest, TestNoDither) { 1473 align_buffer_page_end(src_argb, benchmark_width_ * benchmark_height_ * 4); 1474 align_buffer_page_end(dst_rgb565, benchmark_width_ * benchmark_height_ * 2); 1475 align_buffer_page_end(dst_rgb565dither, 1476 benchmark_width_ * benchmark_height_ * 2); 1477 MemRandomize(src_argb, benchmark_width_ * benchmark_height_ * 4); 1478 MemRandomize(dst_rgb565, benchmark_width_ * benchmark_height_ * 2); 1479 MemRandomize(dst_rgb565dither, benchmark_width_ * benchmark_height_ * 2); 1480 ARGBToRGB565(src_argb, benchmark_width_ * 4, 1481 dst_rgb565, benchmark_width_ * 2, 1482 benchmark_width_, benchmark_height_); 1483 ARGBToRGB565Dither(src_argb, benchmark_width_ * 4, 1484 dst_rgb565dither, benchmark_width_ * 2, 1485 kNoDither4x4, benchmark_width_, benchmark_height_); 1486 for (int i = 0; i < benchmark_width_ * benchmark_height_ * 2; ++i) { 1487 EXPECT_EQ(dst_rgb565[i], dst_rgb565dither[i]); 1488 } 1489 1490 free_aligned_buffer_page_end(src_argb); 1491 free_aligned_buffer_page_end(dst_rgb565); 1492 free_aligned_buffer_page_end(dst_rgb565dither); 1493} 1494 1495// Ordered 4x4 dither for 888 to 565. Values from 0 to 7. 1496static const uint8 kDither565_4x4[16] = { 1497 0, 4, 1, 5, 1498 6, 2, 7, 3, 1499 1, 5, 0, 4, 1500 7, 3, 6, 2, 1501}; 1502 1503TEST_F(LibYUVConvertTest, TestDither) { 1504 align_buffer_page_end(src_argb, benchmark_width_ * benchmark_height_ * 4); 1505 align_buffer_page_end(dst_rgb565, benchmark_width_ * benchmark_height_ * 2); 1506 align_buffer_page_end(dst_rgb565dither, 1507 benchmark_width_ * benchmark_height_ * 2); 1508 align_buffer_page_end(dst_argb, benchmark_width_ * benchmark_height_ * 4); 1509 align_buffer_page_end(dst_argbdither, 1510 benchmark_width_ * benchmark_height_ * 4); 1511 MemRandomize(src_argb, benchmark_width_ * benchmark_height_ * 4); 1512 MemRandomize(dst_rgb565, benchmark_width_ * benchmark_height_ * 2); 1513 MemRandomize(dst_rgb565dither, benchmark_width_ * benchmark_height_ * 2); 1514 MemRandomize(dst_argb, benchmark_width_ * benchmark_height_ * 4); 1515 MemRandomize(dst_argbdither, benchmark_width_ * benchmark_height_ * 4); 1516 ARGBToRGB565(src_argb, benchmark_width_ * 4, 1517 dst_rgb565, benchmark_width_ * 2, 1518 benchmark_width_, benchmark_height_); 1519 ARGBToRGB565Dither(src_argb, benchmark_width_ * 4, 1520 dst_rgb565dither, benchmark_width_ * 2, 1521 kDither565_4x4, benchmark_width_, benchmark_height_); 1522 RGB565ToARGB(dst_rgb565, benchmark_width_ * 2, 1523 dst_argb, benchmark_width_ * 4, 1524 benchmark_width_, benchmark_height_); 1525 RGB565ToARGB(dst_rgb565dither, benchmark_width_ * 2, 1526 dst_argbdither, benchmark_width_ * 4, 1527 benchmark_width_, benchmark_height_); 1528 1529 for (int i = 0; i < benchmark_width_ * benchmark_height_ * 4; ++i) { 1530 EXPECT_NEAR(dst_argb[i], dst_argbdither[i], 9); 1531 } 1532 free_aligned_buffer_page_end(src_argb); 1533 free_aligned_buffer_page_end(dst_rgb565); 1534 free_aligned_buffer_page_end(dst_rgb565dither); 1535 free_aligned_buffer_page_end(dst_argb); 1536 free_aligned_buffer_page_end(dst_argbdither); 1537} 1538 1539#define TESTPLANARTOBID(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1540 YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C) \ 1541TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##Dither##N) { \ 1542 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1543 const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \ 1544 const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \ 1545 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 1546 const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ 1547 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 1548 align_buffer_page_end(src_u, kSizeUV + OFF); \ 1549 align_buffer_page_end(src_v, kSizeUV + OFF); \ 1550 align_buffer_page_end(dst_argb_c, kStrideB * kHeight + OFF); \ 1551 align_buffer_page_end(dst_argb_opt, kStrideB * kHeight + OFF); \ 1552 for (int i = 0; i < kWidth * kHeight; ++i) { \ 1553 src_y[i + OFF] = (fastrand() & 0xff); \ 1554 } \ 1555 for (int i = 0; i < kSizeUV; ++i) { \ 1556 src_u[i + OFF] = (fastrand() & 0xff); \ 1557 src_v[i + OFF] = (fastrand() & 0xff); \ 1558 } \ 1559 memset(dst_argb_c + OFF, 1, kStrideB * kHeight); \ 1560 memset(dst_argb_opt + OFF, 101, kStrideB * kHeight); \ 1561 MaskCpuFlags(disable_cpu_flags_); \ 1562 FMT_PLANAR##To##FMT_B##Dither(src_y + OFF, kWidth, \ 1563 src_u + OFF, kStrideUV, \ 1564 src_v + OFF, kStrideUV, \ 1565 dst_argb_c + OFF, kStrideB, \ 1566 NULL, kWidth, NEG kHeight); \ 1567 MaskCpuFlags(benchmark_cpu_info_); \ 1568 for (int i = 0; i < benchmark_iterations_; ++i) { \ 1569 FMT_PLANAR##To##FMT_B##Dither(src_y + OFF, kWidth, \ 1570 src_u + OFF, kStrideUV, \ 1571 src_v + OFF, kStrideUV, \ 1572 dst_argb_opt + OFF, kStrideB, \ 1573 NULL, kWidth, NEG kHeight); \ 1574 } \ 1575 int max_diff = 0; \ 1576 /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \ 1577 align_buffer_page_end(dst_argb32_c, kWidth * BPP_C * kHeight); \ 1578 align_buffer_page_end(dst_argb32_opt, kWidth * BPP_C * kHeight); \ 1579 memset(dst_argb32_c, 2, kWidth * BPP_C * kHeight); \ 1580 memset(dst_argb32_opt, 102, kWidth * BPP_C * kHeight); \ 1581 FMT_B##To##FMT_C(dst_argb_c + OFF, kStrideB, \ 1582 dst_argb32_c, kWidth * BPP_C , \ 1583 kWidth, kHeight); \ 1584 FMT_B##To##FMT_C(dst_argb_opt + OFF, kStrideB, \ 1585 dst_argb32_opt, kWidth * BPP_C , \ 1586 kWidth, kHeight); \ 1587 for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) { \ 1588 int abs_diff = \ 1589 abs(static_cast<int>(dst_argb32_c[i]) - \ 1590 static_cast<int>(dst_argb32_opt[i])); \ 1591 if (abs_diff > max_diff) { \ 1592 max_diff = abs_diff; \ 1593 } \ 1594 } \ 1595 EXPECT_LE(max_diff, DIFF); \ 1596 free_aligned_buffer_page_end(src_y); \ 1597 free_aligned_buffer_page_end(src_u); \ 1598 free_aligned_buffer_page_end(src_v); \ 1599 free_aligned_buffer_page_end(dst_argb_c); \ 1600 free_aligned_buffer_page_end(dst_argb_opt); \ 1601 free_aligned_buffer_page_end(dst_argb32_c); \ 1602 free_aligned_buffer_page_end(dst_argb32_opt); \ 1603} 1604 1605#define TESTPLANARTOBD(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1606 YALIGN, DIFF, FMT_C, BPP_C) \ 1607 TESTPLANARTOBID(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1608 YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C) \ 1609 TESTPLANARTOBID(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1610 YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, BPP_C) \ 1611 TESTPLANARTOBID(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1612 YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C) \ 1613 TESTPLANARTOBID(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \ 1614 YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C) 1615 1616TESTPLANARTOBD(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4) 1617 1618#define TESTPTOB(NAME, UYVYTOI420, UYVYTONV12) \ 1619TEST_F(LibYUVConvertTest, NAME) { \ 1620 const int kWidth = benchmark_width_; \ 1621 const int kHeight = benchmark_height_; \ 1622 \ 1623 align_buffer_page_end(orig_uyvy, \ 1624 4 * SUBSAMPLE(kWidth, 2) * kHeight); \ 1625 align_buffer_page_end(orig_y, kWidth * kHeight); \ 1626 align_buffer_page_end(orig_u, \ 1627 SUBSAMPLE(kWidth, 2) * \ 1628 SUBSAMPLE(kHeight, 2)); \ 1629 align_buffer_page_end(orig_v, \ 1630 SUBSAMPLE(kWidth, 2) * \ 1631 SUBSAMPLE(kHeight, 2)); \ 1632 \ 1633 align_buffer_page_end(dst_y_orig, kWidth * kHeight); \ 1634 align_buffer_page_end(dst_uv_orig, 2 * \ 1635 SUBSAMPLE(kWidth, 2) * \ 1636 SUBSAMPLE(kHeight, 2)); \ 1637 \ 1638 align_buffer_page_end(dst_y, kWidth * kHeight); \ 1639 align_buffer_page_end(dst_uv, 2 * \ 1640 SUBSAMPLE(kWidth, 2) * \ 1641 SUBSAMPLE(kHeight, 2)); \ 1642 \ 1643 MemRandomize(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2) * kHeight); \ 1644 \ 1645 /* Convert UYVY to NV12 in 2 steps for reference */ \ 1646 libyuv::UYVYTOI420(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2), \ 1647 orig_y, kWidth, \ 1648 orig_u, SUBSAMPLE(kWidth, 2), \ 1649 orig_v, SUBSAMPLE(kWidth, 2), \ 1650 kWidth, kHeight); \ 1651 libyuv::I420ToNV12(orig_y, kWidth, \ 1652 orig_u, SUBSAMPLE(kWidth, 2), \ 1653 orig_v, SUBSAMPLE(kWidth, 2), \ 1654 dst_y_orig, kWidth, \ 1655 dst_uv_orig, 2 * SUBSAMPLE(kWidth, 2), \ 1656 kWidth, kHeight); \ 1657 \ 1658 /* Convert to NV12 */ \ 1659 for (int i = 0; i < benchmark_iterations_; ++i) { \ 1660 libyuv::UYVYTONV12(orig_uyvy, 4 * SUBSAMPLE(kWidth, 2), \ 1661 dst_y, kWidth, \ 1662 dst_uv, 2 * SUBSAMPLE(kWidth, 2), \ 1663 kWidth, kHeight); \ 1664 } \ 1665 \ 1666 for (int i = 0; i < kWidth * kHeight; ++i) { \ 1667 EXPECT_EQ(orig_y[i], dst_y[i]); \ 1668 } \ 1669 for (int i = 0; i < kWidth * kHeight; ++i) { \ 1670 EXPECT_EQ(dst_y_orig[i], dst_y[i]); \ 1671 } \ 1672 for (int i = 0; i < 2 * SUBSAMPLE(kWidth, 2) * SUBSAMPLE(kHeight, 2); ++i) { \ 1673 EXPECT_EQ(dst_uv_orig[i], dst_uv[i]); \ 1674 } \ 1675 \ 1676 free_aligned_buffer_page_end(orig_uyvy); \ 1677 free_aligned_buffer_page_end(orig_y); \ 1678 free_aligned_buffer_page_end(orig_u); \ 1679 free_aligned_buffer_page_end(orig_v); \ 1680 free_aligned_buffer_page_end(dst_y_orig); \ 1681 free_aligned_buffer_page_end(dst_uv_orig); \ 1682 free_aligned_buffer_page_end(dst_y); \ 1683 free_aligned_buffer_page_end(dst_uv); \ 1684} 1685 1686TESTPTOB(TestYUY2ToNV12, YUY2ToI420, YUY2ToNV12) 1687TESTPTOB(TestUYVYToNV12, UYVYToI420, UYVYToNV12) 1688 1689#define TESTPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1690 W1280, N, NEG, OFF, FMT_C, BPP_C) \ 1691TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##_##FMT_C##N) { \ 1692 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1693 const int kHeight = benchmark_height_; \ 1694 const int kStrideB = SUBSAMPLE(kWidth, SUB_B) * BPP_B; \ 1695 const int kStrideUV = SUBSAMPLE(kWidth, SUBSAMP_X); \ 1696 const int kSizeUV = kStrideUV * SUBSAMPLE(kHeight, SUBSAMP_Y); \ 1697 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 1698 align_buffer_page_end(src_u, kSizeUV + OFF); \ 1699 align_buffer_page_end(src_v, kSizeUV + OFF); \ 1700 align_buffer_page_end(dst_argb_b, kStrideB * kHeight + OFF); \ 1701 for (int i = 0; i < kWidth * kHeight; ++i) { \ 1702 src_y[i + OFF] = (fastrand() & 0xff); \ 1703 } \ 1704 for (int i = 0; i < kSizeUV; ++i) { \ 1705 src_u[i + OFF] = (fastrand() & 0xff); \ 1706 src_v[i + OFF] = (fastrand() & 0xff); \ 1707 } \ 1708 memset(dst_argb_b + OFF, 1, kStrideB * kHeight); \ 1709 for (int i = 0; i < benchmark_iterations_; ++i) { \ 1710 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 1711 src_u + OFF, kStrideUV, \ 1712 src_v + OFF, kStrideUV, \ 1713 dst_argb_b + OFF, kStrideB, \ 1714 kWidth, NEG kHeight); \ 1715 } \ 1716 /* Convert to a 3rd format in 1 step and 2 steps and compare */ \ 1717 const int kStrideC = kWidth * BPP_C; \ 1718 align_buffer_page_end(dst_argb_c, kStrideC * kHeight + OFF); \ 1719 align_buffer_page_end(dst_argb_bc, kStrideC * kHeight + OFF); \ 1720 memset(dst_argb_c + OFF, 2, kStrideC * kHeight); \ 1721 memset(dst_argb_bc + OFF, 3, kStrideC * kHeight); \ 1722 FMT_PLANAR##To##FMT_C(src_y + OFF, kWidth, \ 1723 src_u + OFF, kStrideUV, \ 1724 src_v + OFF, kStrideUV, \ 1725 dst_argb_c + OFF, kStrideC, \ 1726 kWidth, NEG kHeight); \ 1727 /* Convert B to C */ \ 1728 FMT_B##To##FMT_C(dst_argb_b + OFF, kStrideB, \ 1729 dst_argb_bc + OFF, kStrideC, \ 1730 kWidth, kHeight); \ 1731 for (int i = 0; i < kStrideC * kHeight; ++i) { \ 1732 EXPECT_EQ(dst_argb_c[i + OFF], dst_argb_bc[i + OFF]); \ 1733 } \ 1734 free_aligned_buffer_page_end(src_y); \ 1735 free_aligned_buffer_page_end(src_u); \ 1736 free_aligned_buffer_page_end(src_v); \ 1737 free_aligned_buffer_page_end(dst_argb_b); \ 1738 free_aligned_buffer_page_end(dst_argb_c); \ 1739 free_aligned_buffer_page_end(dst_argb_bc); \ 1740} 1741 1742#define TESTPLANARTOE(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1743 FMT_C, BPP_C) \ 1744 TESTPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1745 benchmark_width_ - 4, _Any, +, 0, FMT_C, BPP_C) \ 1746 TESTPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1747 benchmark_width_, _Unaligned, +, 1, FMT_C, BPP_C) \ 1748 TESTPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1749 benchmark_width_, _Invert, -, 0, FMT_C, BPP_C) \ 1750 TESTPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1751 benchmark_width_, _Opt, +, 0, FMT_C, BPP_C) 1752 1753TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, ABGR, 4) 1754TESTPLANARTOE(J420, 2, 2, ARGB, 1, 4, ARGB, 4) 1755TESTPLANARTOE(J420, 2, 2, ABGR, 1, 4, ARGB, 4) 1756TESTPLANARTOE(H420, 2, 2, ARGB, 1, 4, ARGB, 4) 1757TESTPLANARTOE(H420, 2, 2, ABGR, 1, 4, ARGB, 4) 1758TESTPLANARTOE(I420, 2, 2, BGRA, 1, 4, ARGB, 4) 1759TESTPLANARTOE(I420, 2, 2, ABGR, 1, 4, ARGB, 4) 1760TESTPLANARTOE(I420, 2, 2, RGBA, 1, 4, ARGB, 4) 1761TESTPLANARTOE(I420, 2, 2, RGB24, 1, 3, ARGB, 4) 1762TESTPLANARTOE(I420, 2, 2, RAW, 1, 3, RGB24, 3) 1763TESTPLANARTOE(I420, 2, 2, RGB24, 1, 3, RAW, 3) 1764TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, RAW, 3) 1765TESTPLANARTOE(I420, 2, 2, RAW, 1, 3, ARGB, 4) 1766TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, RGB565, 2) 1767TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, ARGB1555, 2) 1768TESTPLANARTOE(I420, 2, 2, ARGB, 1, 4, ARGB4444, 2) 1769TESTPLANARTOE(I422, 2, 1, ARGB, 1, 4, ARGB, 4) 1770TESTPLANARTOE(J422, 2, 1, ARGB, 1, 4, ARGB, 4) 1771TESTPLANARTOE(J422, 2, 1, ABGR, 1, 4, ARGB, 4) 1772TESTPLANARTOE(H422, 2, 1, ARGB, 1, 4, ARGB, 4) 1773TESTPLANARTOE(H422, 2, 1, ABGR, 1, 4, ARGB, 4) 1774TESTPLANARTOE(I422, 2, 1, BGRA, 1, 4, ARGB, 4) 1775TESTPLANARTOE(I422, 2, 1, ABGR, 1, 4, ARGB, 4) 1776TESTPLANARTOE(I422, 2, 1, RGBA, 1, 4, ARGB, 4) 1777TESTPLANARTOE(I411, 4, 1, ARGB, 1, 4, ARGB, 4) 1778TESTPLANARTOE(I444, 1, 1, ARGB, 1, 4, ARGB, 4) 1779TESTPLANARTOE(J444, 1, 1, ARGB, 1, 4, ARGB, 4) 1780TESTPLANARTOE(I444, 1, 1, ABGR, 1, 4, ARGB, 4) 1781TESTPLANARTOE(I420, 2, 2, YUY2, 2, 4, ARGB, 4) 1782TESTPLANARTOE(I420, 2, 2, UYVY, 2, 4, ARGB, 4) 1783TESTPLANARTOE(I422, 2, 1, YUY2, 2, 4, ARGB, 4) 1784TESTPLANARTOE(I422, 2, 1, UYVY, 2, 4, ARGB, 4) 1785 1786#define TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1787 W1280, N, NEG, OFF, FMT_C, BPP_C, ATTEN) \ 1788TEST_F(LibYUVConvertTest, FMT_PLANAR##To##FMT_B##_##FMT_C##N) { \ 1789 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ 1790 const int kHeight = benchmark_height_; \ 1791 const int kStrideB = SUBSAMPLE(kWidth, SUB_B) * BPP_B; \ 1792 const int kSizeUV = \ 1793 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y); \ 1794 align_buffer_page_end(src_y, kWidth * kHeight + OFF); \ 1795 align_buffer_page_end(src_u, kSizeUV + OFF); \ 1796 align_buffer_page_end(src_v, kSizeUV + OFF); \ 1797 align_buffer_page_end(src_a, kWidth * kHeight + OFF); \ 1798 align_buffer_page_end(dst_argb_b, kStrideB * kHeight + OFF); \ 1799 for (int i = 0; i < kWidth * kHeight; ++i) { \ 1800 src_y[i + OFF] = (fastrand() & 0xff); \ 1801 src_a[i + OFF] = (fastrand() & 0xff); \ 1802 } \ 1803 for (int i = 0; i < kSizeUV; ++i) { \ 1804 src_u[i + OFF] = (fastrand() & 0xff); \ 1805 src_v[i + OFF] = (fastrand() & 0xff); \ 1806 } \ 1807 memset(dst_argb_b + OFF, 1, kStrideB * kHeight); \ 1808 for (int i = 0; i < benchmark_iterations_; ++i) { \ 1809 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \ 1810 src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1811 src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1812 src_a + OFF, kWidth, \ 1813 dst_argb_b + OFF, kStrideB, \ 1814 kWidth, NEG kHeight, ATTEN); \ 1815 } \ 1816 int max_diff = 0; \ 1817 /* Convert to a 3rd format in 1 step and 2 steps and compare */ \ 1818 const int kStrideC = kWidth * BPP_C; \ 1819 align_buffer_page_end(dst_argb_c, kStrideC * kHeight + OFF); \ 1820 align_buffer_page_end(dst_argb_bc, kStrideC * kHeight + OFF); \ 1821 memset(dst_argb_c + OFF, 2, kStrideC * kHeight); \ 1822 memset(dst_argb_bc + OFF, 3, kStrideC * kHeight); \ 1823 FMT_PLANAR##To##FMT_C(src_y + OFF, kWidth, \ 1824 src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1825 src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \ 1826 src_a + OFF, kWidth, \ 1827 dst_argb_c + OFF, kStrideC, \ 1828 kWidth, NEG kHeight, ATTEN); \ 1829 /* Convert B to C */ \ 1830 FMT_B##To##FMT_C(dst_argb_b + OFF, kStrideB, \ 1831 dst_argb_bc + OFF, kStrideC, \ 1832 kWidth, kHeight); \ 1833 for (int i = 0; i < kStrideC * kHeight; ++i) { \ 1834 EXPECT_EQ(dst_argb_c[i + OFF], dst_argb_bc[i + OFF]); \ 1835 } \ 1836 free_aligned_buffer_page_end(src_y); \ 1837 free_aligned_buffer_page_end(src_u); \ 1838 free_aligned_buffer_page_end(src_v); \ 1839 free_aligned_buffer_page_end(src_a); \ 1840 free_aligned_buffer_page_end(dst_argb_b); \ 1841 free_aligned_buffer_page_end(dst_argb_c); \ 1842 free_aligned_buffer_page_end(dst_argb_bc); \ 1843} 1844 1845#define TESTQPLANARTOE(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1846 FMT_C, BPP_C) \ 1847 TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1848 benchmark_width_ - 4, _Any, +, 0, FMT_C, BPP_C, 0) \ 1849 TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1850 benchmark_width_, _Unaligned, +, 1, FMT_C, BPP_C, 0) \ 1851 TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1852 benchmark_width_, _Invert, -, 0, FMT_C, BPP_C, 0) \ 1853 TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1854 benchmark_width_, _Opt, +, 0, FMT_C, BPP_C, 0) \ 1855 TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \ 1856 benchmark_width_, _Premult, +, 0, FMT_C, BPP_C, 1) 1857 1858TESTQPLANARTOE(I420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4) 1859TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4) 1860 1861} // namespace libyuv 1862