diff options
Diffstat (limited to 'chromium/media/base/yuv_convert_perftest.cc')
-rw-r--r-- | chromium/media/base/yuv_convert_perftest.cc | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/chromium/media/base/yuv_convert_perftest.cc b/chromium/media/base/yuv_convert_perftest.cc new file mode 100644 index 00000000000..0f30bebec8b --- /dev/null +++ b/chromium/media/base/yuv_convert_perftest.cc @@ -0,0 +1,226 @@ +// 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(FILE_PATH_LITERAL("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, + GetLookupTable(YV12)); + } + } + 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, + GetLookupTable(YV12)); + } + } + 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, + GetLookupTable(YV12)); + } + } + 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, + GetLookupTable(YV12)); + } + } + 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, + GetLookupTable(YV12)); + } + } + 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, + GetLookupTable(YV12)); + } + } + 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 |