1 /* 2 * libjingle 3 * Copyright 2010 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sstream> 29 30 #include "libyuv/cpu_id.h" 31 #include "libyuv/scale.h" 32 #include "talk/media/base/testutils.h" 33 #include "webrtc/base/basictypes.h" 34 #include "webrtc/base/flags.h" 35 #include "webrtc/base/gunit.h" 36 #include "webrtc/base/scoped_ptr.h" 37 38 #if defined(_MSC_VER) 39 #define ALIGN16(var) __declspec(align(16)) var 40 #else 41 #define ALIGN16(var) var __attribute__((aligned(16))) 42 #endif 43 44 using cricket::LoadPlanarYuvTestImage; 45 using cricket::DumpPlanarYuvTestImage; 46 using rtc::scoped_ptr; 47 48 DEFINE_bool(yuvscaler_dump, false, 49 "whether to write out scaled images for inspection"); 50 DEFINE_int(yuvscaler_repeat, 1, 51 "how many times to perform each scaling operation (for perf testing)"); 52 53 static const int kAlignment = 16; 54 55 // TEST_UNCACHED flushes cache to test real memory performance. 56 // TEST_RSTSC uses cpu cycles for more accurate benchmark of the scale function. 57 #ifndef __arm__ 58 // #define TEST_UNCACHED 1 59 // #define TEST_RSTSC 1 60 #endif 61 62 #if defined(TEST_UNCACHED) || defined(TEST_RSTSC) 63 #ifdef _MSC_VER 64 #include <emmintrin.h> // NOLINT 65 #endif 66 67 #if defined(__GNUC__) && defined(__i386__) 68 static inline uint64 __rdtsc(void) { 69 uint32_t a, d; 70 __asm__ volatile("rdtsc" : "=a" (a), "=d" (d)); 71 return (reinterpret_cast<uint64>(d) << 32) + a; 72 } 73 74 static inline void _mm_clflush(volatile void *__p) { 75 asm volatile("clflush %0" : "+m" (*(volatile char *)__p)); 76 } 77 #endif 78 79 static void FlushCache(uint8* dst, int count) { 80 while (count >= 32) { 81 _mm_clflush(dst); 82 dst += 32; 83 count -= 32; 84 } 85 } 86 #endif 87 88 class YuvScalerTest : public testing::Test { 89 protected: 90 virtual void SetUp() { 91 dump_ = *rtc::FlagList::Lookup("yuvscaler_dump")->bool_variable(); 92 repeat_ = *rtc::FlagList::Lookup("yuvscaler_repeat")->int_variable(); 93 } 94 95 // Scale an image and compare against a Lanczos-filtered test image. 96 // Lanczos is considered to be the "ideal" image resampling method, so we try 97 // to get as close to that as possible, while being as fast as possible. 98 bool TestScale(int iw, int ih, int ow, int oh, int offset, bool usefile, 99 bool optimize, int cpuflags, bool interpolate, 100 int memoffset, double* error) { 101 *error = 0.; 102 size_t isize = I420_SIZE(iw, ih); 103 size_t osize = I420_SIZE(ow, oh); 104 scoped_ptr<uint8[]> ibuffer(new uint8[isize + kAlignment + memoffset]()); 105 scoped_ptr<uint8[]> obuffer(new uint8[osize + kAlignment + memoffset]()); 106 scoped_ptr<uint8[]> xbuffer(new uint8[osize + kAlignment + memoffset]()); 107 108 uint8 *ibuf = ALIGNP(ibuffer.get(), kAlignment) + memoffset; 109 uint8 *obuf = ALIGNP(obuffer.get(), kAlignment) + memoffset; 110 uint8 *xbuf = ALIGNP(xbuffer.get(), kAlignment) + memoffset; 111 112 if (usefile) { 113 if (!LoadPlanarYuvTestImage("faces", iw, ih, ibuf) || 114 !LoadPlanarYuvTestImage("faces", ow, oh, xbuf)) { 115 LOG(LS_ERROR) << "Failed to load image"; 116 return false; 117 } 118 } else { 119 // These are used to test huge images. 120 memset(ibuf, 213, isize); // Input is constant color. 121 memset(obuf, 100, osize); // Output set to something wrong for now. 122 memset(xbuf, 213, osize); // Expected result. 123 } 124 125 #ifdef TEST_UNCACHED 126 FlushCache(ibuf, isize); 127 FlushCache(obuf, osize); 128 FlushCache(xbuf, osize); 129 #endif 130 131 // Scale down. 132 // If cpu true, disable cpu optimizations. Else allow auto detect 133 // TODO(fbarchard): set flags for libyuv 134 libyuv::MaskCpuFlags(cpuflags); 135 #ifdef TEST_RSTSC 136 uint64 t = 0; 137 #endif 138 for (int i = 0; i < repeat_; ++i) { 139 #ifdef TEST_UNCACHED 140 FlushCache(ibuf, isize); 141 FlushCache(obuf, osize); 142 #endif 143 #ifdef TEST_RSTSC 144 uint64 t1 = __rdtsc(); 145 #endif 146 EXPECT_EQ(0, libyuv::ScaleOffset(ibuf, iw, ih, obuf, ow, oh, 147 offset, interpolate)); 148 #ifdef TEST_RSTSC 149 uint64 t2 = __rdtsc(); 150 t += t2 - t1; 151 #endif 152 } 153 154 #ifdef TEST_RSTSC 155 LOG(LS_INFO) << "Time: " << std::setw(9) << t; 156 #endif 157 158 if (dump_) { 159 const testing::TestInfo* const test_info = 160 testing::UnitTest::GetInstance()->current_test_info(); 161 std::string test_name(test_info->name()); 162 DumpPlanarYuvTestImage(test_name, obuf, ow, oh); 163 } 164 165 double sse = cricket::ComputeSumSquareError(obuf, xbuf, osize); 166 *error = sse / osize; // Mean Squared Error. 167 double PSNR = cricket::ComputePSNR(sse, osize); 168 LOG(LS_INFO) << "Image MSE: " << 169 std::setw(6) << std::setprecision(4) << *error << 170 " Image PSNR: " << PSNR; 171 return true; 172 } 173 174 // Returns the index of the first differing byte. Easier to debug than memcmp. 175 static int FindDiff(const uint8* buf1, const uint8* buf2, int len) { 176 int i = 0; 177 while (i < len && buf1[i] == buf2[i]) { 178 i++; 179 } 180 return (i < len) ? i : -1; 181 } 182 183 protected: 184 bool dump_; 185 int repeat_; 186 }; 187 188 // Tests straight copy of data. 189 TEST_F(YuvScalerTest, TestCopy) { 190 const int iw = 640, ih = 360; 191 const int ow = 640, oh = 360; 192 ALIGN16(uint8 ibuf[I420_SIZE(iw, ih)]); 193 ALIGN16(uint8 obuf[I420_SIZE(ow, oh)]); 194 195 // Load the frame, scale it, check it. 196 ASSERT_TRUE(LoadPlanarYuvTestImage("faces", iw, ih, ibuf)); 197 for (int i = 0; i < repeat_; ++i) { 198 libyuv::ScaleOffset(ibuf, iw, ih, obuf, ow, oh, 0, false); 199 } 200 if (dump_) DumpPlanarYuvTestImage("TestCopy", obuf, ow, oh); 201 EXPECT_EQ(-1, FindDiff(obuf, ibuf, sizeof(ibuf))); 202 } 203 204 // Tests copy from 4:3 to 16:9. 205 TEST_F(YuvScalerTest, TestOffset16_10Copy) { 206 const int iw = 640, ih = 360; 207 const int ow = 640, oh = 480; 208 const int offset = (480 - 360) / 2; 209 scoped_ptr<uint8[]> ibuffer(new uint8[I420_SIZE(iw, ih) + kAlignment]); 210 scoped_ptr<uint8[]> obuffer(new uint8[I420_SIZE(ow, oh) + kAlignment]); 211 212 uint8 *ibuf = ALIGNP(ibuffer.get(), kAlignment); 213 uint8 *obuf = ALIGNP(obuffer.get(), kAlignment); 214 215 // Load the frame, scale it, check it. 216 ASSERT_TRUE(LoadPlanarYuvTestImage("faces", iw, ih, ibuf)); 217 218 // Clear to black, which is Y = 0 and U and V = 128 219 memset(obuf, 0, ow * oh); 220 memset(obuf + ow * oh, 128, ow * oh / 2); 221 for (int i = 0; i < repeat_; ++i) { 222 libyuv::ScaleOffset(ibuf, iw, ih, obuf, ow, oh, offset, false); 223 } 224 if (dump_) DumpPlanarYuvTestImage("TestOffsetCopy16_9", obuf, ow, oh); 225 EXPECT_EQ(-1, FindDiff(obuf + ow * offset, 226 ibuf, 227 iw * ih)); 228 EXPECT_EQ(-1, FindDiff(obuf + ow * oh + ow * offset / 4, 229 ibuf + iw * ih, 230 iw * ih / 4)); 231 EXPECT_EQ(-1, FindDiff(obuf + ow * oh * 5 / 4 + ow * offset / 4, 232 ibuf + iw * ih * 5 / 4, 233 iw * ih / 4)); 234 } 235 236 // The following are 'cpu' flag values: 237 // Allow all SIMD optimizations 238 #define ALLFLAGS -1 239 // Disable SSSE3 but allow other forms of SIMD (SSE2) 240 #define NOSSSE3 ~libyuv::kCpuHasSSSE3 241 // Disable SSE2 and SSSE3 242 #define NOSSE ~libyuv::kCpuHasSSE2 & ~libyuv::kCpuHasSSSE3 243 244 // TEST_M scale factor with variations of opt, align, int 245 #define TEST_M(name, iwidth, iheight, owidth, oheight, mse) \ 246 TEST_F(YuvScalerTest, name##Ref) { \ 247 double error; \ 248 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 249 0, true, false, ALLFLAGS, false, 0, &error)); \ 250 EXPECT_LE(error, mse); \ 251 } \ 252 TEST_F(YuvScalerTest, name##OptAligned) { \ 253 double error; \ 254 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 255 0, true, true, ALLFLAGS, false, 0, &error)); \ 256 EXPECT_LE(error, mse); \ 257 } \ 258 TEST_F(YuvScalerTest, name##OptUnaligned) { \ 259 double error; \ 260 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 261 0, true, true, ALLFLAGS, false, 1, &error)); \ 262 EXPECT_LE(error, mse); \ 263 } \ 264 TEST_F(YuvScalerTest, name##OptSSE2) { \ 265 double error; \ 266 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 267 0, true, true, NOSSSE3, false, 0, &error)); \ 268 EXPECT_LE(error, mse); \ 269 } \ 270 TEST_F(YuvScalerTest, name##OptC) { \ 271 double error; \ 272 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 273 0, true, true, NOSSE, false, 0, &error)); \ 274 EXPECT_LE(error, mse); \ 275 } \ 276 TEST_F(YuvScalerTest, name##IntRef) { \ 277 double error; \ 278 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 279 0, true, false, ALLFLAGS, true, 0, &error)); \ 280 EXPECT_LE(error, mse); \ 281 } \ 282 TEST_F(YuvScalerTest, name##IntOptAligned) { \ 283 double error; \ 284 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 285 0, true, true, ALLFLAGS, true, 0, &error)); \ 286 EXPECT_LE(error, mse); \ 287 } \ 288 TEST_F(YuvScalerTest, name##IntOptUnaligned) { \ 289 double error; \ 290 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 291 0, true, true, ALLFLAGS, true, 1, &error)); \ 292 EXPECT_LE(error, mse); \ 293 } \ 294 TEST_F(YuvScalerTest, name##IntOptSSE2) { \ 295 double error; \ 296 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 297 0, true, true, NOSSSE3, true, 0, &error)); \ 298 EXPECT_LE(error, mse); \ 299 } \ 300 TEST_F(YuvScalerTest, name##IntOptC) { \ 301 double error; \ 302 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 303 0, true, true, NOSSE, true, 0, &error)); \ 304 EXPECT_LE(error, mse); \ 305 } 306 307 #define TEST_H(name, iwidth, iheight, owidth, oheight, opt, cpu, intr, mse) \ 308 TEST_F(YuvScalerTest, name) { \ 309 double error; \ 310 EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \ 311 0, false, opt, cpu, intr, 0, &error)); \ 312 EXPECT_LE(error, mse); \ 313 } 314 315 // Test 4x3 aspect ratio scaling 316 317 // Tests 1/1x scale down. 318 TEST_M(TestScale4by3Down11, 640, 480, 640, 480, 0) 319 320 // Tests 3/4x scale down. 321 TEST_M(TestScale4by3Down34, 640, 480, 480, 360, 60) 322 323 // Tests 1/2x scale down. 324 TEST_M(TestScale4by3Down12, 640, 480, 320, 240, 60) 325 326 // Tests 3/8x scale down. 327 TEST_M(TestScale4by3Down38, 640, 480, 240, 180, 60) 328 329 // Tests 1/4x scale down.. 330 TEST_M(TestScale4by3Down14, 640, 480, 160, 120, 60) 331 332 // Tests 3/16x scale down. 333 TEST_M(TestScale4by3Down316, 640, 480, 120, 90, 120) 334 335 // Tests 1/8x scale down. 336 TEST_M(TestScale4by3Down18, 640, 480, 80, 60, 150) 337 338 // Tests 2/3x scale down. 339 TEST_M(TestScale4by3Down23, 480, 360, 320, 240, 60) 340 341 // Tests 4/3x scale up. 342 TEST_M(TestScale4by3Up43, 480, 360, 640, 480, 60) 343 344 // Tests 2/1x scale up. 345 TEST_M(TestScale4by3Up21, 320, 240, 640, 480, 60) 346 347 // Tests 4/1x scale up. 348 TEST_M(TestScale4by3Up41, 160, 120, 640, 480, 80) 349 350 // Test 16x10 aspect ratio scaling 351 352 // Tests 1/1x scale down. 353 TEST_M(TestScale16by10Down11, 640, 400, 640, 400, 0) 354 355 // Tests 3/4x scale down. 356 TEST_M(TestScale16by10Down34, 640, 400, 480, 300, 60) 357 358 // Tests 1/2x scale down. 359 TEST_M(TestScale16by10Down12, 640, 400, 320, 200, 60) 360 361 // Tests 3/8x scale down. 362 TEST_M(TestScale16by10Down38, 640, 400, 240, 150, 60) 363 364 // Tests 1/4x scale down.. 365 TEST_M(TestScale16by10Down14, 640, 400, 160, 100, 60) 366 367 // Tests 3/16x scale down. 368 TEST_M(TestScale16by10Down316, 640, 400, 120, 75, 120) 369 370 // Tests 1/8x scale down. 371 TEST_M(TestScale16by10Down18, 640, 400, 80, 50, 150) 372 373 // Tests 2/3x scale down. 374 TEST_M(TestScale16by10Down23, 480, 300, 320, 200, 60) 375 376 // Tests 4/3x scale up. 377 TEST_M(TestScale16by10Up43, 480, 300, 640, 400, 60) 378 379 // Tests 2/1x scale up. 380 TEST_M(TestScale16by10Up21, 320, 200, 640, 400, 60) 381 382 // Tests 4/1x scale up. 383 TEST_M(TestScale16by10Up41, 160, 100, 640, 400, 80) 384 385 // Test 16x9 aspect ratio scaling 386 387 // Tests 1/1x scale down. 388 TEST_M(TestScaleDown11, 640, 360, 640, 360, 0) 389 390 // Tests 3/4x scale down. 391 TEST_M(TestScaleDown34, 640, 360, 480, 270, 60) 392 393 // Tests 1/2x scale down. 394 TEST_M(TestScaleDown12, 640, 360, 320, 180, 60) 395 396 // Tests 3/8x scale down. 397 TEST_M(TestScaleDown38, 640, 360, 240, 135, 60) 398 399 // Tests 1/4x scale down.. 400 TEST_M(TestScaleDown14, 640, 360, 160, 90, 60) 401 402 // Tests 3/16x scale down. 403 TEST_M(TestScaleDown316, 640, 360, 120, 68, 120) 404 405 // Tests 1/8x scale down. 406 TEST_M(TestScaleDown18, 640, 360, 80, 45, 150) 407 408 // Tests 2/3x scale down. 409 TEST_M(TestScaleDown23, 480, 270, 320, 180, 60) 410 411 // Tests 4/3x scale up. 412 TEST_M(TestScaleUp43, 480, 270, 640, 360, 60) 413 414 // Tests 2/1x scale up. 415 TEST_M(TestScaleUp21, 320, 180, 640, 360, 60) 416 417 // Tests 4/1x scale up. 418 TEST_M(TestScaleUp41, 160, 90, 640, 360, 80) 419 420 // Test HD 4x3 aspect ratio scaling 421 422 // Tests 1/1x scale down. 423 TEST_M(TestScaleHD4x3Down11, 1280, 960, 1280, 960, 0) 424 425 // Tests 3/4x scale down. 426 TEST_M(TestScaleHD4x3Down34, 1280, 960, 960, 720, 60) 427 428 // Tests 1/2x scale down. 429 TEST_M(TestScaleHD4x3Down12, 1280, 960, 640, 480, 60) 430 431 // Tests 3/8x scale down. 432 TEST_M(TestScaleHD4x3Down38, 1280, 960, 480, 360, 60) 433 434 // Tests 1/4x scale down.. 435 TEST_M(TestScaleHD4x3Down14, 1280, 960, 320, 240, 60) 436 437 // Tests 3/16x scale down. 438 TEST_M(TestScaleHD4x3Down316, 1280, 960, 240, 180, 120) 439 440 // Tests 1/8x scale down. 441 TEST_M(TestScaleHD4x3Down18, 1280, 960, 160, 120, 150) 442 443 // Tests 2/3x scale down. 444 TEST_M(TestScaleHD4x3Down23, 960, 720, 640, 480, 60) 445 446 // Tests 4/3x scale up. 447 TEST_M(TestScaleHD4x3Up43, 960, 720, 1280, 960, 60) 448 449 // Tests 2/1x scale up. 450 TEST_M(TestScaleHD4x3Up21, 640, 480, 1280, 960, 60) 451 452 // Tests 4/1x scale up. 453 TEST_M(TestScaleHD4x3Up41, 320, 240, 1280, 960, 80) 454 455 // Test HD 16x10 aspect ratio scaling 456 457 // Tests 1/1x scale down. 458 TEST_M(TestScaleHD16x10Down11, 1280, 800, 1280, 800, 0) 459 460 // Tests 3/4x scale down. 461 TEST_M(TestScaleHD16x10Down34, 1280, 800, 960, 600, 60) 462 463 // Tests 1/2x scale down. 464 TEST_M(TestScaleHD16x10Down12, 1280, 800, 640, 400, 60) 465 466 // Tests 3/8x scale down. 467 TEST_M(TestScaleHD16x10Down38, 1280, 800, 480, 300, 60) 468 469 // Tests 1/4x scale down.. 470 TEST_M(TestScaleHD16x10Down14, 1280, 800, 320, 200, 60) 471 472 // Tests 3/16x scale down. 473 TEST_M(TestScaleHD16x10Down316, 1280, 800, 240, 150, 120) 474 475 // Tests 1/8x scale down. 476 TEST_M(TestScaleHD16x10Down18, 1280, 800, 160, 100, 150) 477 478 // Tests 2/3x scale down. 479 TEST_M(TestScaleHD16x10Down23, 960, 600, 640, 400, 60) 480 481 // Tests 4/3x scale up. 482 TEST_M(TestScaleHD16x10Up43, 960, 600, 1280, 800, 60) 483 484 // Tests 2/1x scale up. 485 TEST_M(TestScaleHD16x10Up21, 640, 400, 1280, 800, 60) 486 487 // Tests 4/1x scale up. 488 TEST_M(TestScaleHD16x10Up41, 320, 200, 1280, 800, 80) 489 490 // Test HD 16x9 aspect ratio scaling 491 492 // Tests 1/1x scale down. 493 TEST_M(TestScaleHDDown11, 1280, 720, 1280, 720, 0) 494 495 // Tests 3/4x scale down. 496 TEST_M(TestScaleHDDown34, 1280, 720, 960, 540, 60) 497 498 // Tests 1/2x scale down. 499 TEST_M(TestScaleHDDown12, 1280, 720, 640, 360, 60) 500 501 // Tests 3/8x scale down. 502 TEST_M(TestScaleHDDown38, 1280, 720, 480, 270, 60) 503 504 // Tests 1/4x scale down.. 505 TEST_M(TestScaleHDDown14, 1280, 720, 320, 180, 60) 506 507 // Tests 3/16x scale down. 508 TEST_M(TestScaleHDDown316, 1280, 720, 240, 135, 120) 509 510 // Tests 1/8x scale down. 511 TEST_M(TestScaleHDDown18, 1280, 720, 160, 90, 150) 512 513 // Tests 2/3x scale down. 514 TEST_M(TestScaleHDDown23, 960, 540, 640, 360, 60) 515 516 // Tests 4/3x scale up. 517 TEST_M(TestScaleHDUp43, 960, 540, 1280, 720, 60) 518 519 // Tests 2/1x scale up. 520 TEST_M(TestScaleHDUp21, 640, 360, 1280, 720, 60) 521 522 // Tests 4/1x scale up. 523 TEST_M(TestScaleHDUp41, 320, 180, 1280, 720, 80) 524 525 // Tests 1366x768 resolution for comparison to chromium scaler_bench 526 TEST_M(TestScaleHDUp1366, 1280, 720, 1366, 768, 10) 527 528 // Tests odd source/dest sizes. 3 less to make chroma odd as well. 529 TEST_M(TestScaleHDUp1363, 1277, 717, 1363, 765, 10) 530 531 // Tests 1/2x scale down, using optimized algorithm. 532 TEST_M(TestScaleOddDown12, 180, 100, 90, 50, 50) 533 534 // Tests bilinear scale down 535 TEST_M(TestScaleOddDownBilin, 160, 100, 90, 50, 120) 536 537 // Test huge buffer scales that are expected to use a different code path 538 // that avoids stack overflow but still work using point sampling. 539 // Max output size is 640 wide. 540 541 // Tests interpolated 1/8x scale down, using optimized algorithm. 542 TEST_H(TestScaleDown18HDOptInt, 6144, 48, 768, 6, true, ALLFLAGS, true, 1) 543 544 // Tests interpolated 1/8x scale down, using c_only optimized algorithm. 545 TEST_H(TestScaleDown18HDCOnlyOptInt, 6144, 48, 768, 6, true, NOSSE, true, 1) 546 547 // Tests interpolated 3/8x scale down, using optimized algorithm. 548 TEST_H(TestScaleDown38HDOptInt, 2048, 16, 768, 6, true, ALLFLAGS, true, 1) 549 550 // Tests interpolated 3/8x scale down, using no SSSE3 optimized algorithm. 551 TEST_H(TestScaleDown38HDNoSSSE3OptInt, 2048, 16, 768, 6, true, NOSSSE3, true, 1) 552 553 // Tests interpolated 3/8x scale down, using c_only optimized algorithm. 554 TEST_H(TestScaleDown38HDCOnlyOptInt, 2048, 16, 768, 6, true, NOSSE, true, 1) 555 556 // Tests interpolated 3/16x scale down, using optimized algorithm. 557 TEST_H(TestScaleDown316HDOptInt, 4096, 32, 768, 6, true, ALLFLAGS, true, 1) 558 559 // Tests interpolated 3/16x scale down, using no SSSE3 optimized algorithm. 560 TEST_H(TestScaleDown316HDNoSSSE3OptInt, 4096, 32, 768, 6, true, NOSSSE3, true, 561 1) 562 563 // Tests interpolated 3/16x scale down, using c_only optimized algorithm. 564 TEST_H(TestScaleDown316HDCOnlyOptInt, 4096, 32, 768, 6, true, NOSSE, true, 1) 565 566 // Test special sizes dont crash 567 // Tests scaling down to 1 pixel width 568 TEST_H(TestScaleDown1x6OptInt, 3, 24, 1, 6, true, ALLFLAGS, true, 4) 569 570 // Tests scaling down to 1 pixel height 571 TEST_H(TestScaleDown6x1OptInt, 24, 3, 6, 1, true, ALLFLAGS, true, 4) 572 573 // Tests scaling up from 1 pixel width 574 TEST_H(TestScaleUp1x6OptInt, 1, 6, 3, 24, true, ALLFLAGS, true, 4) 575 576 // Tests scaling up from 1 pixel height 577 TEST_H(TestScaleUp6x1OptInt, 6, 1, 24, 3, true, ALLFLAGS, true, 4) 578 579 // Test performance of a range of box filter scale sizes 580 581 // Tests interpolated 1/2x scale down, using optimized algorithm. 582 TEST_H(TestScaleDown2xHDOptInt, 1280, 720, 1280 / 2, 720 / 2, true, ALLFLAGS, 583 true, 1) 584 585 // Tests interpolated 1/3x scale down, using optimized algorithm. 586 TEST_H(TestScaleDown3xHDOptInt, 1280, 720, 1280 / 3, 720 / 3, true, ALLFLAGS, 587 true, 1) 588 589 // Tests interpolated 1/4x scale down, using optimized algorithm. 590 TEST_H(TestScaleDown4xHDOptInt, 1280, 720, 1280 / 4, 720 / 4, true, ALLFLAGS, 591 true, 1) 592 593 // Tests interpolated 1/5x scale down, using optimized algorithm. 594 TEST_H(TestScaleDown5xHDOptInt, 1280, 720, 1280 / 5, 720 / 5, true, ALLFLAGS, 595 true, 1) 596 597 // Tests interpolated 1/6x scale down, using optimized algorithm. 598 TEST_H(TestScaleDown6xHDOptInt, 1280, 720, 1280 / 6, 720 / 6, true, ALLFLAGS, 599 true, 1) 600 601 // Tests interpolated 1/7x scale down, using optimized algorithm. 602 TEST_H(TestScaleDown7xHDOptInt, 1280, 720, 1280 / 7, 720 / 7, true, ALLFLAGS, 603 true, 1) 604 605 // Tests interpolated 1/8x scale down, using optimized algorithm. 606 TEST_H(TestScaleDown8xHDOptInt, 1280, 720, 1280 / 8, 720 / 8, true, ALLFLAGS, 607 true, 1) 608 609 // Tests interpolated 1/8x scale down, using optimized algorithm. 610 TEST_H(TestScaleDown9xHDOptInt, 1280, 720, 1280 / 9, 720 / 9, true, ALLFLAGS, 611 true, 1) 612 613 // Tests interpolated 1/8x scale down, using optimized algorithm. 614 TEST_H(TestScaleDown10xHDOptInt, 1280, 720, 1280 / 10, 720 / 10, true, ALLFLAGS, 615 true, 1) 616