• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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__)
__rdtsc(void)68 static inline uint64_t __rdtsc(void) {
69   uint32_t a, d;
70   __asm__ volatile("rdtsc" : "=a" (a), "=d" (d));
71   return (reinterpret_cast<uint64_t>(d) << 32) + a;
72 }
73 
_mm_clflush(volatile void * __p)74 static inline void _mm_clflush(volatile void *__p) {
75   asm volatile("clflush %0" : "+m" (*(volatile char *)__p));
76 }
77 #endif
78 
FlushCache(uint8_t * dst,int count)79 static void FlushCache(uint8_t* 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:
SetUp()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.
TestScale(int iw,int ih,int ow,int oh,int offset,bool usefile,bool optimize,int cpuflags,bool interpolate,int memoffset,double * error)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_t[]> ibuffer(
105         new uint8_t[isize + kAlignment + memoffset]());
106     scoped_ptr<uint8_t[]> obuffer(
107         new uint8_t[osize + kAlignment + memoffset]());
108     scoped_ptr<uint8_t[]> xbuffer(
109         new uint8_t[osize + kAlignment + memoffset]());
110 
111     uint8_t* ibuf = ALIGNP(ibuffer.get(), kAlignment) + memoffset;
112     uint8_t* obuf = ALIGNP(obuffer.get(), kAlignment) + memoffset;
113     uint8_t* xbuf = ALIGNP(xbuffer.get(), kAlignment) + memoffset;
114 
115     if (usefile) {
116       if (!LoadPlanarYuvTestImage("faces", iw, ih, ibuf) ||
117           !LoadPlanarYuvTestImage("faces", ow, oh, xbuf)) {
118         LOG(LS_ERROR) << "Failed to load image";
119         return false;
120       }
121     } else {
122       // These are used to test huge images.
123       memset(ibuf, 213, isize);  // Input is constant color.
124       memset(obuf, 100, osize);  // Output set to something wrong for now.
125       memset(xbuf, 213, osize);  // Expected result.
126     }
127 
128 #ifdef TEST_UNCACHED
129     FlushCache(ibuf, isize);
130     FlushCache(obuf, osize);
131     FlushCache(xbuf, osize);
132 #endif
133 
134     // Scale down.
135     // If cpu true, disable cpu optimizations.  Else allow auto detect
136     // TODO(fbarchard): set flags for libyuv
137     libyuv::MaskCpuFlags(cpuflags);
138 #ifdef TEST_RSTSC
139     uint64_t t = 0;
140 #endif
141     for (int i = 0; i < repeat_; ++i) {
142 #ifdef TEST_UNCACHED
143       FlushCache(ibuf, isize);
144       FlushCache(obuf, osize);
145 #endif
146 #ifdef TEST_RSTSC
147       uint64_t t1 = __rdtsc();
148 #endif
149       EXPECT_EQ(0, libyuv::ScaleOffset(ibuf, iw, ih, obuf, ow, oh,
150                                        offset, interpolate));
151 #ifdef TEST_RSTSC
152       uint64_t t2 = __rdtsc();
153       t += t2 - t1;
154 #endif
155     }
156 
157 #ifdef TEST_RSTSC
158     LOG(LS_INFO) << "Time: " << std::setw(9) << t;
159 #endif
160 
161     if (dump_) {
162       const testing::TestInfo* const test_info =
163           testing::UnitTest::GetInstance()->current_test_info();
164       std::string test_name(test_info->name());
165       DumpPlanarYuvTestImage(test_name, obuf, ow, oh);
166     }
167 
168     double sse = cricket::ComputeSumSquareError(obuf, xbuf, osize);
169     *error = sse / osize;  // Mean Squared Error.
170     double PSNR = cricket::ComputePSNR(sse, osize);
171     LOG(LS_INFO) << "Image MSE: " <<
172       std::setw(6) << std::setprecision(4) << *error <<
173       " Image PSNR: " << PSNR;
174     return true;
175   }
176 
177   // Returns the index of the first differing byte. Easier to debug than memcmp.
FindDiff(const uint8_t * buf1,const uint8_t * buf2,int len)178   static int FindDiff(const uint8_t* buf1, const uint8_t* buf2, int len) {
179     int i = 0;
180     while (i < len && buf1[i] == buf2[i]) {
181       i++;
182     }
183     return (i < len) ? i : -1;
184   }
185 
186  protected:
187   bool dump_;
188   int repeat_;
189 };
190 
191 // Tests straight copy of data.
TEST_F(YuvScalerTest,TestCopy)192 TEST_F(YuvScalerTest, TestCopy) {
193   const int iw = 640, ih = 360;
194   const int ow = 640, oh = 360;
195   ALIGN16(uint8_t ibuf[I420_SIZE(iw, ih)]);
196   ALIGN16(uint8_t obuf[I420_SIZE(ow, oh)]);
197 
198   // Load the frame, scale it, check it.
199   ASSERT_TRUE(LoadPlanarYuvTestImage("faces", iw, ih, ibuf));
200   for (int i = 0; i < repeat_; ++i) {
201     libyuv::ScaleOffset(ibuf, iw, ih, obuf, ow, oh, 0, false);
202   }
203   if (dump_) DumpPlanarYuvTestImage("TestCopy", obuf, ow, oh);
204   EXPECT_EQ(-1, FindDiff(obuf, ibuf, sizeof(ibuf)));
205 }
206 
207 // Tests copy from 4:3 to 16:9.
TEST_F(YuvScalerTest,TestOffset16_10Copy)208 TEST_F(YuvScalerTest, TestOffset16_10Copy) {
209   const int iw = 640, ih = 360;
210   const int ow = 640, oh = 480;
211   const int offset = (480 - 360) / 2;
212   scoped_ptr<uint8_t[]> ibuffer(new uint8_t[I420_SIZE(iw, ih) + kAlignment]);
213   scoped_ptr<uint8_t[]> obuffer(new uint8_t[I420_SIZE(ow, oh) + kAlignment]);
214 
215   uint8_t* ibuf = ALIGNP(ibuffer.get(), kAlignment);
216   uint8_t* obuf = ALIGNP(obuffer.get(), kAlignment);
217 
218   // Load the frame, scale it, check it.
219   ASSERT_TRUE(LoadPlanarYuvTestImage("faces", iw, ih, ibuf));
220 
221   // Clear to black, which is Y = 0 and U and V = 128
222   memset(obuf, 0, ow * oh);
223   memset(obuf + ow * oh, 128, ow * oh / 2);
224   for (int i = 0; i < repeat_; ++i) {
225     libyuv::ScaleOffset(ibuf, iw, ih, obuf, ow, oh, offset, false);
226   }
227   if (dump_) DumpPlanarYuvTestImage("TestOffsetCopy16_9", obuf, ow, oh);
228   EXPECT_EQ(-1, FindDiff(obuf + ow * offset,
229                          ibuf,
230                          iw * ih));
231   EXPECT_EQ(-1, FindDiff(obuf + ow * oh + ow * offset / 4,
232                          ibuf + iw * ih,
233                          iw * ih / 4));
234   EXPECT_EQ(-1, FindDiff(obuf + ow * oh * 5 / 4 + ow * offset / 4,
235                          ibuf + iw * ih * 5 / 4,
236                          iw * ih / 4));
237 }
238 
239 // The following are 'cpu' flag values:
240 // Allow all SIMD optimizations
241 #define ALLFLAGS -1
242 // Disable SSSE3 but allow other forms of SIMD (SSE2)
243 #define NOSSSE3 ~libyuv::kCpuHasSSSE3
244 // Disable SSE2 and SSSE3
245 #define NOSSE ~libyuv::kCpuHasSSE2 & ~libyuv::kCpuHasSSSE3
246 
247 // TEST_M scale factor with variations of opt, align, int
248 #define TEST_M(name, iwidth, iheight, owidth, oheight, mse) \
249 TEST_F(YuvScalerTest, name##Ref) { \
250   double error; \
251   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
252                         0, true, false, ALLFLAGS, false, 0, &error)); \
253   EXPECT_LE(error, mse); \
254 } \
255 TEST_F(YuvScalerTest, name##OptAligned) { \
256   double error; \
257   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
258                         0, true, true, ALLFLAGS, false, 0, &error)); \
259   EXPECT_LE(error, mse); \
260 } \
261 TEST_F(YuvScalerTest, name##OptUnaligned) { \
262   double error; \
263   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
264                         0, true, true, ALLFLAGS, false, 1, &error)); \
265   EXPECT_LE(error, mse); \
266 } \
267 TEST_F(YuvScalerTest, name##OptSSE2) { \
268   double error; \
269   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
270                         0, true, true, NOSSSE3, false, 0, &error)); \
271   EXPECT_LE(error, mse); \
272 } \
273 TEST_F(YuvScalerTest, name##OptC) { \
274   double error; \
275   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
276                         0, true, true, NOSSE, false, 0, &error)); \
277   EXPECT_LE(error, mse); \
278 } \
279 TEST_F(YuvScalerTest, name##IntRef) { \
280   double error; \
281   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
282                         0, true, false, ALLFLAGS, true, 0, &error)); \
283   EXPECT_LE(error, mse); \
284 } \
285 TEST_F(YuvScalerTest, name##IntOptAligned) { \
286   double error; \
287   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
288                         0, true, true, ALLFLAGS, true, 0, &error)); \
289   EXPECT_LE(error, mse); \
290 } \
291 TEST_F(YuvScalerTest, name##IntOptUnaligned) { \
292   double error; \
293   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
294                         0, true, true, ALLFLAGS, true, 1, &error)); \
295   EXPECT_LE(error, mse); \
296 } \
297 TEST_F(YuvScalerTest, name##IntOptSSE2) { \
298   double error; \
299   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
300                         0, true, true, NOSSSE3, true, 0, &error)); \
301   EXPECT_LE(error, mse); \
302 } \
303 TEST_F(YuvScalerTest, name##IntOptC) { \
304   double error; \
305   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
306                         0, true, true, NOSSE, true, 0, &error)); \
307   EXPECT_LE(error, mse); \
308 }
309 
310 #define TEST_H(name, iwidth, iheight, owidth, oheight, opt, cpu, intr, mse) \
311 TEST_F(YuvScalerTest, name) { \
312   double error; \
313   EXPECT_TRUE(TestScale(iwidth, iheight, owidth, oheight, \
314                         0, false, opt, cpu, intr, 0, &error)); \
315   EXPECT_LE(error, mse); \
316 }
317 
318 // Test 4x3 aspect ratio scaling
319 
320 // Tests 1/1x scale down.
321 TEST_M(TestScale4by3Down11, 640, 480, 640, 480, 0)
322 
323 // Tests 3/4x scale down.
324 TEST_M(TestScale4by3Down34, 640, 480, 480, 360, 60)
325 
326 // Tests 1/2x scale down.
327 TEST_M(TestScale4by3Down12, 640, 480, 320, 240, 60)
328 
329 // Tests 3/8x scale down.
330 TEST_M(TestScale4by3Down38, 640, 480, 240, 180, 60)
331 
332 // Tests 1/4x scale down..
333 TEST_M(TestScale4by3Down14, 640, 480, 160, 120, 60)
334 
335 // Tests 3/16x scale down.
336 TEST_M(TestScale4by3Down316, 640, 480, 120, 90, 120)
337 
338 // Tests 1/8x scale down.
339 TEST_M(TestScale4by3Down18, 640, 480, 80, 60, 150)
340 
341 // Tests 2/3x scale down.
342 TEST_M(TestScale4by3Down23, 480, 360, 320, 240, 60)
343 
344 // Tests 4/3x scale up.
345 TEST_M(TestScale4by3Up43, 480, 360, 640, 480, 60)
346 
347 // Tests 2/1x scale up.
348 TEST_M(TestScale4by3Up21, 320, 240, 640, 480, 60)
349 
350 // Tests 4/1x scale up.
351 TEST_M(TestScale4by3Up41, 160, 120, 640, 480, 80)
352 
353 // Test 16x10 aspect ratio scaling
354 
355 // Tests 1/1x scale down.
356 TEST_M(TestScale16by10Down11, 640, 400, 640, 400, 0)
357 
358 // Tests 3/4x scale down.
359 TEST_M(TestScale16by10Down34, 640, 400, 480, 300, 60)
360 
361 // Tests 1/2x scale down.
362 TEST_M(TestScale16by10Down12, 640, 400, 320, 200, 60)
363 
364 // Tests 3/8x scale down.
365 TEST_M(TestScale16by10Down38, 640, 400, 240, 150, 60)
366 
367 // Tests 1/4x scale down..
368 TEST_M(TestScale16by10Down14, 640, 400, 160, 100, 60)
369 
370 // Tests 3/16x scale down.
371 TEST_M(TestScale16by10Down316, 640, 400, 120, 75, 120)
372 
373 // Tests 1/8x scale down.
374 TEST_M(TestScale16by10Down18, 640, 400, 80, 50, 150)
375 
376 // Tests 2/3x scale down.
377 TEST_M(TestScale16by10Down23, 480, 300, 320, 200, 60)
378 
379 // Tests 4/3x scale up.
380 TEST_M(TestScale16by10Up43, 480, 300, 640, 400, 60)
381 
382 // Tests 2/1x scale up.
383 TEST_M(TestScale16by10Up21, 320, 200, 640, 400, 60)
384 
385 // Tests 4/1x scale up.
386 TEST_M(TestScale16by10Up41, 160, 100, 640, 400, 80)
387 
388 // Test 16x9 aspect ratio scaling
389 
390 // Tests 1/1x scale down.
391 TEST_M(TestScaleDown11, 640, 360, 640, 360, 0)
392 
393 // Tests 3/4x scale down.
394 TEST_M(TestScaleDown34, 640, 360, 480, 270, 60)
395 
396 // Tests 1/2x scale down.
397 TEST_M(TestScaleDown12, 640, 360, 320, 180, 60)
398 
399 // Tests 3/8x scale down.
400 TEST_M(TestScaleDown38, 640, 360, 240, 135, 60)
401 
402 // Tests 1/4x scale down..
403 TEST_M(TestScaleDown14, 640, 360, 160, 90, 60)
404 
405 // Tests 3/16x scale down.
406 TEST_M(TestScaleDown316, 640, 360, 120, 68, 120)
407 
408 // Tests 1/8x scale down.
409 TEST_M(TestScaleDown18, 640, 360, 80, 45, 150)
410 
411 // Tests 2/3x scale down.
412 TEST_M(TestScaleDown23, 480, 270, 320, 180, 60)
413 
414 // Tests 4/3x scale up.
415 TEST_M(TestScaleUp43, 480, 270, 640, 360, 60)
416 
417 // Tests 2/1x scale up.
418 TEST_M(TestScaleUp21, 320, 180, 640, 360, 60)
419 
420 // Tests 4/1x scale up.
421 TEST_M(TestScaleUp41, 160, 90, 640, 360, 80)
422 
423 // Test HD 4x3 aspect ratio scaling
424 
425 // Tests 1/1x scale down.
426 TEST_M(TestScaleHD4x3Down11, 1280, 960, 1280, 960, 0)
427 
428 // Tests 3/4x scale down.
429 TEST_M(TestScaleHD4x3Down34, 1280, 960, 960, 720, 60)
430 
431 // Tests 1/2x scale down.
432 TEST_M(TestScaleHD4x3Down12, 1280, 960, 640, 480, 60)
433 
434 // Tests 3/8x scale down.
435 TEST_M(TestScaleHD4x3Down38, 1280, 960, 480, 360, 60)
436 
437 // Tests 1/4x scale down..
438 TEST_M(TestScaleHD4x3Down14, 1280, 960, 320, 240, 60)
439 
440 // Tests 3/16x scale down.
441 TEST_M(TestScaleHD4x3Down316, 1280, 960, 240, 180, 120)
442 
443 // Tests 1/8x scale down.
444 TEST_M(TestScaleHD4x3Down18, 1280, 960, 160, 120, 150)
445 
446 // Tests 2/3x scale down.
447 TEST_M(TestScaleHD4x3Down23, 960, 720, 640, 480, 60)
448 
449 // Tests 4/3x scale up.
450 TEST_M(TestScaleHD4x3Up43, 960, 720, 1280, 960, 60)
451 
452 // Tests 2/1x scale up.
453 TEST_M(TestScaleHD4x3Up21, 640, 480, 1280, 960, 60)
454 
455 // Tests 4/1x scale up.
456 TEST_M(TestScaleHD4x3Up41, 320, 240, 1280, 960, 80)
457 
458 // Test HD 16x10 aspect ratio scaling
459 
460 // Tests 1/1x scale down.
461 TEST_M(TestScaleHD16x10Down11, 1280, 800, 1280, 800, 0)
462 
463 // Tests 3/4x scale down.
464 TEST_M(TestScaleHD16x10Down34, 1280, 800, 960, 600, 60)
465 
466 // Tests 1/2x scale down.
467 TEST_M(TestScaleHD16x10Down12, 1280, 800, 640, 400, 60)
468 
469 // Tests 3/8x scale down.
470 TEST_M(TestScaleHD16x10Down38, 1280, 800, 480, 300, 60)
471 
472 // Tests 1/4x scale down..
473 TEST_M(TestScaleHD16x10Down14, 1280, 800, 320, 200, 60)
474 
475 // Tests 3/16x scale down.
476 TEST_M(TestScaleHD16x10Down316, 1280, 800, 240, 150, 120)
477 
478 // Tests 1/8x scale down.
479 TEST_M(TestScaleHD16x10Down18, 1280, 800, 160, 100, 150)
480 
481 // Tests 2/3x scale down.
482 TEST_M(TestScaleHD16x10Down23, 960, 600, 640, 400, 60)
483 
484 // Tests 4/3x scale up.
485 TEST_M(TestScaleHD16x10Up43, 960, 600, 1280, 800, 60)
486 
487 // Tests 2/1x scale up.
488 TEST_M(TestScaleHD16x10Up21, 640, 400, 1280, 800, 60)
489 
490 // Tests 4/1x scale up.
491 TEST_M(TestScaleHD16x10Up41, 320, 200, 1280, 800, 80)
492 
493 // Test HD 16x9 aspect ratio scaling
494 
495 // Tests 1/1x scale down.
496 TEST_M(TestScaleHDDown11, 1280, 720, 1280, 720, 0)
497 
498 // Tests 3/4x scale down.
499 TEST_M(TestScaleHDDown34, 1280, 720, 960, 540, 60)
500 
501 // Tests 1/2x scale down.
502 TEST_M(TestScaleHDDown12, 1280, 720, 640, 360, 60)
503 
504 // Tests 3/8x scale down.
505 TEST_M(TestScaleHDDown38, 1280, 720, 480, 270, 60)
506 
507 // Tests 1/4x scale down..
508 TEST_M(TestScaleHDDown14, 1280, 720, 320, 180, 60)
509 
510 // Tests 3/16x scale down.
511 TEST_M(TestScaleHDDown316, 1280, 720, 240, 135, 120)
512 
513 // Tests 1/8x scale down.
514 TEST_M(TestScaleHDDown18, 1280, 720, 160, 90, 150)
515 
516 // Tests 2/3x scale down.
517 TEST_M(TestScaleHDDown23, 960, 540, 640, 360, 60)
518 
519 // Tests 4/3x scale up.
520 TEST_M(TestScaleHDUp43, 960, 540, 1280, 720, 60)
521 
522 // Tests 2/1x scale up.
523 TEST_M(TestScaleHDUp21, 640, 360, 1280, 720, 60)
524 
525 // Tests 4/1x scale up.
526 TEST_M(TestScaleHDUp41, 320, 180, 1280, 720, 80)
527 
528 // Tests 1366x768 resolution for comparison to chromium scaler_bench
529 TEST_M(TestScaleHDUp1366, 1280, 720, 1366, 768, 10)
530 
531 // Tests odd source/dest sizes.  3 less to make chroma odd as well.
532 TEST_M(TestScaleHDUp1363, 1277, 717, 1363, 765, 10)
533 
534 // Tests 1/2x scale down, using optimized algorithm.
535 TEST_M(TestScaleOddDown12, 180, 100, 90, 50, 50)
536 
537 // Tests bilinear scale down
538 TEST_M(TestScaleOddDownBilin, 160, 100, 90, 50, 120)
539 
540 // Test huge buffer scales that are expected to use a different code path
541 // that avoids stack overflow but still work using point sampling.
542 // Max output size is 640 wide.
543 
544 // Tests interpolated 1/8x scale down, using optimized algorithm.
545 TEST_H(TestScaleDown18HDOptInt, 6144, 48, 768, 6, true, ALLFLAGS, true, 1)
546 
547 // Tests interpolated 1/8x scale down, using c_only optimized algorithm.
548 TEST_H(TestScaleDown18HDCOnlyOptInt, 6144, 48, 768, 6, true, NOSSE, true, 1)
549 
550 // Tests interpolated 3/8x scale down, using optimized algorithm.
551 TEST_H(TestScaleDown38HDOptInt, 2048, 16, 768, 6, true, ALLFLAGS, true, 1)
552 
553 // Tests interpolated 3/8x scale down, using no SSSE3 optimized algorithm.
554 TEST_H(TestScaleDown38HDNoSSSE3OptInt, 2048, 16, 768, 6, true, NOSSSE3, true, 1)
555 
556 // Tests interpolated 3/8x scale down, using c_only optimized algorithm.
557 TEST_H(TestScaleDown38HDCOnlyOptInt, 2048, 16, 768, 6, true, NOSSE, true, 1)
558 
559 // Tests interpolated 3/16x scale down, using optimized algorithm.
560 TEST_H(TestScaleDown316HDOptInt, 4096, 32, 768, 6, true, ALLFLAGS, true, 1)
561 
562 // Tests interpolated 3/16x scale down, using no SSSE3 optimized algorithm.
563 TEST_H(TestScaleDown316HDNoSSSE3OptInt, 4096, 32, 768, 6, true, NOSSSE3, true,
564        1)
565 
566 // Tests interpolated 3/16x scale down, using c_only optimized algorithm.
567 TEST_H(TestScaleDown316HDCOnlyOptInt, 4096, 32, 768, 6, true, NOSSE, true, 1)
568 
569 // Test special sizes dont crash
570 // Tests scaling down to 1 pixel width
571 TEST_H(TestScaleDown1x6OptInt, 3, 24, 1, 6, true, ALLFLAGS, true, 4)
572 
573 // Tests scaling down to 1 pixel height
574 TEST_H(TestScaleDown6x1OptInt, 24, 3, 6, 1, true, ALLFLAGS, true, 4)
575 
576 // Tests scaling up from 1 pixel width
577 TEST_H(TestScaleUp1x6OptInt, 1, 6, 3, 24, true, ALLFLAGS, true, 4)
578 
579 // Tests scaling up from 1 pixel height
580 TEST_H(TestScaleUp6x1OptInt, 6, 1, 24, 3, true, ALLFLAGS, true, 4)
581 
582 // Test performance of a range of box filter scale sizes
583 
584 // Tests interpolated 1/2x scale down, using optimized algorithm.
585 TEST_H(TestScaleDown2xHDOptInt, 1280, 720, 1280 / 2, 720 / 2, true, ALLFLAGS,
586        true, 1)
587 
588 // Tests interpolated 1/3x scale down, using optimized algorithm.
589 TEST_H(TestScaleDown3xHDOptInt, 1280, 720, 1280 / 3, 720 / 3, true, ALLFLAGS,
590        true, 1)
591 
592 // Tests interpolated 1/4x scale down, using optimized algorithm.
593 TEST_H(TestScaleDown4xHDOptInt, 1280, 720, 1280 / 4, 720 / 4, true, ALLFLAGS,
594        true, 1)
595 
596 // Tests interpolated 1/5x scale down, using optimized algorithm.
597 TEST_H(TestScaleDown5xHDOptInt, 1280, 720, 1280 / 5, 720 / 5, true, ALLFLAGS,
598        true, 1)
599 
600 // Tests interpolated 1/6x scale down, using optimized algorithm.
601 TEST_H(TestScaleDown6xHDOptInt, 1280, 720, 1280 / 6, 720 / 6, true, ALLFLAGS,
602        true, 1)
603 
604 // Tests interpolated 1/7x scale down, using optimized algorithm.
605 TEST_H(TestScaleDown7xHDOptInt, 1280, 720, 1280 / 7, 720 / 7, true, ALLFLAGS,
606        true, 1)
607 
608 // Tests interpolated 1/8x scale down, using optimized algorithm.
609 TEST_H(TestScaleDown8xHDOptInt, 1280, 720, 1280 / 8, 720 / 8, true, ALLFLAGS,
610        true, 1)
611 
612 // Tests interpolated 1/8x scale down, using optimized algorithm.
613 TEST_H(TestScaleDown9xHDOptInt, 1280, 720, 1280 / 9, 720 / 9, true, ALLFLAGS,
614        true, 1)
615 
616 // Tests interpolated 1/8x scale down, using optimized algorithm.
617 TEST_H(TestScaleDown10xHDOptInt, 1280, 720, 1280 / 10, 720 / 10, true, ALLFLAGS,
618        true, 1)
619