From e36239949bdf906e41a94e5897645642140cfbd7 Mon Sep 17 00:00:00 2001 From: "rileya@chromium.org" Date: Mon, 28 Apr 2014 08:55:09 +0000 Subject: 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 --- media/base/yuv_convert_perftest.cc | 220 +++++++++++++++++++++++++++++++++++++ media/media.gyp | 1 + 2 files changed, 221 insertions(+) create mode 100644 media/base/yuv_convert_perftest.cc (limited to 'media') 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(yuv_bytes_.get()), kYUV12Size); + + CHECK_EQ(bytes_read, kYUV12Size); + } + + scoped_ptr yuv_bytes_; + scoped_ptr 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', ], -- cgit v1.1