diff options
author | rileya@chromium.org <rileya@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-28 08:55:09 +0000 |
---|---|---|
committer | rileya@chromium.org <rileya@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-28 08:55:09 +0000 |
commit | e36239949bdf906e41a94e5897645642140cfbd7 (patch) | |
tree | b30a60bbfbea2c40b929b7a457addd70396704fa /media | |
parent | 1c10f90f9ee8ed93a2f46395787fc329ec822e1c (diff) | |
download | chromium_src-e36239949bdf906e41a94e5897645642140cfbd7.zip chromium_src-e36239949bdf906e41a94e5897645642140cfbd7.tar.gz chromium_src-e36239949bdf906e41a94e5897645642140cfbd7.tar.bz2 |
Add perf tests for simd yuv->rgb conversion functions.
BUG=172898
Review URL: https://codereview.chromium.org/238353008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266490 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/yuv_convert_perftest.cc | 220 | ||||
-rw-r--r-- | media/media.gyp | 1 |
2 files changed, 221 insertions, 0 deletions
diff --git a/media/base/yuv_convert_perftest.cc b/media/base/yuv_convert_perftest.cc new file mode 100644 index 0000000..df1c334 --- /dev/null +++ b/media/base/yuv_convert_perftest.cc @@ -0,0 +1,220 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/base_paths.h" +#include "base/cpu.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/time/time.h" +#include "media/base/simd/convert_yuv_to_rgb.h" +#include "media/base/yuv_convert.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/perf/perf_test.h" + +namespace media { +#if !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY) +// Size of raw image. +static const int kSourceWidth = 640; +static const int kSourceHeight = 360; +static const int kSourceYSize = kSourceWidth * kSourceHeight; +static const int kSourceUOffset = kSourceYSize; +static const int kSourceVOffset = kSourceYSize * 5 / 4; +static const int kBpp = 4; + +// Width of the row to convert. Odd so that we exercise the ending +// one-pixel-leftover case. +static const int kWidth = 639; + +// Surface sizes for various test files. +static const int kYUV12Size = kSourceYSize * 12 / 8; +static const int kRGBSize = kSourceYSize * kBpp; + +static const int kPerfTestIterations = 2000; + +class YUVConvertPerfTest : public testing::Test { + public: + YUVConvertPerfTest() + : yuv_bytes_(new uint8[kYUV12Size]), + rgb_bytes_converted_(new uint8[kRGBSize]) { + base::FilePath path; + CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &path)); + path = path.Append(FILE_PATH_LITERAL("media")) + .Append(FILE_PATH_LITERAL("test")) + .Append(FILE_PATH_LITERAL("data")) + .Append("bali_640x360_P420.yuv"); + + // Verify file size is correct. + int64 actual_size = 0; + base::GetFileSize(path, &actual_size); + CHECK_EQ(actual_size, kYUV12Size); + + // Verify bytes read are correct. + int bytes_read = base::ReadFile( + path, reinterpret_cast<char*>(yuv_bytes_.get()), kYUV12Size); + + CHECK_EQ(bytes_read, kYUV12Size); + } + + scoped_ptr<uint8[]> yuv_bytes_; + scoped_ptr<uint8[]> rgb_bytes_converted_; + + private: + DISALLOW_COPY_AND_ASSIGN(YUVConvertPerfTest); +}; + +TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_MMX) { + ASSERT_TRUE(base::CPU().has_mmx()); + + base::TimeTicks start = base::TimeTicks::HighResNow(); + for (int i = 0; i < kPerfTestIterations; ++i) { + for (int row = 0; row < kSourceHeight; ++row) { + int chroma_row = row / 2; + ConvertYUVToRGB32Row_MMX( + yuv_bytes_.get() + row * kSourceWidth, + yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), + yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), + rgb_bytes_converted_.get(), + kWidth); + } + } + double total_time_seconds = + (base::TimeTicks::HighResNow() - start).InSecondsF(); + perf_test::PrintResult( + "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_MMX", + kPerfTestIterations / total_time_seconds, "runs/s", true); + + media::EmptyRegisterState(); +} + +TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_SSE) { + ASSERT_TRUE(base::CPU().has_sse()); + + base::TimeTicks start = base::TimeTicks::HighResNow(); + for (int i = 0; i < kPerfTestIterations; ++i) { + for (int row = 0; row < kSourceHeight; ++row) { + int chroma_row = row / 2; + ConvertYUVToRGB32Row_SSE( + yuv_bytes_.get() + row * kSourceWidth, + yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), + yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), + rgb_bytes_converted_.get(), + kWidth); + } + } + double total_time_seconds = + (base::TimeTicks::HighResNow() - start).InSecondsF(); + perf_test::PrintResult( + "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_SSE", + kPerfTestIterations / total_time_seconds, "runs/s", true); + media::EmptyRegisterState(); +} + +TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_MMX) { + ASSERT_TRUE(base::CPU().has_mmx()); + + const int kSourceDx = 80000; // This value means a scale down. + + base::TimeTicks start = base::TimeTicks::HighResNow(); + for (int i = 0; i < kPerfTestIterations; ++i) { + for (int row = 0; row < kSourceHeight; ++row) { + int chroma_row = row / 2; + ScaleYUVToRGB32Row_MMX( + yuv_bytes_.get() + row * kSourceWidth, + yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), + yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), + rgb_bytes_converted_.get(), + kWidth, + kSourceDx); + } + } + double total_time_seconds = + (base::TimeTicks::HighResNow() - start).InSecondsF(); + perf_test::PrintResult( + "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_MMX", + kPerfTestIterations / total_time_seconds, "runs/s", true); + media::EmptyRegisterState(); +} + +TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_SSE) { + ASSERT_TRUE(base::CPU().has_sse()); + + const int kSourceDx = 80000; // This value means a scale down. + + base::TimeTicks start = base::TimeTicks::HighResNow(); + for (int i = 0; i < kPerfTestIterations; ++i) { + for (int row = 0; row < kSourceHeight; ++row) { + int chroma_row = row / 2; + ScaleYUVToRGB32Row_SSE( + yuv_bytes_.get() + row * kSourceWidth, + yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), + yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), + rgb_bytes_converted_.get(), + kWidth, + kSourceDx); + } + } + double total_time_seconds = + (base::TimeTicks::HighResNow() - start).InSecondsF(); + perf_test::PrintResult( + "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_SSE", + kPerfTestIterations / total_time_seconds, "runs/s", true); + media::EmptyRegisterState(); +} + +TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_MMX) { + ASSERT_TRUE(base::CPU().has_mmx()); + + const int kSourceDx = 80000; // This value means a scale down. + + base::TimeTicks start = base::TimeTicks::HighResNow(); + for (int i = 0; i < kPerfTestIterations; ++i) { + for (int row = 0; row < kSourceHeight; ++row) { + int chroma_row = row / 2; + LinearScaleYUVToRGB32Row_MMX( + yuv_bytes_.get() + row * kSourceWidth, + yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), + yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), + rgb_bytes_converted_.get(), + kWidth, + kSourceDx); + } + } + double total_time_seconds = + (base::TimeTicks::HighResNow() - start).InSecondsF(); + perf_test::PrintResult( + "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_MMX", + kPerfTestIterations / total_time_seconds, "runs/s", true); + media::EmptyRegisterState(); +} + +TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_SSE) { + ASSERT_TRUE(base::CPU().has_sse()); + + const int kSourceDx = 80000; // This value means a scale down. + + base::TimeTicks start = base::TimeTicks::HighResNow(); + for (int i = 0; i < kPerfTestIterations; ++i) { + for (int row = 0; row < kSourceHeight; ++row) { + int chroma_row = row / 2; + LinearScaleYUVToRGB32Row_SSE( + yuv_bytes_.get() + row * kSourceWidth, + yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), + yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), + rgb_bytes_converted_.get(), + kWidth, + kSourceDx); + } + } + double total_time_seconds = + (base::TimeTicks::HighResNow() - start).InSecondsF(); + perf_test::PrintResult( + "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_SSE", + kPerfTestIterations / total_time_seconds, "runs/s", true); + media::EmptyRegisterState(); +} + +#endif // !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY) + +} // namespace media diff --git a/media/media.gyp b/media/media.gyp index c0a4aa4..b8e5773 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -1200,6 +1200,7 @@ 'base/run_all_perftests.cc', 'base/sinc_resampler_perftest.cc', 'base/vector_math_perftest.cc', + 'base/yuv_convert_perftest.cc', 'filters/pipeline_integration_perftest.cc', 'filters/pipeline_integration_test_base.cc', ], |